@stackable-labs/mcp-app-extension 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{auth-AJDGAQSE.js → auth-37BRWM34.js} +2 -2
- package/dist/{auth-JRYNP3PL.js → auth-7GIVRWDG.js} +2 -2
- package/dist/{chunk-6EMXRSXY.js → chunk-FIIWPDHX.js} +13 -7
- package/dist/{chunk-4XCX3LVH.js → chunk-J3MNH4OK.js} +17 -11
- package/dist/index.js +27 -27
- package/dist/server.js +27 -27
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { writeAuthState } from './chunk-
|
|
2
|
+
import { writeAuthState, STANDALONE_CLIENT_AUTH_FILE } from './chunk-J3MNH4OK.js';
|
|
3
3
|
import { createServer } from 'http';
|
|
4
4
|
import process6 from 'process';
|
|
5
5
|
import { Buffer as Buffer$1 } from 'buffer';
|
|
@@ -661,7 +661,7 @@ var performOAuthFlow = async (discoveryUrl) => {
|
|
|
661
661
|
orgId: payload.orgId,
|
|
662
662
|
userId: payload.sub
|
|
663
663
|
},
|
|
664
|
-
|
|
664
|
+
STANDALONE_CLIENT_AUTH_FILE.MCP
|
|
665
665
|
);
|
|
666
666
|
return tokenResponse.access_token;
|
|
667
667
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { writeAuthState } from './chunk-
|
|
1
|
+
import { writeAuthState, STANDALONE_CLIENT_AUTH_FILE } from './chunk-FIIWPDHX.js';
|
|
2
2
|
import { createServer } from 'http';
|
|
3
3
|
import process6 from 'process';
|
|
4
4
|
import { Buffer as Buffer$1 } from 'buffer';
|
|
@@ -660,7 +660,7 @@ var performOAuthFlow = async (discoveryUrl) => {
|
|
|
660
660
|
orgId: payload.orgId,
|
|
661
661
|
userId: payload.sub
|
|
662
662
|
},
|
|
663
|
-
|
|
663
|
+
STANDALONE_CLIENT_AUTH_FILE.MCP
|
|
664
664
|
);
|
|
665
665
|
return tokenResponse.access_token;
|
|
666
666
|
};
|
|
@@ -3,10 +3,16 @@ import { join } from 'path';
|
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
|
|
5
5
|
// ../../lib/utils-auth/src/constants.ts
|
|
6
|
-
var
|
|
7
|
-
CLI: "@stackable-labs/cli-app-extension",
|
|
8
|
-
MCP: "@stackable-labs/mcp-app-extension"
|
|
6
|
+
var STANDALONE_CLIENT_DATA = {
|
|
7
|
+
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "auth.json" },
|
|
8
|
+
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
9
9
|
};
|
|
10
|
+
var STANDALONE_CLIENT = Object.fromEntries(
|
|
11
|
+
Object.entries(STANDALONE_CLIENT_DATA).map(([k, v]) => [k, v.name])
|
|
12
|
+
);
|
|
13
|
+
var STANDALONE_CLIENT_AUTH_FILE = Object.fromEntries(
|
|
14
|
+
Object.entries(STANDALONE_CLIENT_DATA).map(([k, v]) => [k, v.authFile])
|
|
15
|
+
);
|
|
10
16
|
Object.values(STANDALONE_CLIENT);
|
|
11
17
|
|
|
12
18
|
// ../../lib/contracts/src/permissions.ts
|
|
@@ -28,9 +34,9 @@ var EDITOR_ROLES = [
|
|
|
28
34
|
|
|
29
35
|
// ../../lib/utils-auth/src/index.ts
|
|
30
36
|
var AUTH_DIR = join(homedir(), ".stackable");
|
|
31
|
-
join(AUTH_DIR,
|
|
32
|
-
join(AUTH_DIR,
|
|
33
|
-
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ??
|
|
37
|
+
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.CLI);
|
|
38
|
+
var MCP_AUTH_FILE = join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
39
|
+
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? STANDALONE_CLIENT_AUTH_FILE.CLI);
|
|
34
40
|
var readAuthState = async (filename) => {
|
|
35
41
|
try {
|
|
36
42
|
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
@@ -69,4 +75,4 @@ var getToken = async (filename) => {
|
|
|
69
75
|
return state.token;
|
|
70
76
|
};
|
|
71
77
|
|
|
72
|
-
export { STANDALONE_CLIENT, getToken, writeAuthState };
|
|
78
|
+
export { MCP_AUTH_FILE, STANDALONE_CLIENT, STANDALONE_CLIENT_AUTH_FILE, getToken, writeAuthState };
|
|
@@ -3,6 +3,19 @@ import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
|
|
6
|
+
// ../../lib/utils-auth/src/constants.ts
|
|
7
|
+
var STANDALONE_CLIENT_DATA = {
|
|
8
|
+
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "auth.json" },
|
|
9
|
+
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
10
|
+
};
|
|
11
|
+
var STANDALONE_CLIENT = Object.fromEntries(
|
|
12
|
+
Object.entries(STANDALONE_CLIENT_DATA).map(([k, v]) => [k, v.name])
|
|
13
|
+
);
|
|
14
|
+
var STANDALONE_CLIENT_AUTH_FILE = Object.fromEntries(
|
|
15
|
+
Object.entries(STANDALONE_CLIENT_DATA).map(([k, v]) => [k, v.authFile])
|
|
16
|
+
);
|
|
17
|
+
Object.values(STANDALONE_CLIENT);
|
|
18
|
+
|
|
6
19
|
// ../../lib/contracts/src/permissions.ts
|
|
7
20
|
var SUPER_ROLE = {
|
|
8
21
|
ADMIN: "org:super_admin"
|
|
@@ -20,18 +33,11 @@ var EDITOR_ROLES = [
|
|
|
20
33
|
...Object.values(EDITOR_ROLES)
|
|
21
34
|
];
|
|
22
35
|
|
|
23
|
-
// ../../lib/utils-auth/src/constants.ts
|
|
24
|
-
var STANDALONE_CLIENT = {
|
|
25
|
-
CLI: "@stackable-labs/cli-app-extension",
|
|
26
|
-
MCP: "@stackable-labs/mcp-app-extension"
|
|
27
|
-
};
|
|
28
|
-
Object.values(STANDALONE_CLIENT);
|
|
29
|
-
|
|
30
36
|
// ../../lib/utils-auth/src/index.ts
|
|
31
37
|
var AUTH_DIR = join(homedir(), ".stackable");
|
|
32
|
-
join(AUTH_DIR,
|
|
33
|
-
join(AUTH_DIR,
|
|
34
|
-
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ??
|
|
38
|
+
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.CLI);
|
|
39
|
+
var MCP_AUTH_FILE = join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
40
|
+
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? STANDALONE_CLIENT_AUTH_FILE.CLI);
|
|
35
41
|
var readAuthState = async (filename) => {
|
|
36
42
|
try {
|
|
37
43
|
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
@@ -70,4 +76,4 @@ var getToken = async (filename) => {
|
|
|
70
76
|
return state.token;
|
|
71
77
|
};
|
|
72
78
|
|
|
73
|
-
export { STANDALONE_CLIENT, getToken, writeAuthState };
|
|
79
|
+
export { MCP_AUTH_FILE, STANDALONE_CLIENT, STANDALONE_CLIENT_AUTH_FILE, getToken, writeAuthState };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { STANDALONE_CLIENT, getToken } from './chunk-
|
|
2
|
+
import { STANDALONE_CLIENT, MCP_AUTH_FILE, getToken, STANDALONE_CLIENT_AUTH_FILE } from './chunk-J3MNH4OK.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
-
import {
|
|
5
|
+
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, PERMISSIONS, CAPABILITY_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_ATTRIBUTES, tagToComponentName } from '@stackable-labs/sdk-extension-contracts';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
|
|
8
8
|
// ../../sdk/extension/ai-docs/src/generated/template-content.ts
|
|
@@ -431,8 +431,8 @@ useExtendIdentity(handleExtend)`
|
|
|
431
431
|
};
|
|
432
432
|
|
|
433
433
|
// ../../sdk/extension/ai-docs/src/generators/capabilities.ts
|
|
434
|
-
var
|
|
435
|
-
var
|
|
434
|
+
var IDENTITY_EVENT_VALUES = Object.values(IDENTITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
435
|
+
var ACTIVITY_EVENT_VALUES = Object.values(ACTIVITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
436
436
|
var generateCapabilities = () => {
|
|
437
437
|
const fm = frontmatter({
|
|
438
438
|
root: false,
|
|
@@ -539,7 +539,7 @@ Subscribe to real-time identity events (login, logout, refresh, expired) pushed
|
|
|
539
539
|
- **Permission required:** \`events:identity\`
|
|
540
540
|
- **Manifest events array:** Declare specific events to listen for (e.g. \`["identity:login", "identity:logout"]\`)
|
|
541
541
|
- **Hook:** \`useIdentityEvent(eventType, handler)\`
|
|
542
|
-
- **Event types:** \`${
|
|
542
|
+
- **Event types:** \`${IDENTITY_EVENT_VALUES}\`
|
|
543
543
|
|
|
544
544
|
\`\`\`json
|
|
545
545
|
{
|
|
@@ -579,7 +579,7 @@ Subscribe to host activity events (e.g. page views, clicks, purchases) pushed fr
|
|
|
579
579
|
- **Permission required:** \`events:activity\`
|
|
580
580
|
- **Manifest events array:** Declare specific events to listen for (e.g. \`["activity:product_view", "activity:add_to_cart"]\`) \u2014 manifest uses fully-qualified strings
|
|
581
581
|
- **Hook:** \`useActivityEvent(eventType, handler)\` \u2014 \`ActivityEventHandler\` type exported for use with \`useCallback\`
|
|
582
|
-
- **Event types (domain-stripped):** \`${
|
|
582
|
+
- **Event types (domain-stripped):** \`${ACTIVITY_EVENT_VALUES} | '*'\`
|
|
583
583
|
- **Well-known event names:**
|
|
584
584
|
|
|
585
585
|
| Event | Example payload fields |
|
|
@@ -930,8 +930,8 @@ export function Content(): React.ReactElement {
|
|
|
930
930
|
|
|
931
931
|
// ../../sdk/extension/ai-docs/src/generators/hooks-and-api.ts
|
|
932
932
|
var stripImports = (snippet) => snippet.split("\n").filter((line) => !line.startsWith("import ")).join("\n").trim();
|
|
933
|
-
var
|
|
934
|
-
var
|
|
933
|
+
var identityEventTypes = Object.values(IDENTITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
934
|
+
var activityEventTypes = Object.values(ACTIVITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
935
935
|
var generateHooksAndApi = () => {
|
|
936
936
|
const fm = frontmatter({
|
|
937
937
|
root: false,
|
|
@@ -1007,7 +1007,7 @@ const appStore = createStore<AppState>({ viewState: { type: 'menu' } })
|
|
|
1007
1007
|
|
|
1008
1008
|
## useIdentityEvent(eventType, handler)
|
|
1009
1009
|
Subscribe to identity events pushed from the host. Requires \`events:identity\` permission and matching entries in manifest \`events\` array.
|
|
1010
|
-
- \`eventType: ${
|
|
1010
|
+
- \`eventType: ${identityEventTypes}\`
|
|
1011
1011
|
- \`handler: (event: IdentityEvent) => void\`
|
|
1012
1012
|
- \`IdentityEvent: { eventName: IdentityEventType, data: { state: IdentityState, timestamp: string } }\`
|
|
1013
1013
|
- \`IdentityState: { authenticated: boolean, user: UserIdentity | null, expiresAt?: string }\`
|
|
@@ -1035,7 +1035,7 @@ ${HOOK_SNIPPETS_MEMOIZED["events:messaging"]}
|
|
|
1035
1035
|
|
|
1036
1036
|
## useActivityEvent(eventType, handler)
|
|
1037
1037
|
Subscribe to host activity events. Requires \`events:activity\` permission and matching entries in manifest \`events\` array.
|
|
1038
|
-
- \`eventType: ${
|
|
1038
|
+
- \`eventType: ${activityEventTypes} | '*'\` (domain-stripped)
|
|
1039
1039
|
- \`handler: ActivityEventHandler\` \u2014 \`(event: ActivityEvent) => void\`
|
|
1040
1040
|
- \`ActivityEvent: { eventName: string, data: Record<string, unknown> }\`
|
|
1041
1041
|
- \`'*'\` receives ALL activity events
|
|
@@ -1340,7 +1340,7 @@ ${references}
|
|
|
1340
1340
|
${body}`;
|
|
1341
1341
|
};
|
|
1342
1342
|
var SURFACE_SNIPPETS = {
|
|
1343
|
-
[
|
|
1343
|
+
[SURFACE_TARGET.HEADER]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1344
1344
|
|
|
1345
1345
|
export function Header() {
|
|
1346
1346
|
return (
|
|
@@ -1349,7 +1349,7 @@ export function Header() {
|
|
|
1349
1349
|
</Surface>
|
|
1350
1350
|
)
|
|
1351
1351
|
}`,
|
|
1352
|
-
[
|
|
1352
|
+
[SURFACE_TARGET.CONTENT]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1353
1353
|
|
|
1354
1354
|
export function Content() {
|
|
1355
1355
|
return (
|
|
@@ -1362,7 +1362,7 @@ export function Content() {
|
|
|
1362
1362
|
</Surface>
|
|
1363
1363
|
)
|
|
1364
1364
|
}`,
|
|
1365
|
-
[
|
|
1365
|
+
[SURFACE_TARGET.FOOTER]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1366
1366
|
|
|
1367
1367
|
export function Footer() {
|
|
1368
1368
|
return (
|
|
@@ -1371,7 +1371,7 @@ export function Footer() {
|
|
|
1371
1371
|
</Surface>
|
|
1372
1372
|
)
|
|
1373
1373
|
}`,
|
|
1374
|
-
[
|
|
1374
|
+
[SURFACE_TARGET.FOOTER_LINKS]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1375
1375
|
|
|
1376
1376
|
export function FooterLinks() {
|
|
1377
1377
|
return (
|
|
@@ -1412,7 +1412,7 @@ the \`<Surface>\` wrapper from \`@stackable-labs/sdk-extension-react\`.
|
|
|
1412
1412
|
Each surface is a React component wrapped in \`<Surface>\`:
|
|
1413
1413
|
|
|
1414
1414
|
\`\`\`tsx
|
|
1415
|
-
${SURFACE_SNIPPETS[
|
|
1415
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.CONTENT]}
|
|
1416
1416
|
\`\`\`
|
|
1417
1417
|
|
|
1418
1418
|
The \`id\` prop must match a target declared in your \`manifest.json\`:
|
|
@@ -2197,7 +2197,7 @@ to read state with minimal re-renders.
|
|
|
2197
2197
|
Each surface is a React component in \`src/surfaces/\`:
|
|
2198
2198
|
|
|
2199
2199
|
\`\`\`tsx
|
|
2200
|
-
${SURFACE_SNIPPETS[
|
|
2200
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.CONTENT]}
|
|
2201
2201
|
\`\`\`
|
|
2202
2202
|
|
|
2203
2203
|
The \`id\` prop must match a target in \`manifest.json\`.
|
|
@@ -2578,25 +2578,25 @@ The \`id\` prop must match a target declared in your \`manifest.json\`.
|
|
|
2578
2578
|
### Header
|
|
2579
2579
|
|
|
2580
2580
|
\`\`\`tsx
|
|
2581
|
-
${SURFACE_SNIPPETS[
|
|
2581
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.HEADER]}
|
|
2582
2582
|
\`\`\`
|
|
2583
2583
|
|
|
2584
2584
|
### Content
|
|
2585
2585
|
|
|
2586
2586
|
\`\`\`tsx
|
|
2587
|
-
${SURFACE_SNIPPETS[
|
|
2587
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.CONTENT]}
|
|
2588
2588
|
\`\`\`
|
|
2589
2589
|
|
|
2590
2590
|
### Footer
|
|
2591
2591
|
|
|
2592
2592
|
\`\`\`tsx
|
|
2593
|
-
${SURFACE_SNIPPETS[
|
|
2593
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.FOOTER]}
|
|
2594
2594
|
\`\`\`
|
|
2595
2595
|
|
|
2596
2596
|
### Footer Links
|
|
2597
2597
|
|
|
2598
2598
|
\`\`\`tsx
|
|
2599
|
-
${SURFACE_SNIPPETS[
|
|
2599
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.FOOTER_LINKS]}
|
|
2600
2600
|
\`\`\`
|
|
2601
2601
|
|
|
2602
2602
|
## Store \u2014 Cross-Surface State & Navigation
|
|
@@ -2628,8 +2628,8 @@ ${EXAMPLE_SNIPPETS.surfaceContext}
|
|
|
2628
2628
|
\`\`\`
|
|
2629
2629
|
`;
|
|
2630
2630
|
};
|
|
2631
|
-
var
|
|
2632
|
-
var
|
|
2631
|
+
var identityEventTypes2 = Object.values(IDENTITY_EVENT).map((e) => `\`${e}\``).join(", ");
|
|
2632
|
+
var activityEventTypes2 = Object.values(ACTIVITY_EVENT).map((e) => `\`${e}\``).join(", ");
|
|
2633
2633
|
var generateCookbookEvents = () => {
|
|
2634
2634
|
const fm = frontmatter({
|
|
2635
2635
|
root: false,
|
|
@@ -2650,7 +2650,7 @@ Subscribe to login, logout, refresh, and expired events. Useful for tracking
|
|
|
2650
2650
|
agent authentication state in your extension.
|
|
2651
2651
|
|
|
2652
2652
|
**Permission:** \`events:identity\`
|
|
2653
|
-
**Event types:** ${
|
|
2653
|
+
**Event types:** ${identityEventTypes2}
|
|
2654
2654
|
|
|
2655
2655
|
### Hook usage
|
|
2656
2656
|
|
|
@@ -2690,7 +2690,7 @@ Activity event names are domain-stripped \u2014 use \`useActivityEvent('product_
|
|
|
2690
2690
|
not \`'activity:product_view'\`.
|
|
2691
2691
|
|
|
2692
2692
|
**Permission:** \`events:activity\`
|
|
2693
|
-
**Well-known events:** ${
|
|
2693
|
+
**Well-known events:** ${activityEventTypes2}
|
|
2694
2694
|
|
|
2695
2695
|
### Hook usage
|
|
2696
2696
|
|
|
@@ -3772,10 +3772,10 @@ var createMcpServer = (options = {}) => {
|
|
|
3772
3772
|
return options.authContext.token;
|
|
3773
3773
|
}
|
|
3774
3774
|
try {
|
|
3775
|
-
return await getToken(
|
|
3775
|
+
return await getToken(STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
3776
3776
|
} catch {
|
|
3777
3777
|
}
|
|
3778
|
-
const { performOAuthFlow } = await import('./auth-
|
|
3778
|
+
const { performOAuthFlow } = await import('./auth-37BRWM34.js');
|
|
3779
3779
|
const MCP_API_BASE_URL = process.env.MCP_API_BASE_URL ?? DEFAULT_MCP_API_BASE_URL;
|
|
3780
3780
|
return performOAuthFlow(`${MCP_API_BASE_URL}/.well-known/oauth-authorization-server`);
|
|
3781
3781
|
};
|
|
@@ -3810,7 +3810,7 @@ var createMcpServer = (options = {}) => {
|
|
|
3810
3810
|
if (e.message.includes("fetch")) {
|
|
3811
3811
|
const MCP_API_BASE_URL = process.env.MCP_API_BASE_URL ?? DEFAULT_MCP_API_BASE_URL;
|
|
3812
3812
|
return errorContent(
|
|
3813
|
-
`MCP auth flow failed: ${e.message}. Check MCP_API_BASE_URL env var (currently "${MCP_API_BASE_URL}"). To re-auth from scratch: rm
|
|
3813
|
+
`MCP auth flow failed: ${e.message}. Check MCP_API_BASE_URL env var (currently "${MCP_API_BASE_URL}"). To re-auth from scratch: rm ${MCP_AUTH_FILE}`
|
|
3814
3814
|
);
|
|
3815
3815
|
}
|
|
3816
3816
|
return errorContent(e.message);
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { STANDALONE_CLIENT, getToken } from './chunk-
|
|
1
|
+
import { STANDALONE_CLIENT, MCP_AUTH_FILE, getToken, STANDALONE_CLIENT_AUTH_FILE } from './chunk-FIIWPDHX.js';
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import {
|
|
3
|
+
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, PERMISSIONS, CAPABILITY_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_ATTRIBUTES, tagToComponentName } from '@stackable-labs/sdk-extension-contracts';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
6
6
|
// ../../sdk/extension/ai-docs/src/generated/template-content.ts
|
|
@@ -429,8 +429,8 @@ useExtendIdentity(handleExtend)`
|
|
|
429
429
|
};
|
|
430
430
|
|
|
431
431
|
// ../../sdk/extension/ai-docs/src/generators/capabilities.ts
|
|
432
|
-
var
|
|
433
|
-
var
|
|
432
|
+
var IDENTITY_EVENT_VALUES = Object.values(IDENTITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
433
|
+
var ACTIVITY_EVENT_VALUES = Object.values(ACTIVITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
434
434
|
var generateCapabilities = () => {
|
|
435
435
|
const fm = frontmatter({
|
|
436
436
|
root: false,
|
|
@@ -537,7 +537,7 @@ Subscribe to real-time identity events (login, logout, refresh, expired) pushed
|
|
|
537
537
|
- **Permission required:** \`events:identity\`
|
|
538
538
|
- **Manifest events array:** Declare specific events to listen for (e.g. \`["identity:login", "identity:logout"]\`)
|
|
539
539
|
- **Hook:** \`useIdentityEvent(eventType, handler)\`
|
|
540
|
-
- **Event types:** \`${
|
|
540
|
+
- **Event types:** \`${IDENTITY_EVENT_VALUES}\`
|
|
541
541
|
|
|
542
542
|
\`\`\`json
|
|
543
543
|
{
|
|
@@ -577,7 +577,7 @@ Subscribe to host activity events (e.g. page views, clicks, purchases) pushed fr
|
|
|
577
577
|
- **Permission required:** \`events:activity\`
|
|
578
578
|
- **Manifest events array:** Declare specific events to listen for (e.g. \`["activity:product_view", "activity:add_to_cart"]\`) \u2014 manifest uses fully-qualified strings
|
|
579
579
|
- **Hook:** \`useActivityEvent(eventType, handler)\` \u2014 \`ActivityEventHandler\` type exported for use with \`useCallback\`
|
|
580
|
-
- **Event types (domain-stripped):** \`${
|
|
580
|
+
- **Event types (domain-stripped):** \`${ACTIVITY_EVENT_VALUES} | '*'\`
|
|
581
581
|
- **Well-known event names:**
|
|
582
582
|
|
|
583
583
|
| Event | Example payload fields |
|
|
@@ -928,8 +928,8 @@ export function Content(): React.ReactElement {
|
|
|
928
928
|
|
|
929
929
|
// ../../sdk/extension/ai-docs/src/generators/hooks-and-api.ts
|
|
930
930
|
var stripImports = (snippet) => snippet.split("\n").filter((line) => !line.startsWith("import ")).join("\n").trim();
|
|
931
|
-
var
|
|
932
|
-
var
|
|
931
|
+
var identityEventTypes = Object.values(IDENTITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
932
|
+
var activityEventTypes = Object.values(ACTIVITY_EVENT).map((e) => `'${e}'`).join(" | ");
|
|
933
933
|
var generateHooksAndApi = () => {
|
|
934
934
|
const fm = frontmatter({
|
|
935
935
|
root: false,
|
|
@@ -1005,7 +1005,7 @@ const appStore = createStore<AppState>({ viewState: { type: 'menu' } })
|
|
|
1005
1005
|
|
|
1006
1006
|
## useIdentityEvent(eventType, handler)
|
|
1007
1007
|
Subscribe to identity events pushed from the host. Requires \`events:identity\` permission and matching entries in manifest \`events\` array.
|
|
1008
|
-
- \`eventType: ${
|
|
1008
|
+
- \`eventType: ${identityEventTypes}\`
|
|
1009
1009
|
- \`handler: (event: IdentityEvent) => void\`
|
|
1010
1010
|
- \`IdentityEvent: { eventName: IdentityEventType, data: { state: IdentityState, timestamp: string } }\`
|
|
1011
1011
|
- \`IdentityState: { authenticated: boolean, user: UserIdentity | null, expiresAt?: string }\`
|
|
@@ -1033,7 +1033,7 @@ ${HOOK_SNIPPETS_MEMOIZED["events:messaging"]}
|
|
|
1033
1033
|
|
|
1034
1034
|
## useActivityEvent(eventType, handler)
|
|
1035
1035
|
Subscribe to host activity events. Requires \`events:activity\` permission and matching entries in manifest \`events\` array.
|
|
1036
|
-
- \`eventType: ${
|
|
1036
|
+
- \`eventType: ${activityEventTypes} | '*'\` (domain-stripped)
|
|
1037
1037
|
- \`handler: ActivityEventHandler\` \u2014 \`(event: ActivityEvent) => void\`
|
|
1038
1038
|
- \`ActivityEvent: { eventName: string, data: Record<string, unknown> }\`
|
|
1039
1039
|
- \`'*'\` receives ALL activity events
|
|
@@ -1338,7 +1338,7 @@ ${references}
|
|
|
1338
1338
|
${body}`;
|
|
1339
1339
|
};
|
|
1340
1340
|
var SURFACE_SNIPPETS = {
|
|
1341
|
-
[
|
|
1341
|
+
[SURFACE_TARGET.HEADER]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1342
1342
|
|
|
1343
1343
|
export function Header() {
|
|
1344
1344
|
return (
|
|
@@ -1347,7 +1347,7 @@ export function Header() {
|
|
|
1347
1347
|
</Surface>
|
|
1348
1348
|
)
|
|
1349
1349
|
}`,
|
|
1350
|
-
[
|
|
1350
|
+
[SURFACE_TARGET.CONTENT]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1351
1351
|
|
|
1352
1352
|
export function Content() {
|
|
1353
1353
|
return (
|
|
@@ -1360,7 +1360,7 @@ export function Content() {
|
|
|
1360
1360
|
</Surface>
|
|
1361
1361
|
)
|
|
1362
1362
|
}`,
|
|
1363
|
-
[
|
|
1363
|
+
[SURFACE_TARGET.FOOTER]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1364
1364
|
|
|
1365
1365
|
export function Footer() {
|
|
1366
1366
|
return (
|
|
@@ -1369,7 +1369,7 @@ export function Footer() {
|
|
|
1369
1369
|
</Surface>
|
|
1370
1370
|
)
|
|
1371
1371
|
}`,
|
|
1372
|
-
[
|
|
1372
|
+
[SURFACE_TARGET.FOOTER_LINKS]: `import { Surface, ui } from '@stackable-labs/sdk-extension-react'
|
|
1373
1373
|
|
|
1374
1374
|
export function FooterLinks() {
|
|
1375
1375
|
return (
|
|
@@ -1410,7 +1410,7 @@ the \`<Surface>\` wrapper from \`@stackable-labs/sdk-extension-react\`.
|
|
|
1410
1410
|
Each surface is a React component wrapped in \`<Surface>\`:
|
|
1411
1411
|
|
|
1412
1412
|
\`\`\`tsx
|
|
1413
|
-
${SURFACE_SNIPPETS[
|
|
1413
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.CONTENT]}
|
|
1414
1414
|
\`\`\`
|
|
1415
1415
|
|
|
1416
1416
|
The \`id\` prop must match a target declared in your \`manifest.json\`:
|
|
@@ -2195,7 +2195,7 @@ to read state with minimal re-renders.
|
|
|
2195
2195
|
Each surface is a React component in \`src/surfaces/\`:
|
|
2196
2196
|
|
|
2197
2197
|
\`\`\`tsx
|
|
2198
|
-
${SURFACE_SNIPPETS[
|
|
2198
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.CONTENT]}
|
|
2199
2199
|
\`\`\`
|
|
2200
2200
|
|
|
2201
2201
|
The \`id\` prop must match a target in \`manifest.json\`.
|
|
@@ -2576,25 +2576,25 @@ The \`id\` prop must match a target declared in your \`manifest.json\`.
|
|
|
2576
2576
|
### Header
|
|
2577
2577
|
|
|
2578
2578
|
\`\`\`tsx
|
|
2579
|
-
${SURFACE_SNIPPETS[
|
|
2579
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.HEADER]}
|
|
2580
2580
|
\`\`\`
|
|
2581
2581
|
|
|
2582
2582
|
### Content
|
|
2583
2583
|
|
|
2584
2584
|
\`\`\`tsx
|
|
2585
|
-
${SURFACE_SNIPPETS[
|
|
2585
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.CONTENT]}
|
|
2586
2586
|
\`\`\`
|
|
2587
2587
|
|
|
2588
2588
|
### Footer
|
|
2589
2589
|
|
|
2590
2590
|
\`\`\`tsx
|
|
2591
|
-
${SURFACE_SNIPPETS[
|
|
2591
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.FOOTER]}
|
|
2592
2592
|
\`\`\`
|
|
2593
2593
|
|
|
2594
2594
|
### Footer Links
|
|
2595
2595
|
|
|
2596
2596
|
\`\`\`tsx
|
|
2597
|
-
${SURFACE_SNIPPETS[
|
|
2597
|
+
${SURFACE_SNIPPETS[SURFACE_TARGET.FOOTER_LINKS]}
|
|
2598
2598
|
\`\`\`
|
|
2599
2599
|
|
|
2600
2600
|
## Store \u2014 Cross-Surface State & Navigation
|
|
@@ -2626,8 +2626,8 @@ ${EXAMPLE_SNIPPETS.surfaceContext}
|
|
|
2626
2626
|
\`\`\`
|
|
2627
2627
|
`;
|
|
2628
2628
|
};
|
|
2629
|
-
var
|
|
2630
|
-
var
|
|
2629
|
+
var identityEventTypes2 = Object.values(IDENTITY_EVENT).map((e) => `\`${e}\``).join(", ");
|
|
2630
|
+
var activityEventTypes2 = Object.values(ACTIVITY_EVENT).map((e) => `\`${e}\``).join(", ");
|
|
2631
2631
|
var generateCookbookEvents = () => {
|
|
2632
2632
|
const fm = frontmatter({
|
|
2633
2633
|
root: false,
|
|
@@ -2648,7 +2648,7 @@ Subscribe to login, logout, refresh, and expired events. Useful for tracking
|
|
|
2648
2648
|
agent authentication state in your extension.
|
|
2649
2649
|
|
|
2650
2650
|
**Permission:** \`events:identity\`
|
|
2651
|
-
**Event types:** ${
|
|
2651
|
+
**Event types:** ${identityEventTypes2}
|
|
2652
2652
|
|
|
2653
2653
|
### Hook usage
|
|
2654
2654
|
|
|
@@ -2688,7 +2688,7 @@ Activity event names are domain-stripped \u2014 use \`useActivityEvent('product_
|
|
|
2688
2688
|
not \`'activity:product_view'\`.
|
|
2689
2689
|
|
|
2690
2690
|
**Permission:** \`events:activity\`
|
|
2691
|
-
**Well-known events:** ${
|
|
2691
|
+
**Well-known events:** ${activityEventTypes2}
|
|
2692
2692
|
|
|
2693
2693
|
### Hook usage
|
|
2694
2694
|
|
|
@@ -3770,10 +3770,10 @@ var createMcpServer = (options = {}) => {
|
|
|
3770
3770
|
return options.authContext.token;
|
|
3771
3771
|
}
|
|
3772
3772
|
try {
|
|
3773
|
-
return await getToken(
|
|
3773
|
+
return await getToken(STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
3774
3774
|
} catch {
|
|
3775
3775
|
}
|
|
3776
|
-
const { performOAuthFlow } = await import('./auth-
|
|
3776
|
+
const { performOAuthFlow } = await import('./auth-7GIVRWDG.js');
|
|
3777
3777
|
const MCP_API_BASE_URL = process.env.MCP_API_BASE_URL ?? DEFAULT_MCP_API_BASE_URL;
|
|
3778
3778
|
return performOAuthFlow(`${MCP_API_BASE_URL}/.well-known/oauth-authorization-server`);
|
|
3779
3779
|
};
|
|
@@ -3808,7 +3808,7 @@ var createMcpServer = (options = {}) => {
|
|
|
3808
3808
|
if (e.message.includes("fetch")) {
|
|
3809
3809
|
const MCP_API_BASE_URL = process.env.MCP_API_BASE_URL ?? DEFAULT_MCP_API_BASE_URL;
|
|
3810
3810
|
return errorContent(
|
|
3811
|
-
`MCP auth flow failed: ${e.message}. Check MCP_API_BASE_URL env var (currently "${MCP_API_BASE_URL}"). To re-auth from scratch: rm
|
|
3811
|
+
`MCP auth flow failed: ${e.message}. Check MCP_API_BASE_URL env var (currently "${MCP_API_BASE_URL}"). To re-auth from scratch: rm ${MCP_AUTH_FILE}`
|
|
3812
3812
|
);
|
|
3813
3813
|
}
|
|
3814
3814
|
return errorContent(e.message);
|