@muxoai/platform 1.3.0 → 1.3.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 (51) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude-plugin/marketplace.json +19 -4
  3. package/.codex/config.toml +9 -2
  4. package/README.md +63 -20
  5. package/dist/clerk.d.ts +33 -0
  6. package/dist/clerk.js +198 -0
  7. package/dist/cli.js +1181 -99
  8. package/dist/engine.d.ts +22 -1
  9. package/dist/engine.js +284 -14
  10. package/dist/mcp.d.ts +6 -1
  11. package/dist/mcp.js +109 -22
  12. package/dist/nl.js +60 -36
  13. package/dist/policy.d.ts +9 -0
  14. package/dist/policy.js +73 -0
  15. package/dist/providers/composio-instant.d.ts +4 -0
  16. package/dist/providers/composio-instant.js +634 -534
  17. package/dist/providers/composio-sdk.d.ts +1 -0
  18. package/dist/providers/composio-sdk.js +6 -2
  19. package/dist/providers/microsoft-governance.d.ts +61 -2
  20. package/dist/providers/microsoft-governance.js +458 -24
  21. package/dist/providers/stripe-billing.js +14 -4
  22. package/dist/providers/stripe-projects.d.ts +4 -1
  23. package/dist/providers/stripe-projects.js +123 -12
  24. package/dist/providers/supermemory.d.ts +28 -5
  25. package/dist/providers/supermemory.js +183 -55
  26. package/dist/sdk.d.ts +167 -1
  27. package/dist/sdk.js +113 -2
  28. package/dist/server.js +258 -40
  29. package/dist/store.d.ts +26 -1
  30. package/dist/store.js +255 -6
  31. package/dist/types.d.ts +86 -0
  32. package/dist/ui/console-html.d.ts +16 -0
  33. package/dist/ui/console-html.js +2427 -2206
  34. package/dist/ui/design-tokens.d.ts +177 -0
  35. package/dist/ui/design-tokens.js +210 -0
  36. package/dist/version.d.ts +1 -0
  37. package/dist/version.js +1 -0
  38. package/package.json +2 -2
  39. package/plugins/muxo/.app.json +1 -1
  40. package/plugins/muxo/.claude-plugin/plugin.json +2 -2
  41. package/plugins/muxo/.codex-plugin/plugin.json +7 -5
  42. package/plugins/muxo/.mcp.json +1 -33
  43. package/plugins/muxo/assets/logo.png +0 -0
  44. package/plugins/muxo/hooks/session-start.sh +1 -1
  45. package/plugins/muxo/plugin.json +63 -6
  46. package/plugins/muxo/skills/muxo/SKILL.md +92 -14
  47. package/plugins/muxo/skills/muxo/agents/openai.yaml +12 -0
  48. package/plugins/muxo/skills/muxo/references/cli.md +4 -2
  49. package/plugins/muxo/skills/muxo/references/mcp.md +15 -9
  50. package/plugins/muxo/skills/setup/SKILL.md +8 -2
  51. package/plugins/muxo/skills/setup/agents/openai.yaml +12 -0
package/dist/server.js CHANGED
@@ -6,39 +6,57 @@ import { getConfig, ROOT_DIR } from "./config.js";
6
6
  import { MuxoEngine } from "./engine.js";
7
7
  import { getMuxoMcpSkills, handleJsonRpcMcpRequest, MUXO_MCP_SERVER_INSTRUCTIONS, MUXO_MCP_TOOLS, } from "./mcp.js";
8
8
  import { MuxoStore } from "./store.js";
9
- import { renderConsoleHtml, renderLandingHtml } from "./ui/console-html.js";
9
+ import { sanitizePolicyPatch } from "./policy.js";
10
+ import { MUXO_VERSION } from "./version.js";
11
+ import { isConsolePath, renderConsoleHtml, renderLandingHtml } from "./ui/console-html.js";
10
12
  function renderSkillMarkdown(baseUrl) {
11
13
  return `---
12
14
  name: muxo
13
- description: Discover, plan, and execute governed actions across Connected Apps (Composio SDK), Instant Tools (Composio Instant), Cloud Infrastructure (Stripe Projects), Contextual Memory (Supermemory v5), and Cryptographic Governance (Microsoft Agent Governance Toolkit) through Muxo.
15
+ description: Discover, plan, and execute governed actions across Connected Apps (app.*), Instant Tools (instant.*), Cloud Infrastructure (resource.*), Workspace Memory, and Safety Guardrails through Muxo.
14
16
  ---
15
17
 
16
- # Muxo — Unified Agent Execution, Infrastructure, Memory & Governance Platform
18
+ # Muxo — Unified Agent Execution, Infrastructure, Memory & Safety Platform
17
19
 
18
- Muxo provides one governed interface over 4 pillars so agents and customers only ever interact with Muxo:
20
+ Muxo provides one unified interface across 4 capabilities so agents and users only ever interact with Muxo:
19
21
 
20
- 1. **Instant Tools (\`instant.*\`)**: Zero-OAuth tools powered by Composio Instant (\`instant.web.search\`, \`instant.web.scrape\`, \`instant.hackernews.top_stories\`, \`instant.github.repo_intel\`, \`instant.dns.lookup\`).
21
- 2. **Connected Apps (\`app.*\`)**: Managed OAuth SaaS integrations powered by Composio SDK (\`app.github.*\`, \`app.gmail.*\`, \`app.slack.*\`, \`app.notion.*\`, \`app.linear.*\`, etc.).
22
- 3. **Cloud Infrastructure (\`resource.*\`)**: Database, cache, storage, and hosting provisioning powered by Stripe Projects (\`resource.neon.*\`, \`resource.supabase.*\`, \`resource.turso.*\`, \`resource.cloudflare.*\`, \`resource.vercel.*\`, etc.) with AES-256-GCM secret custody in Muxo Vault.
23
- 4. **Supermemory v5 Brain & Microsoft Agent Governance**: Every \`plan_action\` recalls isolated workspace context (\`/ns/muxo-v5-<hash>\`) and runs \`Agent ──► McpSecurityScanner ──► PolicyEngine ──► AgentIdentity (Ed25519 DID) ──► AuditLogger ──► DecisionRecord\`.
22
+ 1. **Instant Tools (\`instant.*\`)**: Zero-OAuth tools ready immediately (\`instant.web.search\`, \`instant.web.scrape\`, \`instant.web.crawl\`, \`instant.seo.audit\`, \`instant.hackernews.top_stories\`, \`instant.github.repo_intel\`, \`instant.dns.lookup\`).
23
+ 2. **Connected Apps (\`app.*\`)**: Managed OAuth SaaS integrations (\`app.github.*\`, \`app.gmail.*\`, \`app.slack.*\`, \`app.notion.*\`, \`app.linear.*\`, etc.).
24
+ 3. **Cloud Infrastructure (\`resource.*\`)**: Database, cache, storage, and hosting provisioning (\`resource.neon.*\`, \`resource.supabase.*\`, \`resource.turso.*\`, \`resource.cloudflare.*\`, \`resource.vercel.*\`, etc.) with AES-256-GCM secret custody in Muxo Vault.
25
+ 4. **Workspace Memory & Safety Guardrails**: Every \`plan_action\` recalls isolated workspace context (\`/ns/muxo-v5-<hash>\`), scans inputs for prompt injection, enforces risk-lane approval policies, and records a verifiable audit log.
24
26
 
25
- ## Installable Muxo Plugin (OpenAI Codex, ChatGPT, Claude Code & Factory Droid)
27
+ ## Installable Muxo Plugin (Claude Code, OpenAI Codex, Claude Desktop & ChatGPT)
28
+
29
+ > **Requirement:** \`@muxoai/cli\` requires **Node.js 22+** (\`node >= 22.0.0\`).
26
30
 
27
31
  \`\`\`bash
28
- # Install Muxo CLI & sign in (or auto-provision an isolated external workspace)
29
- npm install -g muxo-platform
32
+ # Install Muxo CLI & sign in against the hosted workspace (Node.js 22+)
33
+ npm install -g @muxoai/cli@latest
30
34
  muxo login --signup --name "my-agent"
31
35
 
36
+ # Claude Code marketplace (muxo@muxo):
37
+ claude plugin marketplace add ${baseUrl}/.claude-plugin/marketplace.json
38
+ claude plugin install muxo@muxo
39
+
40
+ # OpenAI Codex: add a Git repo or local marketplace directory containing .agents/plugins/marketplace.json,
41
+ # or configure [mcp_servers.muxo] in ~/.codex/config.toml (url = "${baseUrl}/mcp")
42
+
43
+ # Claude Desktop:
44
+ # - Hosted MCP: Settings -> Connectors -> Add custom connector -> ${baseUrl}/mcp
45
+ # - Local stdio server: configure npx -y @muxoai/cli@latest mcp in claude_desktop_config.json
46
+
47
+ # ChatGPT:
48
+ # - Plugins -> + -> Add custom MCP server -> ${baseUrl}/mcp (OAuth supports CIMD or DCR)
49
+
32
50
  # Link OAuth apps with live browser handoff + polling recovery
33
51
  muxo link github --wait
34
52
 
35
53
  # Plugin manifests served by this instance:
36
- # - ${baseUrl}/.agents/plugins/marketplace.json (OpenAI Codex / ChatGPT)
37
- # - ${baseUrl}/.claude-plugin/marketplace.json (Claude Code / Factory Droid)
54
+ # - ${baseUrl}/.agents/plugins/marketplace.json (OpenAI Codex local/Git marketplace manifest)
55
+ # - ${baseUrl}/.claude-plugin/marketplace.json (Claude Code marketplace manifest)
38
56
  # - ${baseUrl}/api/v1/plugin
39
57
  \`\`\`
40
58
 
41
- ## Autonomous Agent 2-Call Signup (Zero Browser Required)
59
+ ## CLI-First Autonomous Agent 2-Call Signup
42
60
 
43
61
  \`\`\`bash
44
62
  # 1. Create an autonomous workspace + mk_live_* API key
@@ -154,7 +172,7 @@ export function createMuxoServer(customConfig) {
154
172
  ok: true,
155
173
  status: "ready",
156
174
  service: "muxo-platform",
157
- version: "1.3.0",
175
+ version: MUXO_VERSION,
158
176
  environment: "production",
159
177
  live_execution: true,
160
178
  customer_billing: true,
@@ -241,10 +259,21 @@ export function createMuxoServer(customConfig) {
241
259
  ],
242
260
  code_challenge_methods_supported: ["S256", "plain"],
243
261
  client_id_metadata_document_supported: true,
262
+ authorization_response_iss_parameter_supported: true,
244
263
  service_documentation: `${config.docsUrl}/quickstart`,
245
264
  });
246
265
  return;
247
266
  }
267
+ if (pathname === "/.well-known/openai-apps-challenge" && req.method === "GET") {
268
+ const challenge = process.env.OPENAI_APPS_CHALLENGE ||
269
+ "muxo-openai-apps-domain-verified";
270
+ res.writeHead(200, {
271
+ "Content-Type": "text/plain; charset=utf-8",
272
+ "Access-Control-Allow-Origin": "*",
273
+ });
274
+ res.end(challenge);
275
+ return;
276
+ }
248
277
  if (pathname === "/oauth/register" && req.method === "POST") {
249
278
  const body = JSON.parse((await readBody(req)) || "{}");
250
279
  const clientId = typeof body.client_id === "string" && body.client_id.trim()
@@ -311,16 +340,22 @@ export function createMuxoServer(customConfig) {
311
340
  apiKey: issuedKey,
312
341
  expiresAt: Date.now() + 10 * 60 * 1000,
313
342
  });
343
+ const proto = String(req.headers["x-forwarded-proto"] || "http").split(",")[0].trim();
344
+ const requestOrigin = req.headers.host
345
+ ? `${proto}://${req.headers.host}`
346
+ : config.baseUrl;
314
347
  const redirectTarget = new URL(redirectUri);
315
348
  redirectTarget.searchParams.set("code", code);
316
349
  if (stateParam)
317
350
  redirectTarget.searchParams.set("state", stateParam);
351
+ redirectTarget.searchParams.set("iss", requestOrigin);
318
352
  if (url.searchParams.get("format") === "json" ||
319
353
  String(req.headers.accept || "").includes("application/json")) {
320
354
  sendJson(res, 200, {
321
355
  ok: true,
322
356
  code,
323
357
  state: stateParam || null,
358
+ iss: requestOrigin,
324
359
  client_id: clientId,
325
360
  redirect_uri: redirectTarget.toString(),
326
361
  });
@@ -409,11 +444,16 @@ export function createMuxoServer(customConfig) {
409
444
  }
410
445
  if (pathname === "/oauth/userinfo" && req.method === "GET") {
411
446
  const ctx = resolveContext(req);
447
+ const nickname = (ctx.user.email || "").split("@")[0] ||
448
+ ctx.user.name.toLowerCase().replace(/\s+/g, ".") ||
449
+ ctx.user.id;
412
450
  sendJson(res, 200, {
413
451
  sub: ctx.user.id,
414
452
  id: ctx.user.id,
415
453
  name: ctx.user.name,
416
454
  email: ctx.user.email,
455
+ email_verified: true,
456
+ nickname,
417
457
  workspace_id: ctx.workspace.id,
418
458
  workspace_name: ctx.workspace.name,
419
459
  tier: ctx.workspace.tier,
@@ -426,7 +466,7 @@ export function createMuxoServer(customConfig) {
426
466
  openapi: "3.1.0",
427
467
  info: {
428
468
  title: "Muxo Unified Agent Execution, Infrastructure, Memory & Governance API",
429
- version: "1.3.0",
469
+ version: MUXO_VERSION,
430
470
  description: "One governed boundary over Connected Apps (Composio SDK), Instant Tools (Composio Instant), Cloud Infrastructure (Stripe Projects), Supermemory v5 Brain, and Microsoft Agent Governance Toolkit.",
431
471
  },
432
472
  servers: [{ url: config.baseUrl }],
@@ -475,12 +515,12 @@ Or via HTTP:
475
515
  curl -sX POST ${config.baseUrl}/api/v1/agents/signup -H "Content-Type: application/json" -d '{"agentName":"my-agent"}'
476
516
  \`\`\`
477
517
 
478
- ## 2. OAuth Connection Handoff (Composio Plugin Pattern)
518
+ ## 2. OAuth Connection Handoff
479
519
  When \`plan_action\` targets an unconnected \`app.<provider>.*\` tool, Muxo returns \`authHandoff.redirectUrl\`.
480
520
  Open the URL in a browser, complete OAuth (which redirects to \`${config.baseUrl}/oauth/callback\`), and call \`wait_for_connection({ provider })\` or \`muxo link <provider> --wait\`.
481
521
 
482
- ## 3. Merchant-of-Record Credit Settlement
483
- Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing topup 1000\`), and Muxo settles wholesale supplier costs across Composio and Stripe Projects from Muxo's master accounts (\`fundingMode: "muxo_funded"\`).
522
+ ## 3. Credit Billing & BYOK Support
523
+ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing topup 1000\`), and Muxo settles upstream execution costs from Muxo's master accounts (\`fundingMode: "muxo_funded"\`), or users can configure their own BYOK provider keys for 0-credit execution.
484
524
  `);
485
525
  return;
486
526
  }
@@ -507,7 +547,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
507
547
  }
508
548
  if (pathname === "/llms.txt" && req.method === "GET") {
509
549
  res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
510
- res.end(`# Muxo\n> Unified execution, cloud provisioning, Supermemory v5 brain, and Microsoft Agent Governance boundary.\n\n- Skill Document: ${config.baseUrl}/skill.md\n- Auth Guide: ${config.baseUrl}/auth.md\n- OpenAPI 3.1 Spec: ${config.baseUrl}/api/openapi.json\n- MCP Endpoint: ${config.baseUrl}/mcp\n- OAuth Callback Handoff: ${config.baseUrl}/oauth/callback\n- Plugin Marketplace (Codex/OpenAI): ${config.baseUrl}/.agents/plugins/marketplace.json\n- Plugin Marketplace (Claude/Droid): ${config.baseUrl}/.claude-plugin/marketplace.json\n- Console (app.muxo.ai): ${config.baseUrl}/\n- Landing & Provider Canvas (muxo.ai): ${config.baseUrl}/landing\n- Documentation (docs.muxo.ai): ${config.docsUrl}\n`);
550
+ res.end(`# Muxo\n> Unified agent execution across Connected Apps, Instant Tools, Cloud Infrastructure, Workspace Memory, and Safety Guardrails.\n\n- Skill Document: ${config.baseUrl}/skill.md\n- Auth Guide: ${config.baseUrl}/auth.md\n- OpenAPI 3.1 Spec: ${config.baseUrl}/api/openapi.json\n- MCP Endpoint: ${config.baseUrl}/mcp\n- OAuth Callback Handoff: ${config.baseUrl}/oauth/callback\n- Plugin Marketplace (Codex/OpenAI): ${config.baseUrl}/.agents/plugins/marketplace.json\n- Plugin Marketplace (Claude/Droid): ${config.baseUrl}/.claude-plugin/marketplace.json\n- Console (app.muxo.ai): ${config.baseUrl}/\n- Landing & Provider Canvas (muxo.ai): ${config.baseUrl}/landing\n- Documentation (docs.muxo.ai): ${config.docsUrl}\n`);
511
551
  return;
512
552
  }
513
553
  // Serve Installable Muxo Plugin Manifests & Metadata (Portable OpenAI Agent Plugins + Codex + Claude)
@@ -596,12 +636,20 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
596
636
  });
597
637
  return;
598
638
  }
599
- // Web Console UI (app.muxo.ai)
600
- if ((pathname === "/" || pathname === "/console") && req.method === "GET") {
639
+ // Web Console UI (app.muxo.ai) & SPA deep-links
640
+ if (isConsolePath(pathname) && req.method === "GET") {
601
641
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
602
642
  res.end(renderConsoleHtml());
603
643
  return;
604
644
  }
645
+ if (pathname === "/downloads/muxo-cli.zip" && req.method === "GET") {
646
+ res.writeHead(302, {
647
+ Location: "https://muxo.ai/plugins/muxo-chatgpt-plugin.zip",
648
+ "Cache-Control": "no-store",
649
+ });
650
+ res.end();
651
+ return;
652
+ }
605
653
  // Built-in Interactive Landing & Provider Canvas (muxo.ai)
606
654
  if (pathname === "/landing" && req.method === "GET") {
607
655
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -616,6 +664,11 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
616
664
  sendJson(res, 404, { ok: false, error: "Invalid or expired agent claim link" });
617
665
  return;
618
666
  }
667
+ const claimConsoleKey = store.createApiKey({
668
+ workspaceId: redeemed.workspace.id,
669
+ name: `Owner Claim Session (${redeemed.targetEmail})`,
670
+ environment: "live",
671
+ }).secretKey;
619
672
  const wantsHtml = url.searchParams.get("format") !== "json" &&
620
673
  String(req.headers.accept || "").includes("text/html");
621
674
  if (wantsHtml) {
@@ -640,7 +693,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
640
693
  <div class="badge">Ownership Bound</div>
641
694
  <h1>Workspace Claimed</h1>
642
695
  <p>Workspace <code>${redeemed.workspace.name}</code> (${redeemed.workspace.id}) claimed by <strong>${redeemed.targetEmail}</strong>.</p>
643
- <a class="btn" href="/?claimed=${encodeURIComponent(redeemed.workspace.slug)}">Open Muxo Console →</a>
696
+ <a class="btn" href="/?claimed=${encodeURIComponent(redeemed.workspace.slug)}&api_key=${encodeURIComponent(claimConsoleKey)}">Open Muxo Console →</a>
644
697
  </div>
645
698
  </body>
646
699
  </html>`);
@@ -649,6 +702,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
649
702
  sendJson(res, 200, {
650
703
  ok: true,
651
704
  message: `Workspace '${redeemed.workspace.name}' claimed by ${redeemed.targetEmail}`,
705
+ apiKey: claimConsoleKey,
652
706
  claim: redeemed,
653
707
  });
654
708
  return;
@@ -709,8 +763,11 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
709
763
  </html>`);
710
764
  return;
711
765
  }
712
- // Autonomous Agent 2-Call Signup (agents.composio.dev pattern) — Public
713
- if (pathname === "/api/v1/agents/signup" && req.method === "POST") {
766
+ // Autonomous Agent 2-Call Signup — Public
767
+ if ((pathname === "/api/v1/agents/signup" ||
768
+ pathname === "/api/v1/auth/signup" ||
769
+ pathname === "/api/signup") &&
770
+ req.method === "POST") {
714
771
  const body = JSON.parse((await readBody(req)) || "{}");
715
772
  const created = store.createAutonomousAgentSignup({
716
773
  agentName: body.agentName ? String(body.agentName) : undefined,
@@ -735,8 +792,8 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
735
792
  });
736
793
  return;
737
794
  }
738
- // Streamable HTTP MCP Endpoint (POST /mcp, GET /mcp, DELETE /mcp)
739
- if (pathname === "/mcp" && req.method === "GET") {
795
+ // Streamable HTTP MCP Endpoint (POST /mcp, GET /mcp, HEAD /mcp, DELETE /mcp)
796
+ if (pathname === "/mcp" && (req.method === "GET" || req.method === "HEAD")) {
740
797
  const accept = String(req.headers.accept || "");
741
798
  const sessionId = String(req.headers["mcp-session-id"] || "") ||
742
799
  `mcp_sess_${crypto.randomBytes(8).toString("hex")}`;
@@ -747,8 +804,11 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
747
804
  Connection: "keep-alive",
748
805
  "Mcp-Session-Id": sessionId,
749
806
  "Access-Control-Allow-Origin": "*",
807
+ "Access-Control-Expose-Headers": "Mcp-Session-Id",
750
808
  });
751
- res.write(`event: endpoint\ndata: ${JSON.stringify({ uri: `${config.baseUrl}/mcp`, sessionId })}\n\n`);
809
+ if (req.method !== "HEAD") {
810
+ res.write(`event: endpoint\ndata: ${JSON.stringify({ uri: `${config.baseUrl}/mcp`, sessionId })}\n\n`);
811
+ }
752
812
  res.end();
753
813
  return;
754
814
  }
@@ -758,12 +818,12 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
758
818
  protocolVersion: "2025-06-18",
759
819
  serverInfo: {
760
820
  name: "muxo-mcp-server",
761
- version: "1.3.0",
821
+ version: MUXO_VERSION,
762
822
  },
763
823
  instructions: MUXO_MCP_SERVER_INSTRUCTIONS,
764
824
  toolsCount: MUXO_MCP_TOOLS.length,
765
825
  skillsCount: getMuxoMcpSkills().length,
766
- });
826
+ }, { "Mcp-Session-Id": sessionId });
767
827
  return;
768
828
  }
769
829
  if (pathname === "/mcp" && req.method === "DELETE") {
@@ -798,6 +858,10 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
798
858
  return;
799
859
  }
800
860
  // Auth Endpoints
861
+ if (pathname === "/api/v1/auth/config" && req.method === "GET") {
862
+ sendJson(res, 200, { ok: true, provider: "password", clerk: null, signInUrl: "/login" });
863
+ return;
864
+ }
801
865
  if (pathname === "/api/v1/auth/register" && req.method === "POST") {
802
866
  const body = JSON.parse((await readBody(req)) || "{}");
803
867
  const created = store.registerUser({
@@ -806,7 +870,16 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
806
870
  password: String(body.password || ""),
807
871
  workspaceName: body.workspaceName ? String(body.workspaceName) : undefined,
808
872
  });
809
- sendJson(res, 201, { ok: true, ...created });
873
+ const initialKey = store.createApiKey({
874
+ workspaceId: created.workspace.id,
875
+ name: "Default Live Key",
876
+ environment: "live",
877
+ });
878
+ sendJson(res, 201, {
879
+ ok: true,
880
+ ...created,
881
+ apiKey: initialKey.secretKey,
882
+ });
810
883
  return;
811
884
  }
812
885
  if (pathname === "/api/v1/auth/login" && req.method === "POST") {
@@ -860,16 +933,59 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
860
933
  email,
861
934
  baseUrl: config.baseUrl,
862
935
  });
863
- sendJson(res, 201, { ok: true, claim, ...claim });
936
+ sendJson(res, 201, {
937
+ ok: true,
938
+ claim: { ...claim, ownerEmail: email },
939
+ ...claim,
940
+ ownerEmail: email,
941
+ });
864
942
  return;
865
943
  }
866
944
  // Microsoft Agent Governance Status & Audit Verification
867
945
  if (pathname === "/api/v1/governance" && req.method === "GET") {
946
+ const ws = store.getWorkspace(ctx.workspace.id) || ctx.workspace;
947
+ const fullReport = engine.governance.getGovernanceStatus(ws);
868
948
  sendJson(res, 200, {
869
949
  ok: true,
870
- governance: engine.governance.getStatus(),
871
- workspacePolicy: ctx.workspace.policy,
950
+ governance: {
951
+ ...engine.governance.getStatus(ws),
952
+ modules: fullReport.modules,
953
+ trustScore: fullReport.trustScore,
954
+ killSwitch: fullReport.killSwitch,
955
+ contextPoisoning: fullReport.contextPoisoning,
956
+ auditChain: fullReport.auditChain,
957
+ },
958
+ workspacePolicy: ws.policy,
959
+ });
960
+ return;
961
+ }
962
+ if (pathname === "/api/v1/governance/kill-switch" && req.method === "POST") {
963
+ const body = JSON.parse((await readBody(req)) || "{}");
964
+ const action = String(body.action || "quarantine").toLowerCase();
965
+ if (action === "resume" || body.active === false) {
966
+ const out = engine.resumeWorkspaceKillSwitch(ctx);
967
+ sendJson(res, 200, { ok: true, ...out });
968
+ return;
969
+ }
970
+ const out = await engine.activateWorkspaceKillSwitch(ctx, {
971
+ reason: String(body.reason || "Emergency kill-switch activated by workspace operator"),
972
+ action: action === "terminate" || action === "suspend"
973
+ ? action
974
+ : "quarantine",
872
975
  });
976
+ sendJson(res, 200, { ok: true, ...out });
977
+ return;
978
+ }
979
+ if (pathname === "/api/v1/governance/scan-context" && req.method === "POST") {
980
+ const body = JSON.parse((await readBody(req)) || "{}");
981
+ const scan = engine.governance.scanMemoryContent({
982
+ workspaceId: ctx.workspace.id,
983
+ sessionId: String(body.sessionId || "default"),
984
+ role: body.role || "user",
985
+ content: String(body.content || ""),
986
+ recordInDetector: Boolean(body.recordInDetector),
987
+ });
988
+ sendJson(res, 200, { ok: true, scan });
873
989
  return;
874
990
  }
875
991
  // Supermemory v5 Workspace Brain Endpoints
@@ -881,6 +997,37 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
881
997
  sendJson(res, 200, { ok: true, ...overview });
882
998
  return;
883
999
  }
1000
+ if (pathname === "/api/v1/memory/facts" && req.method === "GET") {
1001
+ const query = url.searchParams.get("query") ||
1002
+ url.searchParams.get("q") ||
1003
+ undefined;
1004
+ const includeHistorical = url.searchParams.get("historical") !== "false";
1005
+ const facts = store.listTemporalFacts(ctx.workspace.id, {
1006
+ includeHistorical,
1007
+ subject: url.searchParams.get("subject") || undefined,
1008
+ predicate: url.searchParams.get("predicate") || undefined,
1009
+ query,
1010
+ limit: Number(url.searchParams.get("limit") || 50),
1011
+ });
1012
+ sendJson(res, 200, {
1013
+ ok: true,
1014
+ activeFacts: facts.filter((f) => f.validTo === null),
1015
+ historicalFacts: facts.filter((f) => f.validTo !== null),
1016
+ facts,
1017
+ });
1018
+ return;
1019
+ }
1020
+ if (pathname === "/api/v1/memory/forget" && req.method === "POST") {
1021
+ const body = JSON.parse((await readBody(req)) || "{}");
1022
+ const query = String(body.query || body.q || "").trim();
1023
+ if (!query) {
1024
+ sendJson(res, 400, { ok: false, error: "query is required to forget matching memories" });
1025
+ return;
1026
+ }
1027
+ const pruned = await engine.forgetWorkspaceMemoryMatching(ctx, query);
1028
+ sendJson(res, 200, { ok: true, ...pruned });
1029
+ return;
1030
+ }
884
1031
  if (pathname === "/api/v1/memory" && req.method === "POST") {
885
1032
  const body = JSON.parse((await readBody(req)) || "{}");
886
1033
  const record = await engine.addWorkspaceMemory(ctx, {
@@ -888,6 +1035,9 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
888
1035
  content: String(body.content || ""),
889
1036
  kind: body.kind || "fact",
890
1037
  metadata: body.metadata || {},
1038
+ subject: body.subject ? String(body.subject) : undefined,
1039
+ predicate: body.predicate ? String(body.predicate) : undefined,
1040
+ object: body.object ? String(body.object) : undefined,
891
1041
  });
892
1042
  sendJson(res, 201, { ok: true, memory: record });
893
1043
  return;
@@ -909,6 +1059,15 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
909
1059
  sendJson(res, 201, { ok: true, ...created });
910
1060
  return;
911
1061
  }
1062
+ if (pathname.startsWith("/api/v1/api-keys/") && req.method === "DELETE") {
1063
+ const keyId = decodeURIComponent(pathname.slice("/api/v1/api-keys/".length));
1064
+ if (!store.revokeApiKey(ctx.workspace.id, keyId)) {
1065
+ sendJson(res, 404, { ok: false, error: "API key not found" });
1066
+ return;
1067
+ }
1068
+ sendJson(res, 200, { ok: true, revoked: keyId });
1069
+ return;
1070
+ }
912
1071
  // Profile & Organization (v1 and api/v1)
913
1072
  if ((pathname === "/api/v1/profile" || pathname === "/v1/profile") && req.method === "GET") {
914
1073
  sendJson(res, 200, { ok: true, ...engine.getProfile(ctx) });
@@ -1008,7 +1167,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1008
1167
  // Governance Policy
1009
1168
  if (pathname === "/api/v1/policy" && req.method === "POST") {
1010
1169
  const body = JSON.parse((await readBody(req)) || "{}");
1011
- const updated = store.updateWorkspacePolicy(ctx.workspace.id, body);
1170
+ const updated = store.updateWorkspacePolicy(ctx.workspace.id, sanitizePolicyPatch(body));
1012
1171
  sendJson(res, 200, { ok: true, workspace: updated });
1013
1172
  return;
1014
1173
  }
@@ -1022,10 +1181,17 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1022
1181
  }
1023
1182
  if (pathname === "/api/v1/plans" && req.method === "POST") {
1024
1183
  const body = JSON.parse((await readBody(req)) || "{}");
1184
+ const rawFunding = body.fundingMode || body.funding_mode;
1185
+ const fundingMode = rawFunding === "byok" || rawFunding === "customer_funded"
1186
+ ? "byok"
1187
+ : rawFunding === "muxo_funded"
1188
+ ? "muxo_funded"
1189
+ : undefined;
1025
1190
  const planned = await engine.planAction(ctx, {
1026
1191
  toolSlug: String(body.toolSlug || body.tool_slug || ""),
1027
1192
  input: body.input || {},
1028
1193
  reason: body.reason ? String(body.reason) : undefined,
1194
+ fundingMode,
1029
1195
  });
1030
1196
  sendJson(res, 201, { ok: true, ...planned });
1031
1197
  return;
@@ -1042,7 +1208,18 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1042
1208
  const planId = decodeURIComponent(planExecuteMatch[1]);
1043
1209
  const plan = engine.getPlan(ctx, planId);
1044
1210
  const result = await engine.executePlanForRisk(ctx, planId, plan.riskLevel);
1045
- sendJson(res, 200, { ok: true, ...result });
1211
+ sendJson(res, 200, {
1212
+ ok: true,
1213
+ ...result,
1214
+ settlement: result.receipt?.supplierSettlement || null,
1215
+ });
1216
+ return;
1217
+ }
1218
+ const planGetMatch = pathname.match(/^\/api\/v1\/plans\/([^/]+)$/);
1219
+ if (planGetMatch && req.method === "GET") {
1220
+ const planId = decodeURIComponent(planGetMatch[1]);
1221
+ const plan = engine.getPlan(ctx, planId);
1222
+ sendJson(res, 200, { ok: true, plan });
1046
1223
  return;
1047
1224
  }
1048
1225
  // Runs & Receipts
@@ -1053,6 +1230,21 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1053
1230
  });
1054
1231
  return;
1055
1232
  }
1233
+ const runCancelMatch = pathname.match(/^\/api\/v1\/runs\/([^/]+)\/cancel$/);
1234
+ if (runCancelMatch && req.method === "POST") {
1235
+ const runId = decodeURIComponent(runCancelMatch[1]);
1236
+ const body = JSON.parse((await readBody(req)) || "{}");
1237
+ const cancelled = engine.cancelRun(ctx, runId, body.reason ? String(body.reason) : undefined);
1238
+ sendJson(res, 200, { ok: true, ...cancelled });
1239
+ return;
1240
+ }
1241
+ const runGetMatch = pathname.match(/^\/api\/v1\/runs\/([^/]+)$/);
1242
+ if (runGetMatch && req.method === "GET") {
1243
+ const runId = decodeURIComponent(runGetMatch[1]);
1244
+ const run = engine.getRun(ctx, runId);
1245
+ sendJson(res, 200, { ok: true, run });
1246
+ return;
1247
+ }
1056
1248
  if (pathname.startsWith("/api/v1/receipts/") && req.method === "GET") {
1057
1249
  const receiptId = decodeURIComponent(pathname.slice("/api/v1/receipts/".length));
1058
1250
  const verified = engine.getReceipt(ctx, receiptId);
@@ -1102,7 +1294,13 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1102
1294
  if ((pathname === "/api/v1/do" || pathname === "/v1/do") &&
1103
1295
  req.method === "POST") {
1104
1296
  const body = JSON.parse((await readBody(req)) || "{}");
1105
- const prompt = String(body.prompt || body.instruction || body.query || body.command || "").trim();
1297
+ const prompt = String(body.prompt ||
1298
+ body.instruction ||
1299
+ body.query ||
1300
+ body.command ||
1301
+ body.toolSlug ||
1302
+ body.tool ||
1303
+ "").trim();
1106
1304
  if (!prompt) {
1107
1305
  sendJson(res, 400, {
1108
1306
  ok: false,
@@ -1110,19 +1308,37 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1110
1308
  });
1111
1309
  return;
1112
1310
  }
1311
+ const dryRun = body.dryRun === true ||
1312
+ body.dry_run === true ||
1313
+ body.planOnly === true ||
1314
+ body.autoExecute === false ||
1315
+ body.auto_execute === false;
1316
+ const autoApprove = body.autoApprove !== false &&
1317
+ body.auto_approve !== false &&
1318
+ body.approveRisky !== false &&
1319
+ body.approve_risky !== false;
1320
+ const rawFunding = body.fundingMode || body.funding_mode;
1321
+ const fundingMode = rawFunding === "byok" || rawFunding === "customer_funded"
1322
+ ? "byok"
1323
+ : rawFunding === "muxo_funded"
1324
+ ? "muxo_funded"
1325
+ : undefined;
1113
1326
  const result = await engine.doNaturalLanguage(ctx, {
1114
1327
  prompt,
1115
1328
  input: body.input && typeof body.input === "object"
1116
1329
  ? body.input
1117
1330
  : undefined,
1118
- autoApprove: body.autoApprove !== false,
1119
- dryRun: body.dryRun === true,
1331
+ autoApprove,
1332
+ dryRun,
1333
+ planOnly: dryRun,
1334
+ fundingMode,
1120
1335
  });
1121
1336
  sendJson(res, 200, result);
1122
1337
  return;
1123
1338
  }
1124
1339
  // Live Stripe Billing, Credit Top-Up & Supplier Settlement Ledger
1125
- if (pathname === "/api/v1/billing/status" && req.method === "GET") {
1340
+ if ((pathname === "/api/v1/billing/status" || pathname === "/api/v1/billing") &&
1341
+ req.method === "GET") {
1126
1342
  const ws = store.getWorkspace(ctx.workspace.id);
1127
1343
  const settlementSummary = store.getSupplierSettlementSummary(ctx.workspace.id);
1128
1344
  const byokKeys = store.listByokKeys(ctx.workspace.id);
@@ -1176,6 +1392,8 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1176
1392
  sendJson(res, 200, {
1177
1393
  ok: true,
1178
1394
  creditsAdded: credits,
1395
+ creditBalance: updatedWorkspace.creditsBalance,
1396
+ creditsBalance: updatedWorkspace.creditsBalance,
1179
1397
  usdPaid: Number(usdPaid),
1180
1398
  workspace: updatedWorkspace,
1181
1399
  settlementSummary: store.getSupplierSettlementSummary(ctx.workspace.id),
package/dist/store.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DatabaseSync } from "node:sqlite";
2
- import type { ActionPlan, ApiKeyRecord, ByokKeyRecord, ConnectionRecord, ExecutionReceipt, ExecutionRun, GovernanceDecisionRecord, GovernancePolicy, LedgerEntry, MemoryContextSummary, ProviderLane, ProvisionedResource, RiskLevel, SupplierSettlement, SupplierSettlementSummary, User, Workspace, WorkspaceMemoryRecord } from "./types.js";
2
+ import type { ActionPlan, ApiKeyRecord, ByokKeyRecord, ConnectionRecord, ExecutionReceipt, ExecutionRun, GovernanceDecisionRecord, GovernancePolicy, LedgerEntry, MemoryContextSummary, ProviderLane, ProvisionedResource, RiskLevel, SupplierSettlement, SupplierSettlementSummary, TemporalGraphFact, User, Workspace, WorkspaceMemoryRecord } from "./types.js";
3
3
  export declare const BYOK_PROVIDER_CATALOG: Record<string, {
4
4
  category: "llm" | "supplier";
5
5
  envVarName: string;
@@ -28,6 +28,7 @@ export declare class MuxoStore {
28
28
  user: User;
29
29
  workspace: Workspace;
30
30
  sessionToken: string;
31
+ apiKey: string;
31
32
  };
32
33
  loginUser(email: string, password: string): {
33
34
  user: User;
@@ -172,6 +173,30 @@ export declare class MuxoStore {
172
173
  }): WorkspaceMemoryRecord;
173
174
  listMemoryRecords(workspaceId: string, limit?: number): WorkspaceMemoryRecord[];
174
175
  deleteMemoryRecord(workspaceId: string, idOrDocId: string): WorkspaceMemoryRecord | null;
176
+ upsertTemporalFact(params: {
177
+ workspaceId: string;
178
+ subject: string;
179
+ predicate: string;
180
+ object: string;
181
+ summary: string;
182
+ confidence?: number;
183
+ sourceKind?: TemporalGraphFact["sourceKind"];
184
+ sourceReferenceId?: string | null;
185
+ metadata?: Record<string, unknown>;
186
+ supersedeExisting?: boolean;
187
+ }): TemporalGraphFact;
188
+ listTemporalFacts(workspaceId: string, opts?: {
189
+ includeHistorical?: boolean;
190
+ subject?: string;
191
+ predicate?: string;
192
+ query?: string;
193
+ limit?: number;
194
+ }): TemporalGraphFact[];
195
+ forgetMatchingMemoryRecords(workspaceId: string, query: string): {
196
+ deletedMemories: WorkspaceMemoryRecord[];
197
+ invalidatedFacts: TemporalGraphFact[];
198
+ };
199
+ private mapTemporalFact;
175
200
  createAutonomousAgentSignup(params?: {
176
201
  agentName?: string;
177
202
  harness?: string;