@agent-native/core 0.198.2 → 0.198.3-nightly-20260930154911
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/catalog.json +1 -1
- package/dist/cli/create-tui.js +31 -9
- package/dist/cli/design-connect.js +10 -2
- package/dist/client/chat/agentkit-protocol.js +4 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/workspace-deploy.js +18 -5
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/framework-tools.js +2 -0
- package/dist/localization/core-messages/supplemental/ar-SA.js +2 -0
- package/dist/localization/core-messages/supplemental/de-DE.js +2 -0
- package/dist/localization/core-messages/supplemental/en-US.js +2 -0
- package/dist/localization/core-messages/supplemental/es-ES.js +2 -0
- package/dist/localization/core-messages/supplemental/fr-FR.js +2 -0
- package/dist/localization/core-messages/supplemental/hi-IN.js +2 -0
- package/dist/localization/core-messages/supplemental/ja-JP.js +2 -0
- package/dist/localization/core-messages/supplemental/ko-KR.js +2 -0
- package/dist/localization/core-messages/supplemental/pt-BR.js +2 -0
- package/dist/localization/core-messages/supplemental/zh-CN.js +2 -0
- package/dist/localization/core-messages/supplemental/zh-TW.js +2 -0
- package/dist/localization/mcp-settings-messages.d.ts +2 -0
- package/dist/mcp/connect-route.js +57 -10
- package/dist/mcp/oauth-route.js +4 -21
- package/dist/mcp/org-choice.d.ts +26 -0
- package/dist/mcp/org-choice.js +36 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/org/handlers.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +3 -3
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/agent-engine-default-model-route.d.ts +2 -2
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/dist/server/credential-provider.js +5 -0
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/usage/actions/get-usage-insights.d.ts +7 -0
- package/dist/usage/actions/get-usage-insights.js +23 -0
- package/dist/usage/actions/get-usage-run.d.ts +7 -0
- package/dist/usage/actions/get-usage-run.js +23 -0
- package/dist/usage/insights-store.d.ts +127 -0
- package/dist/usage/insights-store.js +462 -0
- package/dist/usage/metrics-store.d.ts +21 -0
- package/dist/usage/metrics-store.js +67 -3
- package/dist/vite/action-types-plugin.js +8 -0
- package/package.json +6 -4
package/dist/catalog.json
CHANGED
package/dist/cli/create-tui.js
CHANGED
|
@@ -253,18 +253,37 @@ function fitRows(items, activeIndex, rows) {
|
|
|
253
253
|
const start = Math.max(0, Math.min(activeIndex - rows + 1, items.length - rows));
|
|
254
254
|
return items.slice(start, start + rows);
|
|
255
255
|
}
|
|
256
|
+
// Ink hands every key in one stdin chunk to the same input handler before
|
|
257
|
+
// React re-renders, so an input handler must read `latest` and update through
|
|
258
|
+
// the setter: the rendered value is stale from the chunk's second key on.
|
|
259
|
+
function useKeypressState(initial) {
|
|
260
|
+
const [rendered, setRendered] = React.useState(initial);
|
|
261
|
+
const latest = React.useRef(rendered);
|
|
262
|
+
const update = (next) => {
|
|
263
|
+
latest.current = next(latest.current);
|
|
264
|
+
setRendered(latest.current);
|
|
265
|
+
};
|
|
266
|
+
return [rendered, update, latest];
|
|
267
|
+
}
|
|
268
|
+
function wizardChoices(state, installedApps) {
|
|
269
|
+
const apps = availableTemplates(state.kind, installedApps);
|
|
270
|
+
const choices = state.step === "start" ? START_CHOICES : apps;
|
|
271
|
+
return {
|
|
272
|
+
multiSelect: state.kind === "chat-workspace" ||
|
|
273
|
+
state.kind === "first-party" ||
|
|
274
|
+
state.kind === "workspace-add",
|
|
275
|
+
apps,
|
|
276
|
+
required: new Set(requiredTemplateNames(state.kind)),
|
|
277
|
+
choices,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
256
280
|
export function CreateWizard({ options, onFinish, }) {
|
|
257
281
|
const { exit } = useApp();
|
|
258
282
|
const { stdout } = useStdout();
|
|
259
|
-
const [state, setState] =
|
|
283
|
+
const [state, setState, latest] = useKeypressState(() => initialWizardState(options));
|
|
260
284
|
const terminalColumns = Math.max(16, stdout.columns ?? 80);
|
|
261
285
|
const terminalRows = Math.max(14, stdout.rows ?? 24);
|
|
262
|
-
const multiSelect = state.
|
|
263
|
-
state.kind === "first-party" ||
|
|
264
|
-
state.kind === "workspace-add";
|
|
265
|
-
const apps = availableTemplates(state.kind, options.installedApps ?? []);
|
|
266
|
-
const required = new Set(requiredTemplateNames(state.kind));
|
|
267
|
-
const choices = state.step === "start" ? START_CHOICES : apps;
|
|
286
|
+
const { multiSelect, required, choices } = wizardChoices(state, options.installedApps ?? []);
|
|
268
287
|
const listRows = Math.max(3, Math.min(choices.length, Math.floor((terminalRows - 13) / 2)));
|
|
269
288
|
const visibleChoices = fitRows(choices, state.activeIndex, listRows);
|
|
270
289
|
const visibleOffset = Math.max(0, choices.indexOf(visibleChoices[0]));
|
|
@@ -280,6 +299,7 @@ export function CreateWizard({ options, onFinish, }) {
|
|
|
280
299
|
exit();
|
|
281
300
|
};
|
|
282
301
|
const complete = () => {
|
|
302
|
+
const state = latest.current;
|
|
283
303
|
const answer = {
|
|
284
304
|
kind: state.kind ?? "chat-workspace",
|
|
285
305
|
name: state.name,
|
|
@@ -291,6 +311,8 @@ export function CreateWizard({ options, onFinish, }) {
|
|
|
291
311
|
exit();
|
|
292
312
|
};
|
|
293
313
|
useInput((input, key) => {
|
|
314
|
+
const state = latest.current;
|
|
315
|
+
const { multiSelect, apps, required, choices } = wizardChoices(state, options.installedApps ?? []);
|
|
294
316
|
if (state.step === "cancelled")
|
|
295
317
|
return;
|
|
296
318
|
if ((key.ctrl && input.toLowerCase() === "c") || key.escape) {
|
|
@@ -569,7 +591,7 @@ export async function runCreateWizard(options) {
|
|
|
569
591
|
}
|
|
570
592
|
function InkChoicePrompt({ message, choices, onFinish, }) {
|
|
571
593
|
const { exit } = useApp();
|
|
572
|
-
const [activeIndex, setActiveIndex] =
|
|
594
|
+
const [activeIndex, setActiveIndex, latestIndex] = useKeypressState(() => 0);
|
|
573
595
|
useInput((input, key) => {
|
|
574
596
|
if (key.escape || (key.ctrl && input.toLowerCase() === "c")) {
|
|
575
597
|
onFinish(null);
|
|
@@ -581,7 +603,7 @@ function InkChoicePrompt({ message, choices, onFinish, }) {
|
|
|
581
603
|
else if (key.downArrow)
|
|
582
604
|
setActiveIndex((index) => Math.min(choices.length - 1, index + 1));
|
|
583
605
|
else if (key.return) {
|
|
584
|
-
onFinish(choices[
|
|
606
|
+
onFinish(choices[latestIndex.current]?.value ?? null);
|
|
585
607
|
exit();
|
|
586
608
|
}
|
|
587
609
|
});
|
|
@@ -645,6 +645,13 @@ function isLoopbackOrigin(parsed) {
|
|
|
645
645
|
hostname === "::1" ||
|
|
646
646
|
/^127(?:\.\d{1,3}){3}$/.test(hostname));
|
|
647
647
|
}
|
|
648
|
+
function sameDevServerOrigin(a, b) {
|
|
649
|
+
return (a.origin === b.origin ||
|
|
650
|
+
(a.protocol === b.protocol &&
|
|
651
|
+
a.port === b.port &&
|
|
652
|
+
isLoopbackOrigin(a) &&
|
|
653
|
+
isLoopbackOrigin(b)));
|
|
654
|
+
}
|
|
648
655
|
function isApprovedDesignOrigin(rawOrigin, configuredOrigins, opaquePreviewAuthorized = false) {
|
|
649
656
|
// Sandboxed loopback preview documents have an opaque `null` origin. It is
|
|
650
657
|
// only approved when this request carries the non-cookie preview token;
|
|
@@ -976,16 +983,17 @@ class PreviewSessionCookieJar {
|
|
|
976
983
|
}
|
|
977
984
|
function resolvePreviewSnapshotUrl(devServerUrl, rawUrl) {
|
|
978
985
|
const base = normalizeHttpUrl(devServerUrl);
|
|
986
|
+
const baseUrl = new URL(base);
|
|
979
987
|
const parsed = new URL(rawUrl?.trim() || "/", `${base}/`);
|
|
980
988
|
parsed.hash = "";
|
|
981
989
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
982
990
|
throw new Error("Snapshot URL must use http(s).");
|
|
983
991
|
}
|
|
984
|
-
if (!
|
|
992
|
+
if (!sameDevServerOrigin(parsed, baseUrl)) {
|
|
985
993
|
throw new Error("Snapshot URL must stay on the connected dev server.");
|
|
986
994
|
}
|
|
987
995
|
const search = stripQueryPair(parsed.search, FRAME_BRIDGE_KEY_PARAM);
|
|
988
|
-
return `${
|
|
996
|
+
return `${baseUrl.origin}${parsed.pathname}${search}`;
|
|
989
997
|
}
|
|
990
998
|
function stripPreviewTokenQueryParam(search) {
|
|
991
999
|
if (!search.includes("previewToken"))
|
|
@@ -1528,7 +1528,10 @@ export function createAgentKitProtocolAdapter(runtime, options = {}) {
|
|
|
1528
1528
|
{
|
|
1529
1529
|
type: "suggestions.updated",
|
|
1530
1530
|
...base,
|
|
1531
|
-
suggestions: event.suggestions
|
|
1531
|
+
suggestions: event.suggestions.map((suggestion) => ({
|
|
1532
|
+
...suggestion,
|
|
1533
|
+
runId: run.runId,
|
|
1534
|
+
})),
|
|
1532
1535
|
},
|
|
1533
1536
|
];
|
|
1534
1537
|
case "annotation": {
|
|
@@ -38,19 +38,19 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
38
38
|
error: string;
|
|
39
39
|
states?: undefined;
|
|
40
40
|
} | {
|
|
41
|
+
error?: undefined;
|
|
41
42
|
states: {
|
|
42
43
|
clientId: number;
|
|
43
44
|
state: string;
|
|
44
45
|
}[];
|
|
45
|
-
error?: undefined;
|
|
46
46
|
}>>;
|
|
47
47
|
export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
48
48
|
error: string;
|
|
49
49
|
users?: undefined;
|
|
50
50
|
} | {
|
|
51
|
+
error?: undefined;
|
|
51
52
|
users: {
|
|
52
53
|
clientId: number;
|
|
53
54
|
lastSeen: number;
|
|
54
55
|
}[];
|
|
55
|
-
error?: undefined;
|
|
56
56
|
}>>;
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
8
8
|
state: string;
|
|
9
9
|
}>>;
|
|
10
10
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
11
|
-
error: string;
|
|
12
11
|
ok?: undefined;
|
|
12
|
+
error: string;
|
|
13
13
|
} | {
|
|
14
14
|
error?: undefined;
|
|
15
15
|
ok: boolean;
|
|
@@ -18,6 +18,12 @@ import { collectImmutableAssetPaths, IMMUTABLE_ASSET_CACHE_HEADERS, } from "./im
|
|
|
18
18
|
function workspaceFrameworkRoutePrefixEnv() {
|
|
19
19
|
return (process.env.AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX?.trim() || "");
|
|
20
20
|
}
|
|
21
|
+
function workspaceFrameworkRoutePrefixEnvSnippet() {
|
|
22
|
+
const frameworkRoutePrefix = workspaceFrameworkRoutePrefixEnv();
|
|
23
|
+
return frameworkRoutePrefix
|
|
24
|
+
? ` processRef.env.AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX = ${JSON.stringify(frameworkRoutePrefix)};\n`
|
|
25
|
+
: " delete processRef.env.AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX;\n";
|
|
26
|
+
}
|
|
21
27
|
function workspaceFrameworkRoutePrefix() {
|
|
22
28
|
return normalizeFrameworkRoutePrefix(workspaceFrameworkRoutePrefixEnv() || undefined, "AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX");
|
|
23
29
|
}
|
|
@@ -167,6 +173,7 @@ function buildOneApp(workspaceRoot, appsDir, app, preset, execFile, workspaceApp
|
|
|
167
173
|
? workspaceGatewayUrl
|
|
168
174
|
: null);
|
|
169
175
|
const workspaceOAuthUrl = workspaceOAuthOrigin(workspaceGatewayUrl);
|
|
176
|
+
const frameworkRoutePrefix = workspaceFrameworkRoutePrefixEnv();
|
|
170
177
|
const env = {
|
|
171
178
|
...process.env,
|
|
172
179
|
NITRO_PRESET: preset,
|
|
@@ -184,7 +191,6 @@ function buildOneApp(workspaceRoot, appsDir, app, preset, execFile, workspaceApp
|
|
|
184
191
|
: {}),
|
|
185
192
|
APP_BASE_PATH: `/${app}`,
|
|
186
193
|
VITE_APP_BASE_PATH: `/${app}`,
|
|
187
|
-
AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX: workspaceFrameworkRoutePrefixEnv(),
|
|
188
194
|
AGENT_NATIVE_WORKSPACE_APP_AUDIENCE: workspaceAppAudience,
|
|
189
195
|
AGENT_NATIVE_WORKSPACE_APP_PUBLIC_PATHS: JSON.stringify(workspaceAppRouteAccess.publicPaths),
|
|
190
196
|
AGENT_NATIVE_WORKSPACE_APP_PROTECTED_PATHS: JSON.stringify(workspaceAppRouteAccess.protectedPaths),
|
|
@@ -206,6 +212,13 @@ function buildOneApp(workspaceRoot, appsDir, app, preset, execFile, workspaceApp
|
|
|
206
212
|
: {}),
|
|
207
213
|
[WORKSPACE_APPS_ENV_KEY]: JSON.stringify(workspaceApps),
|
|
208
214
|
};
|
|
215
|
+
if (frameworkRoutePrefix) {
|
|
216
|
+
env.AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX =
|
|
217
|
+
frameworkRoutePrefix;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
delete env.AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX;
|
|
221
|
+
}
|
|
209
222
|
if (preset === "netlify" && appUsesNetlifyUnpooledDatabaseUrl(appDir)) {
|
|
210
223
|
env.DATABASE_URL =
|
|
211
224
|
process.env.NETLIFY_DATABASE_URL_UNPOOLED ??
|
|
@@ -641,13 +654,13 @@ ${workspaceDirectoryEnvSnippet(workspaceApps)}
|
|
|
641
654
|
VITE_AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
|
|
642
655
|
VITE_AGENT_NATIVE_WORKSPACE_APP_ID: ${JSON.stringify(app)},
|
|
643
656
|
VITE_APP_BASE_PATH: basePath,
|
|
644
|
-
AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX: ${JSON.stringify(workspaceFrameworkRoutePrefixEnv())},
|
|
645
657
|
VITE_AGENT_NATIVE_WORKSPACE_APP_AUDIENCE: ${JSON.stringify(workspaceAppAudience)},
|
|
646
658
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PUBLIC_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.publicPaths))},
|
|
647
659
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PROTECTED_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.protectedPaths))},
|
|
648
660
|
VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
649
661
|
${JSON.stringify(WORKSPACE_APPS_ENV_KEY)}: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
650
662
|
});
|
|
663
|
+
${workspaceFrameworkRoutePrefixEnvSnippet()}
|
|
651
664
|
}
|
|
652
665
|
|
|
653
666
|
setBasePathEnv();
|
|
@@ -734,13 +747,13 @@ ${workspaceDirectoryEnvSnippet(workspaceApps)}
|
|
|
734
747
|
VITE_AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
|
|
735
748
|
VITE_AGENT_NATIVE_WORKSPACE_APP_ID: ${JSON.stringify(app)},
|
|
736
749
|
VITE_APP_BASE_PATH: basePath,
|
|
737
|
-
AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX: ${JSON.stringify(workspaceFrameworkRoutePrefixEnv())},
|
|
738
750
|
VITE_AGENT_NATIVE_WORKSPACE_APP_AUDIENCE: ${JSON.stringify(workspaceAppAudience)},
|
|
739
751
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PUBLIC_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.publicPaths))},
|
|
740
752
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PROTECTED_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.protectedPaths))},
|
|
741
753
|
VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
742
754
|
${JSON.stringify(WORKSPACE_APPS_ENV_KEY)}: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
743
755
|
});
|
|
756
|
+
${workspaceFrameworkRoutePrefixEnvSnippet()}
|
|
744
757
|
}
|
|
745
758
|
|
|
746
759
|
function enabled() {
|
|
@@ -865,13 +878,13 @@ ${workspaceDirectoryEnvSnippet(workspaceApps)}
|
|
|
865
878
|
VITE_AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
|
|
866
879
|
VITE_AGENT_NATIVE_WORKSPACE_APP_ID: ${JSON.stringify(app)},
|
|
867
880
|
VITE_APP_BASE_PATH: basePath,
|
|
868
|
-
AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX: ${JSON.stringify(workspaceFrameworkRoutePrefixEnv())},
|
|
869
881
|
VITE_AGENT_NATIVE_WORKSPACE_APP_AUDIENCE: ${JSON.stringify(workspaceAppAudience)},
|
|
870
882
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PUBLIC_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.publicPaths))},
|
|
871
883
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PROTECTED_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.protectedPaths))},
|
|
872
884
|
VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
873
885
|
${JSON.stringify(WORKSPACE_APPS_ENV_KEY)}: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
874
886
|
});
|
|
887
|
+
${workspaceFrameworkRoutePrefixEnvSnippet()}
|
|
875
888
|
}
|
|
876
889
|
|
|
877
890
|
setBasePathEnv();
|
|
@@ -928,13 +941,13 @@ ${workspaceDirectoryEnvSnippet(workspaceApps)}
|
|
|
928
941
|
VITE_AGENT_NATIVE_WORKSPACE_AUTH_MODE: ${JSON.stringify(workspaceAuthMode)},
|
|
929
942
|
VITE_AGENT_NATIVE_WORKSPACE_APP_ID: ${JSON.stringify(app)},
|
|
930
943
|
VITE_APP_BASE_PATH: basePath,
|
|
931
|
-
AGENT_NATIVE_CONFIG_RUNTIME_FRAMEWORK_ROUTE_PREFIX: ${JSON.stringify(workspaceFrameworkRoutePrefixEnv())},
|
|
932
944
|
VITE_AGENT_NATIVE_WORKSPACE_APP_AUDIENCE: ${JSON.stringify(workspaceAppAudience)},
|
|
933
945
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PUBLIC_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.publicPaths))},
|
|
934
946
|
VITE_AGENT_NATIVE_WORKSPACE_APP_PROTECTED_PATHS: ${JSON.stringify(JSON.stringify(workspaceAppRouteAccess.protectedPaths))},
|
|
935
947
|
VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
936
948
|
${JSON.stringify(WORKSPACE_APPS_ENV_KEY)}: ${JSON.stringify(JSON.stringify(workspaceApps))},
|
|
937
949
|
});
|
|
950
|
+
${workspaceFrameworkRoutePrefixEnvSnippet()}
|
|
938
951
|
}
|
|
939
952
|
|
|
940
953
|
function normalizeBasePathArgs(args) {
|
|
@@ -35,9 +35,9 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
35
35
|
} | {
|
|
36
36
|
error: string;
|
|
37
37
|
url?: undefined;
|
|
38
|
-
id?: undefined;
|
|
39
38
|
provider?: undefined;
|
|
40
39
|
configured?: undefined;
|
|
40
|
+
id?: undefined;
|
|
41
41
|
} | {
|
|
42
42
|
url: string;
|
|
43
43
|
id: string;
|
|
@@ -46,9 +46,9 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
46
46
|
error?: undefined;
|
|
47
47
|
} | {
|
|
48
48
|
url?: undefined;
|
|
49
|
-
id?: undefined;
|
|
50
49
|
provider?: undefined;
|
|
51
50
|
error: string;
|
|
52
51
|
configured: boolean;
|
|
52
|
+
id?: undefined;
|
|
53
53
|
}>;
|
|
54
54
|
export default _default;
|
package/dist/framework-tools.js
CHANGED
|
@@ -132,6 +132,8 @@ export const CORE_ACTION_GROUPS = {
|
|
|
132
132
|
"get-usage-alerts": "automation",
|
|
133
133
|
"manage-usage-alert": "automation",
|
|
134
134
|
"get-usage-metrics": "automation",
|
|
135
|
+
"get-usage-insights": "automation",
|
|
136
|
+
"get-usage-run": "automation",
|
|
135
137
|
"get-builder-credit-usage": "automation",
|
|
136
138
|
"get-builder-credit-status": "automation",
|
|
137
139
|
"get-builder-referral-info": "automation",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "إلغاء",
|
|
38
38
|
couldNotRevoke: "تعذر إلغاء الرمز.",
|
|
39
39
|
authorizeDevice: "تخويل الجهاز",
|
|
40
|
+
organization: "المؤسسة",
|
|
41
|
+
invalidOrganization: "اختر مؤسسة أنت عضو فيها.",
|
|
40
42
|
fullCatalogRequested: "يطلب هذا الجهاز الوصول إلى كتالوج الإجراءات الكامل.",
|
|
41
43
|
createToken: "إنشاء رمز اتصال",
|
|
42
44
|
authorizingDevice: "جارٍ تخويل الجهاز...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "Widerrufen",
|
|
38
38
|
couldNotRevoke: "Token konnte nicht widerrufen werden.",
|
|
39
39
|
authorizeDevice: "Gerät autorisieren",
|
|
40
|
+
organization: "Organisation",
|
|
41
|
+
invalidOrganization: "Wähle eine Organisation, der du angehörst.",
|
|
40
42
|
fullCatalogRequested: "Dieses Gerät fordert Zugriff auf den vollständigen Aktionskatalog an.",
|
|
41
43
|
createToken: "Verbindungstoken erstellen",
|
|
42
44
|
authorizingDevice: "Gerät wird autorisiert...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "Revoke",
|
|
38
38
|
couldNotRevoke: "Could not revoke token.",
|
|
39
39
|
authorizeDevice: "Authorize device",
|
|
40
|
+
organization: "Organization",
|
|
41
|
+
invalidOrganization: "Choose an organization you belong to.",
|
|
40
42
|
fullCatalogRequested: "This device is requesting access to the full action catalog.",
|
|
41
43
|
createToken: "Create connection token",
|
|
42
44
|
authorizingDevice: "Authorizing device...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "Revocar",
|
|
38
38
|
couldNotRevoke: "No se pudo revocar el token.",
|
|
39
39
|
authorizeDevice: "Autorizar dispositivo",
|
|
40
|
+
organization: "Organización",
|
|
41
|
+
invalidOrganization: "Elige una organización a la que pertenezcas.",
|
|
40
42
|
fullCatalogRequested: "Este dispositivo solicita acceso al catálogo completo de acciones.",
|
|
41
43
|
createToken: "Crear token de conexión",
|
|
42
44
|
authorizingDevice: "Autorizando dispositivo...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "Révoquer",
|
|
38
38
|
couldNotRevoke: "Impossible de révoquer le jeton.",
|
|
39
39
|
authorizeDevice: "Autoriser l’appareil",
|
|
40
|
+
organization: "Organisation",
|
|
41
|
+
invalidOrganization: "Choisissez une organisation dont vous êtes membre.",
|
|
40
42
|
fullCatalogRequested: "Cet appareil demande l’accès au catalogue complet des actions.",
|
|
41
43
|
createToken: "Créer un jeton de connexion",
|
|
42
44
|
authorizingDevice: "Autorisation de l’appareil...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "Revoke करें",
|
|
38
38
|
couldNotRevoke: "Token revoke नहीं किया जा सका।",
|
|
39
39
|
authorizeDevice: "डिवाइस को अनुमति दें",
|
|
40
|
+
organization: "संगठन",
|
|
41
|
+
invalidOrganization: "ऐसा संगठन चुनें जिसके आप सदस्य हैं।",
|
|
40
42
|
fullCatalogRequested: "यह डिवाइस पूरे एक्शन कैटलॉग तक पहुंच का अनुरोध कर रहा है।",
|
|
41
43
|
createToken: "कनेक्शन token बनाएँ",
|
|
42
44
|
authorizingDevice: "डिवाइस को अनुमति दी जा रही है...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "取り消す",
|
|
38
38
|
couldNotRevoke: "トークンを取り消せませんでした。",
|
|
39
39
|
authorizeDevice: "デバイスを承認",
|
|
40
|
+
organization: "組織",
|
|
41
|
+
invalidOrganization: "所属している組織を選択してください。",
|
|
40
42
|
fullCatalogRequested: "このデバイスは、すべてのアクションカタログへのアクセスを要求しています。",
|
|
41
43
|
createToken: "接続トークンを作成",
|
|
42
44
|
authorizingDevice: "デバイスを承認中...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "취소",
|
|
38
38
|
couldNotRevoke: "토큰을 취소할 수 없습니다.",
|
|
39
39
|
authorizeDevice: "기기 승인",
|
|
40
|
+
organization: "조직",
|
|
41
|
+
invalidOrganization: "소속된 조직을 선택하세요.",
|
|
40
42
|
fullCatalogRequested: "이 기기는 전체 작업 카탈로그에 대한 액세스를 요청하고 있습니다.",
|
|
41
43
|
createToken: "연결 토큰 생성",
|
|
42
44
|
authorizingDevice: "기기 승인 중...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "Revogar",
|
|
38
38
|
couldNotRevoke: "Não foi possível revogar o token.",
|
|
39
39
|
authorizeDevice: "Autorizar dispositivo",
|
|
40
|
+
organization: "Organização",
|
|
41
|
+
invalidOrganization: "Escolha uma organização da qual você faz parte.",
|
|
40
42
|
fullCatalogRequested: "Este dispositivo está solicitando acesso ao catálogo completo de ações.",
|
|
41
43
|
createToken: "Criar token de conexão",
|
|
42
44
|
authorizingDevice: "Autorizando dispositivo...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "撤销",
|
|
38
38
|
couldNotRevoke: "无法撤销令牌。",
|
|
39
39
|
authorizeDevice: "授权设备",
|
|
40
|
+
organization: "组织",
|
|
41
|
+
invalidOrganization: "请选择你所属的组织。",
|
|
40
42
|
fullCatalogRequested: "此设备正在请求访问完整的操作目录。",
|
|
41
43
|
createToken: "创建连接令牌",
|
|
42
44
|
authorizingDevice: "正在授权设备...",
|
|
@@ -37,6 +37,8 @@ export const mcpConnectMessages = {
|
|
|
37
37
|
revoke: "撤銷",
|
|
38
38
|
couldNotRevoke: "無法撤銷權杖。",
|
|
39
39
|
authorizeDevice: "授權裝置",
|
|
40
|
+
organization: "組織",
|
|
41
|
+
invalidOrganization: "請選擇你所屬的組織。",
|
|
40
42
|
fullCatalogRequested: "此裝置正在要求存取完整的動作目錄。",
|
|
41
43
|
createToken: "建立連線權杖",
|
|
42
44
|
authorizingDevice: "正在授權裝置...",
|
|
@@ -11,6 +11,7 @@ import { readBody } from "../server/h3-helpers.js";
|
|
|
11
11
|
import { MCP_CONNECT_MCP_URL_TEMPLATE, getMcpConnectGuides, getMcpStaticTokenFallback, interpolateMcpConnectTemplate, resolveMcpConnectGuideId, } from "../shared/mcp-connect-content.js";
|
|
12
12
|
import { recordMintedToken, listTokens, revokeToken, normalizeServiceName, serviceIdentityEmail, createDeviceCode, getDeviceCode, getDeviceCodeByUserCode, approveDeviceCode, consumeDeviceCode, claimDeviceCodeForMint, finishDeviceCodeMint, releaseDeviceCodeMint, expireDeviceCode, MCP_CONNECT_OAUTH_CLIENT_ID, MCP_CONNECT_SCOPE, DEFAULT_TOKEN_TTL_DAYS, MIN_TOKEN_TTL_DAYS, MAX_TOKEN_TTL_DAYS, DEVICE_CODE_TTL_MS, } from "./connect-store.js";
|
|
13
13
|
import { MCP_OAUTH_DEFAULT_SCOPE, signMcpOAuthAccessToken, } from "./oauth-token.js";
|
|
14
|
+
import { resolveMcpOrgChoices } from "./org-choice.js";
|
|
14
15
|
import { MCP_PUBLIC_ROUTE_PREFIX } from "./route-paths.js";
|
|
15
16
|
const DEVICE_POLL_INTERVAL_S = 3;
|
|
16
17
|
const USER_CODE_RE = /^[A-Z2-7]{4}-[A-Z2-7]{4}$/;
|
|
@@ -287,7 +288,7 @@ function renderConnectGuide(guide, activeGuideId, values, copyLabel) {
|
|
|
287
288
|
return `<div class="tab-panel${guide.id === activeGuideId ? " is-active" : ""}" role="tabpanel" id="mcp-guide-panel-${guideId}" aria-labelledby="mcp-guide-tab-${guideId}" data-panel="${guideId}">${content}</div>`;
|
|
288
289
|
}
|
|
289
290
|
function renderConnectPage(params) {
|
|
290
|
-
const { connectBasePath, email, appName, appUrl, serverId, userCode, catalogScope, locale, requestedGuide, } = params;
|
|
291
|
+
const { connectBasePath, email, appName, appUrl, serverId, userCode, catalogScope, locale, requestedGuide, organizations, defaultOrganizationId, } = params;
|
|
291
292
|
const direction = localeDirection(locale);
|
|
292
293
|
const messages = mcpSettingsMessagesForLocale(locale);
|
|
293
294
|
const connectMessages = messages.mcpConnect;
|
|
@@ -316,6 +317,19 @@ function renderConnectPage(params) {
|
|
|
316
317
|
const guidePanelsHtml = guides
|
|
317
318
|
.map((guide) => renderConnectGuide(guide, activeGuideId, connectTemplateValues, messages.mcpCopy))
|
|
318
319
|
.join("\n");
|
|
320
|
+
const organizationSelectorHtml = safeUserCode && organizations.length > 1
|
|
321
|
+
? `<div class="field">
|
|
322
|
+
<label for="organizationId">${localize(connectMessages.organization)}</label>
|
|
323
|
+
<div class="select-wrap">
|
|
324
|
+
<select id="organizationId">
|
|
325
|
+
${organizations
|
|
326
|
+
.map((organization) => `<option value="${escapeHtml(organization.id)}"${organization.id === defaultOrganizationId ? " selected" : ""}>${escapeHtml(organization.name)}${organization.domain ? ` (${escapeHtml(organization.domain)})` : ""}</option>`)
|
|
327
|
+
.join("")}
|
|
328
|
+
</select>
|
|
329
|
+
<span class="chev" aria-hidden="true"></span>
|
|
330
|
+
</div>
|
|
331
|
+
</div>`
|
|
332
|
+
: "";
|
|
319
333
|
const setupHtml = safeUserCode
|
|
320
334
|
? ""
|
|
321
335
|
: `
|
|
@@ -426,7 +440,7 @@ function renderConnectPage(params) {
|
|
|
426
440
|
display: flex; align-items: center; justify-content: space-between;
|
|
427
441
|
gap: 0.75rem; border: 1px solid var(--border);
|
|
428
442
|
border-radius: 8px; padding: 0.5rem 0.65rem; margin: 0 0 0.9rem;
|
|
429
|
-
background: var(--panel-soft); color: var(--muted);
|
|
443
|
+
background: var(--panel-soft); color: var(--muted); line-height: 1.2rem;
|
|
430
444
|
}
|
|
431
445
|
.device-strip .label {
|
|
432
446
|
font-size: 0.76rem; font-weight: 560; color: var(--subtle);
|
|
@@ -503,12 +517,25 @@ function renderConnectPage(params) {
|
|
|
503
517
|
.field:last-child { margin-bottom: 0; }
|
|
504
518
|
.field label { display: block; font-size: 0.78rem; color: var(--muted);
|
|
505
519
|
margin-bottom: 0.35rem; }
|
|
506
|
-
.field input {
|
|
520
|
+
.field input, .field select {
|
|
507
521
|
width: 100%; padding: 0.6rem 0.7rem; font: inherit; color: var(--text);
|
|
508
522
|
background: var(--panel-2); border: 1px solid var(--border-strong);
|
|
509
523
|
border-radius: 8px;
|
|
510
524
|
}
|
|
511
|
-
.
|
|
525
|
+
.select-wrap { position: relative; }
|
|
526
|
+
.select-wrap select {
|
|
527
|
+
appearance: none; -webkit-appearance: none;
|
|
528
|
+
padding: 0.5rem 2.4rem 0.5rem 0.65rem; font-size: 0.78rem;
|
|
529
|
+
line-height: 1.2rem; cursor: pointer;
|
|
530
|
+
}
|
|
531
|
+
.select-wrap .chev {
|
|
532
|
+
position: absolute; top: 50%; right: 1rem; width: 7px; height: 7px;
|
|
533
|
+
border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted);
|
|
534
|
+
transform: translateY(-70%) rotate(45deg); pointer-events: none;
|
|
535
|
+
transition: transform 0.15s ease;
|
|
536
|
+
}
|
|
537
|
+
.select-wrap:has(select:open) .chev { transform: translateY(-30%) rotate(225deg); }
|
|
538
|
+
.field input:focus-visible, .field select:focus-visible {
|
|
512
539
|
outline: none; border-color: var(--ring);
|
|
513
540
|
box-shadow: 0 0 0 3px rgba(250,250,250,0.12);
|
|
514
541
|
}
|
|
@@ -718,6 +745,7 @@ function renderConnectPage(params) {
|
|
|
718
745
|
? `<div id="staticTokenMint">
|
|
719
746
|
<div id="msg" class="msg" role="status" aria-live="polite"></div>
|
|
720
747
|
<div id="mintForm">
|
|
748
|
+
${organizationSelectorHtml}
|
|
721
749
|
<button id="authorizeBtn" class="primary">${localize(connectMessages.authorizeDevice)}</button>
|
|
722
750
|
</div>
|
|
723
751
|
</div>`
|
|
@@ -864,6 +892,7 @@ function renderConnectPage(params) {
|
|
|
864
892
|
if (response.status === 404) return COPY.unknownDeviceCode;
|
|
865
893
|
if (response.status === 410) return COPY.expiredDeviceCode;
|
|
866
894
|
if (response.status === 409) return COPY.alreadyUsedDeviceCode;
|
|
895
|
+
if (response.status === 403) return COPY.invalidOrganization;
|
|
867
896
|
return COPY.couldNotAuthorize;
|
|
868
897
|
}
|
|
869
898
|
|
|
@@ -930,7 +959,13 @@ function renderConnectPage(params) {
|
|
|
930
959
|
clearMsg();
|
|
931
960
|
try {
|
|
932
961
|
if (USER_CODE) {
|
|
933
|
-
var
|
|
962
|
+
var orgSelect = document.getElementById("organizationId");
|
|
963
|
+
var a = await postJson(
|
|
964
|
+
"/device/authorize",
|
|
965
|
+
orgSelect
|
|
966
|
+
? { user_code: USER_CODE, org_id: orgSelect.value }
|
|
967
|
+
: { user_code: USER_CODE },
|
|
968
|
+
);
|
|
934
969
|
if (!a.ok) {
|
|
935
970
|
resetButtonLoading(btn);
|
|
936
971
|
showMsg(deviceAuthorizationError(a));
|
|
@@ -1050,6 +1085,8 @@ export async function handleMcpConnect(event, subpath, options = {}) {
|
|
|
1050
1085
|
catalogScope: null,
|
|
1051
1086
|
locale,
|
|
1052
1087
|
requestedGuide: requestUrl?.searchParams.get("guide") ?? null,
|
|
1088
|
+
organizations: [],
|
|
1089
|
+
defaultOrganizationId: undefined,
|
|
1053
1090
|
}));
|
|
1054
1091
|
}
|
|
1055
1092
|
let userCode = null;
|
|
@@ -1064,6 +1101,9 @@ export async function handleMcpConnect(event, subpath, options = {}) {
|
|
|
1064
1101
|
deviceCode.expiresAt >= Date.now()
|
|
1065
1102
|
? deviceCode.catalogScope
|
|
1066
1103
|
: null;
|
|
1104
|
+
const { organizations, defaultOrganizationId } = userCode
|
|
1105
|
+
? await resolveMcpOrgChoices(event, session)
|
|
1106
|
+
: { organizations: [], defaultOrganizationId: undefined };
|
|
1067
1107
|
return html(renderConnectPage({
|
|
1068
1108
|
connectBasePath: basePath,
|
|
1069
1109
|
email: session.email,
|
|
@@ -1074,6 +1114,8 @@ export async function handleMcpConnect(event, subpath, options = {}) {
|
|
|
1074
1114
|
catalogScope,
|
|
1075
1115
|
locale,
|
|
1076
1116
|
requestedGuide: requestUrl?.searchParams.get("guide") ?? null,
|
|
1117
|
+
organizations,
|
|
1118
|
+
defaultOrganizationId,
|
|
1077
1119
|
}));
|
|
1078
1120
|
}
|
|
1079
1121
|
if (sub === "/token") {
|
|
@@ -1094,9 +1136,10 @@ export async function handleMcpConnect(event, subpath, options = {}) {
|
|
|
1094
1136
|
? "full"
|
|
1095
1137
|
: undefined;
|
|
1096
1138
|
try {
|
|
1139
|
+
const { defaultOrganizationId } = await resolveMcpOrgChoices(event, session);
|
|
1097
1140
|
const { token } = await mintConnectToken({
|
|
1098
1141
|
email: session.email,
|
|
1099
|
-
orgId:
|
|
1142
|
+
orgId: defaultOrganizationId,
|
|
1100
1143
|
label,
|
|
1101
1144
|
ttlDays,
|
|
1102
1145
|
appUrl,
|
|
@@ -1157,10 +1200,14 @@ export async function handleMcpConnect(event, subpath, options = {}) {
|
|
|
1157
1200
|
if (!USER_CODE_RE.test(userCode)) {
|
|
1158
1201
|
return json({ error: "Invalid user code." }, 400);
|
|
1159
1202
|
}
|
|
1160
|
-
const
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1203
|
+
const requestedOrgId = typeof body.org_id === "string" && body.org_id ? body.org_id : undefined;
|
|
1204
|
+
const { organizations, defaultOrganizationId } = await resolveMcpOrgChoices(event, session, requestedOrgId);
|
|
1205
|
+
if (requestedOrgId !== undefined &&
|
|
1206
|
+
!organizations.some(({ id }) => id === requestedOrgId)) {
|
|
1207
|
+
return json({ error: "Choose an organization you belong to." }, 403);
|
|
1208
|
+
}
|
|
1209
|
+
const selectedOrgId = requestedOrgId ?? defaultOrganizationId ?? null;
|
|
1210
|
+
const result = await approveDeviceCode(userCode, session.email, selectedOrgId);
|
|
1164
1211
|
if (result === "not_found") {
|
|
1165
1212
|
return json({ error: "Unknown device code." }, 404);
|
|
1166
1213
|
}
|
package/dist/mcp/oauth-route.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
|
|
2
2
|
import { getHeader, getMethod, getQuery, setResponseStatus } from "h3";
|
|
3
|
-
import {
|
|
3
|
+
import { getOrgDomain } from "../org/context.js";
|
|
4
4
|
import { getConfiguredLoginHtml, getSession } from "../server/auth.js";
|
|
5
5
|
import { getAuthSecret } from "../server/better-auth-instance.js";
|
|
6
6
|
import { readBody } from "../server/h3-helpers.js";
|
|
7
7
|
import { applicationTypeForRedirectUris, isAllowedOAuthRedirectUri, isUrlBasedOAuthClientId, matchesRegisteredRedirectUri, resolveOAuthClientMetadataDocument, } from "./oauth-client-metadata.js";
|
|
8
8
|
import { createOAuthCode, createOAuthRefreshToken, consumeOAuthCode, generateOpaqueToken, getOAuthClient, getOAuthCode, getOAuthRefreshToken, registerOAuthClient, touchOAuthRefreshToken, } from "./oauth-store.js";
|
|
9
9
|
import { MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS, MCP_OAUTH_SCOPES, normalizeOAuthScope, signMcpOAuthAccessToken, } from "./oauth-token.js";
|
|
10
|
+
import { resolveMcpOrgChoices } from "./org-choice.js";
|
|
10
11
|
import { MCP_LEGACY_ROUTE_PREFIX, MCP_PUBLIC_ROUTE_PREFIX, MCP_ROUTE_PREFIXES, } from "./route-paths.js";
|
|
11
12
|
const MCP_OAUTH_RESOURCE_SCOPES = MCP_OAUTH_SCOPES.filter((scope) => scope !== "offline_access");
|
|
12
13
|
const MCP_OAUTH_RESOURCE_SCOPE = MCP_OAUTH_RESOURCE_SCOPES.join(" ");
|
|
@@ -597,27 +598,9 @@ async function handleAuthorize(event, options) {
|
|
|
597
598
|
error: "invalid_scope",
|
|
598
599
|
});
|
|
599
600
|
}
|
|
600
|
-
const
|
|
601
|
-
const requestedOrganizationId = method === "POST" && params.organization_id !== undefined
|
|
601
|
+
const { organizations, defaultOrganizationId } = await resolveMcpOrgChoices(event, session, method === "POST" && params.organization_id !== undefined
|
|
602
602
|
? params.organization_id || null
|
|
603
|
-
:
|
|
604
|
-
let memberships = await listOrgMembershipsForEvent(event, session.email, requestedOrganizationId);
|
|
605
|
-
// A token issued with no org stays org-less for its whole life, even after
|
|
606
|
-
// the app later creates the org, so resolve an account without one to its
|
|
607
|
-
// domain or default org before offering the choice.
|
|
608
|
-
const ensuredOrgId = memberships?.length === 0 ? (await getOrgContext(event)).orgId : null;
|
|
609
|
-
if (ensuredOrgId) {
|
|
610
|
-
memberships = await listOrgMembershipsForEvent(event, session.email, ensuredOrgId);
|
|
611
|
-
}
|
|
612
|
-
const organizations = memberships?.map((membership) => ({
|
|
613
|
-
id: membership.orgId,
|
|
614
|
-
name: membership.orgName,
|
|
615
|
-
domain: membership.allowedDomain,
|
|
616
|
-
})) ??
|
|
617
|
-
(session.orgId
|
|
618
|
-
? [{ id: session.orgId, name: "Organization", domain: null }]
|
|
619
|
-
: []);
|
|
620
|
-
const defaultOrganizationId = [activeOrgSetting?.orgId, ensuredOrgId, session.orgId].find((id) => id && organizations.some((org) => org.id === id)) ?? organizations[0]?.id;
|
|
603
|
+
: undefined);
|
|
621
604
|
if (method === "GET") {
|
|
622
605
|
return html(renderConsentPage({
|
|
623
606
|
appName: options.appName || options.appId || "Agent-Native",
|