@muxoai/platform 1.2.3 → 1.3.0

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.
@@ -611,6 +611,27 @@ export function renderConsoleHtml() {
611
611
  </div>
612
612
  </div>
613
613
 
614
+ <div class="card" style="margin-bottom:18px;border:1px solid var(--accent);background:linear-gradient(180deg, rgba(99,102,241,0.08), rgba(15,17,26,0.95))">
615
+ <div class="section-header" style="margin-bottom:10px">
616
+ <div>
617
+ <div class="section-title">✨ Natural Language Command Bar (<code class="mono">muxo do</code> / <code class="mono">POST /api/v1/do</code>)</div>
618
+ <div class="section-sub">Type any goal in plain English. Muxo extracts tool &amp; schema arguments (via BYOK LLM or semantic router), plans with Supermemory &amp; Ed25519 governance, and executes.</div>
619
+ </div>
620
+ <span id="byok-mode-badge" class="badge badge-projects">Funding: muxo_funded</span>
621
+ </div>
622
+ <div style="display:flex;gap:10px;margin-bottom:10px">
623
+ <input type="text" id="nl-prompt-input" placeholder="e.g. Audit https://muxo.ai for technical SEO, Top up 500 credits, Provision a Turso database named edge-analytics..." onkeydown="if(event.key==='Enter') runNaturalLanguagePrompt()" />
624
+ <button class="btn btn-primary" onclick="runNaturalLanguagePrompt()" style="white-space:nowrap">✨ Run in Plain English</button>
625
+ </div>
626
+ <div style="display:flex;gap:8px;flex-wrap:wrap">
627
+ <button class="btn btn-sm" onclick="fillAndRunNl('Fetch top 3 stories on Hacker News')">HackerNews Top 3</button>
628
+ <button class="btn btn-sm" onclick="fillAndRunNl('Audit https://muxo.ai for technical SEO')">Audit muxo.ai SEO</button>
629
+ <button class="btn btn-sm" onclick="fillAndRunNl('Look up DNS A records for muxo.ai')">DNS Lookup muxo.ai</button>
630
+ <button class="btn btn-sm" onclick="fillAndRunNl('Provision a Turso database named console-nl-db')">Provision Turso DB</button>
631
+ <button class="btn btn-sm" onclick="fillAndRunNl('Top up 500 credits')">Top Up +500 Credits</button>
632
+ </div>
633
+ </div>
634
+
614
635
  <div class="grid-2">
615
636
  <div class="card">
616
637
  <div class="section-header">
@@ -937,43 +958,49 @@ export function renderConsoleHtml() {
937
958
 
938
959
  <!-- TAB 7: BILLING & CREDITS -->
939
960
  <section id="tab-billing" class="tab-pane hidden">
940
- <div class="grid-2">
961
+ <div class="grid-2" style="margin-bottom:18px">
941
962
  <div class="card">
942
963
  <div class="section-header">
943
964
  <div>
944
- <div class="section-title">Subscription & Credit Top-Ups (User Pays Muxo -> Muxo Pays Suppliers)</div>
945
- <div class="section-sub">Users buy Muxo Credits ($0.01/credit); Muxo settles upstream costs with Composio & Stripe Projects from Muxo's master accounts.</div>
965
+ <div class="section-title">Subscription & Credit Top-Ups (Merchant-of-Record + BYOK)</div>
966
+ <div class="section-sub">Buy Muxo Credits ($0.01/credit) where Muxo pays upstream suppliers, or connect BYOK keys below for 0-credit execution.</div>
946
967
  </div>
947
968
  </div>
948
969
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:16px">
949
970
  <div style="border:1px solid var(--border-strong);border-radius:8px;padding:16px;background:var(--bg-elevated)">
950
971
  <div style="font-weight:600;font-size:15px;margin-bottom:4px">Starter Plan — $29/mo</div>
951
972
  <div style="font-size:12.5px;color:var(--text-secondary);margin-bottom:14px">
952
- 5,000 governed actions/month + 1,000 Instant & Provisioning credits included.
973
+ 10,000 governed actions/month + 1,000 Instant & Provisioning credits included.
974
+ </div>
975
+ <div style="display:flex;gap:8px;flex-direction:column">
976
+ <button class="btn btn-primary" style="width:100%;justify-content:center" onclick="startCheckout('starter_subscription')">
977
+ Upgrade via Stripe Checkout ($29/mo)
978
+ </button>
979
+ <button class="btn btn-sm btn-emerald" style="width:100%;justify-content:center" onclick="instantUpgradeStarter()">
980
+ ⚡ Instant Starter Upgrade (+1,000 Credits)
981
+ </button>
953
982
  </div>
954
- <button class="btn btn-primary" style="width:100%;justify-content:center" onclick="startCheckout('starter_subscription')">
955
- Upgrade via Stripe Checkout ($29/mo)
956
- </button>
957
983
  </div>
958
984
  <div style="border:1px solid var(--border-strong);border-radius:8px;padding:16px;background:var(--bg-elevated)">
959
- <div style="font-weight:600;font-size:15px;margin-bottom:4px">+1,000 Credit Pack — $10</div>
960
- <div style="font-size:12.5px;color:var(--text-secondary);margin-bottom:14px">
985
+ <div style="font-weight:600;font-size:15px;margin-bottom:4px">Credit Pack Top-Up ($0.01 / credit)</div>
986
+ <div style="font-size:12.5px;color:var(--text-secondary);margin-bottom:10px">
961
987
  Top up workspace credits for Instant tools, OAuth connectors & cloud provisioning.
962
988
  </div>
963
- <div style="display:flex;gap:8px;flex-direction:column">
964
- <button class="btn btn-emerald" style="width:100%;justify-content:center" onclick="startCheckout('credit_topup')">
965
- Stripe Checkout (+1,000 Credits / $10)
966
- </button>
967
- <button class="btn btn-sm" style="width:100%;justify-content:center" onclick="instantTopup(1000)">
968
- ⚡ Instant Wallet Top-Up (+1,000 Credits)
989
+ <div style="display:flex;gap:6px;margin-bottom:8px">
990
+ <input type="number" id="topup-credits-input" value="1000" min="100" step="100" style="padding:6px 10px;font-size:12.5px" />
991
+ <button class="btn btn-sm btn-emerald" onclick="instantTopupCustom()" style="white-space:nowrap">
992
+ ⚡ Instant Top-Up
969
993
  </button>
970
994
  </div>
995
+ <button class="btn btn-sm" style="width:100%;justify-content:center" onclick="startCheckout('credit_topup')">
996
+ Stripe Checkout Session
997
+ </button>
971
998
  </div>
972
999
  </div>
973
1000
 
974
1001
  <div style="border:1px solid var(--border-strong);border-radius:8px;padding:14px;background:rgba(16,185,129,0.05)">
975
1002
  <div style="font-weight:600;font-size:13px;margin-bottom:8px;color:var(--emerald)">
976
- 💸 Merchant-of-Record Settlement Ledger (muxo_funded)
1003
+ 💸 Merchant-of-Record &amp; BYOK Settlement Ledger
977
1004
  </div>
978
1005
  <div id="settlement-summary-box" style="font-size:12px;color:var(--text-secondary);line-height:1.6">
979
1006
  Loading supplier settlement metrics...
@@ -984,25 +1011,65 @@ export function renderConsoleHtml() {
984
1011
  <div class="card">
985
1012
  <div class="section-header">
986
1013
  <div>
987
- <div class="section-title">Audit Credit & Supplier Settlement Ledger</div>
988
- <div class="section-sub">Immutable record of user credit purchases, run deductions, and upstream supplier payouts.</div>
1014
+ <div class="section-title">🔑 Bring Your Own Key (BYOK) Encrypted Vault</div>
1015
+ <div class="section-sub">Store your own LLM API keys (for natural-language routing) or upstream supplier keys (0 Muxo credit charge / 0% markup). Encrypted with AES-256-GCM.</div>
989
1016
  </div>
990
1017
  </div>
991
- <div class="table-wrap">
1018
+ <div style="display:grid;grid-template-columns:1fr 1.4fr auto;gap:8px;margin-bottom:12px">
1019
+ <select id="byok-provider-select">
1020
+ <option value="openai">OpenAI (LLM Router)</option>
1021
+ <option value="anthropic">Anthropic Claude (LLM Router)</option>
1022
+ <option value="openrouter">OpenRouter (LLM Router)</option>
1023
+ <option value="gemini">Google Gemini (LLM Router)</option>
1024
+ <option value="composio">Composio (0-Credit App &amp; Instant BYOK)</option>
1025
+ <option value="stripe">Stripe Secret Key (0-Credit Infra BYOK)</option>
1026
+ <option value="supermemory">Supermemory v5 (Memory BYOK)</option>
1027
+ <option value="firecrawl">Firecrawl (Scrape/Crawl BYOK)</option>
1028
+ <option value="exa">Exa AI (Search BYOK)</option>
1029
+ </select>
1030
+ <input type="password" id="byok-key-input" placeholder="Paste API key (sk-..., rk_..., sm_...)..." />
1031
+ <button class="btn btn-primary" onclick="saveByokKeyFromUi()">Save Key</button>
1032
+ </div>
1033
+ <div class="table-wrap" style="max-height:240px;overflow-y:auto">
992
1034
  <table>
993
1035
  <thead>
994
1036
  <tr>
995
- <th>Time</th>
996
- <th>Event & Supplier Settlement</th>
997
- <th>Credits Delta</th>
998
- <th>Balance</th>
1037
+ <th>Provider</th>
1038
+ <th>Category</th>
1039
+ <th>Key Hint</th>
1040
+ <th>Env Var</th>
1041
+ <th>Action</th>
999
1042
  </tr>
1000
1043
  </thead>
1001
- <tbody id="ledger-tbody"></tbody>
1044
+ <tbody id="byok-keys-tbody">
1045
+ <tr><td colspan="5" style="color:var(--text-muted)">No BYOK keys saved yet. Using Muxo Master Wallet (muxo_funded).</td></tr>
1046
+ </tbody>
1002
1047
  </table>
1003
1048
  </div>
1004
1049
  </div>
1005
1050
  </div>
1051
+
1052
+ <div class="card">
1053
+ <div class="section-header">
1054
+ <div>
1055
+ <div class="section-title">Audit Credit & Supplier Settlement Ledger</div>
1056
+ <div class="section-sub">Immutable record of user credit purchases, run deductions, BYOK 0-credit runs, and upstream supplier payouts.</div>
1057
+ </div>
1058
+ </div>
1059
+ <div class="table-wrap">
1060
+ <table>
1061
+ <thead>
1062
+ <tr>
1063
+ <th>Time</th>
1064
+ <th>Event & Supplier Settlement</th>
1065
+ <th>Credits Delta</th>
1066
+ <th>Balance</th>
1067
+ </tr>
1068
+ </thead>
1069
+ <tbody id="ledger-tbody"></tbody>
1070
+ </table>
1071
+ </div>
1072
+ </div>
1006
1073
  </section>
1007
1074
  </main>
1008
1075
  </div>
@@ -1803,6 +1870,126 @@ export function renderConsoleHtml() {
1803
1870
  '<td class="mono">' + e.balanceAfter + '</td>' +
1804
1871
  '</tr>'
1805
1872
  ).join('');
1873
+ await loadByokKeys();
1874
+ }
1875
+
1876
+ async function loadByokKeys() {
1877
+ try {
1878
+ const data = await api('/api/v1/byok');
1879
+ const tbody = document.getElementById('byok-keys-tbody');
1880
+ const badge = document.getElementById('byok-mode-badge');
1881
+ if (badge) {
1882
+ const hasSupplier = (data.keys || []).some(k => k.category === 'supplier');
1883
+ badge.textContent = hasSupplier ? 'Funding: byok (0 cr)' : 'Funding: muxo_funded';
1884
+ badge.className = hasSupplier ? 'badge badge-sdk' : 'badge badge-projects';
1885
+ }
1886
+ if (!tbody) return;
1887
+ if (!data.keys || !data.keys.length) {
1888
+ tbody.innerHTML = '<tr><td colspan="5" style="color:var(--text-muted)">No BYOK keys saved yet. Using Muxo Master Wallet (muxo_funded).</td></tr>';
1889
+ return;
1890
+ }
1891
+ tbody.innerHTML = data.keys.map(k =>
1892
+ '<tr>' +
1893
+ '<td style="font-weight:600">' + k.providerName + ' <span class="mono" style="color:var(--text-muted);font-size:11px">(' + k.provider + ')</span></td>' +
1894
+ '<td><span class="badge ' + (k.category === 'llm' ? 'badge-sdk' : 'badge-projects') + '">' + k.category + '</span></td>' +
1895
+ '<td class="mono" style="font-size:12px">' + k.keyHint + '</td>' +
1896
+ '<td class="mono" style="font-size:11.5px;color:var(--text-secondary)">' + k.envVarName + '</td>' +
1897
+ '<td><button class="btn btn-sm" onclick="deleteByokKeyFromUi(\\'' + k.provider + '\\')">Delete</button></td>' +
1898
+ '</tr>'
1899
+ ).join('');
1900
+ } catch (err) {
1901
+ console.error(err);
1902
+ }
1903
+ }
1904
+
1905
+ async function saveByokKeyFromUi() {
1906
+ const provider = document.getElementById('byok-provider-select').value;
1907
+ const secretKey = document.getElementById('byok-key-input').value.trim();
1908
+ if (!secretKey) {
1909
+ showToast('Enter an API key first');
1910
+ return;
1911
+ }
1912
+ try {
1913
+ await api('/api/v1/byok', {
1914
+ method: 'POST',
1915
+ body: JSON.stringify({ provider, secretKey })
1916
+ });
1917
+ document.getElementById('byok-key-input').value = '';
1918
+ showToast('Saved encrypted ' + provider.toUpperCase() + ' BYOK key to Vault!');
1919
+ await loadByokKeys();
1920
+ await refreshOverview();
1921
+ } catch (err) {
1922
+ showToast('BYOK Error: ' + err.message);
1923
+ }
1924
+ }
1925
+
1926
+ async function deleteByokKeyFromUi(provider) {
1927
+ try {
1928
+ await api('/api/v1/byok/' + encodeURIComponent(provider), { method: 'DELETE' });
1929
+ showToast('Removed ' + provider + ' BYOK key from Vault');
1930
+ await loadByokKeys();
1931
+ } catch (err) {
1932
+ showToast('Error: ' + err.message);
1933
+ }
1934
+ }
1935
+
1936
+ async function fillAndRunNl(promptText) {
1937
+ const input = document.getElementById('nl-prompt-input');
1938
+ if (input) input.value = promptText;
1939
+ await runNaturalLanguagePrompt();
1940
+ }
1941
+
1942
+ async function runNaturalLanguagePrompt() {
1943
+ const input = document.getElementById('nl-prompt-input');
1944
+ const promptText = (input ? input.value : '').trim();
1945
+ if (!promptText) {
1946
+ showToast('Enter a natural language instruction first');
1947
+ return;
1948
+ }
1949
+ const box = document.getElementById('quick-run-output');
1950
+ box.textContent = '✨ Routing natural language intent: "' + promptText + '"...';
1951
+ try {
1952
+ const res = await api('/api/v1/do', {
1953
+ method: 'POST',
1954
+ body: JSON.stringify({ prompt: promptText, autoApprove: true })
1955
+ });
1956
+ box.textContent = JSON.stringify({
1957
+ prompt: res.prompt,
1958
+ intent: res.intent,
1959
+ status: res.status,
1960
+ fundingMode: res.plan && res.plan.supplierSettlement ? res.plan.supplierSettlement.fundingMode : 'muxo_funded',
1961
+ creditCost: res.plan ? res.plan.creditCost : 0,
1962
+ planId: res.plan ? res.plan.id : null,
1963
+ runId: res.run ? res.run.id : null,
1964
+ receiptId: res.receipt ? res.receipt.id : null,
1965
+ output: res.run ? res.run.output : (res.authHandoff || res.message)
1966
+ }, null, 2);
1967
+ showToast('Executed NL intent -> ' + res.intent.toolSlug + ' (' + res.status + ')');
1968
+ await refreshOverview();
1969
+ } catch (err) {
1970
+ box.textContent = 'NL Execution Error: ' + err.message;
1971
+ showToast('Error: ' + err.message);
1972
+ }
1973
+ }
1974
+
1975
+ async function instantUpgradeStarter() {
1976
+ try {
1977
+ const res = await api('/api/v1/billing/upgrade', {
1978
+ method: 'POST',
1979
+ body: JSON.stringify({ tier: 'starter' })
1980
+ });
1981
+ showToast(res.message || 'Upgraded workspace to Starter Plan (+1,000 Credits)!');
1982
+ await refreshOverview();
1983
+ await loadLedger();
1984
+ } catch (err) {
1985
+ showToast('Upgrade Error: ' + err.message);
1986
+ }
1987
+ }
1988
+
1989
+ async function instantTopupCustom() {
1990
+ const input = document.getElementById('topup-credits-input');
1991
+ const credits = Math.max(1, Number((input && input.value) || 1000));
1992
+ await instantTopup(credits);
1806
1993
  }
1807
1994
 
1808
1995
  async function instantTopup(credits) {
@@ -1821,10 +2008,12 @@ export function renderConsoleHtml() {
1821
2008
 
1822
2009
  async function startCheckout(kind) {
1823
2010
  try {
1824
- showToast('Creating live Stripe Checkout session...');
2011
+ showToast('Creating Stripe Checkout session...');
2012
+ const input = document.getElementById('topup-credits-input');
2013
+ const credits = Math.max(100, Number((input && input.value) || 1000));
1825
2014
  const res = await api('/api/v1/billing/checkout', {
1826
2015
  method: 'POST',
1827
- body: JSON.stringify({ kind })
2016
+ body: JSON.stringify({ kind, credits })
1828
2017
  });
1829
2018
  if (res.url) {
1830
2019
  window.location.href = res.url;
@@ -1866,6 +2055,7 @@ export function renderConsoleHtml() {
1866
2055
  window.addEventListener('DOMContentLoaded', async () => {
1867
2056
  await checkCheckoutReturn();
1868
2057
  await refreshOverview();
2058
+ loadByokKeys().catch(() => {});
1869
2059
  // Sync live Stripe Projects & Composio providers in background on first load
1870
2060
  loadConnections(true).catch(() => {});
1871
2061
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muxoai/platform",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
4
4
  "description": "Muxo — Unified Execution, Provisioning & Governance Platform over Composio, Stripe Projects, Microsoft Agent Governance & Supermemory",
5
5
  "private": false,
6
6
  "license": "MIT",