@muxoai/platform 1.4.1 → 1.4.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.
Files changed (53) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/README.md +1 -1
  4. package/dist/cli.js +94 -3
  5. package/dist/composio-catalog.d.ts +177 -1
  6. package/dist/composio-catalog.js +1427 -7
  7. package/dist/config.d.ts +6 -0
  8. package/dist/config.js +11 -1
  9. package/dist/durable-workflow.d.ts +71 -4
  10. package/dist/durable-workflow.js +199 -5
  11. package/dist/engine.d.ts +82 -3
  12. package/dist/engine.js +406 -41
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.js +3 -0
  15. package/dist/mcp-schema.d.ts +162 -1
  16. package/dist/mcp-schema.js +1544 -40
  17. package/dist/mcp.d.ts +2 -2
  18. package/dist/mcp.js +474 -26
  19. package/dist/memory-graph.d.ts +26 -2
  20. package/dist/memory-graph.js +127 -7
  21. package/dist/oss-suite.d.ts +217 -0
  22. package/dist/oss-suite.js +836 -0
  23. package/dist/policy.d.ts +108 -1
  24. package/dist/policy.js +406 -1
  25. package/dist/providers/composio-instant.js +38 -3
  26. package/dist/providers/composio-sdk.d.ts +59 -2
  27. package/dist/providers/composio-sdk.js +273 -59
  28. package/dist/providers/stripe-projects.d.ts +4 -0
  29. package/dist/providers/stripe-projects.js +548 -126
  30. package/dist/sdk.d.ts +24 -1
  31. package/dist/sdk.js +53 -2
  32. package/dist/server.js +659 -64
  33. package/dist/store.js +2 -0
  34. package/dist/types.d.ts +34 -1
  35. package/dist/ui/console-html.d.ts +31 -1
  36. package/dist/ui/console-html.js +922 -368
  37. package/dist/ui/design-tokens.js +1 -1
  38. package/dist/version.d.ts +1 -1
  39. package/dist/version.js +1 -1
  40. package/package.json +3 -2
  41. package/plugins/muxo/.claude-plugin/plugin.json +2 -2
  42. package/plugins/muxo/.codex-plugin/plugin.json +15 -8
  43. package/plugins/muxo/.cursor-plugin/plugin.json +30 -0
  44. package/plugins/muxo/hooks/session-start.sh +15 -3
  45. package/plugins/muxo/hooks/user-prompt-submit.sh +14 -1
  46. package/plugins/muxo/mcp.json +0 -10
  47. package/plugins/muxo/plugin.json +4 -4
  48. package/plugins/muxo/skills/muxo/SKILL.md +25 -16
  49. package/plugins/muxo/skills/muxo/references/cli.md +5 -1
  50. package/plugins/muxo/skills/muxo/references/mcp.md +11 -6
  51. package/plugins/muxo/skills/muxo-activity-summary/SKILL.md +81 -0
  52. package/plugins/muxo/skills/setup/SKILL.md +1 -1
  53. package/src/catalogues/stripe-projects-catalog.json +140 -0
package/dist/engine.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import crypto from "node:crypto";
2
- import { APPROVED_PLAN_STATUSES, approvalRequiredError, buildApprovalUrl, clampWaitSeconds, looksLikeToolSlug, unknownToolError, } from "./mcp-schema.js";
3
- import { completeCloudProvisioningWorkflow, createCloudProvisioningWorkflow, normalizeWorkflowTarget, workflowNotFoundError, } from "./durable-workflow.js";
2
+ import { isStripeProjectsExclusiveProvider, normalizeStripeProjectsProviderSlug, wrapMuxoConnectUrl, } from "./composio-catalog.js";
3
+ import { APPROVED_PLAN_STATUSES, approvalRequiredError, buildApprovalHumanHandoff, buildApprovalUrl, buildOAuthHumanHandoff, clampWaitSeconds, looksLikeToolSlug, unknownToolError, } from "./mcp-schema.js";
4
+ import { completeCloudProvisioningWorkflow, createCloudProvisioningWorkflow, exportTemporalEventHistory, normalizeWorkflowTarget, rollbackDurableWorkflow as runSagaRollbackOnWorkflow, signalDurableWorkflow as sendSignalToWorkflow, workflowNotFoundError, } from "./durable-workflow.js";
4
5
  import { buildMemoryKnowledgeGraph } from "./memory-graph.js";
6
+ import { MUXO_COMMERCIAL_PLAYBOOKS, buildCommercialRoiReport, buildOtelTraceExport, buildPlaybookSagaExecution, compileWorkspacePolicyToCedarAndRego, evaluateCedarAndOpaPolicy, getCommercialPlaybook, } from "./oss-suite.js";
5
7
  import { resolveNaturalLanguageIntent, } from "./nl.js";
6
- import { compileNaturalLanguageGuardrailWithLlm, describePolicyInPlainEnglish, formatHumanFriendlyExplanation, parseNaturalLanguageGuardrail, } from "./policy.js";
8
+ import { DEFAULT_WORKSPACE_POLICY, buildLlmPolicyAndGovernanceBrief, compileNaturalLanguageGuardrailWithLlm, describePolicyInPlainEnglish, formatHumanFriendlyExplanation, parseNaturalLanguageGuardrail, simulatePolicyEvaluation, } from "./policy.js";
7
9
  import { ComposioInstantAdapter } from "./providers/composio-instant.js";
8
10
  import { ComposioSdkAdapter } from "./providers/composio-sdk.js";
9
11
  import { MicrosoftGovernanceAdapter } from "./providers/microsoft-governance.js";
@@ -73,6 +75,24 @@ export class MuxoEngine {
73
75
  const connections = this.store.listConnections(ws.id);
74
76
  const supplierSettlementSummary = this.store.getSupplierSettlementSummary(ws.id);
75
77
  const plainEnglishPolicy = describePolicyInPlainEnglish(ws.policy);
78
+ const localMemories = this.store.listMemoryRecords(ws.id, 25);
79
+ const activeFacts = this.store.listTemporalFacts(ws.id, {
80
+ includeHistorical: false,
81
+ limit: 30,
82
+ });
83
+ const inferred = extractActiveMemoryDefaults({
84
+ memories: localMemories,
85
+ temporalFacts: activeFacts,
86
+ });
87
+ const trustScore = this.governance.getWorkspaceTrustScore(ws.id);
88
+ const govStatus = this.governance.getStatus(ws);
89
+ const llmPolicyBrief = buildLlmPolicyAndGovernanceBrief(ws.policy, {
90
+ workspaceName: ws.name,
91
+ workspaceSlug: ws.slug,
92
+ activeDefaults: inferred.activeDefaults,
93
+ trustScore: { overall: trustScore.overall, tier: trustScore.tier },
94
+ agentDid: govStatus.agentDid,
95
+ });
76
96
  return {
77
97
  organization: {
78
98
  id: ws.id,
@@ -88,12 +108,16 @@ export class MuxoEngine {
88
108
  supplierSettlementSummary,
89
109
  policy: ws.policy,
90
110
  plainEnglishPolicy,
111
+ llmPolicyBrief,
112
+ activeDefaults: inferred.activeDefaults,
91
113
  explanation: plainEnglishPolicy.explanation,
92
114
  activeConnectionsCount: connections.filter((c) => c.status === "active").length,
93
115
  provisionedResourcesCount: resources.filter((r) => r.status === "active").length,
94
116
  projectsEnvironment: ws.projectsEnvName,
95
117
  createdAt: ws.createdAt,
96
118
  },
119
+ llmPolicyBrief,
120
+ activeDefaults: inferred.activeDefaults,
97
121
  };
98
122
  }
99
123
  // 3. search_tools
@@ -101,7 +125,16 @@ export class MuxoEngine {
101
125
  const limit = Math.min(100, Math.max(1, Number(params.limit || 25)));
102
126
  const lane = params.lane || "all";
103
127
  const query = params.query?.trim();
128
+ const queryTokens = (query || "")
129
+ .toLowerCase()
130
+ .split(/[\s,._/-]+/)
131
+ .filter(Boolean);
132
+ const prefersStripeProjects = queryTokens.some((tok) => isStripeProjectsExclusiveProvider(tok) ||
133
+ /^(provision|deploy|deployment|publish|host|hosting|static|landing|database|postgres|sqlite|redis)$/.test(tok));
104
134
  const results = [];
135
+ if (lane === "all" && prefersStripeProjects) {
136
+ results.push(...this.stripeProjects.searchTools(query, limit));
137
+ }
105
138
  if (lane === "all" || lane === "composio_instant") {
106
139
  results.push(...this.composioInstant.searchTools(query, limit));
107
140
  }
@@ -109,8 +142,10 @@ export class MuxoEngine {
109
142
  const sdkTools = await this.composioSdk.searchTools(query, limit);
110
143
  results.push(...sdkTools);
111
144
  }
112
- if (lane === "all" || lane === "stripe_projects") {
145
+ if (lane === "stripe_projects" || (lane === "all" && !prefersStripeProjects)) {
113
146
  results.push(...this.stripeProjects.searchTools(query, limit));
147
+ }
148
+ if (lane === "all" || lane === "stripe_projects") {
114
149
  const billingTools = this.stripeBilling.listTools().filter((t) => {
115
150
  if (!query)
116
151
  return true;
@@ -131,7 +166,7 @@ export class MuxoEngine {
131
166
  async listAllCatalogTools() {
132
167
  const instant = this.composioInstant.searchTools(undefined, 100);
133
168
  const sdk = await this.composioSdk.searchTools(undefined, 100);
134
- const proj = this.stripeProjects.searchTools(undefined, 100);
169
+ const proj = this.stripeProjects.getTools();
135
170
  const billing = this.stripeBilling.listTools();
136
171
  return [...instant, ...billing, ...sdk, ...proj];
137
172
  }
@@ -162,6 +197,9 @@ export class MuxoEngine {
162
197
  const composioByok = this.store.getByokKey(ctx.workspace.id, "composio");
163
198
  const liveComposio = await this.composioSdk.listLiveConnections(ctx.workspace.id, composioByok);
164
199
  for (const c of liveComposio) {
200
+ if (isStripeProjectsExclusiveProvider(c.providerSlug)) {
201
+ continue;
202
+ }
165
203
  this.store.upsertConnection({
166
204
  workspaceId: ctx.workspace.id,
167
205
  lane: "composio_sdk",
@@ -191,15 +229,63 @@ export class MuxoEngine {
191
229
  // Keep cached connections if CLI is busy
192
230
  }
193
231
  }
194
- let connections = this.store.listConnections(ctx.workspace.id);
232
+ let connections = this.store.listConnections(ctx.workspace.id).map((c) => {
233
+ if (isStripeProjectsExclusiveProvider(c.providerSlug)) {
234
+ return {
235
+ ...c,
236
+ lane: "stripe_projects",
237
+ status: "active",
238
+ redirectUrl: null,
239
+ };
240
+ }
241
+ return c.lane === "composio_sdk" && c.redirectUrl
242
+ ? {
243
+ ...c,
244
+ redirectUrl: wrapMuxoConnectUrl(c.redirectUrl, this.config.baseUrl, {
245
+ workspaceId: c.workspaceId,
246
+ providerSlug: c.providerSlug,
247
+ externalAccountId: c.externalAccountId,
248
+ }),
249
+ }
250
+ : c;
251
+ });
195
252
  if (params?.provider) {
196
- const target = params.provider.toLowerCase();
197
- connections = connections.filter((c) => c.providerSlug.toLowerCase() === target ||
198
- c.providerName.toLowerCase().includes(target));
253
+ const target = normalizeStripeProjectsProviderSlug(params.provider) || params.provider.toLowerCase();
254
+ if (isStripeProjectsExclusiveProvider(target)) {
255
+ const activeRecord = this.store.upsertConnection({
256
+ workspaceId: ctx.workspace.id,
257
+ lane: "stripe_projects",
258
+ providerSlug: target,
259
+ providerName: target.charAt(0).toUpperCase() + target.slice(1),
260
+ status: "active",
261
+ externalAccountId: `sp_conn_${target}`,
262
+ redirectUrl: null,
263
+ metadata: {
264
+ managedBy: "stripe_projects",
265
+ requiresOAuth: false,
266
+ },
267
+ });
268
+ connections = [activeRecord];
269
+ }
270
+ else {
271
+ connections = connections.filter((c) => c.providerSlug.toLowerCase() === target ||
272
+ c.providerName.toLowerCase().includes(target));
273
+ }
199
274
  }
275
+ const targetConn = connections[0] || null;
276
+ const isActive = targetConn
277
+ ? targetConn.status === "active"
278
+ : connections.some((c) => c.status === "active");
200
279
  return {
280
+ ok: true,
201
281
  workspaceId: ctx.workspace.id,
202
282
  instantWalletStatus: "active",
283
+ connected: isActive,
284
+ ready: isActive,
285
+ timedOut: false,
286
+ status: targetConn?.status || "not_connected",
287
+ redirectUrl: isActive ? null : targetConn?.redirectUrl || null,
288
+ connection: targetConn,
203
289
  connections,
204
290
  summary: {
205
291
  total: connections.length,
@@ -209,11 +295,18 @@ export class MuxoEngine {
209
295
  },
210
296
  };
211
297
  }
298
+ getHostedSiteHtml(slug, filePath) {
299
+ return this.stripeProjects.getHostedSiteHtml(slug, filePath);
300
+ }
212
301
  // 6. start_connection
213
302
  async startConnection(ctx, params) {
214
303
  const rawProvider = params.provider.trim().toLowerCase();
215
- const isProjectsLane = params.lane === "stripe_projects" || rawProvider.startsWith("resource.");
216
- const cleanSlug = rawProvider.replace(/^(app\.|resource\.)/, "");
304
+ const cleanSlug = normalizeStripeProjectsProviderSlug(rawProvider) ||
305
+ rawProvider.replace(/^(app\.|resource\.|projects\.)/, "");
306
+ const isProjectsLane = params.lane === "stripe_projects" ||
307
+ rawProvider.startsWith("resource.") ||
308
+ rawProvider.startsWith("projects.") ||
309
+ isStripeProjectsExclusiveProvider(cleanSlug);
217
310
  if (isProjectsLane) {
218
311
  const stripeByok = this.store.getByokKey(ctx.workspace.id, "stripe");
219
312
  const linked = await this.stripeProjects.linkProvider(cleanSlug, stripeByok);
@@ -258,10 +351,9 @@ export class MuxoEngine {
258
351
  }
259
352
  // 6b. wait_for_connection (OAuth handoff polling & recovery, like COMPOSIO_WAIT_FOR_CONNECTIONS)
260
353
  async waitForConnection(ctx, params) {
261
- const cleanSlug = params.provider
262
- .trim()
263
- .toLowerCase()
264
- .replace(/^(app\.|resource\.)/, "");
354
+ const rawProvider = params.provider.trim().toLowerCase();
355
+ const cleanSlug = normalizeStripeProjectsProviderSlug(rawProvider) ||
356
+ rawProvider.replace(/^(app\.|resource\.|projects\.)/, "");
265
357
  if (!cleanSlug) {
266
358
  throw new Error("provider is required to wait for a connection (e.g. 'github').");
267
359
  }
@@ -283,6 +375,22 @@ export class MuxoEngine {
283
375
  elapsedMs: Date.now() - startedAt,
284
376
  message,
285
377
  });
378
+ if (isStripeProjectsExclusiveProvider(cleanSlug)) {
379
+ const activeRecord = this.store.upsertConnection({
380
+ workspaceId: ctx.workspace.id,
381
+ lane: "stripe_projects",
382
+ providerSlug: cleanSlug,
383
+ providerName: cleanSlug.charAt(0).toUpperCase() + cleanSlug.slice(1),
384
+ status: "active",
385
+ externalAccountId: `sp_conn_${cleanSlug}`,
386
+ redirectUrl: null,
387
+ metadata: {
388
+ managedBy: "stripe_projects",
389
+ requiresOAuth: false,
390
+ },
391
+ });
392
+ return connectedResult(activeRecord, `${activeRecord.providerName} is managed via Stripe Projects Cloud Infrastructure and is active immediately (no OAuth required).`);
393
+ }
286
394
  let current = this.store
287
395
  .listConnections(ctx.workspace.id)
288
396
  .find((c) => c.providerSlug.toLowerCase() === cleanSlug);
@@ -341,6 +449,16 @@ export class MuxoEngine {
341
449
  if (!current) {
342
450
  current = await this.startConnection(ctx, { provider: cleanSlug });
343
451
  }
452
+ else if (current.redirectUrl) {
453
+ current = {
454
+ ...current,
455
+ redirectUrl: wrapMuxoConnectUrl(current.redirectUrl, this.config.baseUrl, {
456
+ workspaceId: ctx.workspace.id,
457
+ providerSlug: cleanSlug,
458
+ externalAccountId: current.externalAccountId,
459
+ }),
460
+ };
461
+ }
344
462
  return {
345
463
  ok: true,
346
464
  connected: false,
@@ -527,14 +645,21 @@ export class MuxoEngine {
527
645
  // Keep existing connection state if offline
528
646
  }
529
647
  if (!existingConn || existingConn.status !== "active") {
648
+ const wrappedRedirectUrl = existingConn?.redirectUrl
649
+ ? wrapMuxoConnectUrl(existingConn.redirectUrl, this.config.baseUrl, {
650
+ workspaceId: ws.id,
651
+ providerSlug: tool.providerSlug,
652
+ externalAccountId: existingConn.externalAccountId,
653
+ })
654
+ : null;
530
655
  authHandoff = {
531
656
  required: true,
532
657
  provider: tool.providerSlug,
533
658
  status: existingConn?.status || "pending",
534
- redirectUrl: existingConn?.redirectUrl || null,
659
+ redirectUrl: wrappedRedirectUrl,
535
660
  externalAccountId: existingConn?.externalAccountId || null,
536
- instructions: existingConn?.redirectUrl
537
- ? `Ask the user to authorize ${tool.providerName} at ${existingConn.redirectUrl}, then call wait_for_connection({ provider: "${tool.providerSlug}" }) before executing ${plan.id}.`
661
+ instructions: wrappedRedirectUrl
662
+ ? `Ask the user to authorize ${tool.providerName} at ${wrappedRedirectUrl}, then call wait_for_connection({ provider: "${tool.providerSlug}" }) before executing ${plan.id}.`
538
663
  : `Call start_connection({ provider: "${tool.providerSlug}" }) to authorize ${tool.providerName} before executing ${plan.id}.`,
539
664
  };
540
665
  }
@@ -606,25 +731,15 @@ export class MuxoEngine {
606
731
  });
607
732
  }
608
733
  buildApprovalHandoff(plan) {
609
- const url = `${this.config.baseUrl}/approve/${encodeURIComponent(plan.id)}`;
610
- return {
611
- kind: "approval",
612
- url,
613
- ctaLabel: "Review & approve",
614
- headline: `Muxo needs your approval to run ${plan.toolSlug}`,
615
- instructions: `Open ${url} to review and approve this ${plan.riskLevel}-risk action with one click (or run \`muxo approve ${plan.id}\`). Nothing runs until you approve.`,
616
- planId: plan.id,
617
- };
734
+ return buildApprovalHumanHandoff(this.config.baseUrl, plan);
618
735
  }
619
736
  buildOAuthHandoff(handoff, providerName) {
620
- return {
621
- kind: "oauth",
622
- url: handoff.redirectUrl,
623
- ctaLabel: `Connect ${providerName}`,
624
- headline: `Connect ${providerName} to continue`,
737
+ return buildOAuthHumanHandoff({
738
+ providerSlug: handoff.provider,
739
+ providerName,
740
+ redirectUrl: handoff.redirectUrl,
625
741
  instructions: handoff.instructions,
626
- provider: handoff.provider,
627
- };
742
+ });
628
743
  }
629
744
  buildPlanLlmGuidance(plan, authHandoff) {
630
745
  const executeTool = `execute_${plan.riskLevel}`;
@@ -767,6 +882,7 @@ export class MuxoEngine {
767
882
  }
768
883
  const enriched = {
769
884
  ...ctx,
885
+ enabled: true,
770
886
  staticFacts,
771
887
  dynamicContext,
772
888
  recalledMemories: recalled,
@@ -833,6 +949,13 @@ export class MuxoEngine {
833
949
  technical: contextTechnical,
834
950
  policy: ws.policy,
835
951
  });
952
+ const llmPolicyBrief = buildLlmPolicyAndGovernanceBrief(ws.policy, {
953
+ workspaceName: ws.name,
954
+ workspaceSlug: ws.slug,
955
+ activeDefaults: memoryContext.activeDefaults || {},
956
+ trustScore: { overall: trustScore.overall, tier: trustScore.tier },
957
+ agentDid: governanceStatus.agentDid,
958
+ });
836
959
  const llmSystemPrompt = [
837
960
  `# Muxo Governed Workspace Context (${ws.name} / ${ws.slug})`,
838
961
  `- **Language Preference**: ${ws.policy.languageMode || "hybrid"}${ws.policy.customInstructions?.length ? ` (Custom Instructions: ${ws.policy.customInstructions.join("; ")})` : ""}`,
@@ -840,6 +963,7 @@ export class MuxoEngine {
840
963
  `- **Learned Memory Defaults (Auto-Fill)**: ${defaultsList.length > 0 ? defaultsList.join(", ") : "none"}`,
841
964
  `- **Credits & Quota**: ${ws.creditsBalance} credits ($${(ws.creditsBalance * 0.01).toFixed(2)}) available, ${actionsRemaining} monthly actions remaining`,
842
965
  `- **Active Cloud Resources**: ${activeResources.length > 0 ? activeResources.map((r) => `${r.resourceName} (${r.serviceSlug})`).join(", ") : "none"}`,
966
+ llmPolicyBrief.llmSystemDirective,
843
967
  memoryContext.formattedPromptContext,
844
968
  ].join("\n");
845
969
  return {
@@ -848,6 +972,7 @@ export class MuxoEngine {
848
972
  projectsEnvironment: ws.projectsEnvName,
849
973
  policy: ws.policy,
850
974
  plainEnglishPolicy,
975
+ llmPolicyBrief,
851
976
  languageMode: ws.policy.languageMode || "hybrid",
852
977
  customInstructions: ws.policy.customInstructions || [],
853
978
  activeDefaults: (memoryContext.activeDefaults ||
@@ -1006,18 +1131,25 @@ export class MuxoEngine {
1006
1131
  }
1007
1132
  /**
1008
1133
  * Synthesizes a Bi-Temporal Knowledge Graph (entities, active relationships, superseded historical relationships,
1009
- * Mermaid diagram, and human + technical explanations) directly from SQLite temporal_facts, memories, resources, and connections.
1134
+ * Mermaid diagram, point-in-time `asOf` time-travel, 2-hop BFS subgraph, and human + technical explanations)
1135
+ * directly from SQLite temporal_facts, memories, resources, and connections.
1010
1136
  */
1011
- async getMemoryGraph(ctx, query) {
1137
+ async getMemoryGraph(ctx, queryOrOptions) {
1012
1138
  const ws = this.store.getWorkspace(ctx.workspace.id);
1013
- const overview = await this.getMemoryOverview(ctx, query);
1139
+ const opts = typeof queryOrOptions === "string"
1140
+ ? { query: queryOrOptions }
1141
+ : queryOrOptions || {};
1142
+ const overview = await this.getMemoryOverview(ctx, opts.query);
1014
1143
  return buildMemoryKnowledgeGraph({
1015
1144
  workspace: ws,
1016
1145
  namespace: overview.namespace,
1017
- query,
1146
+ query: opts.query,
1147
+ asOf: opts.asOf || null,
1148
+ focalEntity: opts.focalEntity || null,
1149
+ maxHops: opts.maxHops,
1018
1150
  facts: this.store.listTemporalFacts(ws.id, {
1019
1151
  includeHistorical: true,
1020
- query,
1152
+ query: opts.query,
1021
1153
  limit: 100,
1022
1154
  }),
1023
1155
  resources: this.store.listResources(ws.id),
@@ -1060,7 +1192,10 @@ export class MuxoEngine {
1060
1192
  // 10-15. execute_<risk_level>
1061
1193
  async executePlanForRisk(ctx, planId, expectedRisk) {
1062
1194
  const plan = this.getPlan(ctx, planId);
1063
- if (plan.riskLevel !== expectedRisk) {
1195
+ const isProjectsWriteCompatible = plan.lane === "stripe_projects" &&
1196
+ plan.riskLevel === "provisioning" &&
1197
+ expectedRisk === "write";
1198
+ if (plan.riskLevel !== expectedRisk && !isProjectsWriteCompatible) {
1064
1199
  throw new Error(`Risk lane mismatch: Plan '${plan.id}' has risk level '${plan.riskLevel}', so it must be executed with 'execute_${plan.riskLevel}' instead of 'execute_${expectedRisk}'.`);
1065
1200
  }
1066
1201
  if (plan.runId) {
@@ -1107,7 +1242,16 @@ export class MuxoEngine {
1107
1242
  }
1108
1243
  let activeConnId = null;
1109
1244
  if (plan.lane === "composio_sdk" && tool.requiresAuth) {
1110
- let connections = this.store.listConnections(ctx.workspace.id);
1245
+ let connections = this.store.listConnections(ctx.workspace.id).map((c) => c.lane === "composio_sdk" && c.redirectUrl
1246
+ ? {
1247
+ ...c,
1248
+ redirectUrl: wrapMuxoConnectUrl(c.redirectUrl, this.config.baseUrl, {
1249
+ workspaceId: c.workspaceId,
1250
+ providerSlug: c.providerSlug,
1251
+ externalAccountId: c.externalAccountId,
1252
+ }),
1253
+ }
1254
+ : c);
1111
1255
  let activeConn = connections.find((c) => c.lane === "composio_sdk" &&
1112
1256
  c.providerSlug === tool.providerSlug &&
1113
1257
  c.status === "active");
@@ -1581,6 +1725,22 @@ export class MuxoEngine {
1581
1725
  const governance = this.governance.getStatus(ws);
1582
1726
  const trustScore = this.governance.getWorkspaceTrustScore(ws.id);
1583
1727
  const plainEnglish = describePolicyInPlainEnglish(ws.policy);
1728
+ const localMemories = this.store.listMemoryRecords(ws.id, 25);
1729
+ const activeFacts = this.store.listTemporalFacts(ws.id, {
1730
+ includeHistorical: false,
1731
+ limit: 30,
1732
+ });
1733
+ const inferred = extractActiveMemoryDefaults({
1734
+ memories: localMemories,
1735
+ temporalFacts: activeFacts,
1736
+ });
1737
+ const llmPolicyBrief = buildLlmPolicyAndGovernanceBrief(ws.policy, {
1738
+ workspaceName: ws.name,
1739
+ workspaceSlug: ws.slug,
1740
+ activeDefaults: inferred.activeDefaults,
1741
+ trustScore: { overall: trustScore.overall, tier: trustScore.tier },
1742
+ agentDid: governance.agentDid,
1743
+ });
1584
1744
  const killSwitch = {
1585
1745
  active: Boolean(ws.policy.killSwitchActive),
1586
1746
  reason: ws.policy.killSwitchReason || null,
@@ -1603,9 +1763,70 @@ export class MuxoEngine {
1603
1763
  trustScore,
1604
1764
  policy: ws.policy,
1605
1765
  plainEnglish,
1766
+ llmPolicyBrief,
1606
1767
  explanation,
1607
1768
  };
1608
1769
  }
1770
+ resetWorkspaceGuardrails(ctx) {
1771
+ const ws = this.store.getWorkspace(ctx.workspace.id);
1772
+ const updated = this.store.updateWorkspacePolicy(ws.id, {
1773
+ ...DEFAULT_WORKSPACE_POLICY,
1774
+ parameterRules: [],
1775
+ customInstructions: [],
1776
+ naturalLanguageRules: [],
1777
+ blockedToolSlugs: [],
1778
+ });
1779
+ this.governance.resumeKillSwitch(ws.id);
1780
+ const plainEnglish = describePolicyInPlainEnglish(updated.policy);
1781
+ const llmPolicyBrief = buildLlmPolicyAndGovernanceBrief(updated.policy, {
1782
+ workspaceName: updated.name,
1783
+ workspaceSlug: updated.slug,
1784
+ });
1785
+ return {
1786
+ ok: true,
1787
+ action: "reset_guardrails",
1788
+ workspace: updated,
1789
+ policy: updated.policy,
1790
+ plainEnglish,
1791
+ llmPolicyBrief,
1792
+ explanation: plainEnglish.explanation,
1793
+ };
1794
+ }
1795
+ async checkToolPolicy(ctx, params) {
1796
+ const ws = this.store.getWorkspace(ctx.workspace.id);
1797
+ const localMemories = this.store.listMemoryRecords(ws.id, 25);
1798
+ const activeFacts = this.store.listTemporalFacts(ws.id, {
1799
+ includeHistorical: false,
1800
+ limit: 30,
1801
+ });
1802
+ const inferred = extractActiveMemoryDefaults({
1803
+ memories: localMemories,
1804
+ temporalFacts: activeFacts,
1805
+ });
1806
+ let riskLevel;
1807
+ let creditCost;
1808
+ let lane;
1809
+ let resolvedSlug = String(params.toolSlug || "instant.web.search").trim();
1810
+ try {
1811
+ const tool = await this.inspectTool(resolvedSlug);
1812
+ resolvedSlug = tool.slug;
1813
+ riskLevel = tool.riskLevel;
1814
+ creditCost = tool.creditCost;
1815
+ lane = tool.lane;
1816
+ }
1817
+ catch {
1818
+ // Fallback to slug prefix heuristics in simulatePolicyEvaluation
1819
+ }
1820
+ return simulatePolicyEvaluation({
1821
+ policy: ws.policy,
1822
+ toolSlug: resolvedSlug,
1823
+ riskLevel,
1824
+ creditCost,
1825
+ lane,
1826
+ input: params.input || {},
1827
+ activeDefaults: inferred.activeDefaults,
1828
+ });
1829
+ }
1609
1830
  setKillSwitch(ctx, active, reason) {
1610
1831
  const ws = this.store.getWorkspace(ctx.workspace.id);
1611
1832
  const updated = this.store.updateWorkspacePolicy(ws.id, {
@@ -1656,10 +1877,16 @@ export class MuxoEngine {
1656
1877
  memories: localMemories,
1657
1878
  temporalFacts: activeFacts,
1658
1879
  });
1880
+ const llmPolicyBrief = buildLlmPolicyAndGovernanceBrief(ws.policy, {
1881
+ workspaceName: ws.name,
1882
+ workspaceSlug: ws.slug,
1883
+ activeDefaults: inferred.activeDefaults,
1884
+ });
1659
1885
  return {
1660
1886
  workspaceId: ws.id,
1661
1887
  policy: ws.policy,
1662
1888
  plainEnglish,
1889
+ llmPolicyBrief,
1663
1890
  activeDefaults: inferred.activeDefaults,
1664
1891
  activeGuardrails: Array.from(new Set([
1665
1892
  ...(ws.policy.naturalLanguageRules || []),
@@ -1701,11 +1928,16 @@ export class MuxoEngine {
1701
1928
  // Non-blocking if memory scan/storage fails
1702
1929
  }
1703
1930
  const plainEnglish = describePolicyInPlainEnglish(updated.policy);
1931
+ const llmPolicyBrief = buildLlmPolicyAndGovernanceBrief(updated.policy, {
1932
+ workspaceName: updated.name,
1933
+ workspaceSlug: updated.slug,
1934
+ });
1704
1935
  return {
1705
1936
  ok: true,
1706
1937
  workspace: updated,
1707
1938
  guardrail: parsed,
1708
1939
  plainEnglish,
1940
+ llmPolicyBrief,
1709
1941
  memoryRecord,
1710
1942
  };
1711
1943
  }
@@ -2249,6 +2481,139 @@ export class MuxoEngine {
2249
2481
  listDurableWorkflows(workspaceId) {
2250
2482
  return Array.from(this.durableWorkflows.values()).filter((w) => w.workspaceId === workspaceId);
2251
2483
  }
2484
+ getDurableWorkflow(ctx, workflowId) {
2485
+ const wf = this.durableWorkflows.get(workflowId);
2486
+ if (!wf || wf.workspaceId !== ctx.workspace.id) {
2487
+ throw workflowNotFoundError(workflowId);
2488
+ }
2489
+ return wf;
2490
+ }
2491
+ getDurableWorkflowHistory(ctx, workflowId) {
2492
+ const wf = this.getDurableWorkflow(ctx, workflowId);
2493
+ return exportTemporalEventHistory(wf);
2494
+ }
2495
+ signalDurableWorkflow(ctx, workflowId, params) {
2496
+ const wf = this.getDurableWorkflow(ctx, workflowId);
2497
+ return sendSignalToWorkflow(wf, params);
2498
+ }
2499
+ rollbackDurableWorkflow(ctx, workflowId, params) {
2500
+ const wf = this.getDurableWorkflow(ctx, workflowId);
2501
+ return runSagaRollbackOnWorkflow(wf, params);
2502
+ }
2503
+ /**
2504
+ * AWS Cedar & Open Policy Agent (OPA / Rego) Policy-as-Code Compiler & Evaluator.
2505
+ */
2506
+ getPolicyAsCodeBundle(ctx) {
2507
+ const ws = this.store.getWorkspace(ctx.workspace.id);
2508
+ return compileWorkspacePolicyToCedarAndRego(ws.policy, ws);
2509
+ }
2510
+ async evaluatePolicyAsCode(ctx, params) {
2511
+ const ws = this.store.getWorkspace(ctx.workspace.id);
2512
+ let resolvedSlug = String(params.toolSlug || "instant.web.search").trim();
2513
+ let riskLevel = params.riskLevel;
2514
+ let creditCost = params.creditCost;
2515
+ let lane = params.lane;
2516
+ try {
2517
+ const tool = await this.inspectTool(resolvedSlug);
2518
+ resolvedSlug = tool.slug;
2519
+ if (!riskLevel)
2520
+ riskLevel = tool.riskLevel;
2521
+ if (typeof creditCost !== "number")
2522
+ creditCost = tool.creditCost;
2523
+ if (!lane)
2524
+ lane = tool.lane;
2525
+ }
2526
+ catch {
2527
+ // Fall back to slug prefix heuristics
2528
+ }
2529
+ return evaluateCedarAndOpaPolicy({
2530
+ policy: ws.policy,
2531
+ workspace: ws,
2532
+ toolSlug: resolvedSlug,
2533
+ input: params.input || {},
2534
+ riskLevel,
2535
+ creditCost,
2536
+ lane,
2537
+ });
2538
+ }
2539
+ /**
2540
+ * OpenTelemetry (OTel GenAI / MCP Semantic Conventions) & Langfuse Trace Exporter.
2541
+ */
2542
+ exportOtelTraces(ctx, limit = 25) {
2543
+ const ws = this.store.getWorkspace(ctx.workspace.id);
2544
+ const runs = this.store.listRuns(ws.id, limit);
2545
+ const receipts = this.store.listReceipts(ws.id, limit);
2546
+ const plans = this.store.listPlans(ws.id, limit);
2547
+ return buildOtelTraceExport({
2548
+ workspace: ws,
2549
+ runs,
2550
+ receipts,
2551
+ plans,
2552
+ });
2553
+ }
2554
+ /**
2555
+ * Turnkey Commercial Business Saga Playbooks.
2556
+ */
2557
+ listCommercialPlaybooks() {
2558
+ return MUXO_COMMERCIAL_PLAYBOOKS;
2559
+ }
2560
+ runCommercialPlaybook(ctx, params) {
2561
+ const ws = this.store.getWorkspace(ctx.workspace.id);
2562
+ const playbook = getCommercialPlaybook(params.slug);
2563
+ if (!playbook) {
2564
+ const err = new Error(`Unknown commercial playbook '${params.slug}'. Available playbooks: ${MUXO_COMMERCIAL_PLAYBOOKS.map((p) => p.slug).join(", ")}`);
2565
+ err.statusCode = 404;
2566
+ err.code = "PLAYBOOK_NOT_FOUND";
2567
+ throw err;
2568
+ }
2569
+ const wfId = `wf_saga_${Date.now()}_${crypto.randomBytes(4).toString("hex")}`;
2570
+ const executed = buildPlaybookSagaExecution({
2571
+ id: wfId,
2572
+ workspaceId: ws.id,
2573
+ workspaceSlug: ws.slug,
2574
+ playbook,
2575
+ input: params.input || {},
2576
+ });
2577
+ this.durableWorkflows.set(wfId, executed.workflow);
2578
+ const savedFact = this.store.upsertTemporalFact({
2579
+ workspaceId: ws.id,
2580
+ subject: executed.temporalFact.subject,
2581
+ predicate: executed.temporalFact.predicate,
2582
+ object: executed.temporalFact.object,
2583
+ summary: executed.temporalFact.summary,
2584
+ confidence: 0.99,
2585
+ sourceKind: "execution_outcome",
2586
+ sourceReferenceId: executed.temporalFact.episodeId,
2587
+ });
2588
+ return {
2589
+ ok: true,
2590
+ playbook: executed.playbook,
2591
+ workflow: executed.workflow,
2592
+ temporalFact: savedFact,
2593
+ };
2594
+ }
2595
+ /**
2596
+ * FinOps & Commercial ROI Unit-Economics Analytics.
2597
+ */
2598
+ getCommercialRoiReport(ctx) {
2599
+ const ws = this.store.getWorkspace(ctx.workspace.id);
2600
+ const runs = this.store.listRuns(ws.id, 100);
2601
+ const plans = this.store.listPlans(ws.id, 100);
2602
+ const resources = this.store.listResources(ws.id);
2603
+ const byokKeys = this.store.listByokKeys(ws.id);
2604
+ const temporalFacts = this.store.listTemporalFacts(ws.id, {
2605
+ includeHistorical: false,
2606
+ limit: 100,
2607
+ });
2608
+ return buildCommercialRoiReport({
2609
+ workspace: ws,
2610
+ runs,
2611
+ plans,
2612
+ resources,
2613
+ byokKeys,
2614
+ temporalFacts,
2615
+ });
2616
+ }
2252
2617
  /**
2253
2618
  * Hybrid Semantic Vector + Bi-Temporal Recall (`@cf/baai/bge-base-en-v1.5` + Vectorize model).
2254
2619
  */
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export { getConfig, ROOT_DIR, type MuxoConfig } from "./config.js";
2
+ export * from "./durable-workflow.js";
2
3
  export { MuxoEngine, type ExecutionContext } from "./engine.js";
3
4
  export { handleJsonRpcMcpRequest, MUXO_MCP_TOOLS, type McpToolDefinition } from "./mcp.js";
5
+ export * from "./memory-graph.js";
6
+ export * from "./oss-suite.js";
4
7
  export { MuxoClient, type MuxoClientOptions } from "./sdk.js";
5
8
  export { createMuxoServer } from "./server.js";
6
9
  export { MuxoStore } from "./store.js";