@muxoai/platform 1.3.1 → 1.3.3

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
@@ -6,7 +6,9 @@ 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
@@ -170,7 +172,7 @@ export function createMuxoServer(customConfig) {
170
172
  ok: true,
171
173
  status: "ready",
172
174
  service: "muxo-platform",
173
- version: "1.3.1",
175
+ version: MUXO_VERSION,
174
176
  environment: "production",
175
177
  live_execution: true,
176
178
  customer_billing: true,
@@ -464,7 +466,7 @@ export function createMuxoServer(customConfig) {
464
466
  openapi: "3.1.0",
465
467
  info: {
466
468
  title: "Muxo Unified Agent Execution, Infrastructure, Memory & Governance API",
467
- version: "1.3.1",
469
+ version: MUXO_VERSION,
468
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.",
469
471
  },
470
472
  servers: [{ url: config.baseUrl }],
@@ -634,12 +636,20 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
634
636
  });
635
637
  return;
636
638
  }
637
- // Web Console UI (app.muxo.ai)
638
- if ((pathname === "/" || pathname === "/console") && req.method === "GET") {
639
+ // Web Console UI (app.muxo.ai) & SPA deep-links
640
+ if (isConsolePath(pathname) && req.method === "GET") {
639
641
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
640
642
  res.end(renderConsoleHtml());
641
643
  return;
642
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
+ }
643
653
  // Built-in Interactive Landing & Provider Canvas (muxo.ai)
644
654
  if (pathname === "/landing" && req.method === "GET") {
645
655
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -683,7 +693,8 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
683
693
  <div class="badge">Ownership Bound</div>
684
694
  <h1>Workspace Claimed</h1>
685
695
  <p>Workspace <code>${redeemed.workspace.name}</code> (${redeemed.workspace.id}) claimed by <strong>${redeemed.targetEmail}</strong>.</p>
686
- <a class="btn" href="/?claimed=${encodeURIComponent(redeemed.workspace.slug)}&api_key=${encodeURIComponent(claimConsoleKey)}">Open Muxo Console →</a>
696
+ <p>Console key: <code>${claimConsoleKey}</code><br />Choose “Use an API key instead” in the console and paste it.</p>
697
+ <a class="btn" href="/?claimed=${encodeURIComponent(redeemed.workspace.slug)}">Open Muxo Console →</a>
687
698
  </div>
688
699
  </body>
689
700
  </html>`);
@@ -753,8 +764,11 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
753
764
  </html>`);
754
765
  return;
755
766
  }
756
- // Autonomous Agent 2-Call Signup (agents.composio.dev pattern) — Public
757
- if (pathname === "/api/v1/agents/signup" && req.method === "POST") {
767
+ // Autonomous Agent 2-Call Signup — Public
768
+ if ((pathname === "/api/v1/agents/signup" ||
769
+ pathname === "/api/v1/auth/signup" ||
770
+ pathname === "/api/signup") &&
771
+ req.method === "POST") {
758
772
  const body = JSON.parse((await readBody(req)) || "{}");
759
773
  const created = store.createAutonomousAgentSignup({
760
774
  agentName: body.agentName ? String(body.agentName) : undefined,
@@ -805,7 +819,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
805
819
  protocolVersion: "2025-06-18",
806
820
  serverInfo: {
807
821
  name: "muxo-mcp-server",
808
- version: "1.3.1",
822
+ version: MUXO_VERSION,
809
823
  },
810
824
  instructions: MUXO_MCP_SERVER_INSTRUCTIONS,
811
825
  toolsCount: MUXO_MCP_TOOLS.length,
@@ -845,6 +859,10 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
845
859
  return;
846
860
  }
847
861
  // Auth Endpoints
862
+ if (pathname === "/api/v1/auth/config" && req.method === "GET") {
863
+ sendJson(res, 200, { ok: true, provider: "password", clerk: null, signInUrl: "/login" });
864
+ return;
865
+ }
848
866
  if (pathname === "/api/v1/auth/register" && req.method === "POST") {
849
867
  const body = JSON.parse((await readBody(req)) || "{}");
850
868
  const created = store.registerUser({
@@ -853,7 +871,16 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
853
871
  password: String(body.password || ""),
854
872
  workspaceName: body.workspaceName ? String(body.workspaceName) : undefined,
855
873
  });
856
- sendJson(res, 201, { ok: true, ...created });
874
+ const initialKey = store.createApiKey({
875
+ workspaceId: created.workspace.id,
876
+ name: "Default Live Key",
877
+ environment: "live",
878
+ });
879
+ sendJson(res, 201, {
880
+ ok: true,
881
+ ...created,
882
+ apiKey: initialKey.secretKey,
883
+ });
857
884
  return;
858
885
  }
859
886
  if (pathname === "/api/v1/auth/login" && req.method === "POST") {
@@ -917,11 +944,49 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
917
944
  }
918
945
  // Microsoft Agent Governance Status & Audit Verification
919
946
  if (pathname === "/api/v1/governance" && req.method === "GET") {
947
+ const ws = store.getWorkspace(ctx.workspace.id) || ctx.workspace;
948
+ const fullReport = engine.governance.getGovernanceStatus(ws);
920
949
  sendJson(res, 200, {
921
950
  ok: true,
922
- governance: engine.governance.getStatus(),
923
- workspacePolicy: ctx.workspace.policy,
951
+ governance: {
952
+ ...engine.governance.getStatus(ws),
953
+ modules: fullReport.modules,
954
+ trustScore: fullReport.trustScore,
955
+ killSwitch: fullReport.killSwitch,
956
+ contextPoisoning: fullReport.contextPoisoning,
957
+ auditChain: fullReport.auditChain,
958
+ },
959
+ workspacePolicy: ws.policy,
960
+ });
961
+ return;
962
+ }
963
+ if (pathname === "/api/v1/governance/kill-switch" && req.method === "POST") {
964
+ const body = JSON.parse((await readBody(req)) || "{}");
965
+ const action = String(body.action || "quarantine").toLowerCase();
966
+ if (action === "resume" || body.active === false) {
967
+ const out = engine.resumeWorkspaceKillSwitch(ctx);
968
+ sendJson(res, 200, { ok: true, ...out });
969
+ return;
970
+ }
971
+ const out = await engine.activateWorkspaceKillSwitch(ctx, {
972
+ reason: String(body.reason || "Emergency kill-switch activated by workspace operator"),
973
+ action: action === "terminate" || action === "suspend"
974
+ ? action
975
+ : "quarantine",
976
+ });
977
+ sendJson(res, 200, { ok: true, ...out });
978
+ return;
979
+ }
980
+ if (pathname === "/api/v1/governance/scan-context" && req.method === "POST") {
981
+ const body = JSON.parse((await readBody(req)) || "{}");
982
+ const scan = engine.governance.scanMemoryContent({
983
+ workspaceId: ctx.workspace.id,
984
+ sessionId: String(body.sessionId || "default"),
985
+ role: body.role || "user",
986
+ content: String(body.content || ""),
987
+ recordInDetector: Boolean(body.recordInDetector),
924
988
  });
989
+ sendJson(res, 200, { ok: true, scan });
925
990
  return;
926
991
  }
927
992
  // Supermemory v5 Workspace Brain Endpoints
@@ -933,6 +998,37 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
933
998
  sendJson(res, 200, { ok: true, ...overview });
934
999
  return;
935
1000
  }
1001
+ if (pathname === "/api/v1/memory/facts" && req.method === "GET") {
1002
+ const query = url.searchParams.get("query") ||
1003
+ url.searchParams.get("q") ||
1004
+ undefined;
1005
+ const includeHistorical = url.searchParams.get("historical") !== "false";
1006
+ const facts = store.listTemporalFacts(ctx.workspace.id, {
1007
+ includeHistorical,
1008
+ subject: url.searchParams.get("subject") || undefined,
1009
+ predicate: url.searchParams.get("predicate") || undefined,
1010
+ query,
1011
+ limit: Number(url.searchParams.get("limit") || 50),
1012
+ });
1013
+ sendJson(res, 200, {
1014
+ ok: true,
1015
+ activeFacts: facts.filter((f) => f.validTo === null),
1016
+ historicalFacts: facts.filter((f) => f.validTo !== null),
1017
+ facts,
1018
+ });
1019
+ return;
1020
+ }
1021
+ if (pathname === "/api/v1/memory/forget" && req.method === "POST") {
1022
+ const body = JSON.parse((await readBody(req)) || "{}");
1023
+ const query = String(body.query || body.q || "").trim();
1024
+ if (!query) {
1025
+ sendJson(res, 400, { ok: false, error: "query is required to forget matching memories" });
1026
+ return;
1027
+ }
1028
+ const pruned = await engine.forgetWorkspaceMemoryMatching(ctx, query);
1029
+ sendJson(res, 200, { ok: true, ...pruned });
1030
+ return;
1031
+ }
936
1032
  if (pathname === "/api/v1/memory" && req.method === "POST") {
937
1033
  const body = JSON.parse((await readBody(req)) || "{}");
938
1034
  const record = await engine.addWorkspaceMemory(ctx, {
@@ -940,6 +1036,9 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
940
1036
  content: String(body.content || ""),
941
1037
  kind: body.kind || "fact",
942
1038
  metadata: body.metadata || {},
1039
+ subject: body.subject ? String(body.subject) : undefined,
1040
+ predicate: body.predicate ? String(body.predicate) : undefined,
1041
+ object: body.object ? String(body.object) : undefined,
943
1042
  });
944
1043
  sendJson(res, 201, { ok: true, memory: record });
945
1044
  return;
@@ -961,6 +1060,15 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
961
1060
  sendJson(res, 201, { ok: true, ...created });
962
1061
  return;
963
1062
  }
1063
+ if (pathname.startsWith("/api/v1/api-keys/") && req.method === "DELETE") {
1064
+ const keyId = decodeURIComponent(pathname.slice("/api/v1/api-keys/".length));
1065
+ if (!store.revokeApiKey(ctx.workspace.id, keyId)) {
1066
+ sendJson(res, 404, { ok: false, error: "API key not found" });
1067
+ return;
1068
+ }
1069
+ sendJson(res, 200, { ok: true, revoked: keyId });
1070
+ return;
1071
+ }
964
1072
  // Profile & Organization (v1 and api/v1)
965
1073
  if ((pathname === "/api/v1/profile" || pathname === "/v1/profile") && req.method === "GET") {
966
1074
  sendJson(res, 200, { ok: true, ...engine.getProfile(ctx) });
@@ -1060,7 +1168,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1060
1168
  // Governance Policy
1061
1169
  if (pathname === "/api/v1/policy" && req.method === "POST") {
1062
1170
  const body = JSON.parse((await readBody(req)) || "{}");
1063
- const updated = store.updateWorkspacePolicy(ctx.workspace.id, body);
1171
+ const updated = store.updateWorkspacePolicy(ctx.workspace.id, sanitizePolicyPatch(body));
1064
1172
  sendJson(res, 200, { ok: true, workspace: updated });
1065
1173
  return;
1066
1174
  }
@@ -1074,10 +1182,17 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1074
1182
  }
1075
1183
  if (pathname === "/api/v1/plans" && req.method === "POST") {
1076
1184
  const body = JSON.parse((await readBody(req)) || "{}");
1185
+ const rawFunding = body.fundingMode || body.funding_mode;
1186
+ const fundingMode = rawFunding === "byok" || rawFunding === "customer_funded"
1187
+ ? "byok"
1188
+ : rawFunding === "muxo_funded"
1189
+ ? "muxo_funded"
1190
+ : undefined;
1077
1191
  const planned = await engine.planAction(ctx, {
1078
1192
  toolSlug: String(body.toolSlug || body.tool_slug || ""),
1079
1193
  input: body.input || {},
1080
1194
  reason: body.reason ? String(body.reason) : undefined,
1195
+ fundingMode,
1081
1196
  });
1082
1197
  sendJson(res, 201, { ok: true, ...planned });
1083
1198
  return;
@@ -1101,6 +1216,13 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1101
1216
  });
1102
1217
  return;
1103
1218
  }
1219
+ const planGetMatch = pathname.match(/^\/api\/v1\/plans\/([^/]+)$/);
1220
+ if (planGetMatch && req.method === "GET") {
1221
+ const planId = decodeURIComponent(planGetMatch[1]);
1222
+ const plan = engine.getPlan(ctx, planId);
1223
+ sendJson(res, 200, { ok: true, plan });
1224
+ return;
1225
+ }
1104
1226
  // Runs & Receipts
1105
1227
  if (pathname === "/api/v1/runs" && req.method === "GET") {
1106
1228
  sendJson(res, 200, {
@@ -1109,6 +1231,21 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1109
1231
  });
1110
1232
  return;
1111
1233
  }
1234
+ const runCancelMatch = pathname.match(/^\/api\/v1\/runs\/([^/]+)\/cancel$/);
1235
+ if (runCancelMatch && req.method === "POST") {
1236
+ const runId = decodeURIComponent(runCancelMatch[1]);
1237
+ const body = JSON.parse((await readBody(req)) || "{}");
1238
+ const cancelled = engine.cancelRun(ctx, runId, body.reason ? String(body.reason) : undefined);
1239
+ sendJson(res, 200, { ok: true, ...cancelled });
1240
+ return;
1241
+ }
1242
+ const runGetMatch = pathname.match(/^\/api\/v1\/runs\/([^/]+)$/);
1243
+ if (runGetMatch && req.method === "GET") {
1244
+ const runId = decodeURIComponent(runGetMatch[1]);
1245
+ const run = engine.getRun(ctx, runId);
1246
+ sendJson(res, 200, { ok: true, run });
1247
+ return;
1248
+ }
1112
1249
  if (pathname.startsWith("/api/v1/receipts/") && req.method === "GET") {
1113
1250
  const receiptId = decodeURIComponent(pathname.slice("/api/v1/receipts/".length));
1114
1251
  const verified = engine.getReceipt(ctx, receiptId);
@@ -1158,7 +1295,13 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1158
1295
  if ((pathname === "/api/v1/do" || pathname === "/v1/do") &&
1159
1296
  req.method === "POST") {
1160
1297
  const body = JSON.parse((await readBody(req)) || "{}");
1161
- const prompt = String(body.prompt || body.instruction || body.query || body.command || "").trim();
1298
+ const prompt = String(body.prompt ||
1299
+ body.instruction ||
1300
+ body.query ||
1301
+ body.command ||
1302
+ body.toolSlug ||
1303
+ body.tool ||
1304
+ "").trim();
1162
1305
  if (!prompt) {
1163
1306
  sendJson(res, 400, {
1164
1307
  ok: false,
@@ -1166,19 +1309,37 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
1166
1309
  });
1167
1310
  return;
1168
1311
  }
1312
+ const dryRun = body.dryRun === true ||
1313
+ body.dry_run === true ||
1314
+ body.planOnly === true ||
1315
+ body.autoExecute === false ||
1316
+ body.auto_execute === false;
1317
+ const autoApprove = body.autoApprove !== false &&
1318
+ body.auto_approve !== false &&
1319
+ body.approveRisky !== false &&
1320
+ body.approve_risky !== false;
1321
+ const rawFunding = body.fundingMode || body.funding_mode;
1322
+ const fundingMode = rawFunding === "byok" || rawFunding === "customer_funded"
1323
+ ? "byok"
1324
+ : rawFunding === "muxo_funded"
1325
+ ? "muxo_funded"
1326
+ : undefined;
1169
1327
  const result = await engine.doNaturalLanguage(ctx, {
1170
1328
  prompt,
1171
1329
  input: body.input && typeof body.input === "object"
1172
1330
  ? body.input
1173
1331
  : undefined,
1174
- autoApprove: body.autoApprove !== false,
1175
- dryRun: body.dryRun === true,
1332
+ autoApprove,
1333
+ dryRun,
1334
+ planOnly: dryRun,
1335
+ fundingMode,
1176
1336
  });
1177
1337
  sendJson(res, 200, result);
1178
1338
  return;
1179
1339
  }
1180
1340
  // Live Stripe Billing, Credit Top-Up & Supplier Settlement Ledger
1181
- if (pathname === "/api/v1/billing/status" && req.method === "GET") {
1341
+ if ((pathname === "/api/v1/billing/status" || pathname === "/api/v1/billing") &&
1342
+ req.method === "GET") {
1182
1343
  const ws = store.getWorkspace(ctx.workspace.id);
1183
1344
  const settlementSummary = store.getSupplierSettlementSummary(ctx.workspace.id);
1184
1345
  const byokKeys = store.listByokKeys(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;
@@ -173,6 +173,30 @@ export declare class MuxoStore {
173
173
  }): WorkspaceMemoryRecord;
174
174
  listMemoryRecords(workspaceId: string, limit?: number): WorkspaceMemoryRecord[];
175
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;
176
200
  createAutonomousAgentSignup(params?: {
177
201
  agentName?: string;
178
202
  harness?: string;