@muxoai/sdk 1.3.0 → 1.4.2

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 (72) hide show
  1. package/.agents/plugins/marketplace.json +2 -2
  2. package/.claude-plugin/marketplace.json +19 -4
  3. package/.codex/config.toml +9 -2
  4. package/ARCHITECTURE.md +16 -6
  5. package/README.md +69 -24
  6. package/dist/clerk.d.ts +35 -0
  7. package/dist/clerk.js +201 -0
  8. package/dist/cli.js +1589 -103
  9. package/dist/composio-catalog.d.ts +234 -0
  10. package/dist/composio-catalog.js +1894 -0
  11. package/dist/config.d.ts +16 -0
  12. package/dist/config.js +27 -1
  13. package/dist/durable-workflow.d.ts +45 -0
  14. package/dist/durable-workflow.js +90 -0
  15. package/dist/engine.d.ts +315 -6
  16. package/dist/engine.js +1778 -94
  17. package/dist/mcp-schema.d.ts +286 -0
  18. package/dist/mcp-schema.js +2559 -0
  19. package/dist/mcp.d.ts +2 -25
  20. package/dist/mcp.js +949 -507
  21. package/dist/memory-graph.d.ts +21 -0
  22. package/dist/memory-graph.js +173 -0
  23. package/dist/nl.js +214 -35
  24. package/dist/oauth.d.ts +32 -0
  25. package/dist/oauth.js +134 -0
  26. package/dist/policy.d.ts +190 -0
  27. package/dist/policy.js +1597 -0
  28. package/dist/providers/composio-instant.d.ts +4 -0
  29. package/dist/providers/composio-instant.js +890 -535
  30. package/dist/providers/composio-sdk.d.ts +126 -5
  31. package/dist/providers/composio-sdk.js +902 -79
  32. package/dist/providers/microsoft-governance.d.ts +89 -3
  33. package/dist/providers/microsoft-governance.js +673 -26
  34. package/dist/providers/stripe-billing.d.ts +42 -0
  35. package/dist/providers/stripe-billing.js +244 -5
  36. package/dist/providers/stripe-projects.d.ts +459 -4
  37. package/dist/providers/stripe-projects.js +2674 -122
  38. package/dist/providers/supermemory.d.ts +102 -6
  39. package/dist/providers/supermemory.js +609 -55
  40. package/dist/provisioning-managed.d.ts +50 -0
  41. package/dist/provisioning-managed.js +155 -0
  42. package/dist/sdk.d.ts +705 -7
  43. package/dist/sdk.js +488 -10
  44. package/dist/server.js +2646 -348
  45. package/dist/store.d.ts +138 -6
  46. package/dist/store.js +932 -58
  47. package/dist/types.d.ts +312 -4
  48. package/dist/ui/console-html.d.ts +62 -0
  49. package/dist/ui/console-html.js +3742 -2228
  50. package/dist/ui/design-tokens.d.ts +177 -0
  51. package/dist/ui/design-tokens.js +210 -0
  52. package/dist/version.d.ts +1 -0
  53. package/dist/version.js +1 -0
  54. package/package.json +5 -4
  55. package/plugins/muxo/.app.json +1 -1
  56. package/plugins/muxo/.claude-plugin/plugin.json +3 -3
  57. package/plugins/muxo/.codex-plugin/plugin.json +19 -10
  58. package/plugins/muxo/.cursor-plugin/plugin.json +30 -0
  59. package/plugins/muxo/.mcp.json +1 -33
  60. package/plugins/muxo/assets/logo.png +0 -0
  61. package/plugins/muxo/hooks/session-start.sh +16 -4
  62. package/plugins/muxo/hooks/user-prompt-submit.sh +14 -1
  63. package/plugins/muxo/mcp.json +0 -10
  64. package/plugins/muxo/plugin.json +65 -8
  65. package/plugins/muxo/skills/muxo/SKILL.md +142 -14
  66. package/plugins/muxo/skills/muxo/agents/openai.yaml +12 -0
  67. package/plugins/muxo/skills/muxo/references/cli.md +9 -3
  68. package/plugins/muxo/skills/muxo/references/mcp.md +22 -10
  69. package/plugins/muxo/skills/muxo-activity-summary/SKILL.md +81 -0
  70. package/plugins/muxo/skills/setup/SKILL.md +17 -3
  71. package/plugins/muxo/skills/setup/agents/openai.yaml +12 -0
  72. package/src/catalogues/stripe-projects-catalog.json +140 -0
@@ -1,11 +1,27 @@
1
1
  import type { MuxoConfig } from "../config.js";
2
2
  import type { MuxoStore } from "../store.js";
3
3
  import type { ToolDescriptor, Workspace } from "../types.js";
4
+ export declare const BILLING_TOOLS: ToolDescriptor[];
5
+ export interface StripeMeterEventRecord {
6
+ identifier: string;
7
+ event_name: string;
8
+ timestamp: string;
9
+ workspaceId: string;
10
+ stripe_customer_id: string;
11
+ value: number;
12
+ lane: string;
13
+ tool_slug: string;
14
+ livemode: boolean;
15
+ source: "stripe_v2_meter_stream" | "muxo_local_meter";
16
+ }
4
17
  export declare class StripeBillingAdapter {
5
18
  private readonly config;
6
19
  private readonly store;
7
20
  private resolvedStarterPriceId;
8
21
  private resolvedCreditsPriceId;
22
+ private meterSessionToken;
23
+ private readonly meterEvents;
24
+ private readonly seenMeterIdentifiers;
9
25
  constructor(config: MuxoConfig, store: MuxoStore);
10
26
  private getEffectiveStripeKey;
11
27
  get isConfigured(): boolean;
@@ -38,4 +54,30 @@ export declare class StripeBillingAdapter {
38
54
  input: Record<string, unknown>;
39
55
  }): Promise<Record<string, unknown>>;
40
56
  verifyWebhookSignature(rawBody: string, signatureHeader: string): boolean;
57
+ createMeterEventSession(workspaceId?: string): Promise<{
58
+ object: "v2.billing.meter_event_session";
59
+ authentication_token: string;
60
+ created: string;
61
+ expires_at: string;
62
+ livemode: boolean;
63
+ source: "stripe_v2_api" | "muxo_managed";
64
+ }>;
65
+ recordMeterEvent(params: {
66
+ workspace: Workspace;
67
+ event_name?: string;
68
+ value: number;
69
+ lane?: string;
70
+ tool_slug?: string;
71
+ identifier?: string;
72
+ timestamp?: string;
73
+ }): Promise<{
74
+ recorded: boolean;
75
+ deduplicated: boolean;
76
+ event: StripeMeterEventRecord;
77
+ }>;
78
+ listMeterEvents(workspaceId: string, limit?: number): {
79
+ events: StripeMeterEventRecord[];
80
+ totalValue: number;
81
+ byLane: Record<string, number>;
82
+ };
41
83
  }
@@ -1,5 +1,5 @@
1
1
  import crypto from "node:crypto";
2
- const BILLING_TOOLS = [
2
+ export const BILLING_TOOLS = [
3
3
  {
4
4
  slug: "billing.credits.topup",
5
5
  upstreamSlug: "STRIPE_BILLING_CREDITS_TOPUP",
@@ -79,12 +79,49 @@ const BILLING_TOOLS = [
79
79
  required: ["kind"],
80
80
  },
81
81
  },
82
+ {
83
+ slug: "billing.stripe.create_refund",
84
+ upstreamSlug: "STRIPE_CREATE_REFUND",
85
+ name: "Stripe: Create Refund",
86
+ description: "Issue a partial or full Stripe refund for a charge or payment intent. Supports conditional dollar threshold guardrails (e.g. auto-approve under $50, require approval over $50).",
87
+ lane: "stripe_projects",
88
+ providerSlug: "stripe_billing",
89
+ providerName: "Stripe Billing",
90
+ categories: ["billing", "finance"],
91
+ riskLevel: "financial",
92
+ requiresAuth: false,
93
+ creditCost: 0,
94
+ billingMode: "provider_wallet",
95
+ inputSchema: {
96
+ type: "object",
97
+ properties: {
98
+ charge_id: {
99
+ type: "string",
100
+ description: "Stripe Charge ID (ch_...) or PaymentIntent ID (pi_...)",
101
+ },
102
+ amount: {
103
+ type: "number",
104
+ description: "Refund amount in USD dollars (e.g. 25 for $25.00)",
105
+ },
106
+ reason: {
107
+ type: "string",
108
+ enum: ["duplicate", "fraudulent", "requested_by_customer"],
109
+ default: "requested_by_customer",
110
+ description: "Reason for refund",
111
+ },
112
+ },
113
+ required: ["amount"],
114
+ },
115
+ },
82
116
  ];
83
117
  export class StripeBillingAdapter {
84
118
  config;
85
119
  store;
86
120
  resolvedStarterPriceId = null;
87
121
  resolvedCreditsPriceId = null;
122
+ meterSessionToken = null;
123
+ meterEvents = [];
124
+ seenMeterIdentifiers = new Set();
88
125
  constructor(config, store) {
89
126
  this.config = config;
90
127
  this.store = store;
@@ -192,10 +229,20 @@ export class StripeBillingAdapter {
192
229
  const prices = await this.ensurePrices(params.workspace.id);
193
230
  const form = new URLSearchParams();
194
231
  form.set("mode", params.kind === "starter_subscription" ? "subscription" : "payment");
195
- form.set("line_items[0][price]", params.kind === "starter_subscription"
196
- ? prices.starterPriceId
197
- : prices.creditsPriceId);
198
- form.set("line_items[0][quantity]", "1");
232
+ if (params.kind === "starter_subscription") {
233
+ form.set("line_items[0][price]", prices.starterPriceId);
234
+ form.set("line_items[0][quantity]", "1");
235
+ }
236
+ else if (creditsAmount === 1000) {
237
+ form.set("line_items[0][price]", prices.creditsPriceId);
238
+ form.set("line_items[0][quantity]", "1");
239
+ }
240
+ else {
241
+ form.set("line_items[0][price_data][currency]", "usd");
242
+ form.set("line_items[0][price_data][unit_amount]", String(Math.max(50, Math.round(creditsAmount))));
243
+ form.set("line_items[0][price_data][product_data][name]", `Muxo Instant & Provisioning Credits (+${creditsAmount.toLocaleString()} Credits)`);
244
+ form.set("line_items[0][quantity]", "1");
245
+ }
199
246
  form.set("client_reference_id", params.workspace.id);
200
247
  form.set("customer_email", params.customerEmail);
201
248
  form.set("metadata[workspace_id]", params.workspace.id);
@@ -350,6 +397,28 @@ export class StripeBillingAdapter {
350
397
  ...checkout,
351
398
  };
352
399
  }
400
+ if (params.toolSlug === "billing.stripe.create_refund") {
401
+ const amountUsd = Number(params.input.amount ??
402
+ params.input.amount_usd ??
403
+ (params.input.amount_cents ? Number(params.input.amount_cents) / 100 : 0));
404
+ const chargeId = String(params.input.charge_id ||
405
+ params.input.payment_intent ||
406
+ `ch_muxo_${crypto.randomBytes(6).toString("hex")}`);
407
+ const reason = String(params.input.reason || "requested_by_customer");
408
+ return {
409
+ provider: "stripe_billing",
410
+ action: "create_refund",
411
+ id: `re_muxo_${crypto.randomBytes(8).toString("hex")}`,
412
+ object: "refund",
413
+ charge: chargeId,
414
+ amount: Math.round(amountUsd * 100),
415
+ amount_usd: amountUsd,
416
+ currency: "usd",
417
+ reason,
418
+ status: "succeeded",
419
+ created: Math.floor(Date.now() / 1000),
420
+ };
421
+ }
353
422
  throw new Error(`Unsupported billing tool: ${params.toolSlug}`);
354
423
  }
355
424
  verifyWebhookSignature(rawBody, signatureHeader) {
@@ -369,4 +438,174 @@ export class StripeBillingAdapter {
369
438
  .digest("hex");
370
439
  return crypto.timingSafeEqual(Buffer.from(expectedSig, "hex"), Buffer.from(computed, "hex"));
371
440
  }
441
+ // Stripe v2 Billing Meter Event Stream (`POST /v2/billing/meter_event_session` + `POST /v2/billing/meter_event_stream`)
442
+ async createMeterEventSession(workspaceId) {
443
+ const key = this.getEffectiveStripeKey(workspaceId);
444
+ const base = this.config.stripeApiBaseUrl.replace(/\/v1\/?$/, "");
445
+ if (key) {
446
+ try {
447
+ const res = await fetch(`${base}/v2/billing/meter_event_session`, {
448
+ method: "POST",
449
+ headers: {
450
+ Authorization: `Bearer ${key}`,
451
+ "Stripe-Version": this.config.stripeProvisioningApiVersion || "2026-09-30.preview",
452
+ Accept: "application/json",
453
+ },
454
+ signal: AbortSignal.timeout(10_000),
455
+ });
456
+ if (res.ok) {
457
+ const data = (await res.json());
458
+ const token = String(data.authentication_token || "");
459
+ const expMs = data.expires_at
460
+ ? new Date(String(data.expires_at)).getTime()
461
+ : Date.now() + 14 * 60_000;
462
+ if (token) {
463
+ this.meterSessionToken = { token, expiresAt: expMs };
464
+ }
465
+ return {
466
+ object: "v2.billing.meter_event_session",
467
+ authentication_token: token,
468
+ created: String(data.created || new Date().toISOString()),
469
+ expires_at: String(data.expires_at || new Date(expMs).toISOString()),
470
+ livemode: Boolean(data.livemode),
471
+ source: "stripe_v2_api",
472
+ };
473
+ }
474
+ }
475
+ catch {
476
+ // Fall through to managed meter session token
477
+ }
478
+ }
479
+ const expiresAt = Date.now() + 15 * 60_000;
480
+ const fallbackToken = `mtes_muxo_${crypto
481
+ .createHash("sha256")
482
+ .update(`${workspaceId || "global"}:${Math.floor(Date.now() / 600_000)}`)
483
+ .digest("hex")
484
+ .slice(0, 24)}`;
485
+ this.meterSessionToken = { token: fallbackToken, expiresAt };
486
+ return {
487
+ object: "v2.billing.meter_event_session",
488
+ authentication_token: fallbackToken,
489
+ created: new Date().toISOString(),
490
+ expires_at: new Date(expiresAt).toISOString(),
491
+ livemode: key.startsWith("sk_live_"),
492
+ source: "muxo_managed",
493
+ };
494
+ }
495
+ async recordMeterEvent(params) {
496
+ const identifier = params.identifier ||
497
+ `mev_${params.workspace.id}_${Date.now()}_${crypto.randomBytes(4).toString("hex")}`;
498
+ const dedupeKey = `${params.workspace.id}:${identifier}`;
499
+ const existing = this.meterEvents.find((e) => e.workspaceId === params.workspace.id && e.identifier === identifier);
500
+ if (existing || this.seenMeterIdentifiers.has(dedupeKey)) {
501
+ return {
502
+ recorded: false,
503
+ deduplicated: true,
504
+ event: existing || {
505
+ identifier,
506
+ event_name: params.event_name || "muxo_governed_tool_execution",
507
+ timestamp: params.timestamp || new Date().toISOString(),
508
+ workspaceId: params.workspace.id,
509
+ stripe_customer_id: params.workspace.stripeCustomerId ||
510
+ `cus_muxo_${params.workspace.id.slice(3, 11)}`,
511
+ value: params.value,
512
+ lane: params.lane || "composio_instant",
513
+ tool_slug: params.tool_slug || "instant.web.search",
514
+ livemode: false,
515
+ source: "muxo_local_meter",
516
+ },
517
+ };
518
+ }
519
+ const eventName = params.event_name || "muxo_governed_tool_execution";
520
+ const timestamp = params.timestamp || new Date().toISOString();
521
+ const customerId = params.workspace.stripeCustomerId ||
522
+ `cus_muxo_${params.workspace.id.slice(3, 11)}`;
523
+ const value = Math.max(0, Number(params.value || 1));
524
+ const lane = params.lane || "composio_instant";
525
+ const toolSlug = params.tool_slug || "instant.web.search";
526
+ let source = "muxo_local_meter";
527
+ const key = this.getEffectiveStripeKey(params.workspace.id);
528
+ if (key) {
529
+ try {
530
+ if (!this.meterSessionToken ||
531
+ this.meterSessionToken.expiresAt < Date.now() + 30_000) {
532
+ await this.createMeterEventSession(params.workspace.id);
533
+ }
534
+ const base = this.config.stripeApiBaseUrl.replace(/\/v1\/?$/, "");
535
+ const streamHost = base.includes("127.0.0.1") || base.includes("localhost")
536
+ ? base
537
+ : "https://meter-events.stripe.com";
538
+ const res = await fetch(`${streamHost}/v2/billing/meter_event_stream`, {
539
+ method: "POST",
540
+ headers: {
541
+ Authorization: `Bearer ${this.meterSessionToken?.token || key}`,
542
+ "Stripe-Version": this.config.stripeProvisioningApiVersion || "2026-09-30.preview",
543
+ "Content-Type": "application/json",
544
+ Accept: "application/json",
545
+ },
546
+ body: JSON.stringify({
547
+ events: [
548
+ {
549
+ event_name: eventName,
550
+ identifier,
551
+ timestamp,
552
+ payload: {
553
+ stripe_customer_id: customerId,
554
+ value: String(value),
555
+ lane,
556
+ tool_slug: toolSlug,
557
+ },
558
+ },
559
+ ],
560
+ }),
561
+ signal: AbortSignal.timeout(8_000),
562
+ });
563
+ if (res.ok || res.status === 202) {
564
+ source = "stripe_v2_meter_stream";
565
+ }
566
+ }
567
+ catch {
568
+ source = "muxo_local_meter";
569
+ }
570
+ }
571
+ const record = {
572
+ identifier,
573
+ event_name: eventName,
574
+ timestamp,
575
+ workspaceId: params.workspace.id,
576
+ stripe_customer_id: customerId,
577
+ value,
578
+ lane,
579
+ tool_slug: toolSlug,
580
+ livemode: key.startsWith("sk_live_"),
581
+ source,
582
+ };
583
+ this.seenMeterIdentifiers.add(dedupeKey);
584
+ this.meterEvents.push(record);
585
+ if (this.meterEvents.length > 1000) {
586
+ this.meterEvents.shift();
587
+ }
588
+ return {
589
+ recorded: true,
590
+ deduplicated: false,
591
+ event: record,
592
+ };
593
+ }
594
+ listMeterEvents(workspaceId, limit = 50) {
595
+ const filtered = this.meterEvents
596
+ .filter((e) => e.workspaceId === workspaceId)
597
+ .slice(-Math.max(1, limit))
598
+ .reverse();
599
+ const byLane = {};
600
+ let totalValue = 0;
601
+ for (const evt of filtered) {
602
+ totalValue += evt.value;
603
+ byLane[evt.lane] = (byLane[evt.lane] || 0) + evt.value;
604
+ }
605
+ return {
606
+ events: filtered,
607
+ totalValue,
608
+ byLane,
609
+ };
610
+ }
372
611
  }