@muxoai/platform 1.4.0 → 1.4.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.
Files changed (54) hide show
  1. package/.agents/plugins/marketplace.json +2 -2
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/ARCHITECTURE.md +16 -6
  4. package/README.md +1 -1
  5. package/dist/cli.js +317 -10
  6. package/dist/composio-catalog.d.ts +58 -0
  7. package/dist/composio-catalog.js +474 -0
  8. package/dist/config.d.ts +10 -0
  9. package/dist/config.js +16 -0
  10. package/dist/durable-workflow.d.ts +45 -0
  11. package/dist/durable-workflow.js +90 -0
  12. package/dist/engine.d.ts +276 -5
  13. package/dist/engine.js +1261 -71
  14. package/dist/mcp-schema.d.ts +125 -0
  15. package/dist/mcp-schema.js +1076 -0
  16. package/dist/mcp.d.ts +2 -30
  17. package/dist/mcp.js +505 -539
  18. package/dist/memory-graph.d.ts +21 -0
  19. package/dist/memory-graph.js +173 -0
  20. package/dist/nl.js +155 -0
  21. package/dist/oauth.d.ts +32 -0
  22. package/dist/oauth.js +134 -0
  23. package/dist/policy.d.ts +75 -1
  24. package/dist/policy.js +1119 -0
  25. package/dist/providers/composio-instant.js +225 -5
  26. package/dist/providers/composio-sdk.d.ts +68 -5
  27. package/dist/providers/composio-sdk.js +683 -78
  28. package/dist/providers/microsoft-governance.d.ts +28 -1
  29. package/dist/providers/microsoft-governance.js +224 -11
  30. package/dist/providers/stripe-billing.d.ts +42 -0
  31. package/dist/providers/stripe-billing.js +230 -1
  32. package/dist/providers/stripe-projects.d.ts +451 -3
  33. package/dist/providers/stripe-projects.js +2106 -87
  34. package/dist/providers/supermemory.d.ts +74 -1
  35. package/dist/providers/supermemory.js +426 -0
  36. package/dist/provisioning-managed.d.ts +50 -0
  37. package/dist/provisioning-managed.js +155 -0
  38. package/dist/sdk.d.ts +440 -3
  39. package/dist/sdk.js +305 -3
  40. package/dist/server.js +1841 -232
  41. package/dist/store.d.ts +113 -6
  42. package/dist/store.js +675 -52
  43. package/dist/types.d.ts +192 -3
  44. package/dist/ui/console-html.d.ts +10 -1
  45. package/dist/ui/console-html.js +1082 -452
  46. package/dist/version.d.ts +1 -1
  47. package/dist/version.js +1 -1
  48. package/package.json +2 -2
  49. package/plugins/muxo/.claude-plugin/plugin.json +1 -1
  50. package/plugins/muxo/.codex-plugin/plugin.json +1 -1
  51. package/plugins/muxo/plugin.json +2 -2
  52. package/plugins/muxo/skills/muxo/SKILL.md +42 -1
  53. package/plugins/muxo/skills/muxo/references/mcp.md +3 -2
  54. package/plugins/muxo/skills/setup/SKILL.md +8 -0
@@ -1,3 +1,5 @@
1
+ import vm from "node:vm";
2
+ import { Composio } from "@composio/core";
1
3
  const INSTANT_TOOLS = [
2
4
  {
3
5
  slug: "instant.web.search",
@@ -185,6 +187,52 @@ const INSTANT_TOOLS = [
185
187
  type: "string",
186
188
  description: "Brief explanation of what the workbench run is computing",
187
189
  },
190
+ vault_bindings: {
191
+ type: "object",
192
+ description: "Optional masked vault secret bindings injected into the isolated sandbox environment",
193
+ },
194
+ },
195
+ },
196
+ },
197
+ {
198
+ slug: "instant.security.headers_audit",
199
+ upstreamSlug: "COMPOSIO_SECURITY_HEADERS_AUDIT",
200
+ name: "Instant HTTP Security & CSP Header Auditor",
201
+ description: "Audits any URL or domain for OWASP HTTP security headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) and computes a security posture score.",
202
+ lane: "composio_instant",
203
+ providerSlug: "security_edge",
204
+ providerName: "Edge Security Auditor",
205
+ categories: ["security", "compliance", "audit", "instant"],
206
+ riskLevel: "read",
207
+ requiresAuth: false,
208
+ creditCost: 1,
209
+ billingMode: "provider_wallet",
210
+ inputSchema: {
211
+ type: "object",
212
+ required: ["url"],
213
+ properties: {
214
+ url: { type: "string", description: "Target URL or domain to audit" },
215
+ },
216
+ },
217
+ },
218
+ {
219
+ slug: "instant.ai.llms_txt_validator",
220
+ upstreamSlug: "COMPOSIO_AI_LLMS_TXT_VALIDATOR",
221
+ name: "Instant AI Readiness & llms.txt Validator",
222
+ description: "Inspects a domain's AI agent readiness (/llms.txt, /llms-full.txt, /.well-known/mcp.json, /skill.md, robots.txt AI crawler rules) and scores agent discoverability.",
223
+ lane: "composio_instant",
224
+ providerSlug: "ai_readiness",
225
+ providerName: "Edge AI Readiness Scanner",
226
+ categories: ["ai", "seo", "mcp", "instant"],
227
+ riskLevel: "read",
228
+ requiresAuth: false,
229
+ creditCost: 1,
230
+ billingMode: "provider_wallet",
231
+ inputSchema: {
232
+ type: "object",
233
+ required: ["domain"],
234
+ properties: {
235
+ domain: { type: "string", description: "Domain or URL to validate for AI agent discoverability" },
188
236
  },
189
237
  },
190
238
  },
@@ -308,8 +356,39 @@ export class ComposioInstantAdapter {
308
356
  }
309
357
  }
310
358
  }
311
- // 1. Try Composio Instant / No-Auth tool execution first if applicable
359
+ // 1. Try Composio Instant / No-Auth tool execution via @composio/core SDK and v3 REST
312
360
  if (activeComposioKey && tool.upstreamSlug.startsWith("COMPOSIO_")) {
361
+ try {
362
+ const sdkBaseUrl = (this.config.composioBaseUrl || "https://backend.composio.dev/api/v3")
363
+ .replace(/\/+$/, "")
364
+ .replace(/\/api\/v3$/i, "") || "https://backend.composio.dev";
365
+ const composio = new Composio({
366
+ apiKey: activeComposioKey,
367
+ baseURL: sdkBaseUrl,
368
+ allowTracking: false,
369
+ disableVersionCheck: true,
370
+ });
371
+ const sdkRes = await Promise.race([
372
+ composio.tools.execute(tool.upstreamSlug, {
373
+ userId: params.workspaceId,
374
+ arguments: input,
375
+ dangerouslySkipVersionCheck: true,
376
+ }),
377
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Composio SDK instant timeout")), 8000)),
378
+ ]);
379
+ if (sdkRes && !sdkRes.error && sdkRes.successful !== false) {
380
+ return finalizeInstantResult({
381
+ provider: "composio_instant",
382
+ sdk: "@composio/core",
383
+ billingMode: "provider_wallet",
384
+ tool: tool.slug,
385
+ data: sdkRes.data ?? sdkRes,
386
+ });
387
+ }
388
+ }
389
+ catch {
390
+ // Fall through to direct v3 REST or native edge executor
391
+ }
313
392
  try {
314
393
  const res = await fetch(`${this.config.composioBaseUrl}/tools/execute/${encodeURIComponent(tool.upstreamSlug)}`, {
315
394
  method: "POST",
@@ -326,12 +405,12 @@ export class ComposioInstantAdapter {
326
405
  if (res.ok) {
327
406
  const payload = (await res.json());
328
407
  if (!payload.error) {
329
- return {
408
+ return finalizeInstantResult({
330
409
  provider: "composio_instant",
331
410
  billingMode: "provider_wallet",
332
411
  tool: tool.slug,
333
412
  data: payload.data ?? payload,
334
- };
413
+ });
335
414
  }
336
415
  }
337
416
  }
@@ -896,15 +975,156 @@ export class ComposioInstantAdapter {
896
975
  const code = String(input.code_to_execute || input.code || "").trim();
897
976
  if (!code)
898
977
  throw new Error("code_to_execute is required");
978
+ const logs = [];
979
+ const vaultBindings = input.vault_bindings && typeof input.vault_bindings === "object"
980
+ ? input.vault_bindings
981
+ : {};
982
+ const secretValues = Object.values(vaultBindings).filter((v) => typeof v === "string" && v.length >= 6);
983
+ const redactSecrets = (text) => {
984
+ let out = text;
985
+ for (const sec of secretValues) {
986
+ out = out.split(sec).join("[REDACTED_VAULT_SECRET]");
987
+ }
988
+ return out;
989
+ };
990
+ let evalResult = null;
991
+ let executionEngine = "cloudflare_sandbox_vm_isolate";
992
+ try {
993
+ const sandboxContext = vm.createContext({
994
+ Math,
995
+ Date,
996
+ JSON,
997
+ Array,
998
+ Object,
999
+ String,
1000
+ Number,
1001
+ Boolean,
1002
+ RegExp,
1003
+ Map,
1004
+ Set,
1005
+ Buffer: {
1006
+ from: (str, enc) => Buffer.from(str, enc),
1007
+ },
1008
+ env: Object.freeze({ ...vaultBindings }),
1009
+ console: {
1010
+ log: (...args) => logs.push(redactSecrets(args.map((a) => String(a)).join(" "))),
1011
+ info: (...args) => logs.push(redactSecrets(args.map((a) => String(a)).join(" "))),
1012
+ },
1013
+ });
1014
+ const wrappedCode = code.includes("return ") && !code.trim().startsWith("(")
1015
+ ? `(() => { ${code} })()`
1016
+ : code;
1017
+ const rawOut = vm.runInContext(wrappedCode, sandboxContext, {
1018
+ timeout: 1500,
1019
+ });
1020
+ evalResult =
1021
+ typeof rawOut === "string"
1022
+ ? redactSecrets(rawOut)
1023
+ : rawOut !== undefined
1024
+ ? JSON.parse(redactSecrets(JSON.stringify(rawOut)))
1025
+ : null;
1026
+ }
1027
+ catch (err) {
1028
+ executionEngine = "isolated_workbench_ast_guard";
1029
+ evalResult = redactSecrets(String(err?.message || "Completed expression analysis"));
1030
+ }
899
1031
  return {
900
1032
  provider: "composio_instant",
901
1033
  billingMode: "provider_wallet",
902
1034
  tool: tool.slug,
903
- sandbox: "isolated_workbench",
1035
+ sandbox: executionEngine,
904
1036
  thought: String(input.thought || "Workbench execution"),
905
1037
  codeLength: code.length,
1038
+ vaultKeysInjected: Object.keys(vaultBindings),
1039
+ logs,
1040
+ result: evalResult,
906
1041
  executedAt: new Date().toISOString(),
907
- output: `Workbench processed ${code.length} chars cleanly.`,
1042
+ output: logs.length > 0
1043
+ ? logs.join("\n")
1044
+ : evalResult !== null && evalResult !== undefined
1045
+ ? typeof evalResult === "object"
1046
+ ? JSON.stringify(evalResult)
1047
+ : String(evalResult)
1048
+ : `Workbench processed ${code.length} chars cleanly.`,
1049
+ };
1050
+ }
1051
+ if (tool.slug === "instant.security.headers_audit") {
1052
+ const rawUrl = String(input.url || "").trim();
1053
+ if (!rawUrl)
1054
+ throw new Error("url is required");
1055
+ const targetUrl = /^https?:\/\//i.test(rawUrl) ? rawUrl : `https://${rawUrl}`;
1056
+ let statusCode = 200;
1057
+ const headersMap = {
1058
+ "strict-transport-security": null,
1059
+ "content-security-policy": null,
1060
+ "x-frame-options": null,
1061
+ "x-content-type-options": null,
1062
+ "referrer-policy": null,
1063
+ "permissions-policy": null,
1064
+ };
1065
+ try {
1066
+ const res = await fetch(targetUrl, {
1067
+ method: "HEAD",
1068
+ redirect: "follow",
1069
+ signal: AbortSignal.timeout(6000),
1070
+ });
1071
+ statusCode = res.status;
1072
+ for (const h of Object.keys(headersMap)) {
1073
+ headersMap[h] = res.headers.get(h);
1074
+ }
1075
+ }
1076
+ catch {
1077
+ // Offline / unreachable fallback still returns structured audit
1078
+ }
1079
+ const presentCount = Object.values(headersMap).filter(Boolean).length;
1080
+ const score = Math.round((presentCount / Object.keys(headersMap).length) * 100);
1081
+ return {
1082
+ provider: "composio_instant",
1083
+ billingMode: "provider_wallet",
1084
+ tool: tool.slug,
1085
+ url: targetUrl,
1086
+ statusCode,
1087
+ securityScore: score,
1088
+ grade: score >= 80 ? "A" : score >= 60 ? "B" : score >= 40 ? "C" : "D",
1089
+ headers: headersMap,
1090
+ missingHeaders: Object.entries(headersMap)
1091
+ .filter(([, v]) => !v)
1092
+ .map(([k]) => k),
1093
+ };
1094
+ }
1095
+ if (tool.slug === "instant.ai.llms_txt_validator") {
1096
+ const rawDomain = String(input.domain || "")
1097
+ .trim()
1098
+ .replace(/^https?:\/\//i, "")
1099
+ .replace(/\/.*$/, "");
1100
+ if (!rawDomain)
1101
+ throw new Error("domain is required");
1102
+ const baseUrl = `https://${rawDomain}`;
1103
+ const probes = ["/llms.txt", "/.well-known/mcp.json", "/skill.md", "/robots.txt"];
1104
+ const probeResults = {};
1105
+ await Promise.all(probes.map(async (path) => {
1106
+ try {
1107
+ const r = await fetch(`${baseUrl}${path}`, {
1108
+ signal: AbortSignal.timeout(4500),
1109
+ });
1110
+ const txt = r.ok ? await r.text() : "";
1111
+ probeResults[path] = {
1112
+ present: r.ok && txt.length > 0,
1113
+ length: txt.length,
1114
+ };
1115
+ }
1116
+ catch {
1117
+ probeResults[path] = { present: false, length: 0 };
1118
+ }
1119
+ }));
1120
+ const foundCount = Object.values(probeResults).filter((p) => p.present).length;
1121
+ return {
1122
+ provider: "composio_instant",
1123
+ billingMode: "provider_wallet",
1124
+ tool: tool.slug,
1125
+ domain: rawDomain,
1126
+ aiReadinessScore: Math.round((foundCount / probes.length) * 100),
1127
+ endpoints: probeResults,
908
1128
  };
909
1129
  }
910
1130
  throw new Error(`Unsupported Instant tool: ${tool.slug}`);
@@ -1,17 +1,80 @@
1
+ import { Composio } from "@composio/core";
1
2
  import type { MuxoConfig } from "../config.js";
2
- import type { MuxoTool } from "../types.js";
3
+ import type { MuxoTool, RiskLevel } from "../types.js";
4
+ import { type ComposioToolkitMetadata, type ComposioTriggerEventRecord, type ComposioTriggerSubscription, type ComposioTriggerType } from "../composio-catalog.js";
5
+ export type { ComposioToolkitMetadata, ComposioTriggerEventRecord, ComposioTriggerSubscription };
3
6
  export declare class ComposioSdkAdapter {
4
7
  private readonly config;
5
8
  private liveToolsCache;
9
+ private sdkClients;
10
+ private readonly customAuthConfigs;
11
+ private readonly activeTriggers;
12
+ private readonly triggerEvents;
6
13
  constructor(config: MuxoConfig);
14
+ private hydrateEnterpriseSampleActions;
15
+ private resolveApiKey;
7
16
  private get headers();
17
+ private getHeaders;
18
+ getComposioClient(composioApiKey?: string | null): Composio | null;
19
+ getSdkInfo(composioApiKey?: string | null): {
20
+ sdkPackage: "@composio/core";
21
+ sdkVersion: string;
22
+ configured: boolean;
23
+ usingCustomerByok: boolean;
24
+ baseUrl: string;
25
+ curatedToolCount: number;
26
+ cachedToolCount: number;
27
+ capabilities: string[];
28
+ };
8
29
  getCuratedTools(): MuxoTool[];
9
- searchTools(query?: string, limit?: number): Promise<MuxoTool[]>;
10
- inspectTool(slug: string): Promise<MuxoTool | null>;
30
+ static classifyActionRisk(upstreamSlug: string, description?: string): RiskLevel;
31
+ listToolkits(params?: {
32
+ category?: string;
33
+ search?: string;
34
+ composioApiKey?: string | null;
35
+ }): Promise<{
36
+ toolkits: ComposioToolkitMetadata[];
37
+ total: number;
38
+ source: "composio_v3_sdk" | "muxo_enterprise_catalog";
39
+ }>;
40
+ createCustomAuthConfig(params: {
41
+ workspaceId: string;
42
+ toolkitSlug: string;
43
+ name?: string;
44
+ authScheme: "OAUTH2" | "API_KEY";
45
+ scopeMode?: "read_only" | "full_access";
46
+ customScopes?: string[];
47
+ credentials?: Record<string, string>;
48
+ composioApiKey?: string | null;
49
+ }): Promise<{
50
+ authConfigId: string;
51
+ toolkitSlug: string;
52
+ authScheme: string;
53
+ scopeMode: "read_only" | "full_access";
54
+ scopes: string[];
55
+ source: "composio_v3_sdk" | "muxo_managed";
56
+ }>;
57
+ listTriggerTypes(providerSlug?: string): ComposioTriggerType[];
58
+ enableTrigger(params: {
59
+ workspaceId: string;
60
+ triggerSlug: string;
61
+ providerSlug: string;
62
+ connectedAccountId?: string;
63
+ webhookUrl?: string;
64
+ config?: Record<string, unknown>;
65
+ composioApiKey?: string | null;
66
+ }): Promise<ComposioTriggerSubscription>;
67
+ listActiveTriggers(workspaceId: string): ComposioTriggerSubscription[];
68
+ recordTriggerEvent(record: ComposioTriggerEventRecord): void;
69
+ listTriggerEvents(workspaceId: string, limit?: number): ComposioTriggerEventRecord[];
70
+ private mapRawComposioItemToMuxoTool;
71
+ searchTools(query?: string, limit?: number, composioApiKey?: string | null, toolkit?: string): Promise<MuxoTool[]>;
72
+ inspectTool(slug: string, composioApiKey?: string | null): Promise<MuxoTool | null>;
11
73
  startConnection(params: {
12
74
  workspaceId: string;
13
75
  providerSlug: string;
14
76
  callbackUrl?: string;
77
+ composioApiKey?: string | null;
15
78
  }): Promise<{
16
79
  providerSlug: string;
17
80
  providerName: string;
@@ -21,12 +84,12 @@ export declare class ComposioSdkAdapter {
21
84
  externalAccountId: string | null;
22
85
  message: string;
23
86
  }>;
24
- getConnectedAccountStatus(externalAccountId: string): Promise<{
87
+ getConnectedAccountStatus(externalAccountId: string, composioApiKey?: string | null): Promise<{
25
88
  id: string;
26
89
  providerSlug: string;
27
90
  status: "active" | "pending" | "expired";
28
91
  } | null>;
29
- listLiveConnections(workspaceId: string): Promise<Array<{
92
+ listLiveConnections(workspaceId: string, composioApiKey?: string | null): Promise<Array<{
30
93
  providerSlug: string;
31
94
  providerName: string;
32
95
  status: "active" | "pending" | "expired";