@muxoai/platform 1.2.3 → 1.3.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.
- package/.agents/plugins/marketplace.json +1 -1
- package/.claude-plugin/marketplace.json +19 -4
- package/.codex/config.toml +9 -2
- package/README.md +72 -28
- package/dist/cli.js +1047 -43
- package/dist/engine.d.ts +29 -0
- package/dist/engine.js +221 -16
- package/dist/mcp.d.ts +6 -1
- package/dist/mcp.js +120 -26
- package/dist/nl.d.ts +34 -0
- package/dist/nl.js +601 -0
- package/dist/providers/composio-instant.d.ts +1 -0
- package/dist/providers/composio-instant.js +6 -5
- package/dist/providers/composio-sdk.d.ts +1 -0
- package/dist/providers/composio-sdk.js +6 -2
- package/dist/providers/stripe-billing.d.ts +13 -3
- package/dist/providers/stripe-billing.js +250 -36
- package/dist/providers/stripe-projects.js +61 -4
- package/dist/providers/supermemory.d.ts +2 -0
- package/dist/providers/supermemory.js +58 -40
- package/dist/sdk.d.ts +77 -1
- package/dist/sdk.js +46 -0
- package/dist/server.js +202 -29
- package/dist/store.d.ts +19 -2
- package/dist/store.js +216 -11
- package/dist/types.d.ts +14 -2
- package/dist/ui/console-html.js +329 -119
- package/package.json +1 -1
- package/plugins/muxo/.app.json +1 -1
- package/plugins/muxo/.claude-plugin/plugin.json +2 -2
- package/plugins/muxo/.codex-plugin/plugin.json +7 -5
- package/plugins/muxo/.mcp.json +1 -33
- package/plugins/muxo/assets/logo.png +0 -0
- package/plugins/muxo/hooks/session-start.sh +1 -1
- package/plugins/muxo/plugin.json +63 -6
- package/plugins/muxo/skills/muxo/SKILL.md +92 -14
- package/plugins/muxo/skills/muxo/agents/openai.yaml +12 -0
- package/plugins/muxo/skills/muxo/references/cli.md +4 -2
- package/plugins/muxo/skills/muxo/references/mcp.md +15 -9
- package/plugins/muxo/skills/setup/SKILL.md +8 -2
- package/plugins/muxo/skills/setup/agents/openai.yaml +12 -0
package/dist/server.js
CHANGED
|
@@ -10,35 +10,51 @@ import { renderConsoleHtml, renderLandingHtml } from "./ui/console-html.js";
|
|
|
10
10
|
function renderSkillMarkdown(baseUrl) {
|
|
11
11
|
return `---
|
|
12
12
|
name: muxo
|
|
13
|
-
description: Discover, plan, and execute governed actions across Connected Apps (
|
|
13
|
+
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
14
|
---
|
|
15
15
|
|
|
16
|
-
# Muxo — Unified Agent Execution, Infrastructure, Memory &
|
|
16
|
+
# Muxo — Unified Agent Execution, Infrastructure, Memory & Safety Platform
|
|
17
17
|
|
|
18
|
-
Muxo provides one
|
|
18
|
+
Muxo provides one unified interface across 4 capabilities so agents and users only ever interact with Muxo:
|
|
19
19
|
|
|
20
|
-
1. **Instant Tools (\`instant.*\`)**: Zero-OAuth tools
|
|
21
|
-
2. **Connected Apps (\`app.*\`)**: Managed OAuth SaaS integrations
|
|
22
|
-
3. **Cloud Infrastructure (\`resource.*\`)**: Database, cache, storage, and hosting provisioning
|
|
23
|
-
4. **
|
|
20
|
+
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\`).
|
|
21
|
+
2. **Connected Apps (\`app.*\`)**: Managed OAuth SaaS integrations (\`app.github.*\`, \`app.gmail.*\`, \`app.slack.*\`, \`app.notion.*\`, \`app.linear.*\`, etc.).
|
|
22
|
+
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.
|
|
23
|
+
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
24
|
|
|
25
|
-
## Installable Muxo Plugin (OpenAI Codex,
|
|
25
|
+
## Installable Muxo Plugin (Claude Code, OpenAI Codex, Claude Desktop & ChatGPT)
|
|
26
|
+
|
|
27
|
+
> **Requirement:** \`@muxoai/cli\` requires **Node.js 22+** (\`node >= 22.0.0\`).
|
|
26
28
|
|
|
27
29
|
\`\`\`bash
|
|
28
|
-
# Install Muxo CLI & sign in
|
|
29
|
-
npm install -g
|
|
30
|
+
# Install Muxo CLI & sign in against the hosted workspace (Node.js 22+)
|
|
31
|
+
npm install -g @muxoai/cli@latest
|
|
30
32
|
muxo login --signup --name "my-agent"
|
|
31
33
|
|
|
34
|
+
# Claude Code marketplace (muxo@muxo):
|
|
35
|
+
claude plugin marketplace add ${baseUrl}/.claude-plugin/marketplace.json
|
|
36
|
+
claude plugin install muxo@muxo
|
|
37
|
+
|
|
38
|
+
# OpenAI Codex: add a Git repo or local marketplace directory containing .agents/plugins/marketplace.json,
|
|
39
|
+
# or configure [mcp_servers.muxo] in ~/.codex/config.toml (url = "${baseUrl}/mcp")
|
|
40
|
+
|
|
41
|
+
# Claude Desktop:
|
|
42
|
+
# - Hosted MCP: Settings -> Connectors -> Add custom connector -> ${baseUrl}/mcp
|
|
43
|
+
# - Local stdio server: configure npx -y @muxoai/cli@latest mcp in claude_desktop_config.json
|
|
44
|
+
|
|
45
|
+
# ChatGPT:
|
|
46
|
+
# - Plugins -> + -> Add custom MCP server -> ${baseUrl}/mcp (OAuth supports CIMD or DCR)
|
|
47
|
+
|
|
32
48
|
# Link OAuth apps with live browser handoff + polling recovery
|
|
33
49
|
muxo link github --wait
|
|
34
50
|
|
|
35
51
|
# Plugin manifests served by this instance:
|
|
36
|
-
# - ${baseUrl}/.agents/plugins/marketplace.json (OpenAI Codex /
|
|
37
|
-
# - ${baseUrl}/.claude-plugin/marketplace.json (Claude Code
|
|
52
|
+
# - ${baseUrl}/.agents/plugins/marketplace.json (OpenAI Codex local/Git marketplace manifest)
|
|
53
|
+
# - ${baseUrl}/.claude-plugin/marketplace.json (Claude Code marketplace manifest)
|
|
38
54
|
# - ${baseUrl}/api/v1/plugin
|
|
39
55
|
\`\`\`
|
|
40
56
|
|
|
41
|
-
## Autonomous Agent 2-Call Signup
|
|
57
|
+
## CLI-First Autonomous Agent 2-Call Signup
|
|
42
58
|
|
|
43
59
|
\`\`\`bash
|
|
44
60
|
# 1. Create an autonomous workspace + mk_live_* API key
|
|
@@ -154,7 +170,7 @@ export function createMuxoServer(customConfig) {
|
|
|
154
170
|
ok: true,
|
|
155
171
|
status: "ready",
|
|
156
172
|
service: "muxo-platform",
|
|
157
|
-
version: "1.
|
|
173
|
+
version: "1.3.1",
|
|
158
174
|
environment: "production",
|
|
159
175
|
live_execution: true,
|
|
160
176
|
customer_billing: true,
|
|
@@ -241,10 +257,21 @@ export function createMuxoServer(customConfig) {
|
|
|
241
257
|
],
|
|
242
258
|
code_challenge_methods_supported: ["S256", "plain"],
|
|
243
259
|
client_id_metadata_document_supported: true,
|
|
260
|
+
authorization_response_iss_parameter_supported: true,
|
|
244
261
|
service_documentation: `${config.docsUrl}/quickstart`,
|
|
245
262
|
});
|
|
246
263
|
return;
|
|
247
264
|
}
|
|
265
|
+
if (pathname === "/.well-known/openai-apps-challenge" && req.method === "GET") {
|
|
266
|
+
const challenge = process.env.OPENAI_APPS_CHALLENGE ||
|
|
267
|
+
"muxo-openai-apps-domain-verified";
|
|
268
|
+
res.writeHead(200, {
|
|
269
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
270
|
+
"Access-Control-Allow-Origin": "*",
|
|
271
|
+
});
|
|
272
|
+
res.end(challenge);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
248
275
|
if (pathname === "/oauth/register" && req.method === "POST") {
|
|
249
276
|
const body = JSON.parse((await readBody(req)) || "{}");
|
|
250
277
|
const clientId = typeof body.client_id === "string" && body.client_id.trim()
|
|
@@ -311,16 +338,22 @@ export function createMuxoServer(customConfig) {
|
|
|
311
338
|
apiKey: issuedKey,
|
|
312
339
|
expiresAt: Date.now() + 10 * 60 * 1000,
|
|
313
340
|
});
|
|
341
|
+
const proto = String(req.headers["x-forwarded-proto"] || "http").split(",")[0].trim();
|
|
342
|
+
const requestOrigin = req.headers.host
|
|
343
|
+
? `${proto}://${req.headers.host}`
|
|
344
|
+
: config.baseUrl;
|
|
314
345
|
const redirectTarget = new URL(redirectUri);
|
|
315
346
|
redirectTarget.searchParams.set("code", code);
|
|
316
347
|
if (stateParam)
|
|
317
348
|
redirectTarget.searchParams.set("state", stateParam);
|
|
349
|
+
redirectTarget.searchParams.set("iss", requestOrigin);
|
|
318
350
|
if (url.searchParams.get("format") === "json" ||
|
|
319
351
|
String(req.headers.accept || "").includes("application/json")) {
|
|
320
352
|
sendJson(res, 200, {
|
|
321
353
|
ok: true,
|
|
322
354
|
code,
|
|
323
355
|
state: stateParam || null,
|
|
356
|
+
iss: requestOrigin,
|
|
324
357
|
client_id: clientId,
|
|
325
358
|
redirect_uri: redirectTarget.toString(),
|
|
326
359
|
});
|
|
@@ -409,11 +442,16 @@ export function createMuxoServer(customConfig) {
|
|
|
409
442
|
}
|
|
410
443
|
if (pathname === "/oauth/userinfo" && req.method === "GET") {
|
|
411
444
|
const ctx = resolveContext(req);
|
|
445
|
+
const nickname = (ctx.user.email || "").split("@")[0] ||
|
|
446
|
+
ctx.user.name.toLowerCase().replace(/\s+/g, ".") ||
|
|
447
|
+
ctx.user.id;
|
|
412
448
|
sendJson(res, 200, {
|
|
413
449
|
sub: ctx.user.id,
|
|
414
450
|
id: ctx.user.id,
|
|
415
451
|
name: ctx.user.name,
|
|
416
452
|
email: ctx.user.email,
|
|
453
|
+
email_verified: true,
|
|
454
|
+
nickname,
|
|
417
455
|
workspace_id: ctx.workspace.id,
|
|
418
456
|
workspace_name: ctx.workspace.name,
|
|
419
457
|
tier: ctx.workspace.tier,
|
|
@@ -426,7 +464,7 @@ export function createMuxoServer(customConfig) {
|
|
|
426
464
|
openapi: "3.1.0",
|
|
427
465
|
info: {
|
|
428
466
|
title: "Muxo Unified Agent Execution, Infrastructure, Memory & Governance API",
|
|
429
|
-
version: "1.
|
|
467
|
+
version: "1.3.1",
|
|
430
468
|
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
469
|
},
|
|
432
470
|
servers: [{ url: config.baseUrl }],
|
|
@@ -475,12 +513,12 @@ Or via HTTP:
|
|
|
475
513
|
curl -sX POST ${config.baseUrl}/api/v1/agents/signup -H "Content-Type: application/json" -d '{"agentName":"my-agent"}'
|
|
476
514
|
\`\`\`
|
|
477
515
|
|
|
478
|
-
## 2. OAuth Connection Handoff
|
|
516
|
+
## 2. OAuth Connection Handoff
|
|
479
517
|
When \`plan_action\` targets an unconnected \`app.<provider>.*\` tool, Muxo returns \`authHandoff.redirectUrl\`.
|
|
480
518
|
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
519
|
|
|
482
|
-
## 3.
|
|
483
|
-
Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing topup 1000\`), and Muxo settles
|
|
520
|
+
## 3. Credit Billing & BYOK Support
|
|
521
|
+
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
522
|
`);
|
|
485
523
|
return;
|
|
486
524
|
}
|
|
@@ -507,7 +545,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
507
545
|
}
|
|
508
546
|
if (pathname === "/llms.txt" && req.method === "GET") {
|
|
509
547
|
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
|
|
510
|
-
res.end(`# Muxo\n> Unified execution,
|
|
548
|
+
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
549
|
return;
|
|
512
550
|
}
|
|
513
551
|
// Serve Installable Muxo Plugin Manifests & Metadata (Portable OpenAI Agent Plugins + Codex + Claude)
|
|
@@ -616,6 +654,11 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
616
654
|
sendJson(res, 404, { ok: false, error: "Invalid or expired agent claim link" });
|
|
617
655
|
return;
|
|
618
656
|
}
|
|
657
|
+
const claimConsoleKey = store.createApiKey({
|
|
658
|
+
workspaceId: redeemed.workspace.id,
|
|
659
|
+
name: `Owner Claim Session (${redeemed.targetEmail})`,
|
|
660
|
+
environment: "live",
|
|
661
|
+
}).secretKey;
|
|
619
662
|
const wantsHtml = url.searchParams.get("format") !== "json" &&
|
|
620
663
|
String(req.headers.accept || "").includes("text/html");
|
|
621
664
|
if (wantsHtml) {
|
|
@@ -640,7 +683,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
640
683
|
<div class="badge">Ownership Bound</div>
|
|
641
684
|
<h1>Workspace Claimed</h1>
|
|
642
685
|
<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>
|
|
686
|
+
<a class="btn" href="/?claimed=${encodeURIComponent(redeemed.workspace.slug)}&api_key=${encodeURIComponent(claimConsoleKey)}">Open Muxo Console →</a>
|
|
644
687
|
</div>
|
|
645
688
|
</body>
|
|
646
689
|
</html>`);
|
|
@@ -649,6 +692,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
649
692
|
sendJson(res, 200, {
|
|
650
693
|
ok: true,
|
|
651
694
|
message: `Workspace '${redeemed.workspace.name}' claimed by ${redeemed.targetEmail}`,
|
|
695
|
+
apiKey: claimConsoleKey,
|
|
652
696
|
claim: redeemed,
|
|
653
697
|
});
|
|
654
698
|
return;
|
|
@@ -735,8 +779,8 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
735
779
|
});
|
|
736
780
|
return;
|
|
737
781
|
}
|
|
738
|
-
// Streamable HTTP MCP Endpoint (POST /mcp, GET /mcp, DELETE /mcp)
|
|
739
|
-
if (pathname === "/mcp" && req.method === "GET") {
|
|
782
|
+
// Streamable HTTP MCP Endpoint (POST /mcp, GET /mcp, HEAD /mcp, DELETE /mcp)
|
|
783
|
+
if (pathname === "/mcp" && (req.method === "GET" || req.method === "HEAD")) {
|
|
740
784
|
const accept = String(req.headers.accept || "");
|
|
741
785
|
const sessionId = String(req.headers["mcp-session-id"] || "") ||
|
|
742
786
|
`mcp_sess_${crypto.randomBytes(8).toString("hex")}`;
|
|
@@ -747,8 +791,11 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
747
791
|
Connection: "keep-alive",
|
|
748
792
|
"Mcp-Session-Id": sessionId,
|
|
749
793
|
"Access-Control-Allow-Origin": "*",
|
|
794
|
+
"Access-Control-Expose-Headers": "Mcp-Session-Id",
|
|
750
795
|
});
|
|
751
|
-
|
|
796
|
+
if (req.method !== "HEAD") {
|
|
797
|
+
res.write(`event: endpoint\ndata: ${JSON.stringify({ uri: `${config.baseUrl}/mcp`, sessionId })}\n\n`);
|
|
798
|
+
}
|
|
752
799
|
res.end();
|
|
753
800
|
return;
|
|
754
801
|
}
|
|
@@ -758,12 +805,12 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
758
805
|
protocolVersion: "2025-06-18",
|
|
759
806
|
serverInfo: {
|
|
760
807
|
name: "muxo-mcp-server",
|
|
761
|
-
version: "1.
|
|
808
|
+
version: "1.3.1",
|
|
762
809
|
},
|
|
763
810
|
instructions: MUXO_MCP_SERVER_INSTRUCTIONS,
|
|
764
811
|
toolsCount: MUXO_MCP_TOOLS.length,
|
|
765
812
|
skillsCount: getMuxoMcpSkills().length,
|
|
766
|
-
});
|
|
813
|
+
}, { "Mcp-Session-Id": sessionId });
|
|
767
814
|
return;
|
|
768
815
|
}
|
|
769
816
|
if (pathname === "/mcp" && req.method === "DELETE") {
|
|
@@ -838,6 +885,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
838
885
|
landingUrl: `${config.baseUrl}/landing`,
|
|
839
886
|
},
|
|
840
887
|
apiKeys: store.listApiKeys(ctx.workspace.id),
|
|
888
|
+
byokKeys: store.listByokKeys(ctx.workspace.id),
|
|
841
889
|
defaultApiKey: bootstrap.defaultApiKey || null,
|
|
842
890
|
connections: store.listConnections(ctx.workspace.id),
|
|
843
891
|
resources: store.listResources(ctx.workspace.id),
|
|
@@ -859,7 +907,12 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
859
907
|
email,
|
|
860
908
|
baseUrl: config.baseUrl,
|
|
861
909
|
});
|
|
862
|
-
sendJson(res, 201, {
|
|
910
|
+
sendJson(res, 201, {
|
|
911
|
+
ok: true,
|
|
912
|
+
claim: { ...claim, ownerEmail: email },
|
|
913
|
+
...claim,
|
|
914
|
+
ownerEmail: email,
|
|
915
|
+
});
|
|
863
916
|
return;
|
|
864
917
|
}
|
|
865
918
|
// Microsoft Agent Governance Status & Audit Verification
|
|
@@ -1041,7 +1094,11 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
1041
1094
|
const planId = decodeURIComponent(planExecuteMatch[1]);
|
|
1042
1095
|
const plan = engine.getPlan(ctx, planId);
|
|
1043
1096
|
const result = await engine.executePlanForRisk(ctx, planId, plan.riskLevel);
|
|
1044
|
-
sendJson(res, 200, {
|
|
1097
|
+
sendJson(res, 200, {
|
|
1098
|
+
ok: true,
|
|
1099
|
+
...result,
|
|
1100
|
+
settlement: result.receipt?.supplierSettlement || null,
|
|
1101
|
+
});
|
|
1045
1102
|
return;
|
|
1046
1103
|
}
|
|
1047
1104
|
// Runs & Receipts
|
|
@@ -1058,7 +1115,91 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
1058
1115
|
sendJson(res, 200, { ok: true, ...verified });
|
|
1059
1116
|
return;
|
|
1060
1117
|
}
|
|
1118
|
+
// BYOK (Bring Your Own Key) Encrypted Vault Management
|
|
1119
|
+
if (pathname === "/api/v1/byok" && req.method === "GET") {
|
|
1120
|
+
sendJson(res, 200, {
|
|
1121
|
+
ok: true,
|
|
1122
|
+
workspaceId: ctx.workspace.id,
|
|
1123
|
+
keys: store.listByokKeys(ctx.workspace.id),
|
|
1124
|
+
});
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
if (pathname === "/api/v1/byok" && req.method === "POST") {
|
|
1128
|
+
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1129
|
+
const provider = String(body.provider || "").trim();
|
|
1130
|
+
const secretKey = String(body.secretKey || body.apiKey || body.key || "").trim();
|
|
1131
|
+
if (!provider || !secretKey) {
|
|
1132
|
+
sendJson(res, 400, {
|
|
1133
|
+
ok: false,
|
|
1134
|
+
error: "Both 'provider' and 'secretKey' are required",
|
|
1135
|
+
});
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
const record = store.setByokKey(ctx.workspace.id, provider, secretKey);
|
|
1139
|
+
sendJson(res, 201, {
|
|
1140
|
+
ok: true,
|
|
1141
|
+
key: record,
|
|
1142
|
+
keys: store.listByokKeys(ctx.workspace.id),
|
|
1143
|
+
});
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
if (pathname.startsWith("/api/v1/byok/") && req.method === "DELETE") {
|
|
1147
|
+
const provider = decodeURIComponent(pathname.slice("/api/v1/byok/".length));
|
|
1148
|
+
const deleted = store.deleteByokKey(ctx.workspace.id, provider);
|
|
1149
|
+
sendJson(res, 200, {
|
|
1150
|
+
ok: true,
|
|
1151
|
+
deleted,
|
|
1152
|
+
provider,
|
|
1153
|
+
keys: store.listByokKeys(ctx.workspace.id),
|
|
1154
|
+
});
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
// Natural Language Intent & Governed Execution Endpoint
|
|
1158
|
+
if ((pathname === "/api/v1/do" || pathname === "/v1/do") &&
|
|
1159
|
+
req.method === "POST") {
|
|
1160
|
+
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1161
|
+
const prompt = String(body.prompt || body.instruction || body.query || body.command || "").trim();
|
|
1162
|
+
if (!prompt) {
|
|
1163
|
+
sendJson(res, 400, {
|
|
1164
|
+
ok: false,
|
|
1165
|
+
error: "Missing 'prompt' or 'instruction' in request body",
|
|
1166
|
+
});
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
const result = await engine.doNaturalLanguage(ctx, {
|
|
1170
|
+
prompt,
|
|
1171
|
+
input: body.input && typeof body.input === "object"
|
|
1172
|
+
? body.input
|
|
1173
|
+
: undefined,
|
|
1174
|
+
autoApprove: body.autoApprove !== false,
|
|
1175
|
+
dryRun: body.dryRun === true,
|
|
1176
|
+
});
|
|
1177
|
+
sendJson(res, 200, result);
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1061
1180
|
// Live Stripe Billing, Credit Top-Up & Supplier Settlement Ledger
|
|
1181
|
+
if (pathname === "/api/v1/billing/status" && req.method === "GET") {
|
|
1182
|
+
const ws = store.getWorkspace(ctx.workspace.id);
|
|
1183
|
+
const settlementSummary = store.getSupplierSettlementSummary(ctx.workspace.id);
|
|
1184
|
+
const byokKeys = store.listByokKeys(ctx.workspace.id);
|
|
1185
|
+
sendJson(res, 200, {
|
|
1186
|
+
ok: true,
|
|
1187
|
+
workspaceId: ws.id,
|
|
1188
|
+
workspace: ws,
|
|
1189
|
+
tier: ws.tier,
|
|
1190
|
+
creditsBalance: ws.creditsBalance,
|
|
1191
|
+
creditBalance: ws.creditsBalance,
|
|
1192
|
+
monthlyActionsUsed: ws.monthlyActionsUsed,
|
|
1193
|
+
monthlyActionsLimit: ws.monthlyActionsLimit,
|
|
1194
|
+
stripeConfigured: engine.stripeBilling.isConfigured,
|
|
1195
|
+
stripeCustomerId: ws.stripeCustomerId,
|
|
1196
|
+
stripeSubscriptionId: ws.stripeSubscriptionId,
|
|
1197
|
+
settlementSummary,
|
|
1198
|
+
byokKeys,
|
|
1199
|
+
entries: store.listLedgerEntries(ctx.workspace.id, 25),
|
|
1200
|
+
});
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1062
1203
|
if (pathname === "/api/v1/billing/ledger" && req.method === "GET") {
|
|
1063
1204
|
sendJson(res, 200, {
|
|
1064
1205
|
ok: true,
|
|
@@ -1091,27 +1232,59 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
1091
1232
|
sendJson(res, 200, {
|
|
1092
1233
|
ok: true,
|
|
1093
1234
|
creditsAdded: credits,
|
|
1235
|
+
creditBalance: updatedWorkspace.creditsBalance,
|
|
1236
|
+
creditsBalance: updatedWorkspace.creditsBalance,
|
|
1094
1237
|
usdPaid: Number(usdPaid),
|
|
1095
1238
|
workspace: updatedWorkspace,
|
|
1096
1239
|
settlementSummary: store.getSupplierSettlementSummary(ctx.workspace.id),
|
|
1097
1240
|
});
|
|
1098
1241
|
return;
|
|
1099
1242
|
}
|
|
1243
|
+
if (pathname === "/api/v1/billing/upgrade" && req.method === "POST") {
|
|
1244
|
+
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1245
|
+
const referenceId = String(body.referenceId || "").trim() ||
|
|
1246
|
+
`upgrade_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1247
|
+
const bonusCredits = body.bonusCredits !== undefined ? Number(body.bonusCredits) : 1000;
|
|
1248
|
+
const updatedWorkspace = store.upgradeWorkspaceToStarter({
|
|
1249
|
+
workspaceId: ctx.workspace.id,
|
|
1250
|
+
stripeCustomerId: ctx.workspace.stripeCustomerId ||
|
|
1251
|
+
`cus_muxo_${ctx.workspace.id.slice(3, 11)}`,
|
|
1252
|
+
stripeSubscriptionId: ctx.workspace.stripeSubscriptionId ||
|
|
1253
|
+
`sub_muxo_${referenceId.slice(-10)}`,
|
|
1254
|
+
referenceId,
|
|
1255
|
+
bonusCredits,
|
|
1256
|
+
});
|
|
1257
|
+
sendJson(res, 200, {
|
|
1258
|
+
ok: true,
|
|
1259
|
+
tier: updatedWorkspace.tier,
|
|
1260
|
+
creditsBalance: updatedWorkspace.creditsBalance,
|
|
1261
|
+
creditBalance: updatedWorkspace.creditsBalance,
|
|
1262
|
+
workspace: updatedWorkspace,
|
|
1263
|
+
settlementSummary: store.getSupplierSettlementSummary(ctx.workspace.id),
|
|
1264
|
+
});
|
|
1265
|
+
return;
|
|
1266
|
+
}
|
|
1100
1267
|
if (pathname === "/api/v1/billing/checkout" && req.method === "POST") {
|
|
1101
1268
|
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1102
1269
|
const kind = body.kind === "credit_topup" ? "credit_topup" : "starter_subscription";
|
|
1270
|
+
const credits = body.credits ? Number(body.credits) : 1000;
|
|
1103
1271
|
const session = await engine.stripeBilling.createCheckoutSession({
|
|
1104
1272
|
workspace: ctx.workspace,
|
|
1105
1273
|
customerEmail: ctx.user.email,
|
|
1106
1274
|
kind,
|
|
1107
|
-
|
|
1275
|
+
credits,
|
|
1276
|
+
returnBaseUrl: body.returnBaseUrl ? String(body.returnBaseUrl) : config.baseUrl,
|
|
1108
1277
|
});
|
|
1109
1278
|
sendJson(res, 200, { ok: true, ...session });
|
|
1110
1279
|
return;
|
|
1111
1280
|
}
|
|
1112
1281
|
if (pathname === "/api/v1/billing/verify-session" && req.method === "POST") {
|
|
1113
1282
|
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1114
|
-
const verified = await engine.stripeBilling.verifyAndFulfillCheckoutSession(String(body.sessionId || "")
|
|
1283
|
+
const verified = await engine.stripeBilling.verifyAndFulfillCheckoutSession(String(body.sessionId || ""), ctx.workspace.id, body.kind === "credit_topup"
|
|
1284
|
+
? "credit_topup"
|
|
1285
|
+
: body.kind === "starter_subscription"
|
|
1286
|
+
? "starter_subscription"
|
|
1287
|
+
: undefined);
|
|
1115
1288
|
sendJson(res, 200, { ok: true, ...verified });
|
|
1116
1289
|
return;
|
|
1117
1290
|
}
|
package/dist/store.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { DatabaseSync } from "node:sqlite";
|
|
2
|
-
import type { ActionPlan, ApiKeyRecord, 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, User, Workspace, WorkspaceMemoryRecord } from "./types.js";
|
|
3
|
+
export declare const BYOK_PROVIDER_CATALOG: Record<string, {
|
|
4
|
+
category: "llm" | "supplier";
|
|
5
|
+
envVarName: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}>;
|
|
3
8
|
export declare class MuxoStore {
|
|
4
9
|
readonly db: DatabaseSync;
|
|
5
10
|
private readonly vaultKey;
|
|
@@ -23,6 +28,7 @@ export declare class MuxoStore {
|
|
|
23
28
|
user: User;
|
|
24
29
|
workspace: Workspace;
|
|
25
30
|
sessionToken: string;
|
|
31
|
+
apiKey: string;
|
|
26
32
|
};
|
|
27
33
|
loginUser(email: string, password: string): {
|
|
28
34
|
user: User;
|
|
@@ -77,6 +83,16 @@ export declare class MuxoStore {
|
|
|
77
83
|
getResource(workspaceId: string, resourceNameOrId: string): ProvisionedResource | null;
|
|
78
84
|
listResources(workspaceId: string): ProvisionedResource[];
|
|
79
85
|
getDecryptedWorkspaceEnv(workspaceId: string): Record<string, string>;
|
|
86
|
+
normalizeByokProvider(providerInput: string): {
|
|
87
|
+
provider: string;
|
|
88
|
+
category: "llm" | "supplier";
|
|
89
|
+
envVarName: string;
|
|
90
|
+
};
|
|
91
|
+
setByokKey(workspaceId: string, providerInput: string, secretKey: string): ByokKeyRecord;
|
|
92
|
+
getByokKey(workspaceId: string, providerInput: string): string | null;
|
|
93
|
+
deleteByokKey(workspaceId: string, providerInput: string): boolean;
|
|
94
|
+
listByokKeys(workspaceId: string): ByokKeyRecord[];
|
|
95
|
+
hasByokForLane(workspaceId: string, lane: ProviderLane, toolSlug?: string): boolean;
|
|
80
96
|
createPlan(params: {
|
|
81
97
|
workspaceId: string;
|
|
82
98
|
actorId: string;
|
|
@@ -126,6 +142,7 @@ export declare class MuxoStore {
|
|
|
126
142
|
stripeCustomerId?: string | null;
|
|
127
143
|
stripeSubscriptionId?: string | null;
|
|
128
144
|
referenceId: string;
|
|
145
|
+
bonusCredits?: number;
|
|
129
146
|
}): Workspace;
|
|
130
147
|
addWorkspaceCredits(params: {
|
|
131
148
|
workspaceId: string;
|
|
@@ -142,7 +159,7 @@ export declare class MuxoStore {
|
|
|
142
159
|
referenceId: string | null;
|
|
143
160
|
description: string;
|
|
144
161
|
}): LedgerEntry;
|
|
145
|
-
computeSupplierSettlement(lane: ProviderLane, toolSlug: string, creditCost: number, settlementStatus?: "settled_by_muxo_master_wallet" | "planned_muxo_master_wallet"): SupplierSettlement;
|
|
162
|
+
computeSupplierSettlement(lane: ProviderLane, toolSlug: string, creditCost: number, settlementStatus?: "settled_by_muxo_master_wallet" | "planned_muxo_master_wallet" | "settled_by_customer_byok" | "planned_customer_byok", workspaceId?: string): SupplierSettlement;
|
|
146
163
|
getSupplierSettlementSummary(workspaceId: string): SupplierSettlementSummary;
|
|
147
164
|
listLedgerEntries(workspaceId: string, limit?: number): LedgerEntry[];
|
|
148
165
|
saveMemoryRecord(params: {
|