@stackable-labs/mcp-app-extension 0.24.0 → 1.0.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/server.js CHANGED
@@ -1,8 +1,12 @@
1
- import { STANDALONE_CLIENT, MCP_AUTH_FILE, getToken, STANDALONE_CLIENT_AUTH_FILE } from './chunk-HOOVB46Z.js';
2
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
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';
2
+ import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, TEMPLATE_FLAVORS, PERMISSIONS, CAPABILITY_PERMISSION_MAP, EVENT_HOOK_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_ATTRIBUTES, tagToComponentName } from '@stackable-labs/sdk-extension-contracts';
3
+ import { readFile } from 'fs/promises';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
4
6
  import { z } from 'zod';
5
7
 
8
+ // src/server.ts
9
+
6
10
  // ../../sdk/extension/ai-docs/src/generated/template-content.ts
7
11
  var PATTERN_SECTIONS = [
8
12
  {
@@ -1736,8 +1740,6 @@ export const Header = () => {
1736
1740
  - **Use ScrollArea** \u2014 wrap content surfaces in \`<ui.ScrollArea>\` for overflow handling
1737
1741
  `;
1738
1742
  };
1739
-
1740
- // ../../sdk/extension/ai-docs/src/cli-commands.ts
1741
1743
  var DLX = "pnpm --config.dlx-cache-max-age=0 dlx";
1742
1744
  var CLI = {
1743
1745
  /** Scaffold a new extension project */
@@ -1766,11 +1768,14 @@ var CLI = {
1766
1768
  mcp: `${DLX} @stackable-labs/cli-app-extension@latest ai mcp`
1767
1769
  }
1768
1770
  };
1769
- var TEMPLATE_FLAVORS = [
1770
- { name: "minimal", label: "Minimal", description: "Bare minimum \u2014 single surface, hello-world component" },
1771
- { name: "starter", label: "Starter", description: "Common patterns \u2014 store, api helpers, menu (default)" },
1772
- { name: "kitchen-sink", label: "Kitchen Sink", description: "Everything \u2014 every component, capability, surface, and hook" }
1773
- ];
1771
+ var TEMPLATE_FLAVOR_META = {
1772
+ minimal: { label: "Minimal", description: "Bare minimum \u2014 single surface, hello-world component" },
1773
+ starter: { label: "Starter", description: "Common patterns \u2014 store, api helpers, menu (default)" },
1774
+ "kitchen-sink": { label: "Kitchen Sink", description: "Everything \u2014 every component, capability, surface, and hook" }
1775
+ };
1776
+ var TEMPLATE_FLAVOR_DETAILS = TEMPLATE_FLAVORS.map(
1777
+ (name) => ({ name, ...TEMPLATE_FLAVOR_META[name] })
1778
+ );
1774
1779
 
1775
1780
  // ../../sdk/extension/ai-docs/src/generators/quick-start.ts
1776
1781
  var generateQuickStart = () => {
@@ -1962,7 +1967,7 @@ var generateCliReference = () => {
1962
1967
  description: "CLI commands for creating, developing, and deploying Stackable extensions",
1963
1968
  globs: ["packages/extension/src/**/*.tsx", "packages/extension/src/**/*.ts"]
1964
1969
  });
1965
- const templateRows = TEMPLATE_FLAVORS.map((t) => `| \`${t.name}\` | ${t.description} |`).join("\n");
1970
+ const templateRows = TEMPLATE_FLAVOR_DETAILS.map((t) => `| \`${t.name}\` | ${t.description} |`).join("\n");
1966
1971
  return `${fm}
1967
1972
 
1968
1973
  # CLI Reference
@@ -3380,6 +3385,7 @@ var generateValidateExtensionCommand = () => {
3380
3385
  description: "Validate this extension for common errors before deploying (manifest, permissions, surfaces, imports)",
3381
3386
  targets: ["*"]
3382
3387
  });
3388
+ const eventHookBullets = Object.keys(EVENT_HOOK_PERMISSION_MAP).map((hook) => `- \`${hook}\` \u2192 needs \`${EVENT_HOOK_PERMISSION_MAP[hook]}\` permission (also check manifest \`events\` array has matching entries)`).join("\n");
3383
3389
  return `${fm}
3384
3390
 
3385
3391
  # Validate Extension
@@ -3415,9 +3421,7 @@ Scan all \`.tsx\` files in \`packages/extension/src/\` for capability usage:
3415
3421
  - \`capabilities.actions.toast\` \u2192 needs \`actions:toast\` permission
3416
3422
  - \`capabilities.actions.invoke\` \u2192 needs \`actions:invoke\` permission
3417
3423
  - \`useExtendIdentity\` \u2192 needs \`extend:identity\` permission
3418
- - \`useIdentityEvent\` \u2192 needs \`events:identity\` permission (also check manifest \`events\` array has matching entries)
3419
- - \`useMessagingEvent\` \u2192 needs \`events:messaging\` permission (also check manifest \`events\` array has matching entries)
3420
- - \`useActivityEvent\` \u2192 needs \`events:activity\` permission (also check manifest \`events\` array has matching entries)
3424
+ ${eventHookBullets}
3421
3425
 
3422
3426
  Report:
3423
3427
  - **Missing permissions:** capabilities used in code but not declared in manifest
@@ -4431,6 +4435,64 @@ pair(EXAMPLE_SNIPPETS, EXAMPLE_SNIPPETS2);
4431
4435
  pair(CAPABILITY_SNIPPETS, CAPABILITY_SNIPPETS2);
4432
4436
  pair(EVENT_SNIPPETS, EVENT_SNIPPETS2);
4433
4437
 
4438
+ // ../../lib/contracts/src/custom.ts
4439
+ var CUSTOM_ROLE = {
4440
+ SUPER_ADMIN: "super_admin"
4441
+ };
4442
+ new Set(Object.values(CUSTOM_ROLE));
4443
+
4444
+ // ../../lib/utils-auth/src/constants.ts
4445
+ var STANDALONE_CLIENT_DATA = {
4446
+ CLI: { name: "@stackable-labs/cli-app-extension", authFile: "cli-auth.json" },
4447
+ MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
4448
+ };
4449
+ var STANDALONE_CLIENT = Object.fromEntries(
4450
+ Object.entries(STANDALONE_CLIENT_DATA).map(([k, v]) => [k, v.name])
4451
+ );
4452
+ var STANDALONE_CLIENT_AUTH_FILE = Object.fromEntries(
4453
+ Object.entries(STANDALONE_CLIENT_DATA).map(([k, v]) => [k, v.authFile])
4454
+ );
4455
+ Object.values(STANDALONE_CLIENT);
4456
+
4457
+ // ../../lib/utils-auth/src/index.ts
4458
+ var AUTH_DIR = join(homedir(), ".stackable");
4459
+ join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.CLI);
4460
+ var MCP_AUTH_FILE = join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.MCP);
4461
+ var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? STANDALONE_CLIENT_AUTH_FILE.CLI);
4462
+ var readAuthState = async (filename) => {
4463
+ try {
4464
+ const content = await readFile(resolveAuthFile(filename), "utf8");
4465
+ return JSON.parse(content);
4466
+ } catch {
4467
+ return null;
4468
+ }
4469
+ };
4470
+ var decodeJwtPayload = (token) => {
4471
+ try {
4472
+ const [, payload] = token.split(".");
4473
+ if (!payload) {
4474
+ return null;
4475
+ }
4476
+ const json = Buffer.from(payload, "base64url").toString("utf8");
4477
+ return JSON.parse(json);
4478
+ } catch {
4479
+ return null;
4480
+ }
4481
+ };
4482
+ var getToken = async (filename) => {
4483
+ const state = await readAuthState(filename);
4484
+ if (!state) {
4485
+ throw new Error("Not authenticated. Run `stackable-app-extension auth login` first.");
4486
+ }
4487
+ const payload = decodeJwtPayload(state.token);
4488
+ if (payload?.exp && typeof payload.exp === "number") {
4489
+ if (Date.now() >= payload.exp * 1e3) {
4490
+ throw new Error("Session expired. Run `stackable-app-extension auth login` to re-authenticate.");
4491
+ }
4492
+ }
4493
+ return state.token;
4494
+ };
4495
+
4434
4496
  // package.json
4435
4497
  var package_default = {
4436
4498
  version: "0.0.0"};
@@ -4454,9 +4516,13 @@ var createMcpServer = (options = {}) => {
4454
4516
  return await getToken(STANDALONE_CLIENT_AUTH_FILE.MCP);
4455
4517
  } catch {
4456
4518
  }
4457
- const { performOAuthFlow } = await import('./auth-DWIWIJNN.js');
4519
+ if (!options.performOAuthFlow) {
4520
+ throw new Error(
4521
+ "No auth token available. Provide authContext (server) or performOAuthFlow (CLI)."
4522
+ );
4523
+ }
4458
4524
  const MCP_API_BASE_URL = process.env.MCP_API_BASE_URL ?? DEFAULT_MCP_API_BASE_URL;
4459
- return performOAuthFlow(`${MCP_API_BASE_URL}/.well-known/oauth-authorization-server`);
4525
+ return options.performOAuthFlow(`${MCP_API_BASE_URL}/.well-known/oauth-authorization-server`);
4460
4526
  };
4461
4527
  const authHeaders = (token) => ({
4462
4528
  authorization: `Bearer ${token}`,
@@ -4593,12 +4659,7 @@ ${errors.map((e) => `- ${e}`).join("\n")}`);
4593
4659
  usedPermissions.add(permission);
4594
4660
  }
4595
4661
  }
4596
- const eventHookMap = {
4597
- useIdentityEvent: "events:identity",
4598
- useMessagingEvent: "events:messaging",
4599
- useActivityEvent: "events:activity"
4600
- };
4601
- for (const [hook, permission] of Object.entries(eventHookMap)) {
4662
+ for (const [hook, permission] of Object.entries(EVENT_HOOK_PERMISSION_MAP)) {
4602
4663
  if (allSource.includes(hook)) {
4603
4664
  usedPermissions.add(permission);
4604
4665
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackable-labs/mcp-app-extension",
3
- "version": "0.24.0",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mcp-app-extension": "./dist/index.js"