xytara 3.1.0 → 3.1.2
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/.env.example +67 -58
- package/ADAPTER_START_HERE.md +56 -56
- package/CARRIED_HANDOFF_DEMO.md +60 -60
- package/EXAMPLE_PATHS.md +53 -53
- package/FINAL_CONTRACT.md +498 -498
- package/LICENSE +201 -201
- package/NOTICE +3 -3
- package/PARTNER_READY_PATH.md +71 -71
- package/PUBLIC_DEMO_SCRIPT.md +78 -78
- package/README.md +6 -1
- package/REAL_PAYMENT_SETUP.md +32 -3
- package/RELEASE_NOTES.md +14 -14
- package/SERVICE_CONTRACT.md +419 -419
- package/START_HERE.md +1 -1
- package/SUPABASE_RUNTIME_STATE_SETUP.md +61 -61
- package/TERMINOLOGY.md +50 -50
- package/WHY_XYTARA_XOONYA.md +63 -63
- package/XT1_EXECUTION_TRUTH_STANDARD.md +78 -78
- package/XYTARA_ADAPTER_PROTOCOL_TRUTH_MODEL.md +75 -75
- package/XYTARA_AUTONOMOUS_ENTRY_MODEL.md +124 -124
- package/XYTARA_DEFAULT_PATH_MODEL.md +84 -84
- package/XYTARA_EXECUTION_TRUTH_MODEL.md +171 -171
- package/XYTARA_PAYMENT_RAIL_TRUTH_MODEL.md +68 -68
- package/adapters/AUTHORING_GUIDE.md +243 -243
- package/adapters/ONBOARDING_POSTURE.md +61 -61
- package/adapters/THIRD_PARTY_SUBMISSION_PROCESS.md +84 -84
- package/adapters/adapter-manifest.schema.json +283 -283
- package/adapters/examples/example-execution-adapter.js +61 -61
- package/adapters/examples/example-execution-adapter.manifest.json +81 -81
- package/adapters/examples/example-settlement-adapter.js +55 -55
- package/adapters/examples/example-settlement-adapter.manifest.json +78 -78
- package/adapters/examples/example-third-party-acp-registration.submission-bundle.json +124 -124
- package/adapters/examples/example-third-party-erc8004-registration.submission-bundle.json +121 -121
- package/adapters/examples/example-third-party-identity-registration.certification-pack.json +22 -22
- package/adapters/examples/example-third-party-identity-registration.record.json +26 -26
- package/adapters/examples/example-third-party-identity-registration.submission-bundle.json +126 -126
- package/adapters/examples/example-third-party-langchain-registration.submission-bundle.json +124 -124
- package/adapters/examples/example-third-party-mpp-registration.submission-bundle.json +120 -120
- package/adapters/examples/example-third-party-registration.certification-pack.json +22 -22
- package/adapters/examples/example-third-party-registration.record.json +28 -28
- package/adapters/examples/example-third-party-registration.submission-bundle.json +126 -126
- package/adapters/examples/example-third-party-settlement-registration.certification-pack.json +22 -22
- package/adapters/examples/example-third-party-settlement-registration.record.json +26 -26
- package/adapters/examples/example-third-party-settlement-registration.submission-bundle.json +127 -127
- package/adapters/examples/langchain-reference-execution-adapter.js +81 -81
- package/adapters/examples/langchain-reference-execution-adapter.manifest.json +79 -79
- package/adapters/examples/langgraph-reference-execution-adapter.js +81 -81
- package/adapters/examples/langgraph-reference-execution-adapter.manifest.json +79 -79
- package/adapters/examples/minimal-third-party-execution-adapter.js +61 -61
- package/adapters/examples/minimal-third-party-execution-adapter.manifest.json +79 -79
- package/adapters/examples/minimal-third-party-execution-registration.record.json +26 -26
- package/adapters/examples/minimal-third-party-execution.certification-pack.json +22 -22
- package/adapters/examples/minimal-third-party-execution.submission-bundle.json +126 -126
- package/adapters/integration-certification-pack.schema.json +82 -82
- package/adapters/integration-registration-record.schema.json +114 -114
- package/adapters/integration-submission-bundle-set.schema.json +39 -39
- package/adapters/integration-submission-bundle.schema.json +34 -34
- package/adapters/interfaces.js +56 -56
- package/bin/xytara-first-run.js +244 -244
- package/bin/xytara-release.js +1429 -1429
- package/bin/xytara-run.js +186 -186
- package/bin/xytara.js +80 -80
- package/client.js +3 -3
- package/examples/_demo_env.js +40 -0
- package/examples/adapter_review_walkthrough.js +54 -53
- package/examples/export_carried_handoff.js +81 -80
- package/examples/funded_runtime_walkthrough.js +71 -70
- package/examples/generated.carried-handoff.json +30 -0
- package/examples/partner_launch_walkthrough.js +44 -43
- package/examples/quickstart.js +3256 -3255
- package/fixtures/catalog.js +1134 -1134
- package/index.js +395 -395
- package/integrations/dispatch.js +276 -276
- package/integrations/registry-snapshot.schema.json +36 -36
- package/integrations/registry.js +2261 -2261
- package/integrations/views.js +28 -28
- package/lib/a2a_lane_contract.js +104 -104
- package/lib/a2c_lane_contract.js +111 -111
- package/lib/account_auth.js +518 -518
- package/lib/acp_lane_contract.js +54 -54
- package/lib/activity_audit_contract.js +322 -322
- package/lib/adapter_certification_contract.js +130 -130
- package/lib/adapter_depth_contract.js +156 -156
- package/lib/adapter_pack.js +118 -118
- package/lib/adapter_partner_pack.js +89 -89
- package/lib/adapter_promotion_pack.js +89 -89
- package/lib/adapter_protocol_truth_contract.js +229 -229
- package/lib/announcement_pack.js +61 -61
- package/lib/artifact_distribution_lane_contract.js +54 -54
- package/lib/asyncapi_contract.js +150 -150
- package/lib/auth_interop_contract.js +80 -80
- package/lib/authority_binding_lifecycle_contract.js +182 -182
- package/lib/autonomous_entry_contract.js +409 -409
- package/lib/bolt_lane_contract.js +55 -55
- package/lib/bolt_payment_front.js +172 -172
- package/lib/business_cockpit.js +378 -378
- package/lib/capability_execution_truth.js +272 -272
- package/lib/capability_registry.js +633 -633
- package/lib/catalog_contract.js +966 -966
- package/lib/catalog_family_model.js +193 -193
- package/lib/catalog_views.js +55 -55
- package/lib/checkout_event_security.js +142 -142
- package/lib/cloudevents_contract.js +80 -80
- package/lib/command_flow.js +411 -406
- package/lib/commerce_artifacts.js +503 -503
- package/lib/commerce_authority.js +449 -449
- package/lib/commerce_cases.js +317 -317
- package/lib/commerce_checkout.js +509 -509
- package/lib/commerce_client.js +7687 -7676
- package/lib/commerce_coordination.js +346 -346
- package/lib/commerce_economics.js +4017 -4016
- package/lib/commerce_identity.js +578 -578
- package/lib/commerce_quotes.js +237 -237
- package/lib/commerce_reports.js +14461 -14461
- package/lib/commerce_runtime.js +315 -315
- package/lib/commerce_shell.js +257 -257
- package/lib/crypto_agility_matrix.js +125 -125
- package/lib/default_path_contract.js +412 -412
- package/lib/delivery_summary_contract.js +95 -95
- package/lib/ecosystem_entry.js +64 -64
- package/lib/erc8004_lane_contract.js +65 -65
- package/lib/event_system_lane_contract.js +75 -75
- package/lib/execution_truth_contract.js +234 -234
- package/lib/external_credit_bridge.js +142 -142
- package/lib/external_execution_runtime.js +132 -132
- package/lib/feature_control_lane_contract.js +54 -54
- package/lib/first_run_conversion_contract.js +290 -290
- package/lib/framework_lane_contract.js +89 -89
- package/lib/framework_provider_promotion.js +235 -235
- package/lib/full_catalog_contract.js +525 -525
- package/lib/go_live_operator_pack.js +391 -391
- package/lib/http_transport.js +73 -73
- package/lib/identity_auth.js +175 -175
- package/lib/identity_interop_contract.js +82 -82
- package/lib/integration_matrix_contract.js +102 -102
- package/lib/l402_lane_contract.js +55 -55
- package/lib/l402_payment_front.js +192 -192
- package/lib/launch_narrative.js +53 -53
- package/lib/lifecycle_continuity_contract.js +115 -115
- package/lib/machine_identity_registry_contract.js +199 -199
- package/lib/major_rails_lane_contract.js +150 -150
- package/lib/market_lane_contract.js +467 -467
- package/lib/market_lane_depth_contract.js +182 -182
- package/lib/market_lane_promotion_contract.js +210 -210
- package/lib/market_lane_trace_contract.js +278 -278
- package/lib/mcp_lane_contract.js +137 -137
- package/lib/network_transport.js +110 -110
- package/lib/offline_verifiability_recovery_contract.js +155 -155
- package/lib/openapi_contract.js +296 -296
- package/lib/operational_receipt_contract.js +165 -165
- package/lib/operator_intelligence.js +407 -407
- package/lib/outreach_copy_pack.js +51 -51
- package/lib/outreach_message_pack.js +71 -71
- package/lib/outreach_proof.js +71 -71
- package/lib/outreach_target_pack.js +60 -60
- package/lib/partner_intelligence.js +105 -105
- package/lib/payment_config.js +239 -191
- package/lib/payment_front_registry.js +53 -53
- package/lib/payment_protocol_contract.js +165 -165
- package/lib/payment_rail_truth_contract.js +324 -324
- package/lib/payment_verification.js +312 -264
- package/lib/phase_10_closeout_pack.js +45 -45
- package/lib/phase_10_completion_pack.js +76 -76
- package/lib/phase_10_decision_record_pack.js +54 -54
- package/lib/phase_10_decision_resolution_pack.js +53 -53
- package/lib/phase_10_demand_signal_adapters_runtime_pack.js +74 -74
- package/lib/phase_10_ecosystem_backlog_triage_runtime_pack.js +74 -74
- package/lib/phase_10_freeze_baseline_pack.js +67 -67
- package/lib/phase_10_freeze_review_pack.js +64 -64
- package/lib/phase_10_gate_pack.js +57 -57
- package/lib/phase_10_long_tail_continuity_pack.js +80 -80
- package/lib/phase_10_long_tail_ecosystem_pack.js +66 -66
- package/lib/phase_10_niche_extension_registry_runtime_pack.js +74 -74
- package/lib/phase_1_claude_mcp_pack.js +60 -60
- package/lib/phase_1_claude_mcp_runtime_pack.js +52 -52
- package/lib/phase_1_ecosystem_pack.js +67 -67
- package/lib/phase_1_openai_codex_pack.js +60 -60
- package/lib/phase_1_openai_codex_runtime_pack.js +52 -52
- package/lib/phase_2_base_runtime_pack.js +71 -71
- package/lib/phase_2_base_usdc_runtime_pack.js +72 -72
- package/lib/phase_2_closeout_pack.js +65 -65
- package/lib/phase_2_completion_pack.js +113 -113
- package/lib/phase_2_decision_record_pack.js +66 -66
- package/lib/phase_2_decision_resolution_pack.js +69 -69
- package/lib/phase_2_eth_runtime_pack.js +70 -70
- package/lib/phase_2_evm_base_runtime_pack.js +73 -73
- package/lib/phase_2_evm_runtime_pack.js +71 -71
- package/lib/phase_2_flip_preview_pack.js +60 -60
- package/lib/phase_2_freeze_review_pack.js +99 -99
- package/lib/phase_2_gate_pack.js +77 -77
- package/lib/phase_2_payment_rails_pack.js +71 -71
- package/lib/phase_2_usdc_runtime_pack.js +71 -71
- package/lib/phase_3_brc_runtime_pack.js +81 -81
- package/lib/phase_3_bsv_teranode_runtime_pack.js +83 -83
- package/lib/phase_3_closeout_pack.js +62 -62
- package/lib/phase_3_completion_pack.js +94 -94
- package/lib/phase_3_decision_record_pack.js +64 -64
- package/lib/phase_3_decision_resolution_pack.js +69 -69
- package/lib/phase_3_freeze_baseline_pack.js +67 -67
- package/lib/phase_3_freeze_review_pack.js +80 -80
- package/lib/phase_3_gate_pack.js +76 -76
- package/lib/phase_3_metanet_runtime_pack.js +81 -81
- package/lib/phase_3_native_bsv_pack.js +91 -91
- package/lib/phase_3_native_continuity_pack.js +82 -82
- package/lib/phase_4_attestation_runtime_pack.js +75 -75
- package/lib/phase_4_closeout_pack.js +45 -45
- package/lib/phase_4_completion_pack.js +94 -94
- package/lib/phase_4_decision_record_pack.js +54 -54
- package/lib/phase_4_decision_resolution_pack.js +45 -45
- package/lib/phase_4_erc8004_runtime_pack.js +76 -76
- package/lib/phase_4_freeze_baseline_pack.js +67 -67
- package/lib/phase_4_freeze_review_pack.js +68 -68
- package/lib/phase_4_gate_pack.js +58 -58
- package/lib/phase_4_identity_registry_runtime_pack.js +75 -75
- package/lib/phase_4_identity_trust_pack.js +73 -73
- package/lib/phase_4_trust_continuity_pack.js +86 -86
- package/lib/phase_5_antelope_runtime_pack.js +76 -76
- package/lib/phase_5_closeout_pack.js +44 -44
- package/lib/phase_5_completion_pack.js +82 -82
- package/lib/phase_5_constellation_dag_runtime_pack.js +76 -76
- package/lib/phase_5_decision_record_pack.js +54 -54
- package/lib/phase_5_decision_resolution_pack.js +45 -45
- package/lib/phase_5_digibyte_dgb_runtime_pack.js +76 -76
- package/lib/phase_5_freeze_baseline_pack.js +67 -67
- package/lib/phase_5_freeze_review_pack.js +68 -68
- package/lib/phase_5_gate_pack.js +58 -58
- package/lib/phase_5_hedera_hbar_runtime_pack.js +76 -76
- package/lib/phase_5_kaspa_kas_runtime_pack.js +76 -76
- package/lib/phase_5_major_rails_continuity_pack.js +86 -86
- package/lib/phase_5_major_rails_pack.js +110 -110
- package/lib/phase_5_metal_runtime_pack.js +76 -76
- package/lib/phase_5_polkadot_dot_runtime_pack.js +76 -76
- package/lib/phase_5_proton_xpr_runtime_pack.js +76 -76
- package/lib/phase_5_solana_runtime_pack.js +76 -76
- package/lib/phase_6_autogen_runtime_pack.js +72 -72
- package/lib/phase_6_closeout_pack.js +46 -46
- package/lib/phase_6_completion_pack.js +77 -77
- package/lib/phase_6_decision_record_pack.js +54 -54
- package/lib/phase_6_decision_resolution_pack.js +53 -53
- package/lib/phase_6_framework_continuity_pack.js +81 -81
- package/lib/phase_6_framework_runtime_pack.js +68 -68
- package/lib/phase_6_freeze_baseline_pack.js +68 -68
- package/lib/phase_6_freeze_review_pack.js +65 -65
- package/lib/phase_6_gate_pack.js +59 -59
- package/lib/phase_6_langchain_runtime_pack.js +72 -72
- package/lib/phase_6_langgraph_runtime_pack.js +72 -72
- package/lib/phase_6_semantic_kernel_runtime_pack.js +72 -72
- package/lib/phase_7_closeout_pack.js +45 -45
- package/lib/phase_7_completion_pack.js +85 -85
- package/lib/phase_7_decision_record_pack.js +53 -53
- package/lib/phase_7_decision_resolution_pack.js +53 -53
- package/lib/phase_7_event_system_continuity_pack.js +89 -89
- package/lib/phase_7_event_system_pack.js +76 -76
- package/lib/phase_7_freeze_baseline_pack.js +74 -74
- package/lib/phase_7_freeze_review_pack.js +65 -65
- package/lib/phase_7_gate_pack.js +58 -58
- package/lib/phase_7_kafka_runtime_pack.js +74 -74
- package/lib/phase_7_mqtt_runtime_pack.js +74 -74
- package/lib/phase_7_nats_runtime_pack.js +74 -74
- package/lib/phase_7_webhook_event_bus_runtime_pack.js +74 -74
- package/lib/phase_8_closeout_pack.js +46 -46
- package/lib/phase_8_completion_pack.js +82 -82
- package/lib/phase_8_decision_record_pack.js +54 -54
- package/lib/phase_8_decision_resolution_pack.js +53 -53
- package/lib/phase_8_external_receipt_import_runtime_pack.js +74 -74
- package/lib/phase_8_external_result_import_runtime_pack.js +74 -74
- package/lib/phase_8_freeze_baseline_pack.js +71 -71
- package/lib/phase_8_freeze_review_pack.js +64 -64
- package/lib/phase_8_gate_pack.js +58 -58
- package/lib/phase_8_proof_bridge_continuity_pack.js +86 -86
- package/lib/phase_8_proof_bridges_pack.js +72 -72
- package/lib/phase_8_proof_bundle_normalization_runtime_pack.js +74 -74
- package/lib/phase_9_closeout_pack.js +46 -46
- package/lib/phase_9_completion_pack.js +82 -82
- package/lib/phase_9_custody_refs_runtime_pack.js +74 -74
- package/lib/phase_9_decision_record_pack.js +54 -54
- package/lib/phase_9_decision_resolution_pack.js +53 -53
- package/lib/phase_9_freeze_baseline_pack.js +71 -71
- package/lib/phase_9_freeze_review_pack.js +64 -64
- package/lib/phase_9_gate_pack.js +58 -58
- package/lib/phase_9_operator_accounting_bridges_runtime_pack.js +74 -74
- package/lib/phase_9_treasury_connectivity_pack.js +72 -72
- package/lib/phase_9_treasury_continuity_pack.js +86 -86
- package/lib/phase_9_treasury_destinations_runtime_pack.js +74 -74
- package/lib/phase_program_pack.js +120 -120
- package/lib/pricing_optimization_contract.js +775 -775
- package/lib/protocol_lane_contract.js +117 -117
- package/lib/provenance_lane_contract.js +54 -54
- package/lib/provider_lane_contract.js +240 -240
- package/lib/provider_runtime_journey_contract.js +183 -183
- package/lib/public_surface_policy_contract.js +111 -111
- package/lib/publish_plan.js +51 -51
- package/lib/record_queries.js +48 -48
- package/lib/release_candidate.js +50 -50
- package/lib/release_center.js +1093 -1093
- package/lib/release_history.js +205 -205
- package/lib/release_manifest.js +113 -113
- package/lib/release_pack.js +453 -453
- package/lib/request_rate_limit.js +144 -144
- package/lib/resource_views.js +31 -31
- package/lib/revenue_launch_path_contract.js +326 -326
- package/lib/route_matchers.js +34 -34
- package/lib/route_params.js +19 -19
- package/lib/runtime_bridge.js +124 -124
- package/lib/runtime_operations_worker.js +282 -282
- package/lib/runtime_state_store.js +354 -354
- package/lib/settlement_lane_contract.js +111 -111
- package/lib/shared_signals_lane_contract.js +54 -54
- package/lib/signed_audit_provenance_contract.js +83 -83
- package/lib/soft_launch_pack.js +78 -78
- package/lib/stablecoin_lane_contract.js +76 -76
- package/lib/stripe_mpp_lane_contract.js +96 -96
- package/lib/stripe_mpp_payment_front.js +158 -158
- package/lib/telemetry_lane_contract.js +54 -54
- package/lib/treasury_destinations_contract.js +764 -764
- package/lib/treasury_egress_policy_contract.js +91 -91
- package/lib/treasury_lane_contract.js +84 -84
- package/lib/trust_portability_boundary_contract.js +72 -72
- package/lib/x402_facilitator.js +155 -0
- package/lib/x402_lane_contract.js +118 -118
- package/package.json +106 -105
- package/scripts/registry_cli.js +275 -275
- package/scripts/verify_adapters.js +554 -554
- package/scripts/verify_all.js +4962 -4962
- package/scripts/verify_control_plane_contracts.js +34 -34
- package/scripts/verify_control_plane_routes.js +70 -70
- package/scripts/verify_delivery_summary.js +112 -112
- package/scripts/verify_examples.js +19 -19
- package/scripts/verify_first_run_conversions.js +81 -81
- package/scripts/verify_framework_provider_promotion.js +152 -152
- package/scripts/verify_full_catalog.js +174 -174
- package/scripts/verify_integrations.js +620 -620
- package/scripts/verify_lifecycle_continuity.js +96 -96
- package/scripts/verify_market_lane_depth.js +94 -94
- package/scripts/verify_market_lane_promotion.js +103 -103
- package/scripts/verify_market_lane_traces.js +98 -98
- package/scripts/verify_market_lanes.js +102 -102
- package/scripts/verify_operator_observability_boundary.js +83 -83
- package/scripts/verify_pricing_experiment_plan.js +124 -124
- package/scripts/verify_provider_runtime_breadth.js +109 -109
- package/scripts/verify_provider_runtime_journeys.js +111 -111
- package/scripts/verify_revenue_launch_paths.js +105 -105
- package/scripts/verify_runtime_durability.js +52 -52
- package/scripts/verify_service.js +15410 -15250
- package/scripts/verify_tooling.js +1412 -1412
- package/scripts/verify_treasury_public_boundary.js +97 -97
- package/scripts/verify_x402_facilitator.js +174 -0
- package/server.js +11117 -11006
- package/.env.production.checklist +0 -77
- package/.env.production.template +0 -54
- package/.github/workflows/publish-mcp-executor.yml +0 -43
- package/ADAPTER_PARTNER_PATH.md +0 -47
- package/ADAPTER_PROMOTION_START_HERE.md +0 -44
- package/BOLT_BINDINGS.production.worksheet.json +0 -31
- package/EXECUTION_TARGETS.production.worksheet.json +0 -73
- package/GO_LIVE_OPERATOR_PACK.md +0 -412
- package/L402_BINDINGS.production.worksheet.json +0 -30
- package/OPERATIONS_RUNBOOK.md +0 -115
- package/OPERATOR_START_HERE.md +0 -63
- package/OUTREACH_MESSAGES.md +0 -19
- package/OUTREACH_START_HERE.md +0 -36
- package/PRODUCTION_MANUAL_CLOSEOUT_SEQUENCE.md +0 -172
- package/PROGRAM_COMPLETE_RELEASE.md +0 -63
- package/PROGRAM_STATUS.md +0 -57
- package/PUBLISH_PLAN.md +0 -26
- package/RELEASE_CHECKLIST.md +0 -16
- package/SOFT_LAUNCH_KIT.md +0 -47
- package/services/mcp-execution-target/DISCOVERY_REGISTRY_PLAYBOOK.md +0 -141
- package/services/mcp-execution-target/README.md +0 -319
- package/services/mcp-execution-target/package.json +0 -14
- package/services/mcp-execution-target/server.js +0 -1031
- package/services/mcp-execution-target/server.json +0 -16
- package/services/mcp-execution-target/verify.js +0 -308
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const assert = require("assert");
|
|
4
|
-
const {
|
|
5
|
-
buildOperatorTreasuryDestinationsPack,
|
|
6
|
-
buildTreasuryDestinationsPack,
|
|
7
|
-
validateTreasuryDestinationPublicBoundary
|
|
8
|
-
} = require("../lib/treasury_destinations_contract");
|
|
9
|
-
|
|
10
|
-
function clone(value) {
|
|
11
|
-
return JSON.parse(JSON.stringify(value));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function assertRejected(pack, expectedCode) {
|
|
15
|
-
const validation = validateTreasuryDestinationPublicBoundary(pack);
|
|
16
|
-
assert.strictEqual(validation.public_boundary_valid, false, `expected ${expectedCode} to block treasury public boundary`);
|
|
17
|
-
assert.strictEqual(
|
|
18
|
-
validation.rejection_codes.includes(expectedCode),
|
|
19
|
-
true,
|
|
20
|
-
`missing deterministic rejection code ${expectedCode}`
|
|
21
|
-
);
|
|
22
|
-
return validation;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function main() {
|
|
26
|
-
const publicPack = buildTreasuryDestinationsPack();
|
|
27
|
-
const operatorPack = buildOperatorTreasuryDestinationsPack();
|
|
28
|
-
const publicValidation = validateTreasuryDestinationPublicBoundary(publicPack);
|
|
29
|
-
const operatorValidation = validateTreasuryDestinationPublicBoundary(operatorPack);
|
|
30
|
-
|
|
31
|
-
assert.strictEqual(publicPack.category, "machine-commerce-treasury-destinations-pack", "public treasury pack category mismatch");
|
|
32
|
-
assert.strictEqual(publicValidation.public_boundary_valid, true, "public treasury boundary should validate");
|
|
33
|
-
assert.deepStrictEqual(publicValidation.rejection_codes, [], "public treasury boundary should not carry rejections");
|
|
34
|
-
assert.strictEqual(operatorValidation.public_boundary_valid, true, "operator treasury boundary should validate");
|
|
35
|
-
assert.strictEqual(publicValidation.deterministic_rejection_codes.length >= 11, true, "treasury rejection code count missing");
|
|
36
|
-
|
|
37
|
-
const custodyLeak = clone(publicPack);
|
|
38
|
-
custodyLeak.profiles[0].custody_destination = {
|
|
39
|
-
external_ref: "bsv://real-merchant-treasury"
|
|
40
|
-
};
|
|
41
|
-
assertRejected(custodyLeak, "public_custody_destination_leak");
|
|
42
|
-
|
|
43
|
-
const externalRefLeak = clone(publicPack);
|
|
44
|
-
externalRefLeak.profiles[0].destination_visibility.external_ref = "bsv://real-merchant-treasury";
|
|
45
|
-
assertRejected(externalRefLeak, "public_external_ref_leak");
|
|
46
|
-
|
|
47
|
-
const custodyRefLeak = clone(publicPack);
|
|
48
|
-
custodyRefLeak.profiles[0].custody_ref = "vault://private";
|
|
49
|
-
assertRejected(custodyRefLeak, "public_custody_ref_leak");
|
|
50
|
-
|
|
51
|
-
const reportingRefLeak = clone(publicPack);
|
|
52
|
-
reportingRefLeak.profiles[0].destination_visibility.reporting_ref = "ledger://private";
|
|
53
|
-
assertRejected(reportingRefLeak, "public_reporting_ref_leak");
|
|
54
|
-
|
|
55
|
-
const walletRefLeak = clone(publicPack);
|
|
56
|
-
walletRefLeak.profiles[0].wallet_ref = "wallet://private";
|
|
57
|
-
assertRejected(walletRefLeak, "public_wallet_ref_leak");
|
|
58
|
-
|
|
59
|
-
const providerRefLeak = clone(publicPack);
|
|
60
|
-
providerRefLeak.profiles[0].destination_visibility.provider_ref = "rpc://private";
|
|
61
|
-
assertRejected(providerRefLeak, "public_provider_ref_leak");
|
|
62
|
-
|
|
63
|
-
const internalClaim = clone(publicPack);
|
|
64
|
-
const moneroProfile = internalClaim.profiles.find((entry) => entry.rail_id === "monero");
|
|
65
|
-
moneroProfile.public_claim_allowed = true;
|
|
66
|
-
assertRejected(internalClaim, "internal_rail_public_claimed");
|
|
67
|
-
|
|
68
|
-
const readinessClaim = clone(publicPack);
|
|
69
|
-
readinessClaim.public_claim_boundary.readiness_only_rails = [readinessClaim.profiles[0].rail_id];
|
|
70
|
-
readinessClaim.profiles[0].public_claim_allowed = true;
|
|
71
|
-
assertRejected(readinessClaim, "readiness_only_rail_public_claimed");
|
|
72
|
-
|
|
73
|
-
const boundaryMismatch = clone(publicPack);
|
|
74
|
-
boundaryMismatch.public_claim_boundary.internal_only_rails = [];
|
|
75
|
-
assertRejected(boundaryMismatch, "claim_boundary_mismatch");
|
|
76
|
-
|
|
77
|
-
const unsupportedLiveRail = clone(publicPack);
|
|
78
|
-
unsupportedLiveRail.public_claim_boundary.live_claimable_rails = ["made_up_rail"];
|
|
79
|
-
assertRejected(unsupportedLiveRail, "unsupported_live_claim_rail");
|
|
80
|
-
|
|
81
|
-
const operatorRuleMissing = clone(operatorPack);
|
|
82
|
-
operatorRuleMissing.custody_visibility_rule = "unsafe";
|
|
83
|
-
assertRejected(operatorRuleMissing, "operator_visibility_rule_missing");
|
|
84
|
-
|
|
85
|
-
const output = {
|
|
86
|
-
ok: true,
|
|
87
|
-
product: "xytara",
|
|
88
|
-
category: "xytara-treasury-public-boundary-verification",
|
|
89
|
-
status: "treasury_public_surfaces_do_not_leak_landing_or_custody_refs_and_claim_boundary_matches_profiles",
|
|
90
|
-
deterministic_rejection_code_count: publicValidation.deterministic_rejection_codes.length,
|
|
91
|
-
adversarial_case_count: 11,
|
|
92
|
-
boundary: publicValidation.boundary
|
|
93
|
-
};
|
|
94
|
-
process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
main();
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
const {
|
|
5
|
+
buildOperatorTreasuryDestinationsPack,
|
|
6
|
+
buildTreasuryDestinationsPack,
|
|
7
|
+
validateTreasuryDestinationPublicBoundary
|
|
8
|
+
} = require("../lib/treasury_destinations_contract");
|
|
9
|
+
|
|
10
|
+
function clone(value) {
|
|
11
|
+
return JSON.parse(JSON.stringify(value));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function assertRejected(pack, expectedCode) {
|
|
15
|
+
const validation = validateTreasuryDestinationPublicBoundary(pack);
|
|
16
|
+
assert.strictEqual(validation.public_boundary_valid, false, `expected ${expectedCode} to block treasury public boundary`);
|
|
17
|
+
assert.strictEqual(
|
|
18
|
+
validation.rejection_codes.includes(expectedCode),
|
|
19
|
+
true,
|
|
20
|
+
`missing deterministic rejection code ${expectedCode}`
|
|
21
|
+
);
|
|
22
|
+
return validation;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function main() {
|
|
26
|
+
const publicPack = buildTreasuryDestinationsPack();
|
|
27
|
+
const operatorPack = buildOperatorTreasuryDestinationsPack();
|
|
28
|
+
const publicValidation = validateTreasuryDestinationPublicBoundary(publicPack);
|
|
29
|
+
const operatorValidation = validateTreasuryDestinationPublicBoundary(operatorPack);
|
|
30
|
+
|
|
31
|
+
assert.strictEqual(publicPack.category, "machine-commerce-treasury-destinations-pack", "public treasury pack category mismatch");
|
|
32
|
+
assert.strictEqual(publicValidation.public_boundary_valid, true, "public treasury boundary should validate");
|
|
33
|
+
assert.deepStrictEqual(publicValidation.rejection_codes, [], "public treasury boundary should not carry rejections");
|
|
34
|
+
assert.strictEqual(operatorValidation.public_boundary_valid, true, "operator treasury boundary should validate");
|
|
35
|
+
assert.strictEqual(publicValidation.deterministic_rejection_codes.length >= 11, true, "treasury rejection code count missing");
|
|
36
|
+
|
|
37
|
+
const custodyLeak = clone(publicPack);
|
|
38
|
+
custodyLeak.profiles[0].custody_destination = {
|
|
39
|
+
external_ref: "bsv://real-merchant-treasury"
|
|
40
|
+
};
|
|
41
|
+
assertRejected(custodyLeak, "public_custody_destination_leak");
|
|
42
|
+
|
|
43
|
+
const externalRefLeak = clone(publicPack);
|
|
44
|
+
externalRefLeak.profiles[0].destination_visibility.external_ref = "bsv://real-merchant-treasury";
|
|
45
|
+
assertRejected(externalRefLeak, "public_external_ref_leak");
|
|
46
|
+
|
|
47
|
+
const custodyRefLeak = clone(publicPack);
|
|
48
|
+
custodyRefLeak.profiles[0].custody_ref = "vault://private";
|
|
49
|
+
assertRejected(custodyRefLeak, "public_custody_ref_leak");
|
|
50
|
+
|
|
51
|
+
const reportingRefLeak = clone(publicPack);
|
|
52
|
+
reportingRefLeak.profiles[0].destination_visibility.reporting_ref = "ledger://private";
|
|
53
|
+
assertRejected(reportingRefLeak, "public_reporting_ref_leak");
|
|
54
|
+
|
|
55
|
+
const walletRefLeak = clone(publicPack);
|
|
56
|
+
walletRefLeak.profiles[0].wallet_ref = "wallet://private";
|
|
57
|
+
assertRejected(walletRefLeak, "public_wallet_ref_leak");
|
|
58
|
+
|
|
59
|
+
const providerRefLeak = clone(publicPack);
|
|
60
|
+
providerRefLeak.profiles[0].destination_visibility.provider_ref = "rpc://private";
|
|
61
|
+
assertRejected(providerRefLeak, "public_provider_ref_leak");
|
|
62
|
+
|
|
63
|
+
const internalClaim = clone(publicPack);
|
|
64
|
+
const moneroProfile = internalClaim.profiles.find((entry) => entry.rail_id === "monero");
|
|
65
|
+
moneroProfile.public_claim_allowed = true;
|
|
66
|
+
assertRejected(internalClaim, "internal_rail_public_claimed");
|
|
67
|
+
|
|
68
|
+
const readinessClaim = clone(publicPack);
|
|
69
|
+
readinessClaim.public_claim_boundary.readiness_only_rails = [readinessClaim.profiles[0].rail_id];
|
|
70
|
+
readinessClaim.profiles[0].public_claim_allowed = true;
|
|
71
|
+
assertRejected(readinessClaim, "readiness_only_rail_public_claimed");
|
|
72
|
+
|
|
73
|
+
const boundaryMismatch = clone(publicPack);
|
|
74
|
+
boundaryMismatch.public_claim_boundary.internal_only_rails = [];
|
|
75
|
+
assertRejected(boundaryMismatch, "claim_boundary_mismatch");
|
|
76
|
+
|
|
77
|
+
const unsupportedLiveRail = clone(publicPack);
|
|
78
|
+
unsupportedLiveRail.public_claim_boundary.live_claimable_rails = ["made_up_rail"];
|
|
79
|
+
assertRejected(unsupportedLiveRail, "unsupported_live_claim_rail");
|
|
80
|
+
|
|
81
|
+
const operatorRuleMissing = clone(operatorPack);
|
|
82
|
+
operatorRuleMissing.custody_visibility_rule = "unsafe";
|
|
83
|
+
assertRejected(operatorRuleMissing, "operator_visibility_rule_missing");
|
|
84
|
+
|
|
85
|
+
const output = {
|
|
86
|
+
ok: true,
|
|
87
|
+
product: "xytara",
|
|
88
|
+
category: "xytara-treasury-public-boundary-verification",
|
|
89
|
+
status: "treasury_public_surfaces_do_not_leak_landing_or_custody_refs_and_claim_boundary_matches_profiles",
|
|
90
|
+
deterministic_rejection_code_count: publicValidation.deterministic_rejection_codes.length,
|
|
91
|
+
adversarial_case_count: 11,
|
|
92
|
+
boundary: publicValidation.boundary
|
|
93
|
+
};
|
|
94
|
+
process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
main();
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Verifies the x402_facilitator payment mode end to end against a mock facilitator:
|
|
4
|
+
// - an unpaid x402 execute returns 402 and advertises the configured accepts
|
|
5
|
+
// - a well-formed payment is verified and settled, the command runs, and the
|
|
6
|
+
// response carries a PAYMENT-RESPONSE settlement receipt
|
|
7
|
+
// - malformed, mismatched, facilitator-rejected, and unsettled payments all 402
|
|
8
|
+
//
|
|
9
|
+
// No real network or chain is used; the mock facilitator stands in for x402.org.
|
|
10
|
+
|
|
11
|
+
const assert = require("assert");
|
|
12
|
+
const http = require("http");
|
|
13
|
+
|
|
14
|
+
const ACCEPTS = [
|
|
15
|
+
{
|
|
16
|
+
scheme: "exact",
|
|
17
|
+
network: "eip155:84532",
|
|
18
|
+
asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
19
|
+
amount: "1000",
|
|
20
|
+
payTo: "0x7cd2E0Ed2721319B20FAac4109774d030833F84D",
|
|
21
|
+
extra: { name: "USDC", version: "2" },
|
|
22
|
+
maxTimeoutSeconds: 60
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
function startMockFacilitator() {
|
|
27
|
+
const calls = { verify: 0, settle: 0 };
|
|
28
|
+
const server = http.createServer((req, res) => {
|
|
29
|
+
const chunks = [];
|
|
30
|
+
req.on("data", (c) => chunks.push(c));
|
|
31
|
+
req.on("end", () => {
|
|
32
|
+
let body = {};
|
|
33
|
+
try { body = JSON.parse(Buffer.concat(chunks).toString("utf8") || "{}"); } catch (_) { body = {}; }
|
|
34
|
+
const sig = body && body.paymentPayload && body.paymentPayload.payload ? String(body.paymentPayload.payload.signature || "") : "";
|
|
35
|
+
const reply = (payload) => {
|
|
36
|
+
const text = JSON.stringify(payload);
|
|
37
|
+
res.writeHead(200, { "content-type": "application/json", "content-length": Buffer.byteLength(text) });
|
|
38
|
+
res.end(text);
|
|
39
|
+
};
|
|
40
|
+
if (req.method === "POST" && req.url === "/verify") {
|
|
41
|
+
calls.verify += 1;
|
|
42
|
+
if (sig === "reject-me") return reply({ isValid: false, invalidReason: "invalid_signature" });
|
|
43
|
+
return reply({ isValid: true, payer: "0x1111111111111111111111111111111111111111" });
|
|
44
|
+
}
|
|
45
|
+
if (req.method === "POST" && req.url === "/settle") {
|
|
46
|
+
calls.settle += 1;
|
|
47
|
+
if (sig === "settle-fails") return reply({ success: false, errorReason: "insufficient_funds" });
|
|
48
|
+
return reply({ success: true, transaction: "0xmocktx", network: "eip155:84532", payer: "0x1111111111111111111111111111111111111111" });
|
|
49
|
+
}
|
|
50
|
+
res.writeHead(404); res.end();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
return new Promise((resolve) => server.listen(0, "127.0.0.1", () => resolve({ server, calls, port: server.address().port })));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function paymentHeader(signature, overrides = {}) {
|
|
57
|
+
const accepted = ACCEPTS[0];
|
|
58
|
+
return Buffer.from(JSON.stringify({
|
|
59
|
+
x402Version: 2,
|
|
60
|
+
accepted: { ...accepted, ...overrides.accepted },
|
|
61
|
+
payload: {
|
|
62
|
+
signature,
|
|
63
|
+
authorization: {
|
|
64
|
+
from: "0x1111111111111111111111111111111111111111",
|
|
65
|
+
to: accepted.payTo,
|
|
66
|
+
value: accepted.amount,
|
|
67
|
+
validAfter: "0",
|
|
68
|
+
validBefore: String(Math.floor(Date.now() / 1000) + 600),
|
|
69
|
+
nonce: `0x${"ab".repeat(32)}`
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}), "utf8").toString("base64");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function post(baseUrl, path, body, headers = {}) {
|
|
76
|
+
const res = await fetch(`${baseUrl}${path}`, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: { "content-type": "application/json", ...headers },
|
|
79
|
+
body: JSON.stringify(body)
|
|
80
|
+
});
|
|
81
|
+
let json = null;
|
|
82
|
+
try { json = await res.json(); } catch (_) { json = null; }
|
|
83
|
+
return { status: res.status, json, headers: res.headers };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function main() {
|
|
87
|
+
const facilitator = await startMockFacilitator();
|
|
88
|
+
const previous = {
|
|
89
|
+
mode: process.env.XYTARA_PAYMENT_VERIFICATION_MODE,
|
|
90
|
+
accepts: process.env.XYTARA_X402_ACCEPTS_JSON,
|
|
91
|
+
facUrl: process.env.XYTARA_X402_FACILITATOR_URL
|
|
92
|
+
};
|
|
93
|
+
process.env.XYTARA_PAYMENT_VERIFICATION_MODE = "x402_facilitator";
|
|
94
|
+
process.env.XYTARA_X402_ACCEPTS_JSON = JSON.stringify(ACCEPTS);
|
|
95
|
+
process.env.XYTARA_X402_FACILITATOR_URL = `http://127.0.0.1:${facilitator.port}`;
|
|
96
|
+
|
|
97
|
+
delete require.cache[require.resolve("../server")];
|
|
98
|
+
const { createServer } = require("../server");
|
|
99
|
+
const server = createServer();
|
|
100
|
+
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
|
101
|
+
const baseUrl = `http://127.0.0.1:${server.address().port}`;
|
|
102
|
+
const execBody = { account_id: "acct_x402", command: "x402 facilitator demo", task_ref: "trust.verify", body: { subject_id: "s-1" } };
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
// 1. Unpaid -> 402 advertising accepts.
|
|
106
|
+
const unpaid = await post(baseUrl, "/x402/commands/execute", execBody);
|
|
107
|
+
assert.strictEqual(unpaid.status, 402, "unpaid x402 execute must return 402");
|
|
108
|
+
const required = unpaid.json && unpaid.json.payment_required;
|
|
109
|
+
assert.ok(required, "402 must carry payment_required");
|
|
110
|
+
assert.strictEqual(required.x402Version, 2, "challenge must be x402 v2");
|
|
111
|
+
assert.ok(Array.isArray(required.accepts) && required.accepts.length === 1, "challenge must advertise accepts");
|
|
112
|
+
assert.strictEqual(required.accepts[0].network, "eip155:84532", "advertised network mismatch");
|
|
113
|
+
assert.strictEqual(typeof unpaid.headers.get("payment-required"), "string", "PAYMENT-REQUIRED header missing");
|
|
114
|
+
|
|
115
|
+
// 2. Bogus header -> 402 payment_signature_invalid.
|
|
116
|
+
const bogus = await post(baseUrl, "/x402/commands/execute", execBody, { "payment-signature": "not-a-payment" });
|
|
117
|
+
assert.strictEqual(bogus.status, 402, "bogus payment header must 402");
|
|
118
|
+
assert.strictEqual(bogus.json.reason, "payment_signature_invalid", "bogus reason mismatch");
|
|
119
|
+
|
|
120
|
+
// 3. Mismatched requirements -> 402 before the facilitator.
|
|
121
|
+
const verifyBefore = facilitator.calls.verify;
|
|
122
|
+
const mismatch = await post(baseUrl, "/x402/commands/execute", execBody, { "payment-signature": paymentHeader("ok", { accepted: { amount: "9" } }) });
|
|
123
|
+
assert.strictEqual(mismatch.status, 402, "mismatched requirements must 402");
|
|
124
|
+
assert.strictEqual(mismatch.json.reason, "payment_requirements_mismatch", "mismatch reason");
|
|
125
|
+
assert.strictEqual(facilitator.calls.verify, verifyBefore, "facilitator must not be called on a requirements mismatch");
|
|
126
|
+
|
|
127
|
+
// 4. Facilitator rejects -> 402 payment_verification_failed.
|
|
128
|
+
const rejected = await post(baseUrl, "/x402/commands/execute", execBody, { "payment-signature": paymentHeader("reject-me") });
|
|
129
|
+
assert.strictEqual(rejected.status, 402, "facilitator-rejected payment must 402");
|
|
130
|
+
assert.strictEqual(rejected.json.reason, "payment_verification_failed", "rejection reason");
|
|
131
|
+
assert.strictEqual(rejected.json.detail, "invalid_signature", "rejection detail");
|
|
132
|
+
|
|
133
|
+
// 5. Settlement fails -> 402, no tool output.
|
|
134
|
+
const settleFails = await post(baseUrl, "/x402/commands/execute", execBody, { "payment-signature": paymentHeader("settle-fails") });
|
|
135
|
+
assert.strictEqual(settleFails.status, 402, "failed settlement must 402");
|
|
136
|
+
assert.strictEqual(settleFails.json.reason, "payment_settlement_failed", "settlement failure reason");
|
|
137
|
+
|
|
138
|
+
// 6. Verified + settled -> 200 with a result and a PAYMENT-RESPONSE receipt.
|
|
139
|
+
const settleBefore = facilitator.calls.settle;
|
|
140
|
+
const paid = await post(baseUrl, "/x402/commands/execute", execBody, { "payment-signature": paymentHeader("ok") });
|
|
141
|
+
assert.strictEqual(paid.status, 200, "verified+settled payment must 200");
|
|
142
|
+
assert.strictEqual(typeof paid.json.transaction.transaction_id, "string", "paid result missing transaction");
|
|
143
|
+
assert.strictEqual(paid.json.transaction.status, "completed", "paid transaction must be completed");
|
|
144
|
+
assert.strictEqual(paid.json.transaction.payment.verification_mode, "x402_facilitator", "verification mode not recorded");
|
|
145
|
+
assert.strictEqual(facilitator.calls.settle, settleBefore + 1, "facilitator settle must be called once");
|
|
146
|
+
const receiptHeader = paid.headers.get("payment-response");
|
|
147
|
+
assert.strictEqual(typeof receiptHeader, "string", "PAYMENT-RESPONSE header missing on a settled 200");
|
|
148
|
+
const receipt = JSON.parse(Buffer.from(receiptHeader, "base64").toString("utf8"));
|
|
149
|
+
assert.strictEqual(receipt.success, true, "settlement receipt must report success");
|
|
150
|
+
assert.strictEqual(receipt.transaction, "0xmocktx", "settlement receipt transaction mismatch");
|
|
151
|
+
|
|
152
|
+
// 7. Native routes must not be disabled by x402_facilitator: a native paid attempt
|
|
153
|
+
// falls back to local_signed semantics, never payment_verification_mode_unsupported.
|
|
154
|
+
const nativeAttempt = await post(baseUrl, "/v1/commands/execute", execBody, {
|
|
155
|
+
"x-wallet-id": "wallet-not-registered",
|
|
156
|
+
"x-payment": "encoded",
|
|
157
|
+
"x-payment-signature": "sig"
|
|
158
|
+
});
|
|
159
|
+
assert.notStrictEqual(nativeAttempt.json && nativeAttempt.json.reason, "payment_verification_mode_unsupported", "native route must fall back to local_signed under x402_facilitator");
|
|
160
|
+
|
|
161
|
+
console.log("xytara verify:x402-facilitator passed");
|
|
162
|
+
} finally {
|
|
163
|
+
await new Promise((resolve) => server.close(resolve));
|
|
164
|
+
await new Promise((resolve) => facilitator.server.close(resolve));
|
|
165
|
+
if (previous.mode === undefined) delete process.env.XYTARA_PAYMENT_VERIFICATION_MODE; else process.env.XYTARA_PAYMENT_VERIFICATION_MODE = previous.mode;
|
|
166
|
+
if (previous.accepts === undefined) delete process.env.XYTARA_X402_ACCEPTS_JSON; else process.env.XYTARA_X402_ACCEPTS_JSON = previous.accepts;
|
|
167
|
+
if (previous.facUrl === undefined) delete process.env.XYTARA_X402_FACILITATOR_URL; else process.env.XYTARA_X402_FACILITATOR_URL = previous.facUrl;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
main().catch((error) => {
|
|
172
|
+
console.error(error && error.message ? error.message : error);
|
|
173
|
+
process.exitCode = 1;
|
|
174
|
+
});
|