xytara 2.2.0 → 2.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.
package/RELEASE_NOTES.md CHANGED
@@ -1,17 +1,17 @@
1
- # xytara 2.2.0 Release Notes
1
+ # xytara 2.3.0 Release Notes
2
2
 
3
- `xytara` 2.2.0 is the public machine-commerce program-complete line.
3
+ `xytara` 2.3.0 is the public machine-commerce intelligence line.
4
4
 
5
5
  Highlights:
6
6
 
7
7
  - direct one-line machine execution with `xytara-run`
8
- - release, comparison, adoption, scenario, and launch packs over HTTP and CLI
9
- - release-center, announcement-pack, and release-candidate surfaces for public launch readiness
10
- - credits-first reusable spend posture
11
- - native settlement-aware runtime inspection
12
- - proof-compatible handoff into `xoonya`
13
- - partner-ready onboarding and launch docs
14
- - explicit runtime durability posture, including Supabase-backed persistence on hosts without persistent disk
8
+ - account-level economics intelligence with bounded next-best-action guidance
9
+ - treasury intelligence for value-capture, reconciliation risk, and replenishment posture
10
+ - partner/adoption intelligence for readiness, onboarding friction, and promotion posture
11
+ - operator intelligence that compresses runtime economics and partner posture into one operating view
12
+ - credits-first reusable spend posture with durable runtime economics state
13
+ - native settlement-aware runtime inspection and proof-compatible handoff into `xoonya`
14
+ - partner-ready onboarding, launch docs, and public example paths remain in place
15
15
 
16
16
  Recommended first checks:
17
17
 
@@ -19,7 +19,9 @@ Recommended first checks:
19
19
  2. `xytara-release --candidate --summary`
20
20
  3. `npm run verify:release-candidate`
21
21
  4. `node examples/partner_launch_walkthrough.js`
22
- 5. inspect `/v1/release-candidate/summary` and `/v1/runtime/durability` on the deployed service
22
+ 5. inspect `/v1/economics/accounts/:account_id/intelligence-summary`
23
+ 6. inspect `/v1/partner-intelligence` and `/v1/operator-intelligence?account_id=...`
24
+ 7. inspect `/v1/runtime/durability` on the deployed service
23
25
 
24
26
  Recommended first docs:
25
27
 
@@ -3776,6 +3776,30 @@ class CommerceClient {
3776
3776
  return result && result.data ? result.data : null;
3777
3777
  }
3778
3778
 
3779
+ async getPartnerIntelligenceSummary() {
3780
+ const result = await this.getJson("/v1/partner-intelligence/summary");
3781
+ return result && result.data ? result.data : null;
3782
+ }
3783
+
3784
+ async getPartnerIntelligencePack() {
3785
+ const result = await this.getJson("/v1/partner-intelligence");
3786
+ return result && result.data ? result.data : null;
3787
+ }
3788
+
3789
+ async getOperatorIntelligenceSummary(accountId) {
3790
+ const resolvedAccountId = String(accountId || this.accountId || "").trim();
3791
+ const suffix = resolvedAccountId ? `?account_id=${encodeURIComponent(resolvedAccountId)}` : "";
3792
+ const result = await this.getJson(`/v1/operator-intelligence/summary${suffix}`);
3793
+ return result && result.data ? result.data : null;
3794
+ }
3795
+
3796
+ async getOperatorIntelligencePack(accountId) {
3797
+ const resolvedAccountId = String(accountId || this.accountId || "").trim();
3798
+ const suffix = resolvedAccountId ? `?account_id=${encodeURIComponent(resolvedAccountId)}` : "";
3799
+ const result = await this.getJson(`/v1/operator-intelligence${suffix}`);
3800
+ return result && result.data ? result.data : null;
3801
+ }
3802
+
3779
3803
  async getCreditBalance(accountId) {
3780
3804
  const resolvedAccountId = String(accountId || this.accountId || "").trim();
3781
3805
  if (!resolvedAccountId) throw new Error("getCreditBalance requires accountId");
@@ -3783,6 +3807,20 @@ class CommerceClient {
3783
3807
  return result && result.data ? result.data : null;
3784
3808
  }
3785
3809
 
3810
+ async getEconomicsIntelligenceSummary(accountId) {
3811
+ const resolvedAccountId = String(accountId || this.accountId || "").trim();
3812
+ if (!resolvedAccountId) throw new Error("getEconomicsIntelligenceSummary requires accountId");
3813
+ const result = await this.getJson(`/v1/economics/accounts/${encodeURIComponent(resolvedAccountId)}/intelligence-summary`);
3814
+ return result && result.data ? result.data : null;
3815
+ }
3816
+
3817
+ async getTreasuryIntelligenceSummary(accountId) {
3818
+ const resolvedAccountId = String(accountId || this.accountId || "").trim();
3819
+ if (!resolvedAccountId) throw new Error("getTreasuryIntelligenceSummary requires accountId");
3820
+ const result = await this.getJson(`/v1/economics/accounts/${encodeURIComponent(resolvedAccountId)}/treasury-intelligence-summary`);
3821
+ return result && result.data ? result.data : null;
3822
+ }
3823
+
3786
3824
  async getUsageMeteringSummary(accountId) {
3787
3825
  const resolvedAccountId = String(accountId || this.accountId || "").trim();
3788
3826
  if (!resolvedAccountId) throw new Error("getUsageMeteringSummary requires accountId");
@@ -478,6 +478,113 @@ function buildCreditBalanceSummary(state, accountId) {
478
478
  };
479
479
  }
480
480
 
481
+ function buildWalletSummary(state, accountId) {
482
+ const balance = buildCreditBalanceSummary(state, accountId);
483
+ const allocations = listAllocationEventsForAccount(state, accountId);
484
+ const usageMeters = listUsageMetersForAccount(state, accountId);
485
+ const reserveUnits = allocations
486
+ .filter((entry) => entry && entry.direction === "reserve")
487
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
488
+ const committedUnits = allocations
489
+ .filter((entry) => entry && entry.direction === "commit")
490
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
491
+ const releasedUnits = allocations
492
+ .filter((entry) => entry && entry.direction === "release")
493
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
494
+ const reversedUnits = allocations
495
+ .filter((entry) => entry && entry.direction === "reverse")
496
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
497
+ const reserveCount = allocations.filter((entry) => entry && entry.direction === "reserve").length;
498
+ const walletState = balance.available_units <= 0
499
+ ? "depleted"
500
+ : balance.entitlement_summary.low_entitlement_count > 0
501
+ ? "low_balance"
502
+ : "healthy";
503
+
504
+ return {
505
+ wallet_version: "xytara-machine-wallet-summary-v1",
506
+ wallet_id: `wallet_${accountId}`,
507
+ account_id: accountId,
508
+ canonical_unit: "usage_units",
509
+ wallet_state: walletState,
510
+ issued_units: balance.issued_units,
511
+ available_units: balance.available_units,
512
+ reserved_units: reserveUnits,
513
+ committed_units: committedUnits,
514
+ released_units: releasedUnits,
515
+ reversed_units: reversedUnits,
516
+ consumed_units: balance.consumed_units,
517
+ reserve_count: reserveCount,
518
+ entitlement_count: balance.entitlement_summary.entitlement_count,
519
+ active_entitlement_count: balance.entitlement_summary.active_entitlement_count,
520
+ usage_meter_count: usageMeters.length,
521
+ replenishment_posture: balance.replenishment_summary.depleted_count > 0
522
+ ? "replenishment_required"
523
+ : balance.replenishment_summary.low_balance_count > 0
524
+ ? "replenishment_recommended"
525
+ : "sufficient_capacity",
526
+ linked_surfaces: {
527
+ credit_balance_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/credit-balance`,
528
+ entitlements_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/entitlements`,
529
+ usage_meters_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/usage-meters`,
530
+ wallet_ledger_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-ledger-summary`
531
+ },
532
+ generated_at_iso: nowIso()
533
+ };
534
+ }
535
+
536
+ function buildWalletLedgerSummary(state, accountId) {
537
+ const wallet = buildWalletSummary(state, accountId);
538
+ const allocations = listAllocationEventsForAccount(state, accountId);
539
+ const spends = listCreditSpendsForAccount(state, accountId);
540
+ const railCredits = listRailCreditsForAccount(state, accountId);
541
+ const consequences = {
542
+ mint_count: allocations.filter((entry) => entry && entry.direction === "mint").length + railCredits.length,
543
+ reserve_count: allocations.filter((entry) => entry && entry.direction === "reserve").length,
544
+ commit_count: allocations.filter((entry) => entry && entry.direction === "commit").length + spends.length,
545
+ release_count: allocations.filter((entry) => entry && entry.direction === "release").length,
546
+ reverse_count: allocations.filter((entry) => entry && entry.direction === "reverse").length
547
+ };
548
+
549
+ return {
550
+ summary_version: "xytara-wallet-ledger-summary-v1",
551
+ wallet_id: wallet.wallet_id,
552
+ account_id: accountId,
553
+ canonical_truth_posture: "allocation_and_consequence_records_with_materialized_wallet_summary",
554
+ canonical_unit: wallet.canonical_unit,
555
+ wallet_state: wallet.wallet_state,
556
+ wallet_summary: {
557
+ issued_units: wallet.issued_units,
558
+ available_units: wallet.available_units,
559
+ reserved_units: wallet.reserved_units,
560
+ committed_units: wallet.committed_units,
561
+ released_units: wallet.released_units,
562
+ reversed_units: wallet.reversed_units,
563
+ consumed_units: wallet.consumed_units
564
+ },
565
+ ledger_lifecycle_counts: consequences,
566
+ source_record_counts: {
567
+ allocation_count: allocations.length,
568
+ rail_credit_count: railCredits.length,
569
+ credit_spend_count: spends.length,
570
+ entitlement_count: wallet.entitlement_count,
571
+ usage_meter_count: wallet.usage_meter_count
572
+ },
573
+ translation_boundary: {
574
+ public_commercial_shell: "credits",
575
+ canonical_hidden_unit: "usage_units",
576
+ canonical_wallet_truth: "hidden_machine_wallet",
577
+ materialized_projection: "wallet_summary"
578
+ },
579
+ linked_surfaces: {
580
+ wallet_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet`,
581
+ ledger_export_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/ledger-export`,
582
+ reconciliation_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/reconciliation-pack`
583
+ },
584
+ generated_at_iso: nowIso()
585
+ };
586
+ }
587
+
481
588
  function getWorkflowTaskRefs(workflowRef) {
482
589
  const workflow = findWorkflow(workflowRef);
483
590
  if (!workflow || !Array.isArray(workflow.tasks)) return [];
@@ -922,6 +1029,199 @@ function buildTreasurySummary(state, accountId) {
922
1029
  };
923
1030
  }
924
1031
 
1032
+ function selectRecommendedCreditPack(totalUnits, usageMeterCount) {
1033
+ if (totalUnits >= 1500 || usageMeterCount >= 20) return "credits.fleet";
1034
+ if (totalUnits >= 500 || usageMeterCount >= 10) return "credits.agent";
1035
+ if (totalUnits >= 100 || usageMeterCount >= 3) return "credits.builder";
1036
+ if (totalUnits > 0 || usageMeterCount > 0) return "credits.starter";
1037
+ return null;
1038
+ }
1039
+
1040
+ function buildEconomicsIntelligenceSummary(state, accountId) {
1041
+ const balanceSummary = buildCreditBalanceSummary(state, accountId);
1042
+ const meteringSummary = buildUsageMeteringSummary(state, accountId);
1043
+ const replenishmentSummary = buildEntitlementReplenishmentSummary(state, accountId);
1044
+ const treasurySummary = buildTreasurySummary(state, accountId);
1045
+
1046
+ const usageMeterCount = Number(meteringSummary.usage_meter_count || 0);
1047
+ const totalUnits = Number(meteringSummary.total_units || 0);
1048
+ const availableUnits = Number(balanceSummary.available_units || 0);
1049
+ const consumedUnits = Number(balanceSummary.consumed_units || 0);
1050
+ const lowBalanceCount = Number(replenishmentSummary.low_balance_count || 0);
1051
+ const depletedCount = Number(replenishmentSummary.depleted_count || 0);
1052
+ const mintedUnits = Number(treasurySummary.treasury && treasurySummary.treasury.minted_units || 0);
1053
+ const settledAmountMinor = Number(treasurySummary.treasury && treasurySummary.treasury.settled_amount_minor || 0);
1054
+ const budgetCount = Number(treasurySummary.budgets && treasurySummary.budgets.total || 0);
1055
+
1056
+ let recommendedFundingPosture = "direct_pay_first";
1057
+ if (availableUnits > 0 || consumedUnits > 0 || usageMeterCount > 0) {
1058
+ recommendedFundingPosture = "credits_first";
1059
+ }
1060
+ if (availableUnits <= 0 && (usageMeterCount > 0 || consumedUnits > 0)) {
1061
+ recommendedFundingPosture = "pack_backed_credits_first";
1062
+ }
1063
+
1064
+ const recommendedPackId = replenishmentSummary.recommended_pack_ids[0] || selectRecommendedCreditPack(totalUnits, usageMeterCount);
1065
+
1066
+ let replenishmentRiskState = "low";
1067
+ if (lowBalanceCount > 0) replenishmentRiskState = "watch";
1068
+ if (depletedCount > 0 || (availableUnits > 0 && availableUnits <= Math.max(8, totalUnits))) {
1069
+ replenishmentRiskState = "high";
1070
+ }
1071
+
1072
+ let treasuryHealthState = "healthy";
1073
+ if (mintedUnits === 0 && settledAmountMinor === 0 && usageMeterCount === 0) {
1074
+ treasuryHealthState = "pre_funding";
1075
+ } else if (availableUnits <= 0 && (consumedUnits > 0 || usageMeterCount > 0)) {
1076
+ treasuryHealthState = "constrained";
1077
+ } else if (lowBalanceCount > 0 || budgetCount > 0) {
1078
+ treasuryHealthState = "watch";
1079
+ }
1080
+
1081
+ let nextBestAction = "continue_current_posture";
1082
+ if (recommendedFundingPosture === "direct_pay_first") {
1083
+ nextBestAction = "start_with_direct_pay";
1084
+ }
1085
+ if (recommendedFundingPosture === "credits_first" && recommendedPackId && usageMeterCount >= 3) {
1086
+ nextBestAction = "consider_pack_funding";
1087
+ }
1088
+ if (replenishmentRiskState === "watch") {
1089
+ nextBestAction = "prepare_replenishment";
1090
+ }
1091
+ if (replenishmentRiskState === "high") {
1092
+ nextBestAction = "replenish_credits";
1093
+ }
1094
+ if (treasuryHealthState === "constrained") {
1095
+ nextBestAction = "restore_runtime_balance";
1096
+ }
1097
+
1098
+ return {
1099
+ account_id: accountId,
1100
+ category: "machine-commerce-account-economics-intelligence-summary",
1101
+ recommended_funding_posture: recommendedFundingPosture,
1102
+ recommended_pack_id: recommendedPackId,
1103
+ replenishment_risk_state: replenishmentRiskState,
1104
+ treasury_health_state: treasuryHealthState,
1105
+ next_best_action: nextBestAction,
1106
+ explanation_signals: {
1107
+ available_units: availableUnits,
1108
+ consumed_units: consumedUnits,
1109
+ usage_meter_count: usageMeterCount,
1110
+ metered_units: totalUnits,
1111
+ low_balance_count: lowBalanceCount,
1112
+ depleted_count: depletedCount,
1113
+ recommended_replenishment_pack_ids: replenishmentSummary.recommended_pack_ids,
1114
+ pricing_bands: meteringSummary.pricing_bands,
1115
+ minted_units: mintedUnits,
1116
+ settled_amount_minor: settledAmountMinor,
1117
+ budget_count: budgetCount
1118
+ },
1119
+ linked_surfaces: {
1120
+ credit_balance_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/credit-balance`,
1121
+ metering_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/metering-summary`,
1122
+ entitlement_replenishment_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/entitlements/replenishment-summary`,
1123
+ treasury_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-summary`,
1124
+ operator_dashboard_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/operator-dashboard`
1125
+ },
1126
+ generated_at_iso: nowIso()
1127
+ };
1128
+ }
1129
+
1130
+ function buildTreasuryIntelligenceSummary(state, accountId) {
1131
+ const treasurySummary = buildTreasurySummary(state, accountId);
1132
+ const treasuryDrilldown = buildTreasuryDrilldown(state, accountId);
1133
+ const reconciliationPack = buildReconciliationPack(state, accountId);
1134
+ const meteringSummary = buildUsageMeteringSummary(state, accountId);
1135
+ const balanceSummary = buildCreditBalanceSummary(state, accountId);
1136
+ const railSummary = buildRailSummary(state, accountId);
1137
+
1138
+ const mintedUnits = Number(treasurySummary.treasury.minted_units || 0);
1139
+ const consumedUnits = Number(treasurySummary.treasury.consumed_units || 0);
1140
+ const availableUnits = Number(treasurySummary.treasury.available_units || 0);
1141
+ const settledAmountMinor = Number(treasurySummary.treasury.settled_amount_minor || 0);
1142
+ const usageMeterCount = Number(meteringSummary.usage_meter_count || 0);
1143
+ const pendingTransactions = Number(treasuryDrilldown.unresolved_flags.pending_transactions || 0);
1144
+ const pendingReceipts = Number(treasuryDrilldown.unresolved_flags.pending_receipts || 0);
1145
+ const disputedReceipts = Number(reconciliationPack.unresolved_state.disputed_receipt_count || 0);
1146
+ const escalatedReceipts = Number(reconciliationPack.unresolved_state.escalated_receipt_count || 0);
1147
+ const paymentLedgerCount = Number(treasurySummary.payment_ledger_count || 0);
1148
+ const railCreditEventCount = Number(railSummary.credit_event_count || 0);
1149
+
1150
+ let treasuryEfficiencyState = "healthy";
1151
+ if (mintedUnits === 0 && settledAmountMinor === 0 && usageMeterCount === 0) {
1152
+ treasuryEfficiencyState = "pre_funding";
1153
+ } else if (availableUnits <= 0 && (consumedUnits > 0 || usageMeterCount > 0)) {
1154
+ treasuryEfficiencyState = "constrained";
1155
+ } else if (pendingTransactions > 0 || pendingReceipts > 0) {
1156
+ treasuryEfficiencyState = "watch";
1157
+ }
1158
+
1159
+ let valueCaptureState = "aligned";
1160
+ if (usageMeterCount === 0 && paymentLedgerCount === 0 && railCreditEventCount === 0) {
1161
+ valueCaptureState = "pre_conversion";
1162
+ } else if (usageMeterCount >= 3 && paymentLedgerCount <= 1 && consumedUnits > 0) {
1163
+ valueCaptureState = "repeat_use_ready";
1164
+ } else if (consumedUnits > mintedUnits && mintedUnits > 0) {
1165
+ valueCaptureState = "leaking";
1166
+ }
1167
+
1168
+ let reconciliationRiskState = "low";
1169
+ if (pendingTransactions > 0 || pendingReceipts > 0) reconciliationRiskState = "watch";
1170
+ if (disputedReceipts > 0 || escalatedReceipts > 0) reconciliationRiskState = "high";
1171
+
1172
+ let replenishmentFatigueState = "low";
1173
+ if (railCreditEventCount >= 2 && availableUnits <= Math.max(8, meteringSummary.total_units || 0)) {
1174
+ replenishmentFatigueState = "watch";
1175
+ }
1176
+ if (railCreditEventCount >= 3 && balanceSummary.replenishment_summary.low_balance_count > 0) {
1177
+ replenishmentFatigueState = "high";
1178
+ }
1179
+
1180
+ let nextBestAction = "continue_treasury_posture";
1181
+ if (treasuryEfficiencyState === "pre_funding") {
1182
+ nextBestAction = "establish_runtime_funding";
1183
+ } else if (treasuryEfficiencyState === "constrained") {
1184
+ nextBestAction = "restore_runtime_balance";
1185
+ } else if (reconciliationRiskState === "high") {
1186
+ nextBestAction = "review_reconciliation_pack";
1187
+ } else if (reconciliationRiskState === "watch") {
1188
+ nextBestAction = "inspect_treasury_drilldown";
1189
+ } else if (replenishmentFatigueState === "high" || valueCaptureState === "repeat_use_ready") {
1190
+ nextBestAction = "recommend_larger_pack_posture";
1191
+ }
1192
+
1193
+ return {
1194
+ account_id: accountId,
1195
+ category: "machine-commerce-account-treasury-intelligence-summary",
1196
+ treasury_efficiency_state: treasuryEfficiencyState,
1197
+ value_capture_state: valueCaptureState,
1198
+ reconciliation_risk_state: reconciliationRiskState,
1199
+ replenishment_fatigue_state: replenishmentFatigueState,
1200
+ next_best_action: nextBestAction,
1201
+ explanation_signals: {
1202
+ minted_units: mintedUnits,
1203
+ consumed_units: consumedUnits,
1204
+ available_units: availableUnits,
1205
+ settled_amount_minor: settledAmountMinor,
1206
+ usage_meter_count: usageMeterCount,
1207
+ payment_ledger_count: paymentLedgerCount,
1208
+ rail_credit_event_count: railCreditEventCount,
1209
+ pending_transaction_count: pendingTransactions,
1210
+ pending_receipt_count: pendingReceipts,
1211
+ disputed_receipt_count: disputedReceipts,
1212
+ escalated_receipt_count: escalatedReceipts
1213
+ },
1214
+ linked_surfaces: {
1215
+ treasury_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-summary`,
1216
+ treasury_drilldown_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-drilldown`,
1217
+ reconciliation_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/reconciliation-pack`,
1218
+ metering_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/metering-summary`,
1219
+ rail_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/rail-summary`
1220
+ },
1221
+ generated_at_iso: nowIso()
1222
+ };
1223
+ }
1224
+
925
1225
  function buildLedgerExport(state, accountId) {
926
1226
  return {
927
1227
  export_version: "xytara-economics-ledger-export-v1",
@@ -1402,6 +1702,10 @@ module.exports = {
1402
1702
  previewRailCredits,
1403
1703
  applyRailCredits,
1404
1704
  buildCreditBalanceSummary,
1705
+ buildWalletSummary,
1706
+ buildWalletLedgerSummary,
1707
+ buildEconomicsIntelligenceSummary,
1708
+ buildTreasuryIntelligenceSummary,
1405
1709
  buildTreasurySummary,
1406
1710
  buildLedgerExport,
1407
1711
  buildTreasuryDrilldown,
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+
3
+ const { buildEconomicsIntelligenceSummary } = require("./commerce_economics");
4
+ const { buildPartnerIntelligencePack } = require("./partner_intelligence");
5
+
6
+ function buildOperatorIntelligencePack(state, input) {
7
+ const payload = input && typeof input === "object" && !Array.isArray(input) ? input : {};
8
+ const accountId = String(payload.account_id || "acct_demo").trim() || "acct_demo";
9
+ const economicsIntelligence = buildEconomicsIntelligenceSummary(state, accountId);
10
+ const partnerIntelligence = buildPartnerIntelligencePack();
11
+
12
+ const actionQueue = [];
13
+
14
+ if (economicsIntelligence.next_best_action && economicsIntelligence.next_best_action !== "continue_current_posture") {
15
+ actionQueue.push({
16
+ lane: "runtime_economics",
17
+ priority: economicsIntelligence.replenishment_risk_state === "high" ? "high" : "medium",
18
+ action: economicsIntelligence.next_best_action,
19
+ reason: `funding posture is ${economicsIntelligence.recommended_funding_posture} with ${economicsIntelligence.replenishment_risk_state} replenishment risk`
20
+ });
21
+ }
22
+
23
+ if (partnerIntelligence.next_best_action) {
24
+ actionQueue.push({
25
+ lane: "partner_adoption",
26
+ priority: partnerIntelligence.onboarding_friction_state === "low" ? "medium" : "high",
27
+ action: partnerIntelligence.next_best_action,
28
+ reason: `partner readiness is ${partnerIntelligence.partner_readiness_state} and onboarding friction is ${partnerIntelligence.onboarding_friction_state}`
29
+ });
30
+ }
31
+
32
+ if (actionQueue.length === 0) {
33
+ actionQueue.push({
34
+ lane: "operator_posture",
35
+ priority: "low",
36
+ action: "continue_current_posture",
37
+ reason: "runtime economics and partner posture are both stable enough to continue current operation"
38
+ });
39
+ }
40
+
41
+ return {
42
+ ok: true,
43
+ account_id: accountId,
44
+ category: "machine-commerce-operator-intelligence-pack",
45
+ overall_operator_state: {
46
+ runtime_economics_state: economicsIntelligence.treasury_health_state,
47
+ partner_adoption_state: partnerIntelligence.partner_readiness_state,
48
+ top_priority: actionQueue[0].priority
49
+ },
50
+ recommended_operator_motion: actionQueue[0].action,
51
+ next_action_queue: actionQueue,
52
+ intelligence_refs: {
53
+ economics_intelligence_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/intelligence-summary`,
54
+ partner_intelligence_ref: "/v1/partner-intelligence",
55
+ operator_dashboard_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/operator-dashboard`
56
+ },
57
+ explanation_signals: {
58
+ runtime_next_best_action: economicsIntelligence.next_best_action,
59
+ runtime_funding_posture: economicsIntelligence.recommended_funding_posture,
60
+ runtime_replenishment_risk_state: economicsIntelligence.replenishment_risk_state,
61
+ runtime_treasury_health_state: economicsIntelligence.treasury_health_state,
62
+ partner_next_best_action: partnerIntelligence.next_best_action,
63
+ partner_readiness_state: partnerIntelligence.partner_readiness_state,
64
+ partner_onboarding_friction_state: partnerIntelligence.onboarding_friction_state,
65
+ partner_promotion_readiness_state: partnerIntelligence.promotion_readiness_state
66
+ },
67
+ generated_from: {
68
+ economics_category: economicsIntelligence.category,
69
+ partner_category: partnerIntelligence.category
70
+ }
71
+ };
72
+ }
73
+
74
+ function summarizeOperatorIntelligencePack(state, input) {
75
+ const pack = buildOperatorIntelligencePack(state, input);
76
+ return {
77
+ ok: true,
78
+ account_id: pack.account_id,
79
+ category: pack.category,
80
+ recommended_operator_motion: pack.recommended_operator_motion,
81
+ queue_length: pack.next_action_queue.length,
82
+ runtime_economics_state: pack.overall_operator_state.runtime_economics_state,
83
+ partner_adoption_state: pack.overall_operator_state.partner_adoption_state
84
+ };
85
+ }
86
+
87
+ module.exports = {
88
+ buildOperatorIntelligencePack,
89
+ summarizeOperatorIntelligencePack
90
+ };
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+
3
+ const packageJson = require("../package.json");
4
+ const { buildAdoptionPack } = require("./release_pack");
5
+ const { buildAdapterPartnerPack } = require("./adapter_partner_pack");
6
+
7
+ function classifyPartnerReadinessState(adoptionPack, adapterPartnerPack) {
8
+ const targetCount = adoptionPack.initial_adoption_targets.length;
9
+ const firstSuccessPathCount = adoptionPack.first_success_paths.length;
10
+ const partnerValueCount = adapterPartnerPack.partner_value.length;
11
+ const maturityStepCount = adapterPartnerPack.trust_path.maturity_path.length;
12
+
13
+ if (targetCount >= 4 && firstSuccessPathCount >= 3 && partnerValueCount >= 4 && maturityStepCount >= 5) {
14
+ return "strong";
15
+ }
16
+ if (targetCount >= 2 && firstSuccessPathCount >= 2 && partnerValueCount >= 2) {
17
+ return "working";
18
+ }
19
+ return "early";
20
+ }
21
+
22
+ function classifyOnboardingFrictionState(adapterPartnerPack) {
23
+ const docCount = adapterPartnerPack.start_path.first_docs.length;
24
+ const commandCount = adapterPartnerPack.start_path.first_commands.length;
25
+ const exampleCount = adapterPartnerPack.start_path.first_examples.length;
26
+
27
+ if (docCount >= 2 && commandCount >= 4 && exampleCount >= 2) return "low";
28
+ if (docCount >= 1 && commandCount >= 2) return "manageable";
29
+ return "high";
30
+ }
31
+
32
+ function classifyPromotionReadinessState(adapterPartnerPack) {
33
+ const publicSurfaceCount = Object.keys(adapterPartnerPack.public_surfaces).length;
34
+ const maturityStepCount = adapterPartnerPack.trust_path.maturity_path.length;
35
+ if (publicSurfaceCount >= 5 && maturityStepCount >= 5) return "strong";
36
+ if (publicSurfaceCount >= 3 && maturityStepCount >= 3) return "working";
37
+ return "early";
38
+ }
39
+
40
+ function buildPartnerIntelligencePack() {
41
+ const adoptionPack = buildAdoptionPack();
42
+ const adapterPartnerPack = buildAdapterPartnerPack();
43
+ const partnerReadinessState = classifyPartnerReadinessState(adoptionPack, adapterPartnerPack);
44
+ const onboardingFrictionState = classifyOnboardingFrictionState(adapterPartnerPack);
45
+ const promotionReadinessState = classifyPromotionReadinessState(adapterPartnerPack);
46
+
47
+ let nextBestAction = "promote_partner_start_path";
48
+ if (onboardingFrictionState !== "low") {
49
+ nextBestAction = "tighten_partner_onboarding";
50
+ } else if (promotionReadinessState !== "strong") {
51
+ nextBestAction = "strengthen_promotion_trust_path";
52
+ }
53
+
54
+ return {
55
+ ok: true,
56
+ product: packageJson.name,
57
+ category: "machine-commerce-partner-intelligence-pack",
58
+ partner_readiness_state: partnerReadinessState,
59
+ onboarding_friction_state: onboardingFrictionState,
60
+ promotion_readiness_state: promotionReadinessState,
61
+ first_partner_segment: adapterPartnerPack.adoption_message.first_partner_type,
62
+ recommended_partner_motion: "lead_with_adapter_authors_and_agent_builders",
63
+ next_best_action: nextBestAction,
64
+ explanation_signals: {
65
+ adoption_target_count: adoptionPack.initial_adoption_targets.length,
66
+ target_ecosystem_count: adoptionPack.target_ecosystems.length,
67
+ first_success_path_count: adoptionPack.first_success_paths.length,
68
+ partner_value_count: adapterPartnerPack.partner_value.length,
69
+ onboarding_doc_count: adapterPartnerPack.start_path.first_docs.length,
70
+ onboarding_command_count: adapterPartnerPack.start_path.first_commands.length,
71
+ onboarding_example_count: adapterPartnerPack.start_path.first_examples.length,
72
+ maturity_step_count: adapterPartnerPack.trust_path.maturity_path.length,
73
+ public_surface_count: Object.keys(adapterPartnerPack.public_surfaces).length
74
+ },
75
+ linked_surfaces: {
76
+ adoption_summary_ref: "/v1/release-pack/adoption/summary",
77
+ adapter_partner_summary_ref: "/v1/adapter-partners/summary",
78
+ release_center_summary_ref: "/v1/release-center/summary"
79
+ },
80
+ generated_from: {
81
+ adoption_pack_category: adoptionPack.category,
82
+ adapter_partner_pack_category: adapterPartnerPack.category
83
+ }
84
+ };
85
+ }
86
+
87
+ function summarizePartnerIntelligencePack() {
88
+ const pack = buildPartnerIntelligencePack();
89
+ return {
90
+ ok: true,
91
+ product: pack.product,
92
+ category: pack.category,
93
+ partner_readiness_state: pack.partner_readiness_state,
94
+ onboarding_friction_state: pack.onboarding_friction_state,
95
+ promotion_readiness_state: pack.promotion_readiness_state,
96
+ first_partner_segment: pack.first_partner_segment,
97
+ next_best_action: pack.next_best_action,
98
+ signal_count: Object.keys(pack.explanation_signals).length
99
+ };
100
+ }
101
+
102
+ module.exports = {
103
+ buildPartnerIntelligencePack,
104
+ summarizePartnerIntelligencePack
105
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xytara",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Machine commerce SDK for discovery, quoting, execution, lifecycle inspection, and adapters.",
5
5
  "main": "index.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -64,6 +64,10 @@ const {
64
64
  previewRailCredits,
65
65
  applyRailCredits,
66
66
  buildCreditBalanceSummary,
67
+ buildWalletSummary,
68
+ buildWalletLedgerSummary,
69
+ buildEconomicsIntelligenceSummary,
70
+ buildTreasuryIntelligenceSummary,
67
71
  buildTreasurySummary,
68
72
  buildLedgerExport,
69
73
  buildTreasuryDrilldown,
@@ -242,6 +246,14 @@ const {
242
246
  buildAdapterPartnerPack,
243
247
  summarizeAdapterPartnerPack
244
248
  } = require("./lib/adapter_partner_pack");
249
+ const {
250
+ buildPartnerIntelligencePack,
251
+ summarizePartnerIntelligencePack
252
+ } = require("./lib/partner_intelligence");
253
+ const {
254
+ buildOperatorIntelligencePack,
255
+ summarizeOperatorIntelligencePack
256
+ } = require("./lib/operator_intelligence");
245
257
  const {
246
258
  buildSoftLaunchPack,
247
259
  summarizeSoftLaunchPack
@@ -3259,6 +3271,42 @@ async function routeRequest(req, res) {
3259
3271
  return;
3260
3272
  }
3261
3273
 
3274
+ if (req.method === "GET" && url.pathname === "/v1/partner-intelligence") {
3275
+ sendJson(res, 200, buildPartnerIntelligencePack());
3276
+ return;
3277
+ }
3278
+
3279
+ if (req.method === "GET" && url.pathname === "/v1/partner-intelligence/summary") {
3280
+ sendJson(res, 200, summarizePartnerIntelligencePack());
3281
+ return;
3282
+ }
3283
+
3284
+ if (req.method === "GET" && url.pathname === "/v1/operator-intelligence") {
3285
+ sendJson(res, 200, buildOperatorIntelligencePack(state, {
3286
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3287
+ }));
3288
+ return;
3289
+ }
3290
+
3291
+ if (req.method === "GET" && url.pathname === "/v1/operator-intelligence/summary") {
3292
+ sendJson(res, 200, summarizeOperatorIntelligencePack(state, {
3293
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3294
+ }));
3295
+ return;
3296
+ }
3297
+
3298
+ if (req.method === "POST" && url.pathname === "/v1/operator-intelligence") {
3299
+ const body = await readJsonBody(req);
3300
+ sendJson(res, 200, buildOperatorIntelligencePack(state, body));
3301
+ return;
3302
+ }
3303
+
3304
+ if (req.method === "POST" && url.pathname === "/v1/operator-intelligence/summary") {
3305
+ const body = await readJsonBody(req);
3306
+ sendJson(res, 200, summarizeOperatorIntelligencePack(state, body));
3307
+ return;
3308
+ }
3309
+
3262
3310
  if (req.method === "GET" && url.pathname === "/v1/soft-launch") {
3263
3311
  sendJson(res, 200, buildSoftLaunchPack());
3264
3312
  return;
@@ -5757,6 +5805,30 @@ async function routeRequest(req, res) {
5757
5805
  return;
5758
5806
  }
5759
5807
 
5808
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/wallet")) {
5809
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/wallet$/, "");
5810
+ sendJson(res, 200, buildWalletSummary(state, accountId));
5811
+ return;
5812
+ }
5813
+
5814
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/wallet-ledger-summary")) {
5815
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/wallet-ledger-summary$/, "");
5816
+ sendJson(res, 200, buildWalletLedgerSummary(state, accountId));
5817
+ return;
5818
+ }
5819
+
5820
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/intelligence-summary")) {
5821
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/intelligence-summary$/, "");
5822
+ sendJson(res, 200, buildEconomicsIntelligenceSummary(state, accountId));
5823
+ return;
5824
+ }
5825
+
5826
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/treasury-intelligence-summary")) {
5827
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/treasury-intelligence-summary$/, "");
5828
+ sendJson(res, 200, buildTreasuryIntelligenceSummary(state, accountId));
5829
+ return;
5830
+ }
5831
+
5760
5832
  if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/metering-summary")) {
5761
5833
  const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/metering-summary$/, "");
5762
5834
  sendJson(res, 200, buildUsageMeteringSummary(state, accountId));