@01.software/cli 0.11.2 → 0.13.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.
@@ -26,49 +26,79 @@ var MCP_RESOURCE_INVENTORY = [
26
26
  {
27
27
  uri: "docs://sdk/getting-started",
28
28
  label: "getting-started",
29
- registeredName: "docs-getting-started"
29
+ registeredName: "docs-getting-started",
30
+ canonicalDocsSlug: ["developers", "sdk"],
31
+ canonicalDocsKeywords: ["Install the package", "@01.software/sdk"]
32
+ },
33
+ {
34
+ uri: "docs://sdk/guides",
35
+ label: "guides",
36
+ registeredName: "docs-guides",
37
+ canonicalDocsSlug: ["developers", "sdk"],
38
+ canonicalDocsKeywords: ["Setup Flow", "Next Actions"]
39
+ },
40
+ {
41
+ uri: "docs://sdk/api",
42
+ label: "api",
43
+ registeredName: "docs-api",
44
+ canonicalDocsSlug: ["developers", "api"],
45
+ canonicalDocsKeywords: ["/api/openapi", "OpenAPI"]
30
46
  },
31
- { uri: "docs://sdk/guides", label: "guides", registeredName: "docs-guides" },
32
- { uri: "docs://sdk/api", label: "api", registeredName: "docs-api" },
33
47
  {
34
48
  uri: "docs://sdk/query-builder",
35
49
  label: "query-builder",
36
- registeredName: "docs-query-builder"
50
+ registeredName: "docs-query-builder",
51
+ canonicalDocsSlug: ["developers", "sdk"],
52
+ canonicalDocsKeywords: ["query helpers", "@01.software/sdk/query"]
37
53
  },
38
54
  {
39
55
  uri: "docs://sdk/react-query",
40
56
  label: "react-query",
41
- registeredName: "docs-react-query"
57
+ registeredName: "docs-react-query",
58
+ canonicalDocsSlug: ["developers", "sdk"],
59
+ canonicalDocsKeywords: ["React", "@tanstack/react-query"]
42
60
  },
43
61
  {
44
62
  uri: "docs://sdk/server-api",
45
63
  label: "server-api",
46
- registeredName: "docs-server-api"
64
+ registeredName: "docs-server-api",
65
+ canonicalDocsSlug: ["developers", "api"],
66
+ canonicalDocsKeywords: ["Server writes", "trusted server credentials"]
47
67
  },
48
68
  {
49
69
  uri: "docs://sdk/customer-auth",
50
70
  label: "customer-auth",
51
- registeredName: "docs-customer-auth"
71
+ registeredName: "docs-customer-auth",
72
+ canonicalDocsSlug: ["developers", "authentication"],
73
+ canonicalDocsKeywords: ["Publishable Key", "Secret Key"]
52
74
  },
53
75
  {
54
76
  uri: "docs://sdk/browser-vs-server",
55
77
  label: "browser-vs-server",
56
- registeredName: "docs-browser-vs-server"
78
+ registeredName: "docs-browser-vs-server",
79
+ canonicalDocsSlug: ["developers", "sdk"],
80
+ canonicalDocsKeywords: ["browser client", "server client"]
57
81
  },
58
82
  {
59
83
  uri: "docs://sdk/file-upload",
60
84
  label: "file-upload",
61
- registeredName: "docs-file-upload"
85
+ registeredName: "docs-file-upload",
86
+ canonicalDocsSlug: ["developers", "api"],
87
+ canonicalDocsKeywords: ["direct HTTP", "machine-readable contract"]
62
88
  },
63
89
  {
64
90
  uri: "docs://sdk/webhook",
65
91
  label: "webhook",
66
- registeredName: "docs-webhook"
92
+ registeredName: "docs-webhook",
93
+ canonicalDocsSlug: ["developers", "webhooks"],
94
+ canonicalDocsKeywords: ["Webhook", "commerce.notification"]
67
95
  },
68
96
  {
69
97
  uri: "docs://sdk/product-detail",
70
98
  label: "product-detail",
71
- registeredName: "docs-product-detail"
99
+ registeredName: "docs-product-detail",
100
+ canonicalDocsSlug: ["recipes", "product-detail"],
101
+ canonicalDocsKeywords: ["Product detail page", "commerce.product.detail"]
72
102
  }
73
103
  ];
74
104
  var MCP_RESOURCE_LABELS = MCP_RESOURCE_INVENTORY.map(
@@ -336,7 +366,6 @@ var productFieldShape = {
336
366
  weight: z2.number().int().min(0).optional().nullable(),
337
367
  minOrderQuantity: z2.number().int().min(1).optional().nullable(),
338
368
  maxOrderQuantity: z2.number().int().min(1).optional().nullable(),
339
- listingPrimaryOption: IdSchema.optional().nullable(),
340
369
  isFeatured: z2.boolean().optional(),
341
370
  publishedAt: z2.string().optional().nullable(),
342
371
  categories: z2.array(IdSchema).optional(),
@@ -461,6 +490,29 @@ var transactionStatusSchema = z3.enum([
461
490
  "failed",
462
491
  "canceled"
463
492
  ]);
493
+ var financialStatusSchema = z3.enum([
494
+ "pending",
495
+ "paid",
496
+ "failed",
497
+ "canceled",
498
+ "partially_refunded",
499
+ "refunded"
500
+ ]);
501
+ var confirmationStatusSchema = z3.enum(["unconfirmed", "confirmed"]);
502
+ var fulfillmentOrderStatusSchema = z3.enum([
503
+ "open",
504
+ "in_progress",
505
+ "on_hold",
506
+ "canceled",
507
+ "closed"
508
+ ]);
509
+ var shipmentStatusSchema = z3.enum([
510
+ "pending",
511
+ "shipped",
512
+ "delivered",
513
+ "canceled",
514
+ "failed"
515
+ ]);
464
516
  var orderStatusSchema = z3.enum([
465
517
  "pending",
466
518
  "paid",
@@ -475,7 +527,7 @@ var orderStatusSchema = z3.enum([
475
527
  "return_processing",
476
528
  "returned"
477
529
  ]);
478
- var entityIdSchema = z3.union([z3.string(), z3.number()]).transform(String);
530
+ var entityIdSchema = z3.union([z3.string().min(1), z3.number()]).transform(String);
479
531
  var createOrderItemSchema = z3.object({
480
532
  product: entityIdSchema,
481
533
  variant: entityIdSchema,
@@ -483,7 +535,7 @@ var createOrderItemSchema = z3.object({
483
535
  quantity: z3.number().int().positive("quantity must be a positive integer"),
484
536
  unitPrice: z3.number().optional(),
485
537
  totalPrice: z3.number().optional()
486
- });
538
+ }).strict();
487
539
  var createOrderSchema = z3.object({
488
540
  pgPaymentId: z3.string().min(1).optional(),
489
541
  orderNumber: z3.string().min(1, "orderNumber is required"),
@@ -492,7 +544,7 @@ var createOrderSchema = z3.object({
492
544
  name: z3.string().optional(),
493
545
  email: z3.string().email("Invalid email format"),
494
546
  phone: z3.string().optional()
495
- }),
547
+ }).strict(),
496
548
  shippingAddress: z3.object({
497
549
  postalCode: z3.string().optional(),
498
550
  address: z3.string().optional(),
@@ -500,12 +552,12 @@ var createOrderSchema = z3.object({
500
552
  deliveryMessage: z3.string().optional(),
501
553
  recipientName: z3.string().optional(),
502
554
  phone: z3.string().optional()
503
- }),
555
+ }).strict(),
504
556
  orderItems: z3.array(createOrderItemSchema).min(1, "At least one order item is required").max(100, "Maximum 100 items per order"),
505
557
  totalAmount: z3.number().nonnegative("totalAmount must be non-negative"),
506
558
  shippingAmount: z3.number().min(0).optional(),
507
559
  discountCode: z3.string().optional()
508
- });
560
+ }).strict();
509
561
  var CreateOrderSchema = createOrderSchema;
510
562
  var updateTransactionSchema = z3.object({
511
563
  pgPaymentId: z3.string().min(1, "pgPaymentId is required").describe("PG payment ID (required)"),
@@ -539,6 +591,9 @@ var confirmPaymentSchema = z3.object({
539
591
  "provider_api_confirm",
540
592
  "manual_server"
541
593
  ]).optional(),
594
+ paymentKey: z3.string().min(1).optional().describe(
595
+ "Optional provider payment key from the client confirm handshake; stored for BFF/provider refund workflows (also accepted as metadata.tossPaymentKey). Local cancel does not read this field."
596
+ ),
542
597
  metadata: z3.record(z3.string(), z3.unknown()).optional()
543
598
  }).strict();
544
599
  var ConfirmPaymentSchema = confirmPaymentSchema;
@@ -551,7 +606,7 @@ var returnReasonSchema = z3.enum([
551
606
  ]);
552
607
  var restockActionSchema = z3.enum(["return_to_stock", "discard"]);
553
608
  var returnWithRefundItemSchema = z3.object({
554
- orderItem: z3.union([z3.string(), z3.number()]).transform(String),
609
+ orderItem: z3.union([z3.string().min(1), z3.number()]).transform(String),
555
610
  quantity: z3.number().int().positive("quantity must be a positive integer"),
556
611
  restockAction: restockActionSchema.default("return_to_stock"),
557
612
  restockingFee: z3.number().min(0, "restockingFee must be non-negative").optional().describe("Restocking fee charged for this line (ADR 0005 \xA7Gap 1)")
@@ -565,10 +620,29 @@ var returnWithRefundSchema = z3.object({
565
620
  returnShippingFee: z3.number().min(0, "returnShippingFee must be non-negative").optional().describe(
566
621
  "Return shipping fee charged to the customer (ADR 0005 \xA7Gap 1)"
567
622
  ),
623
+ initialShippingRefundAmount: z3.number().min(0, "initialShippingRefundAmount must be non-negative").optional().describe("Initial order shipping amount refunded to the customer"),
624
+ initialShippingRefundOverrideNote: z3.string().min(1).optional().describe(
625
+ "Operator audit note required when overriding policy suggestion"
626
+ ),
568
627
  pgPaymentId: z3.string().min(1, "pgPaymentId is required").describe("PG payment ID for refund (required)"),
569
628
  paymentKey: z3.string().min(1).optional().describe("Provider payment key for verified refund"),
570
629
  refundReceiptUrl: z3.string().optional().describe("Refund receipt URL (optional)")
571
630
  }).strict();
631
+ var createReturnSchema = z3.object({
632
+ orderNumber: z3.string().min(1, "orderNumber is required").describe("Order number (required)"),
633
+ reason: returnReasonSchema.optional().describe("Return reason (optional)"),
634
+ reasonDetail: z3.string().optional().describe("Detailed reason text (optional)"),
635
+ returnItems: z3.array(returnWithRefundItemSchema).min(1, "At least one return item is required").max(100, "Too many return items").describe("Array of products to return (required)"),
636
+ refundAmount: z3.number().min(0, "refundAmount must be non-negative").describe(
637
+ "Line refund amount before initial shipping refund (required, min 0)"
638
+ ),
639
+ returnShippingFee: z3.number().min(0, "returnShippingFee must be non-negative").optional().describe("Return shipping fee charged to the customer"),
640
+ initialShippingRefundAmount: z3.number().min(0, "initialShippingRefundAmount must be non-negative").optional().describe("Initial order shipping amount refunded to the customer"),
641
+ initialShippingRefundOverrideNote: z3.string().min(1).optional().describe(
642
+ "Operator audit note required when overriding policy suggestion"
643
+ )
644
+ }).strict();
645
+ var CreateReturnSchema = createReturnSchema;
572
646
  var ReturnWithRefundSchema = returnWithRefundSchema;
573
647
  var cancelReasonCodeSchema = z3.enum([
574
648
  "customer",
@@ -591,20 +665,32 @@ var CancelOrderSchema = cancelOrderSchema;
591
665
  var cancelOrderResponseBaseSchema = {
592
666
  orderId: z3.string().min(1)
593
667
  };
594
- var unpaidCancelResponseFields = {
668
+ var unpaidLocalCancelCommittedResponseFields = {
595
669
  refundedAmount: z3.literal(0),
596
670
  providerRefunded: z3.literal(false)
597
671
  };
598
- var alreadyCanceledResponseFields = {
599
- refundedAmount: z3.number().int().nonnegative(),
600
- providerRefunded: z3.literal(false)
672
+ var paidLocalCancelCommittedResponseFields = {
673
+ transactionId: z3.string().min(1),
674
+ refundedAmount: z3.literal(0),
675
+ providerRefunded: z3.literal(false),
676
+ refundPending: z3.literal(true)
601
677
  };
602
- var providerRefundResponseFields = {
678
+ var legacyProviderRefundResponseFields = {
603
679
  transactionId: z3.string().min(1),
604
680
  refundedAmount: z3.number().int().positive(),
605
681
  refundSeq: z3.number().int().positive(),
606
682
  providerRefunded: z3.literal(true)
607
683
  };
684
+ var alreadyCanceledResponseFields = {
685
+ refundedAmount: z3.number().int().nonnegative(),
686
+ providerRefunded: z3.literal(false)
687
+ };
688
+ var alreadyCanceledRefundPendingResponseFields = {
689
+ transactionId: z3.string().min(1),
690
+ refundedAmount: z3.number().int().nonnegative(),
691
+ providerRefunded: z3.literal(false),
692
+ refundPending: z3.literal(true)
693
+ };
608
694
  var cancelOrderReconciliationStatusSchema = z3.enum([
609
695
  "paid",
610
696
  "preparing",
@@ -619,13 +705,13 @@ var cancelOrderReconciliationStatusSchema = z3.enum([
619
705
  var cancelOrderResponseSchema = z3.union([
620
706
  z3.object({
621
707
  ...cancelOrderResponseBaseSchema,
622
- ...unpaidCancelResponseFields,
708
+ ...paidLocalCancelCommittedResponseFields,
623
709
  status: z3.literal("canceled"),
624
710
  cancelCommitted: z3.literal(true)
625
711
  }).strict(),
626
712
  z3.object({
627
713
  ...cancelOrderResponseBaseSchema,
628
- ...providerRefundResponseFields,
714
+ ...unpaidLocalCancelCommittedResponseFields,
629
715
  status: z3.literal("canceled"),
630
716
  cancelCommitted: z3.literal(true)
631
717
  }).strict(),
@@ -638,12 +724,75 @@ var cancelOrderResponseSchema = z3.union([
638
724
  }).strict(),
639
725
  z3.object({
640
726
  ...cancelOrderResponseBaseSchema,
641
- ...providerRefundResponseFields,
727
+ ...alreadyCanceledRefundPendingResponseFields,
728
+ status: z3.literal("canceled"),
729
+ cancelCommitted: z3.literal(false),
730
+ alreadyCanceled: z3.literal(true)
731
+ }).strict(),
732
+ z3.object({
733
+ ...cancelOrderResponseBaseSchema,
734
+ ...legacyProviderRefundResponseFields,
642
735
  status: cancelOrderReconciliationStatusSchema,
643
736
  cancelCommitted: z3.literal(false),
644
737
  reconciliationRequired: z3.literal(true)
645
738
  }).strict()
646
739
  ]);
740
+ var resolveCancelRefundOutcomeSchema = z3.enum(["succeeded", "failed"]);
741
+ var resolveCancelRefundSchema = z3.object({
742
+ orderNumber: z3.string().min(1, "orderNumber is required").describe("Order number whose pending cancel refund is being resolved"),
743
+ idempotencyKey: idempotencyKeySchema.describe(
744
+ "Stable key for this PG refund result report"
745
+ ),
746
+ outcome: resolveCancelRefundOutcomeSchema.describe(
747
+ "PG refund result reported by the storefront or BFF"
748
+ ),
749
+ refundedAmount: z3.number().int("refundedAmount must be an integer minor-unit amount").nonnegative("refundedAmount must be nonnegative"),
750
+ pgProvider: z3.string().trim().min(1, "pgProvider is required").regex(
751
+ /^[a-z0-9][a-z0-9_-]*$/,
752
+ "pgProvider must be a lowercase provider slug"
753
+ ),
754
+ pgRefundId: z3.string().trim().min(1).optional()
755
+ }).strict().superRefine((value, ctx) => {
756
+ if (value.outcome === "succeeded" && value.refundedAmount <= 0) {
757
+ ctx.addIssue({
758
+ code: z3.ZodIssueCode.custom,
759
+ path: ["refundedAmount"],
760
+ message: "refundedAmount must be positive when outcome is succeeded"
761
+ });
762
+ }
763
+ if (value.outcome === "succeeded" && !value.pgRefundId) {
764
+ ctx.addIssue({
765
+ code: z3.ZodIssueCode.custom,
766
+ path: ["pgRefundId"],
767
+ message: "pgRefundId is required when outcome is succeeded"
768
+ });
769
+ }
770
+ if (value.outcome === "failed" && value.refundedAmount !== 0) {
771
+ ctx.addIssue({
772
+ code: z3.ZodIssueCode.custom,
773
+ path: ["refundedAmount"],
774
+ message: "refundedAmount must be 0 when outcome is failed"
775
+ });
776
+ }
777
+ });
778
+ var resolveCancelRefundResponseSchema = z3.union([
779
+ z3.object({
780
+ orderId: z3.string().min(1),
781
+ transactionId: z3.string().min(1),
782
+ refundTransactionId: z3.string().min(1),
783
+ refundedAmount: z3.number().int().positive(),
784
+ refundStatus: z3.literal("succeeded"),
785
+ transactionStatus: z3.literal("refunded")
786
+ }).strict(),
787
+ z3.object({
788
+ orderId: z3.string().min(1),
789
+ transactionId: z3.string().min(1),
790
+ refundTransactionId: z3.string().min(1),
791
+ refundedAmount: z3.literal(0),
792
+ refundStatus: z3.literal("failed"),
793
+ transactionStatus: z3.literal("paid")
794
+ }).strict()
795
+ ]);
647
796
 
648
797
  // ../../packages/contracts/src/mcp/index.ts
649
798
  var MCP_TOOL_CONTRACT = {
@@ -767,6 +916,11 @@ var MCP_TOOL_CONTRACT = {
767
916
  oauthScope: "mcp:write",
768
917
  readOnly: false
769
918
  },
919
+ "prepare-fulfillment-order": {
920
+ consoleRole: "tenant-admin",
921
+ oauthScope: "mcp:write",
922
+ readOnly: false
923
+ },
770
924
  "update-fulfillment": {
771
925
  consoleRole: "tenant-admin",
772
926
  oauthScope: "mcp:write",
@@ -1039,6 +1193,13 @@ var TOOL_POLICY_MANIFEST = {
1039
1193
  consoleSurface: "POST /api/orders/create-fulfillment",
1040
1194
  annotationPolicy: NON_DESTRUCTIVE_MUTATION_ANNOTATION
1041
1195
  },
1196
+ "prepare-fulfillment-order": {
1197
+ category: "mutation-fulfillment",
1198
+ oauthScope: MCP_SCOPES.write,
1199
+ consoleRole: "tenant-admin",
1200
+ consoleSurface: "POST /api/fulfillment-orders/prepare-fulfillment-order",
1201
+ annotationPolicy: NON_DESTRUCTIVE_MUTATION_ANNOTATION
1202
+ },
1042
1203
  "update-fulfillment": {
1043
1204
  category: "mutation-fulfillment",
1044
1205
  oauthScope: MCP_SCOPES.write,
@@ -1665,22 +1826,13 @@ async function createOrder(params) {
1665
1826
  import { z as z7 } from "zod";
1666
1827
  var schema5 = {
1667
1828
  orderNumber: z7.string().min(1).describe("Order number (required)"),
1668
- status: z7.enum([
1669
- "pending",
1670
- "paid",
1671
- "failed",
1672
- "canceled",
1673
- "preparing",
1674
- "shipped",
1675
- "delivered",
1676
- "confirmed"
1677
- ]).describe(
1678
- "New operator-driven order status. The schema keeps SDK status values for compatibility, but the Console update endpoint rejects server-derived statuses (paid, canceled, returned, refunded); those must be set by payment/refund flows, and return-related statuses must be set via Return endpoints."
1829
+ status: z7.enum(["confirmed"]).describe(
1830
+ "Order confirmation status mutation. Shipping/display statuses are derived from fulfillment orders and shipments; financial/refund states are set by payment/refund flows."
1679
1831
  )
1680
1832
  };
1681
1833
  var metadata5 = {
1682
1834
  name: "update-order",
1683
- description: "Update operator-driven order status. Console accepts transitions such as paid\u2192preparing/shipped/delivered/confirmed and rejects server-derived payment/refund statuses such as paid, canceled, returned, and refunded; the MCP schema keeps SDK status values for compatibility.",
1835
+ description: "Confirm an order after delivery. Financial, fulfillment-order, shipment, return, and display statuses are explicit server-derived axes and are not writable through this tool.",
1684
1836
  annotations: {
1685
1837
  title: "Update order status",
1686
1838
  readOnlyHint: false,
@@ -1738,20 +1890,19 @@ async function checkout(params) {
1738
1890
  import { z as z9 } from "zod";
1739
1891
  var schema7 = {
1740
1892
  orderNumber: z9.string().min(1).describe("Order number (required)"),
1741
- carrier: z9.string().optional().describe("Shipping carrier name (optional)"),
1742
- trackingNumber: z9.string().optional().describe(
1743
- 'Tracking number (optional). Setting carrier + tracking triggers "shipped" status'
1744
- ),
1893
+ fulfillmentOrderId: z9.string().optional().describe("Fulfillment order ID to ship (optional)"),
1894
+ carrier: z9.string().min(1).optional().describe("Shipping carrier name"),
1895
+ trackingNumber: z9.string().min(1).optional().describe("Tracking number"),
1745
1896
  items: z9.array(
1746
1897
  z9.object({
1747
1898
  orderItem: z9.string().min(1).describe("Order item ID"),
1748
1899
  quantity: z9.number().int().positive().describe("Quantity to fulfill")
1749
1900
  })
1750
- ).describe("Array of items to fulfill (required)")
1901
+ ).optional().describe("Array of items to fulfill (optional)")
1751
1902
  };
1752
1903
  var metadata7 = {
1753
1904
  name: "create-fulfillment",
1754
- description: "Create a shipment/fulfillment for order items. Auto-updates order status (paid \u2192 preparing \u2192 shipped).",
1905
+ description: "Create a shipment for fulfillment order items. Tracking information can be supplied now or updated later with update-fulfillment.",
1755
1906
  annotations: {
1756
1907
  title: "Create fulfillment",
1757
1908
  readOnlyHint: false,
@@ -1761,6 +1912,7 @@ var metadata7 = {
1761
1912
  };
1762
1913
  async function createFulfillment({
1763
1914
  orderNumber,
1915
+ fulfillmentOrderId,
1764
1916
  carrier,
1765
1917
  trackingNumber,
1766
1918
  items
@@ -1769,8 +1921,9 @@ async function createFulfillment({
1769
1921
  const client = getClient();
1770
1922
  const result = await client.commerce.orders.createFulfillment({
1771
1923
  orderNumber,
1772
- carrier,
1773
- trackingNumber,
1924
+ fulfillmentOrderId,
1925
+ ...carrier ? { carrier } : {},
1926
+ ...trackingNumber ? { trackingNumber } : {},
1774
1927
  items
1775
1928
  });
1776
1929
  return toolSuccess({ data: result });
@@ -1779,23 +1932,48 @@ async function createFulfillment({
1779
1932
  }
1780
1933
  }
1781
1934
 
1782
- // src/tools/update-fulfillment.ts
1935
+ // src/tools/prepare-fulfillment-order.ts
1783
1936
  import { z as z10 } from "zod";
1784
1937
  var schema8 = {
1785
- fulfillmentId: z10.string().min(1).describe("Fulfillment ID (required)"),
1786
- status: z10.enum(["packed", "shipped", "delivered", "failed"]).describe(
1787
- "New fulfillment status (required). FSM: pending\u2192packed/shipped/failed, packed\u2192shipped/failed, shipped\u2192delivered/failed"
1788
- ),
1789
- carrier: z10.string().optional().describe(
1790
- "Shipping carrier (optional, changeable only in pending/packed status)"
1791
- ),
1792
- trackingNumber: z10.string().optional().describe(
1793
- "Tracking number (optional, changeable only in pending/packed status)"
1794
- )
1938
+ orderNumber: z10.string().min(1).describe("Order number (required)")
1795
1939
  };
1796
1940
  var metadata8 = {
1941
+ name: "prepare-fulfillment-order",
1942
+ description: "Prepare starts fulfillment work and does not require carrier/tracking.",
1943
+ annotations: {
1944
+ title: "Prepare fulfillment order",
1945
+ readOnlyHint: false,
1946
+ destructiveHint: false,
1947
+ idempotentHint: false
1948
+ }
1949
+ };
1950
+ async function prepareFulfillmentOrder({
1951
+ orderNumber
1952
+ }) {
1953
+ try {
1954
+ const client = getClient();
1955
+ const result = await client.commerce.orders.prepareFulfillmentOrder({
1956
+ orderNumber
1957
+ });
1958
+ return toolSuccess({ data: result });
1959
+ } catch (error) {
1960
+ return toolError(error);
1961
+ }
1962
+ }
1963
+
1964
+ // src/tools/update-fulfillment.ts
1965
+ import { z as z11 } from "zod";
1966
+ var schema9 = {
1967
+ fulfillmentId: z11.string().min(1).describe("Fulfillment ID (required)"),
1968
+ status: z11.enum(["shipped", "delivered", "failed"]).optional().describe(
1969
+ "New shipment status. Shipment lifecycle: shipped\u2192delivered/failed"
1970
+ ),
1971
+ carrier: z11.string().optional().describe("Shipping carrier (optional; can be added or corrected later)"),
1972
+ trackingNumber: z11.string().optional().describe("Tracking number (optional; can be added or corrected later)")
1973
+ };
1974
+ var metadata9 = {
1797
1975
  name: "update-fulfillment",
1798
- description: "Update fulfillment status, carrier, and tracking number. Auto-updates order status when all fulfillments are delivered.",
1976
+ description: "Update shipment status, carrier, or tracking number. Tracking can be added after shipment creation.",
1799
1977
  annotations: {
1800
1978
  title: "Update fulfillment",
1801
1979
  readOnlyHint: false,
@@ -1811,11 +1989,16 @@ async function updateFulfillment({
1811
1989
  }) {
1812
1990
  try {
1813
1991
  const client = getClient();
1992
+ if (status === void 0 && carrier === void 0 && trackingNumber === void 0) {
1993
+ return toolError(
1994
+ new Error("status, carrier, or trackingNumber is required")
1995
+ );
1996
+ }
1814
1997
  const result = await client.commerce.orders.updateFulfillment({
1815
1998
  fulfillmentId,
1816
- status,
1817
- carrier,
1818
- trackingNumber
1999
+ ...status ? { status } : {},
2000
+ ...carrier ? { carrier } : {},
2001
+ ...trackingNumber ? { trackingNumber } : {}
1819
2002
  });
1820
2003
  return toolSuccess({ data: result });
1821
2004
  } catch (error) {
@@ -1824,8 +2007,8 @@ async function updateFulfillment({
1824
2007
  }
1825
2008
 
1826
2009
  // src/tools/update-transaction.ts
1827
- var schema9 = UpdateTransactionSchema.shape;
1828
- var metadata9 = {
2010
+ var schema10 = UpdateTransactionSchema.shape;
2011
+ var metadata10 = {
1829
2012
  name: "update-transaction",
1830
2013
  description: "Update transaction status, payment method, and receipt URL.",
1831
2014
  annotations: {
@@ -1861,8 +2044,8 @@ async function updateTransaction({
1861
2044
  }
1862
2045
 
1863
2046
  // src/tools/confirm-payment.ts
1864
- var schema10 = ConfirmPaymentSchema.shape;
1865
- var metadata10 = {
2047
+ var schema11 = ConfirmPaymentSchema.shape;
2048
+ var metadata11 = {
1866
2049
  name: "confirm-payment",
1867
2050
  description: "Confirm a provider-verified ecommerce payment through the generic payment confirmation flow.",
1868
2051
  annotations: {
@@ -1889,10 +2072,10 @@ var CancelOrderToolSchema = CancelOrderSchema.extend({
1889
2072
  "Optional X-Idempotency-Key forwarded to the Console cancel endpoint"
1890
2073
  )
1891
2074
  }).strict();
1892
- var schema11 = CancelOrderToolSchema.shape;
1893
- var metadata11 = {
2075
+ var schema12 = CancelOrderToolSchema.shape;
2076
+ var metadata12 = {
1894
2077
  name: "cancel-order",
1895
- description: "Cancel an eligible pre-fulfillment order through the provider-verified cancellation flow. Paid captured orders are refunded before the local order moves to canceled; shipped, delivered, active-return, and fulfilled orders are rejected.",
2078
+ description: "Cancel an eligible order through the server-derived local cancellation flow. Paid captured orders move to canceled locally and require separate storefront PG refund resolution; preparation fulfillment orders are voided when no shipment exists, while shipped, delivered, active-return, and fulfilled orders are rejected.",
1896
2079
  annotations: {
1897
2080
  title: "Cancel order",
1898
2081
  readOnlyHint: false,
@@ -1917,20 +2100,8 @@ async function cancelOrder(params) {
1917
2100
  }
1918
2101
 
1919
2102
  // src/tools/create-return.ts
1920
- import { z as z11 } from "zod";
1921
- var schema12 = {
1922
- orderNumber: z11.string().min(1).describe("Order number (required)"),
1923
- reason: z11.enum(["change_of_mind", "defective", "wrong_delivery", "damaged", "other"]).optional().describe("Return reason (optional)"),
1924
- reasonDetail: z11.string().optional().describe("Detailed reason text (optional)"),
1925
- returnItems: z11.array(
1926
- z11.object({
1927
- orderItem: z11.string().min(1).describe("Order item ID"),
1928
- quantity: z11.number().int().positive().describe("Quantity to return")
1929
- })
1930
- ).describe("Array of products to return (required)"),
1931
- refundAmount: z11.number().nonnegative().describe("Refund amount (required, min 0)")
1932
- };
1933
- var metadata12 = {
2103
+ var schema13 = CreateReturnSchema.shape;
2104
+ var metadata13 = {
1934
2105
  name: "create-return",
1935
2106
  description: "Create a return request for an order. Only works for delivered/confirmed orders. Updates order status to return_requested.",
1936
2107
  annotations: {
@@ -1945,7 +2116,10 @@ async function createReturn({
1945
2116
  reason,
1946
2117
  reasonDetail,
1947
2118
  returnItems,
1948
- refundAmount
2119
+ refundAmount,
2120
+ returnShippingFee,
2121
+ initialShippingRefundAmount,
2122
+ initialShippingRefundOverrideNote
1949
2123
  }) {
1950
2124
  try {
1951
2125
  const client = getClient();
@@ -1954,7 +2128,10 @@ async function createReturn({
1954
2128
  reason,
1955
2129
  reasonDetail,
1956
2130
  returnItems,
1957
- refundAmount
2131
+ refundAmount,
2132
+ returnShippingFee,
2133
+ initialShippingRefundAmount,
2134
+ initialShippingRefundOverrideNote
1958
2135
  });
1959
2136
  return toolSuccess({ data: result });
1960
2137
  } catch (error) {
@@ -1964,13 +2141,13 @@ async function createReturn({
1964
2141
 
1965
2142
  // src/tools/update-return.ts
1966
2143
  import { z as z12 } from "zod";
1967
- var schema13 = {
2144
+ var schema14 = {
1968
2145
  returnId: z12.string().min(1).describe("Return ID (required)"),
1969
2146
  status: z12.enum(["processing", "approved", "rejected", "completed"]).describe(
1970
2147
  "New operator-driven return status (required). The schema keeps SDK status values for compatibility, but Console accepts only requested\u2192processing/rejected and processing\u2192approved/rejected here; completed is server-derived and must be set by return-with-refund."
1971
2148
  )
1972
2149
  };
1973
- var metadata13 = {
2150
+ var metadata14 = {
1974
2151
  name: "update-return",
1975
2152
  description: "Update operator-driven return status with FSM validation. Rejection can restore the order flow; completion and inventory restoration are handled by return-with-refund after provider-verified refund, while the MCP schema keeps SDK status values for compatibility.",
1976
2153
  annotations: {
@@ -1997,8 +2174,8 @@ async function updateReturn({
1997
2174
  }
1998
2175
 
1999
2176
  // src/tools/return-with-refund.ts
2000
- var schema14 = ReturnWithRefundSchema.shape;
2001
- var metadata14 = {
2177
+ var schema15 = ReturnWithRefundSchema.shape;
2178
+ var metadata15 = {
2002
2179
  name: "return-with-refund",
2003
2180
  description: "Combined provider-verified return + refund operation. Creates a completed return, restores eligible stock, records the refund transaction, and advances the order to the returned state.",
2004
2181
  annotations: {
@@ -2015,6 +2192,8 @@ async function returnWithRefund({
2015
2192
  returnItems,
2016
2193
  refundAmount,
2017
2194
  returnShippingFee,
2195
+ initialShippingRefundAmount,
2196
+ initialShippingRefundOverrideNote,
2018
2197
  pgPaymentId,
2019
2198
  paymentKey,
2020
2199
  refundReceiptUrl
@@ -2028,6 +2207,8 @@ async function returnWithRefund({
2028
2207
  returnItems,
2029
2208
  refundAmount,
2030
2209
  returnShippingFee,
2210
+ initialShippingRefundAmount,
2211
+ initialShippingRefundOverrideNote,
2031
2212
  pgPaymentId,
2032
2213
  paymentKey,
2033
2214
  refundReceiptUrl
@@ -2041,14 +2222,14 @@ async function returnWithRefund({
2041
2222
 
2042
2223
  // src/tools/add-cart-item.ts
2043
2224
  import { z as z13 } from "zod";
2044
- var schema15 = {
2225
+ var schema16 = {
2045
2226
  cartId: z13.string().min(1).describe("Cart ID (required)"),
2046
2227
  product: z13.string().min(1).describe("Product ID (required)"),
2047
2228
  variant: z13.string().min(1).describe("Product variant ID (required)"),
2048
2229
  option: z13.string().min(1).describe("Product option ID (required)"),
2049
2230
  quantity: z13.number().int().positive().describe("Quantity to add (required, positive integer)")
2050
2231
  };
2051
- var metadata15 = {
2232
+ var metadata16 = {
2052
2233
  name: "add-cart-item",
2053
2234
  description: "Add a product to cart. Validates stock, merges quantity if item already exists, recalculates totals.",
2054
2235
  annotations: {
@@ -2082,11 +2263,11 @@ async function addCartItem({
2082
2263
 
2083
2264
  // src/tools/update-cart-item.ts
2084
2265
  import { z as z14 } from "zod";
2085
- var schema16 = {
2266
+ var schema17 = {
2086
2267
  cartItemId: z14.string().min(1).describe("Cart item ID (required)"),
2087
2268
  quantity: z14.number().int().positive().describe("New quantity (required, positive integer)")
2088
2269
  };
2089
- var metadata16 = {
2270
+ var metadata17 = {
2090
2271
  name: "update-cart-item",
2091
2272
  description: "Update cart item quantity. Validates stock availability, recalculates cart totals.",
2092
2273
  annotations: {
@@ -2111,10 +2292,10 @@ async function updateCartItem({
2111
2292
 
2112
2293
  // src/tools/remove-cart-item.ts
2113
2294
  import { z as z15 } from "zod";
2114
- var schema17 = {
2295
+ var schema18 = {
2115
2296
  cartItemId: z15.string().min(1).describe("Cart item ID to remove (required)")
2116
2297
  };
2117
- var metadata17 = {
2298
+ var metadata18 = {
2118
2299
  name: "remove-cart-item",
2119
2300
  description: "Remove an item from cart. Recalculates cart totals after removal.",
2120
2301
  annotations: {
@@ -2138,11 +2319,11 @@ async function removeCartItem({
2138
2319
 
2139
2320
  // src/tools/apply-discount.ts
2140
2321
  import { z as z16 } from "zod";
2141
- var schema18 = {
2322
+ var schema19 = {
2142
2323
  cartId: z16.string().min(1).describe("Cart ID (required)"),
2143
2324
  discountCode: z16.string().describe("Discount code to apply (required)")
2144
2325
  };
2145
- var metadata18 = {
2326
+ var metadata19 = {
2146
2327
  name: "apply-discount",
2147
2328
  description: "Apply a discount code to a cart. Validates the code, updates cart totals, and sets free shipping if applicable.",
2148
2329
  annotations: {
@@ -2167,10 +2348,10 @@ async function applyDiscount({
2167
2348
 
2168
2349
  // src/tools/remove-discount.ts
2169
2350
  import { z as z17 } from "zod";
2170
- var schema19 = {
2351
+ var schema20 = {
2171
2352
  cartId: z17.string().min(1).describe("Cart ID (required)")
2172
2353
  };
2173
- var metadata19 = {
2354
+ var metadata20 = {
2174
2355
  name: "remove-discount",
2175
2356
  description: "Remove the applied discount code from a cart and recalculate totals.",
2176
2357
  annotations: {
@@ -2194,10 +2375,10 @@ async function removeDiscount({
2194
2375
 
2195
2376
  // src/tools/clear-cart.ts
2196
2377
  import { z as z18 } from "zod";
2197
- var schema20 = {
2378
+ var schema21 = {
2198
2379
  cartId: z18.string().min(1).describe("Cart ID (required)")
2199
2380
  };
2200
- var metadata20 = {
2381
+ var metadata21 = {
2201
2382
  name: "clear-cart",
2202
2383
  description: "Remove all items from a cart, reset discount and amounts. Shipping fee is preserved.",
2203
2384
  annotations: {
@@ -2221,11 +2402,11 @@ async function clearCart({
2221
2402
 
2222
2403
  // src/tools/validate-discount.ts
2223
2404
  import { z as z19 } from "zod";
2224
- var schema21 = {
2405
+ var schema22 = {
2225
2406
  code: z19.string().describe("Discount code to validate (required)"),
2226
2407
  orderAmount: z19.number().describe("Order amount for validation (required)")
2227
2408
  };
2228
- var metadata21 = {
2409
+ var metadata22 = {
2229
2410
  name: "validate-discount",
2230
2411
  description: "Validate a discount code. Checks active status, date range, usage limits, minimum order amount, and calculates discount.",
2231
2412
  annotations: {
@@ -2253,12 +2434,12 @@ async function validateDiscount({
2253
2434
 
2254
2435
  // src/tools/calculate-shipping.ts
2255
2436
  import { z as z20 } from "zod";
2256
- var schema22 = {
2437
+ var schema23 = {
2257
2438
  shippingPolicyId: z20.string().optional().describe("Shipping policy ID (uses default policy if omitted)"),
2258
2439
  orderAmount: z20.number().describe("Order amount for fee calculation (required)"),
2259
2440
  postalCode: z20.string().optional().describe("Postal code for Jeju surcharge detection (63000-63644)")
2260
2441
  };
2261
- var metadata22 = {
2442
+ var metadata23 = {
2262
2443
  name: "calculate-shipping",
2263
2444
  description: "Calculate shipping fee based on order amount and postal code. Supports free shipping threshold and Jeju surcharge.",
2264
2445
  annotations: {
@@ -2288,7 +2469,7 @@ async function calculateShipping({
2288
2469
 
2289
2470
  // src/tools/stock-check.ts
2290
2471
  import { z as z21 } from "zod";
2291
- var schema23 = {
2472
+ var schema24 = {
2292
2473
  items: z21.array(
2293
2474
  z21.object({
2294
2475
  variantId: z21.string().describe("Product variant ID"),
@@ -2298,7 +2479,7 @@ var schema23 = {
2298
2479
  "Array of items to check stock for (required, max 100). Each: { variantId, quantity }"
2299
2480
  )
2300
2481
  };
2301
- var metadata23 = {
2482
+ var metadata24 = {
2302
2483
  name: "stock-check",
2303
2484
  description: "Batch check product option stock availability. Returns per-item availability and an allAvailable flag.",
2304
2485
  annotations: {
@@ -2322,11 +2503,11 @@ async function stockCheck({
2322
2503
 
2323
2504
  // src/tools/product-detail.ts
2324
2505
  import { z as z22 } from "zod";
2325
- var schema24 = {
2506
+ var schema25 = {
2326
2507
  slug: z22.string().optional().describe("Product slug (one of slug or id required)"),
2327
2508
  id: z22.string().optional().describe("Product id (one of slug or id required)")
2328
2509
  };
2329
- var metadata24 = {
2510
+ var metadata25 = {
2330
2511
  name: "product-detail",
2331
2512
  description: "Fetch full product detail by slug or id. Returns one resolver-ready product with variants, option slugs, option value slugs/media, brand, categories, tags, images, videos, and listing rollup, or found:false with a reason if missing/unpublished/feature disabled. Permission/auth errors still throw.",
2332
2513
  annotations: {
@@ -2354,7 +2535,7 @@ async function productDetail({
2354
2535
  }
2355
2536
 
2356
2537
  // src/tools/product-upsert.ts
2357
- var schema25 = {
2538
+ var schema26 = {
2358
2539
  productId: ProductUpsertObjectSchema.shape.productId.describe(
2359
2540
  "Existing product id for graph-only updates. Prefer this for an existing product on edit after loading GET /api/products/:id/composer-draft."
2360
2541
  ),
@@ -2371,7 +2552,7 @@ var schema25 = {
2371
2552
  "Full desired variant graph. On edit, omitted variants are deleted or deactivated according to server references. Prefer stable option-value IDs."
2372
2553
  )
2373
2554
  };
2374
- var metadata25 = {
2555
+ var metadata26 = {
2375
2556
  name: "product-upsert",
2376
2557
  description: "Create a product or update an existing product graph. Existing products should load composer-draft first, send productId plus graphRevision, and include the full desired options/variants graph.",
2377
2558
  annotations: {
@@ -2412,8 +2593,8 @@ async function getCollectionSchema(collection) {
2412
2593
  }
2413
2594
 
2414
2595
  // src/tools/get-collection-schema.ts
2415
- var schema26 = createCollectionSchemaToolInputSchema(SERVER_COLLECTIONS3).shape;
2416
- var metadata26 = {
2596
+ var schema27 = createCollectionSchemaToolInputSchema(SERVER_COLLECTIONS3).shape;
2597
+ var metadata27 = {
2417
2598
  name: "get-collection-schema",
2418
2599
  description: "Get the authoritative tenant-aware collection schema from console. Use this before create/update to understand writable fields, hidden fields, required metadata, and collection-level visibility.",
2419
2600
  annotations: {
@@ -2464,8 +2645,8 @@ async function getTenantFeatureProgress(feature, includeEvidence = false) {
2464
2645
  }
2465
2646
 
2466
2647
  // src/tools/get-tenant-context.ts
2467
- var schema27 = tenantContextToolInputSchema.shape;
2468
- var metadata27 = {
2648
+ var schema28 = tenantContextToolInputSchema.shape;
2649
+ var metadata28 = {
2469
2650
  name: "get-tenant-context",
2470
2651
  description: "Get current tenant features, active collections, and field visibility. Call this at the start of every session. Use includeCounts=true to also get per-collection document counts for setup diagnostics.",
2471
2652
  annotations: {
@@ -2542,8 +2723,8 @@ async function handler({
2542
2723
  }
2543
2724
 
2544
2725
  // src/tools/check-feature-progress.ts
2545
- var schema28 = tenantFeatureProgressInputSchema.shape;
2546
- var metadata28 = {
2726
+ var schema29 = tenantFeatureProgressInputSchema.shape;
2727
+ var metadata29 = {
2547
2728
  name: "check-feature-progress",
2548
2729
  description: "Check tenant implementation progress for a supported feature. Start with feature=ecommerce to inspect catalog, cart, checkout, payment result, webhook, and operations readiness without mutating tenant data.",
2549
2730
  annotations: {
@@ -2589,12 +2770,12 @@ function invalidateFieldConfigCache() {
2589
2770
  }
2590
2771
 
2591
2772
  // src/tools/list-configurable-fields.ts
2592
- var schema29 = {
2773
+ var schema30 = {
2593
2774
  collection: z23.string().optional().describe(
2594
2775
  "Filter by collection slug (optional \u2014 returns all if omitted). Use this filter to reduce response size when you know which collection to check."
2595
2776
  )
2596
2777
  };
2597
- var metadata29 = {
2778
+ var metadata30 = {
2598
2779
  name: "list-configurable-fields",
2599
2780
  description: "List all configurable fields for tenant collections with current visibility state. Shows which fields can be shown/hidden and their current status. Returns all collections including inactive features \u2014 cross-reference with get-tenant-context for active features. Response includes ~300 fields across 47 collections \u2014 use collection filter when possible.",
2600
2781
  annotations: {
@@ -2626,7 +2807,7 @@ async function listConfigurableFields(params) {
2626
2807
 
2627
2808
  // src/tools/update-field-config.ts
2628
2809
  import { z as z24 } from "zod";
2629
- var schema30 = {
2810
+ var schema31 = {
2630
2811
  collection: z24.string().min(1).describe("Collection slug (required)"),
2631
2812
  hiddenFields: z24.array(z24.string().min(1).max(200)).max(300).describe(
2632
2813
  "Fields to hide (required). This is a FULL REPLACE \u2014 fields NOT in this list will be shown. Pass [] to show all fields. Use list-configurable-fields first to see available field paths."
@@ -2635,7 +2816,7 @@ var schema30 = {
2635
2816
  "Hide the entire collection from Admin Panel (optional). When true, individual hiddenFields are irrelevant."
2636
2817
  )
2637
2818
  };
2638
- var metadata30 = {
2819
+ var metadata31 = {
2639
2820
  name: "update-field-config",
2640
2821
  description: "Update field visibility configuration for a tenant collection. Hidden fields are removed from the Admin Panel UI. IMPORTANT: hiddenFields is a full replace, not a merge. Always call list-configurable-fields first to see current state.",
2641
2822
  annotations: {
@@ -3104,7 +3285,7 @@ function getRecipe(goal, runtime = "both") {
3104
3285
  }
3105
3286
 
3106
3287
  // src/tools/sdk-get-recipe.ts
3107
- var schema31 = {
3288
+ var schema32 = {
3108
3289
  goal: z25.enum([
3109
3290
  "fetch-list",
3110
3291
  "fetch-by-id",
@@ -3121,7 +3302,7 @@ var schema31 = {
3121
3302
  collection: z25.string().optional().describe("Specific collection name if applicable"),
3122
3303
  includeExample: z25.boolean().default(true).describe("Whether to include a full code example")
3123
3304
  };
3124
- var metadata31 = {
3305
+ var metadata32 = {
3125
3306
  name: "sdk-get-recipe",
3126
3307
  description: "Get a complete SDK code recipe for a specific task. Returns recommended approach, code example, and related documentation links. Use this FIRST when the user asks how to do something with the SDK.",
3127
3308
  annotations: {
@@ -3302,9 +3483,16 @@ var docIndex = [
3302
3483
  "order",
3303
3484
  "orderChanged",
3304
3485
  "collection.orderChanged",
3305
- "isOrderChangedWebhookEvent"
3486
+ "isOrderChangedWebhookEvent",
3487
+ "commerce.notification",
3488
+ "createCommerceNotificationWebhookHandler",
3489
+ "createCommerceEmailWebhookHandler",
3490
+ "orderCanceled",
3491
+ "resolveCancelRefund",
3492
+ "cancel refund",
3493
+ "external PG refund"
3306
3494
  ],
3307
- summary: "Tenant webhooks deliver signed server-to-server events via WEBHOOK_SECRET, including customer password reset and semantic order changes with collection.orderChanged / isOrderChangedWebhookEvent.",
3495
+ summary: "Tenant webhooks deliver signed server-to-server events via WEBHOOK_SECRET, including customer password reset, semantic order changes, and commerce.notification workers with createCommerceNotificationWebhookHandler for orderCanceled refund handoff.",
3308
3496
  resourceUri: "docs://sdk/webhook"
3309
3497
  },
3310
3498
  // Order API
@@ -3316,8 +3504,8 @@ var docIndex = [
3316
3504
  },
3317
3505
  {
3318
3506
  title: "Order API \u2014 Fulfillment and Shipping",
3319
- keywords: ["fulfillment", "shipping", "tracking", "carrier", "trackingNumber", "createFulfillment", "updateFulfillment", "shipped", "delivered"],
3320
- summary: "client.commerce.orders.createFulfillment({ orderNumber, items, carrier?, trackingNumber? }) creates a shipment. updateFulfillment() advances fulfillment status.",
3507
+ keywords: ["fulfillment", "shipping", "tracking", "carrier", "trackingNumber", "prepareFulfillmentOrder", "createFulfillment", "updateFulfillment", "shipped", "delivered"],
3508
+ summary: "client.commerce.orders.prepareFulfillmentOrder({ orderNumber }) starts fulfillment work. createFulfillment({ orderNumber, ... }) creates a shipment with optional tracking. updateFulfillment() advances shipment status or updates tracking.",
3321
3509
  resourceUri: "docs://sdk/server-api"
3322
3510
  },
3323
3511
  {
@@ -3350,11 +3538,11 @@ function searchDocs(query, limit = 5) {
3350
3538
  }
3351
3539
 
3352
3540
  // src/tools/sdk-search-docs.ts
3353
- var schema32 = {
3541
+ var schema33 = {
3354
3542
  query: z26.string().min(2).describe('Search keyword or phrase (e.g. "infinite scroll", "webhook", "customer login")'),
3355
3543
  limit: z26.number().min(1).max(10).default(5).describe("Maximum results to return (1-10, default: 5)")
3356
3544
  };
3357
- var metadata32 = {
3545
+ var metadata33 = {
3358
3546
  name: "sdk-search-docs",
3359
3547
  description: "Search SDK documentation by keyword. Returns matching topics with summaries and resource links. Use when looking for specific SDK features or patterns.",
3360
3548
  annotations: {
@@ -3390,7 +3578,7 @@ function handler4({
3390
3578
 
3391
3579
  // src/tools/sdk-get-auth-setup.ts
3392
3580
  import { z as z27 } from "zod";
3393
- var schema33 = {
3581
+ var schema34 = {
3394
3582
  scenario: z27.enum([
3395
3583
  "browser-client",
3396
3584
  "server-client",
@@ -3400,7 +3588,7 @@ var schema33 = {
3400
3588
  "webhook-verification"
3401
3589
  ]).describe("Authentication scenario")
3402
3590
  };
3403
- var metadata33 = {
3591
+ var metadata34 = {
3404
3592
  name: "sdk-get-auth-setup",
3405
3593
  description: "Get the current authentication setup for a specific scenario. Returns env var names, code snippets, and security notes.",
3406
3594
  annotations: {
@@ -3564,12 +3752,12 @@ function handler5({
3564
3752
  // src/tools/sdk-get-collection-pattern.ts
3565
3753
  import { z as z28 } from "zod";
3566
3754
  import { COLLECTIONS, SERVER_COLLECTIONS as SERVER_COLLECTIONS4 } from "@01.software/sdk";
3567
- var schema34 = {
3755
+ var schema35 = {
3568
3756
  collection: z28.enum(SERVER_COLLECTIONS4).describe("Collection name"),
3569
3757
  operation: z28.enum(["read", "write", "full-crud"]).default("read").describe("What operations are needed"),
3570
3758
  surface: z28.enum(["query-builder", "react-query", "server-api"]).default("query-builder").describe("Preferred API surface")
3571
3759
  };
3572
- var metadata34 = {
3760
+ var metadata35 = {
3573
3761
  name: "sdk-get-collection-pattern",
3574
3762
  description: "Get the recommended CRUD pattern for a specific collection. Returns code examples for the chosen API surface and operation type.",
3575
3763
  annotations: {
@@ -3766,13 +3954,13 @@ function handler6({
3766
3954
 
3767
3955
  // src/prompts/sdk-usage-guide.ts
3768
3956
  import { z as z29 } from "zod";
3769
- var schema35 = {
3957
+ var schema36 = {
3770
3958
  goal: z29.string().describe('What the user wants to accomplish (e.g., "query product list", "create order")'),
3771
3959
  runtime: z29.enum(["browser", "server"]).optional().describe("Target runtime: browser (React/Next.js client) or server (Node.js)"),
3772
3960
  surface: z29.enum(["query-builder", "react-query", "customer-api", "server-api"]).optional().describe("Preferred API surface"),
3773
3961
  collection: z29.string().optional().describe("Specific collection if relevant")
3774
3962
  };
3775
- var metadata35 = {
3963
+ var metadata36 = {
3776
3964
  name: "sdk-usage-guide",
3777
3965
  title: "SDK Usage Guide",
3778
3966
  description: "Provides guidance on how to perform a specific task using the 01.software SDK",
@@ -3946,12 +4134,12 @@ const { allAvailable } = await client.commerce.product.stockCheck({
3946
4134
  // src/prompts/collection-query-help.ts
3947
4135
  import { z as z30 } from "zod";
3948
4136
  import { COLLECTIONS as COLLECTIONS2, SERVER_COLLECTIONS as SERVER_COLLECTIONS5 } from "@01.software/sdk";
3949
- var schema36 = {
4137
+ var schema37 = {
3950
4138
  collection: z30.enum(SERVER_COLLECTIONS5).describe("Collection name"),
3951
4139
  operation: z30.enum(["find", "create", "update", "delete"]).describe("Operation to perform (find, create, update, delete)"),
3952
4140
  filters: z30.string().optional().describe("Filter conditions (JSON string, optional)")
3953
4141
  };
3954
- var metadata36 = {
4142
+ var metadata37 = {
3955
4143
  name: "collection-query-help",
3956
4144
  title: "Collection Query Help",
3957
4145
  description: "Provides guidance on how to write queries for a specific collection",
@@ -4049,7 +4237,7 @@ ${operation === "find" ? `- Use \`where\` option for filtering (Payload query sy
4049
4237
 
4050
4238
  // src/prompts/order-flow-guide.ts
4051
4239
  import { z as z31 } from "zod";
4052
- var schema37 = {
4240
+ var schema38 = {
4053
4241
  scenario: z31.enum([
4054
4242
  "simple-order",
4055
4243
  "cart-checkout",
@@ -4058,7 +4246,7 @@ var schema37 = {
4058
4246
  "fulfillment-tracking"
4059
4247
  ]).describe("Order flow scenario")
4060
4248
  };
4061
- var metadata37 = {
4249
+ var metadata38 = {
4062
4250
  name: "order-flow-guide",
4063
4251
  title: "Order Flow Guide",
4064
4252
  description: "Provides step-by-step guidance for ecommerce order flows including creation, checkout, returns, and fulfillment.",
@@ -4078,10 +4266,16 @@ var SCENARIOS = {
4078
4266
  - Successful confirmation transitions the order to \`paid\`
4079
4267
  - Paid orders reserve sellable quantity (reservedStock += qty); physical stock is decremented on delivery
4080
4268
 
4081
- 3. **Fulfillment** \u2192 \`create-fulfillment\` tool
4082
- - Provide carrier + trackingNumber for shipped status
4083
- - Partial shipment \u2192 order becomes \`preparing\`
4084
- - All items shipped \u2192 order becomes \`shipped\`
4269
+ 3. **Prepare Fulfillment Work** \u2192 \`prepare-fulfillment-order\` tool
4270
+ - Provide orderNumber only
4271
+ - Starts fulfillment-order work without carrier/tracking
4272
+ - Order display status is derived as \`preparing\`
4273
+
4274
+ 4. **Create Shipment** \u2192 \`create-fulfillment\` tool
4275
+ - Provide orderNumber
4276
+ - Optional: carrier + trackingNumber can be supplied now or later
4277
+ - Shipment status starts as \`shipped\`
4278
+ - Shipment state drives the derived order display status
4085
4279
 
4086
4280
  ### Code Example (ServerClient)
4087
4281
  \`\`\`typescript
@@ -4112,7 +4306,12 @@ await client.commerce.orders.confirmPayment({
4112
4306
  confirmationSource: 'provider_api_confirm'
4113
4307
  })
4114
4308
 
4115
- // 3. Ship items
4309
+ // 3. Start fulfillment work without tracking
4310
+ await client.commerce.orders.prepareFulfillmentOrder({
4311
+ orderNumber: 'ORD-240101-001'
4312
+ })
4313
+
4314
+ // 4. Ship items; tracking can be added now or later
4116
4315
  await client.commerce.orders.createFulfillment({
4117
4316
  orderNumber: 'ORD-240101-001',
4118
4317
  carrier: 'cj',
@@ -4169,7 +4368,7 @@ const order = await client.commerce.orders.checkout({
4169
4368
  - Requires pgPaymentId and paymentKey for provider-verified refund
4170
4369
 
4171
4370
  ### Key Points
4172
- - Full refund: original transaction \u2192 \`canceled\`
4371
+ - Full refund: original transaction \u2192 \`canceled\` (**return-with-refund only**; order-cancel does NOT cancel the transaction \u2014 it stays \`paid\` until the storefront PG refund resolves it)
4173
4372
  - Partial refund: new refund transaction created
4174
4373
  - Stock restored: stock += qty, reservedStock -= qty
4175
4374
  - Cumulative refunds tracked: refundAmount + order.refundedAmount \u2264 totalAmount
@@ -4188,23 +4387,25 @@ await client.commerce.orders.returnWithRefund({
4188
4387
  paymentKey: 'payment_key_xxx'
4189
4388
  })
4190
4389
  \`\`\``,
4191
- "order-cancel": `## Provider-Verified Order Cancellation
4390
+ "order-cancel": `## Local Order Cancellation (PG refund separate)
4192
4391
 
4193
4392
  ### Flow
4194
4393
 
4195
4394
  1. **Cancel Order** -> \`cancel-order\` tool
4196
- - Pending or failed unpaid orders cancel without a provider call
4197
- - Paid captured orders use the server-stored provider payment key from the captured transaction
4198
- - Paid captured orders are refunded through the provider-verified path before local status changes
4199
- - Successful paid cancellation releases reservedStock and moves the order to \`canceled\`
4200
- - Duplicate local success returns \`alreadyCanceled: true\`; do not issue a second refund
4201
- - Provider-refunded local blockers return \`reconciliationRequired: true\` on retry
4395
+ - Pending or failed unpaid orders cancel locally without a PG call
4396
+ - Paid captured orders cancel **locally only**: order \`canceled\`, payment transaction stays \`paid\`, reservedStock released
4397
+ - **PG refund is not performed by Console** \u2014 storefront/BFF calls Toss/Portone; webhook sync is a follow-up
4398
+ - \`refundedAmount\` is not incremented on local cancel; new cancels return \`providerRefunded: false\`
4399
+ - \`refundPending: true\` signals storefront PG refund is still required; idempotent retries may return it from server metadata
4400
+ - \`in_progress\` / \`on_hold\` preparation fulfillment orders are voided during cancel when no shipment exists
4401
+ - Legacy inline-PG-cancel rows may still return \`reconciliationRequired: true\` with \`providerRefunded: true\`
4402
+ - Duplicate local success returns \`alreadyCanceled: true\`
4202
4403
 
4203
4404
  ### V1 Rejections
4204
- - Orders with non-failed fulfillments are rejected
4405
+ - Orders with active fulfillments (not \`failed\` / \`canceled\`) are rejected
4205
4406
  - \`shipped\`, \`delivered\`, \`confirmed\`, and return-axis orders are rejected
4206
4407
  - Active returns are rejected; use \`return-with-refund\` after delivery
4207
- - Partial line-item cancellation and no-refund paid cancellation are not supported in v1
4408
+ - Partial line-item cancellation is not supported in v1
4208
4409
 
4209
4410
  ### Code Example
4210
4411
  \`\`\`typescript
@@ -4216,36 +4417,78 @@ await client.commerce.orders.cancelOrder({
4216
4417
  })
4217
4418
  \`\`\`
4218
4419
 
4219
- If \`reconciliationRequired\` is true, stop provider retries and hand off to an operator to reconcile fulfillment, stock, and accounting manually.`,
4420
+ ### Storefront PG refund (BFF only)
4421
+
4422
+ After \`cancelOrder\`, initiate PG refund **only when all of the following hold**:
4423
+
4424
+ - First response: \`cancelCommitted: true\` **and** \`refundPending: true\`
4425
+ - Idempotent retry: \`alreadyCanceled: true\` **and** \`refundPending: true\` (read from server metadata)
4426
+ - PG lookup confirms the payment is still captured / not yet refunded
4427
+
4428
+ **Never** call PG refund when:
4429
+
4430
+ - \`providerRefunded: true\` (legacy inline-PG-cancel or refund already recorded)
4431
+ - \`reconciliationRequired: true\` (escalate to ops \u2014 do not auto-refund)
4432
+ - \`refundPending\` is absent on an unpaid / never-captured order
4433
+
4434
+ Prefer persisting the first \`cancelOrder\` response; use PG \`getPayment\` before refund when state is uncertain.
4435
+
4436
+ After a PG refund attempt reaches a terminal result, report that exact result back to Console. This is a BFF/server-only operation and requires an \`sk01_\` server API key.
4437
+
4438
+ \`\`\`typescript
4439
+ await client.commerce.orders.resolveCancelRefund({
4440
+ orderNumber: 'ORD-240101-001',
4441
+ idempotencyKey: 'refund-cancel-ORD-240101-001-attempt-1',
4442
+ outcome: 'succeeded',
4443
+ refundedAmount: 59800,
4444
+ pgProvider: 'toss',
4445
+ pgRefundId: 'toss-refund-abc'
4446
+ })
4447
+ \`\`\`
4448
+
4449
+ Use one idempotency key per distinct PG refund attempt/result. For PG refund failure, call \`resolveCancelRefund({ outcome: 'failed', refundedAmount: 0, ... })\` with that attempt key. If a later PG attempt succeeds after a reported failure, use a new key such as \`refund-cancel-ORD-240101-001-attempt-2\`. Reuse the exact same \`idempotencyKey\` only for transport retries of the same reported result; never reuse it for a different order, outcome, provider, amount, or provider refund id.`,
4220
4450
  "fulfillment-tracking": `## Fulfillment & Tracking
4221
4451
 
4222
4452
  ### Creating Fulfillment
4223
- 1. **Create Fulfillment** \u2192 \`create-fulfillment\` tool
4224
- - Order must be \`paid\` or \`preparing\`
4225
- - With carrier + trackingNumber \u2192 fulfillment status = \`shipped\`
4226
- - Without \u2192 fulfillment status = \`pending\`
4453
+ 1. **Prepare Fulfillment Work** \u2192 \`prepare-fulfillment-order\` tool
4454
+ - Order must be paid and fulfillable
4455
+ - Provide orderNumber only
4456
+ - No carrier/tracking is required
4457
+ - Fulfillment order status becomes \`in_progress\`
4458
+
4459
+ 2. **Create Shipment** \u2192 \`create-fulfillment\` tool
4460
+ - Provide orderNumber
4461
+ - Optional: carrier and trackingNumber can be supplied now or updated later
4462
+ - Optional: fulfillmentOrderId and item quantities for partial shipments
4463
+ - Shipment status starts as \`shipped\`
4227
4464
 
4228
4465
  ### Updating Fulfillment
4229
- 2. **Update** \u2192 \`update-fulfillment\` tool
4230
- - FSM: pending \u2192 packed \u2192 shipped \u2192 delivered (terminal)
4231
- - Or: pending/packed/shipped \u2192 failed (terminal)
4232
- - Carrier/trackingNumber changeable only in pending/packed status
4466
+ 3. **Update Shipment** \u2192 \`update-fulfillment\` tool
4467
+ - Shipment lifecycle: shipped \u2192 delivered
4468
+ - Or: shipped \u2192 failed
4469
+ - Carrier/trackingNumber can be added or corrected after shipment creation
4233
4470
 
4234
4471
  ### Auto Timestamps
4235
4472
  - \`shipped\` \u2192 sets \`shippedAt\`
4236
4473
  - \`delivered\` \u2192 sets \`deliveredAt\`
4237
4474
 
4238
- ### Order Auto-sync
4239
- - All items shipped with carrier \u2192 order \`shipped\`
4240
- - Partial shipment \u2192 order \`preparing\`
4241
- - All non-failed fulfillments delivered \u2192 order \`delivered\`
4475
+ ### Order Display Projection
4476
+ - \`preparing\` is derived from active fulfillment-order work
4477
+ - \`shipped\` is derived from active shipment rows
4478
+ - \`delivered\` is derived only after all active shipments are delivered
4479
+ - \`confirmed\` is set through \`update-order\` after delivery
4242
4480
 
4243
4481
  ### Carriers
4244
4482
  cj, hanjin, lotte, epost, logen, other
4245
4483
 
4246
4484
  ### Code Example
4247
4485
  \`\`\`typescript
4248
- // Create fulfillment with tracking
4486
+ // Prepare fulfillment work first
4487
+ await client.commerce.orders.prepareFulfillmentOrder({
4488
+ orderNumber: 'ORD-240101-001'
4489
+ })
4490
+
4491
+ // Create shipment; carrier/tracking are optional
4249
4492
  await client.commerce.orders.createFulfillment({
4250
4493
  orderNumber: 'ORD-240101-001',
4251
4494
  carrier: 'cj',
@@ -4253,6 +4496,13 @@ await client.commerce.orders.createFulfillment({
4253
4496
  items: [{ orderItem: 'oi-id', quantity: 2 }]
4254
4497
  })
4255
4498
 
4499
+ // Add or update tracking later
4500
+ await client.commerce.orders.updateFulfillment({
4501
+ fulfillmentId: 'ful-id',
4502
+ carrier: 'cj',
4503
+ trackingNumber: '1234567890'
4504
+ })
4505
+
4256
4506
  // Mark as delivered
4257
4507
  await client.commerce.orders.updateFulfillment({
4258
4508
  fulfillmentId: 'ful-id',
@@ -4270,7 +4520,7 @@ ${SCENARIOS[scenario] || "Unknown scenario."}
4270
4520
  ## Related MCP Tools
4271
4521
  - \`create-order\`, \`get-order\`, \`update-order\`
4272
4522
  - \`checkout\`
4273
- - \`create-fulfillment\`, \`update-fulfillment\`
4523
+ - \`prepare-fulfillment-order\`, \`create-fulfillment\`, \`update-fulfillment\`
4274
4524
  - \`create-return\`, \`update-return\`, \`return-with-refund\`
4275
4525
  - \`confirm-payment\`, \`cancel-order\`, \`update-transaction\`
4276
4526
  - \`validate-discount\`, \`calculate-shipping\``;
@@ -4278,7 +4528,7 @@ ${SCENARIOS[scenario] || "Unknown scenario."}
4278
4528
 
4279
4529
  // src/prompts/feature-setup-guide.ts
4280
4530
  import { z as z32 } from "zod";
4281
- var schema38 = {
4531
+ var schema39 = {
4282
4532
  feature: z32.enum([
4283
4533
  "ecommerce",
4284
4534
  "customers",
@@ -4294,7 +4544,7 @@ var schema38 = {
4294
4544
  "community"
4295
4545
  ]).describe("Feature to get setup guide for")
4296
4546
  };
4297
- var metadata38 = {
4547
+ var metadata39 = {
4298
4548
  name: "feature-setup-guide",
4299
4549
  title: "Feature Setup Guide",
4300
4550
  description: "Setup checklist and remediation guide for a tenant feature. Load with check-feature-progress and get-tenant-context to diagnose setup gaps.",
@@ -4502,7 +4752,7 @@ ${FEATURES[feature] || "Unknown feature."}
4502
4752
  }
4503
4753
 
4504
4754
  // src/resources/(config)/app.ts
4505
- var metadata39 = {
4755
+ var metadata40 = {
4506
4756
  name: "app-config",
4507
4757
  title: "Application Config",
4508
4758
  description: "01.software SDK and MCP server configuration information"
@@ -4546,7 +4796,7 @@ The hosted HTTP MCP endpoint at https://mcp.01.software/mcp exposes only these O
4546
4796
  - \`sdk-get-auth-setup\` - Get framework-specific auth setup guidance
4547
4797
  - \`sdk-get-collection-pattern\` - Get collection-specific usage patterns
4548
4798
 
4549
- ## Local CLI Stdio Surface (33)
4799
+ ## Local CLI Stdio Surface (35)
4550
4800
 
4551
4801
  For trusted local server-key workflows, start the stdio server:
4552
4802
 
@@ -4568,7 +4818,7 @@ Rate limits depend on your tenant plan:
4568
4818
 
4569
4819
  // src/resources/(collections)/schema.ts
4570
4820
  import { COLLECTIONS as COLLECTIONS3 } from "@01.software/sdk";
4571
- var metadata40 = {
4821
+ var metadata41 = {
4572
4822
  name: "collections-schema",
4573
4823
  title: "Collection Schema Info",
4574
4824
  description: "Available collections and their schema information"
@@ -4705,7 +4955,7 @@ Total available collections: ${COLLECTIONS3.length}`;
4705
4955
  }
4706
4956
 
4707
4957
  // src/resources/(docs)/getting-started.ts
4708
- var metadata41 = {
4958
+ var metadata42 = {
4709
4959
  name: "docs-getting-started",
4710
4960
  title: "Getting Started",
4711
4961
  description: "01.software SDK getting started guide"
@@ -4766,7 +5016,7 @@ const result = await client.collections.from('products').find({
4766
5016
  }
4767
5017
 
4768
5018
  // src/resources/(docs)/guides.ts
4769
- var metadata42 = {
5019
+ var metadata43 = {
4770
5020
  name: "docs-guides",
4771
5021
  title: "Guides",
4772
5022
  description: "01.software SDK usage guides"
@@ -4979,7 +5229,7 @@ For more implementation guidance, see the [SDK Guide](/developers/sdk).`;
4979
5229
  }
4980
5230
 
4981
5231
  // src/resources/(docs)/api.ts
4982
- var metadata43 = {
5232
+ var metadata44 = {
4983
5233
  name: "docs-api",
4984
5234
  title: "API Reference",
4985
5235
  description: "01.software SDK API reference documentation"
@@ -5262,7 +5512,7 @@ For more details, see the [API documentation](/developers/api).`;
5262
5512
  }
5263
5513
 
5264
5514
  // src/resources/(docs)/query-builder.ts
5265
- var metadata44 = {
5515
+ var metadata45 = {
5266
5516
  name: "docs-query-builder",
5267
5517
  title: "Query Builder",
5268
5518
  description: "01.software SDK Query Builder API reference (client.collections.from)"
@@ -5415,6 +5665,33 @@ if (page1.hasNextPage) {
5415
5665
  }
5416
5666
  \`\`\`
5417
5667
 
5668
+ ## Join fields (\`joins\`)
5669
+
5670
+ Payload \`type: 'join'\` reverse-relations (e.g. \`products.variants\`, \`products.options\`) are **not** controlled by \`depth\`. When \`joins\` is omitted, each join field defaults to **limit 10** docs.
5671
+
5672
+ Storefront PLPs that query \`products\` with only \`depth\` and group client-side can silently drop color swatches when a product has more than 10 option values. Prefer \`commerce.product.listingGroupsCatalog()\` + \`buildProductListingCard()\`, or spread \`PRODUCT_PLP_FIND_OPTIONS\` from \`@01.software/sdk\` into raw \`find()\` calls.
5673
+
5674
+ \`\`\`typescript
5675
+ import { PRODUCT_PLP_FIND_OPTIONS } from '@01.software/sdk'
5676
+
5677
+ await client.collections.from('products').find({
5678
+ ...PRODUCT_PLP_FIND_OPTIONS,
5679
+ where: { status: { equals: 'published' } },
5680
+ limit: 24,
5681
+ })
5682
+
5683
+ // Or configure joins explicitly (tune limits to your catalog size):
5684
+ await client.collections.from('products').find({
5685
+ joins: {
5686
+ variants: { limit: 50, sort: '_order' },
5687
+ options: { limit: 30, sort: '_order' },
5688
+ },
5689
+ })
5690
+
5691
+ // Disable all join-field population for lightweight lists:
5692
+ await client.collections.from('products').find({ joins: false })
5693
+ \`\`\`
5694
+
5418
5695
  ## Sorting
5419
5696
 
5420
5697
  \`\`\`typescript
@@ -5456,7 +5733,7 @@ console.log(result.hasNextPage) // true
5456
5733
  }
5457
5734
 
5458
5735
  // src/resources/(docs)/react-query.ts
5459
- var metadata45 = {
5736
+ var metadata46 = {
5460
5737
  name: "docs-react-query",
5461
5738
  title: "React Query Hooks",
5462
5739
  description: "01.software SDK React Query hooks reference (@01.software/sdk/query)"
@@ -5688,7 +5965,7 @@ export function ProductList() {
5688
5965
  }
5689
5966
 
5690
5967
  // src/resources/(docs)/server-api.ts
5691
- var metadata46 = {
5968
+ var metadata47 = {
5692
5969
  name: "docs-server-api",
5693
5970
  title: "Server-side API",
5694
5971
  description: "01.software SDK server-side API reference (client.commerce) for orders, fulfillments, returns, carts, and validation"
@@ -5764,25 +6041,34 @@ const order = docs[0] ?? null
5764
6041
  \`\`\`
5765
6042
 
5766
6043
  ### updateOrder()
5767
- Update order status.
6044
+ Confirm an order after delivery. Financial and shipment/display statuses are server-derived.
5768
6045
 
5769
6046
  \`\`\`typescript
5770
6047
  const order = await client.commerce.orders.update({
5771
6048
  orderNumber: 'ORD-20240101-0001',
5772
- status: 'paid', // pending | paid | failed | canceled | preparing | shipped | delivered | confirmed
6049
+ status: 'confirmed',
5773
6050
  })
5774
6051
  \`\`\`
5775
6052
 
5776
6053
  ## Fulfillment API
5777
6054
 
6055
+ ### prepareFulfillmentOrder()
6056
+ Start fulfillment-order work without carrier or tracking.
6057
+
6058
+ \`\`\`typescript
6059
+ const result = await client.commerce.orders.prepareFulfillmentOrder({
6060
+ orderNumber: 'ORD-20240101-0001',
6061
+ })
6062
+ \`\`\`
6063
+
5778
6064
  ### createFulfillment()
5779
- Create a shipment record for order items.
6065
+ Create a shipment record for order items. Carrier and trackingNumber are optional and can be added later.
5780
6066
 
5781
6067
  \`\`\`typescript
5782
6068
  const fulfillment = await client.commerce.orders.createFulfillment({
5783
6069
  orderNumber: 'ORD-20240101-0001',
5784
- carrier?: 'cj', // cj | hanjin | lotte | epost | logen | other
5785
- trackingNumber?: '123456789012',
6070
+ carrier: 'cj', // optional: cj | hanjin | lotte | epost | logen | other
6071
+ trackingNumber: '123456789012', // optional
5786
6072
  items: [
5787
6073
  { orderItem: 'order-item-id', quantity: 2 }
5788
6074
  ],
@@ -5790,14 +6076,13 @@ const fulfillment = await client.commerce.orders.createFulfillment({
5790
6076
  \`\`\`
5791
6077
 
5792
6078
  ### updateFulfillment()
5793
- Update fulfillment status and optionally carrier/tracking.
6079
+ Update fulfillment status or tracking information.
5794
6080
 
5795
6081
  \`\`\`typescript
5796
6082
  const fulfillment = await client.commerce.orders.updateFulfillment({
5797
6083
  fulfillmentId: 'fulfillment-id',
5798
- status: 'delivered', // packed | shipped | delivered | failed
5799
- carrier?: 'cj',
5800
- trackingNumber?: '123456789012',
6084
+ carrier: 'cj',
6085
+ trackingNumber: '123456789012',
5801
6086
  })
5802
6087
  \`\`\`
5803
6088
 
@@ -5812,9 +6097,12 @@ const ret = await client.commerce.orders.createReturn({
5812
6097
  reason?: 'defective', // change_of_mind | defective | wrong_delivery | damaged | other
5813
6098
  reasonDetail?: 'Screen cracked on arrival',
5814
6099
  returnItems: [
5815
- { orderItem: 'order-item-id', quantity: 1 }
6100
+ { orderItem: 'order-item-id', quantity: 1, restockingFee?: 500 }
5816
6101
  ],
5817
6102
  refundAmount: 29900,
6103
+ returnShippingFee?: 1500,
6104
+ initialShippingRefundAmount?: 3000,
6105
+ initialShippingRefundOverrideNote?: 'Policy override note',
5818
6106
  })
5819
6107
  \`\`\`
5820
6108
 
@@ -5841,6 +6129,8 @@ const result = await client.commerce.orders.returnWithRefund({
5841
6129
  ],
5842
6130
  refundAmount: 29900,
5843
6131
  returnShippingFee?: 1500,
6132
+ initialShippingRefundAmount?: 3000,
6133
+ initialShippingRefundOverrideNote?: 'Policy override note',
5844
6134
  pgPaymentId: 'provider-payment-id', // required
5845
6135
  paymentKey: 'provider-payment-key', // required for provider refund
5846
6136
  refundReceiptUrl?: 'https://...',
@@ -5972,7 +6262,7 @@ const result = await client.commerce.shipping.calculate({
5972
6262
  }
5973
6263
 
5974
6264
  // src/resources/(docs)/customer-auth.ts
5975
- var metadata47 = {
6265
+ var metadata48 = {
5976
6266
  name: "docs-customer-auth",
5977
6267
  title: "Customer Auth API",
5978
6268
  description: "01.software SDK Customer Auth API reference (client.customer)"
@@ -6150,7 +6440,7 @@ async function loadProfile() {
6150
6440
  }
6151
6441
 
6152
6442
  // src/resources/(docs)/browser-vs-server.ts
6153
- var metadata48 = {
6443
+ var metadata49 = {
6154
6444
  name: "docs-browser-vs-server",
6155
6445
  title: "Client vs ServerClient",
6156
6446
  description: "When to use Client (createClient) vs ServerClient (createServerClient) in the 01.software SDK"
@@ -6316,7 +6606,7 @@ export function ProductList() {
6316
6606
  }
6317
6607
 
6318
6608
  // src/resources/(docs)/file-upload.ts
6319
- var metadata49 = {
6609
+ var metadata50 = {
6320
6610
  name: "docs-file-upload",
6321
6611
  title: "File Upload",
6322
6612
  description: "01.software SDK file upload patterns using the images collection"
@@ -6467,7 +6757,7 @@ The platform stores files in Cloudflare R2 and serves via CDN (\`cdn.01.software
6467
6757
  }
6468
6758
 
6469
6759
  // src/resources/(docs)/webhook.ts
6470
- var metadata50 = {
6760
+ var metadata51 = {
6471
6761
  name: "docs-webhook",
6472
6762
  title: "Webhooks",
6473
6763
  description: "01.software SDK webhook verification and event handling"
@@ -6536,8 +6826,8 @@ export async function POST(request: Request) {
6536
6826
 
6537
6827
  \`\`\`typescript
6538
6828
  import {
6829
+ createCommerceNotificationWebhookHandler,
6539
6830
  handleWebhook,
6540
- isCommerceNotificationWebhookEvent,
6541
6831
  } from '@01.software/sdk/webhook'
6542
6832
 
6543
6833
  function getWebhookSecret(): string {
@@ -6546,26 +6836,25 @@ function getWebhookSecret(): string {
6546
6836
  return secret
6547
6837
  }
6548
6838
 
6549
- export async function POST(request: Request) {
6550
- return handleWebhook(request, async (event) => {
6551
- if (!isCommerceNotificationWebhookEvent(event)) return
6552
-
6553
- const idempotencyKey = \`\${event.notification.intentId}:\${event.notification.dedupeKey}\`
6554
- const processed = await processOnce(idempotencyKey, async () => {
6555
- if (event.notification.event === 'orderPaid') {
6556
- const orderId = event.notification.orderId ?? event.data.orderId
6557
- if (orderId) await updateOrderWorkflow(orderId)
6558
- }
6839
+ const commerceNotificationHandler = createCommerceNotificationWebhookHandler({
6840
+ async orderPaid({ event, idempotencyKey }) {
6841
+ await processOnce(idempotencyKey, async () => {
6842
+ const orderId = event.notification.orderId ?? event.data.orderId
6843
+ if (orderId) await updateOrderWorkflow(orderId)
6844
+ })
6845
+ },
6559
6846
 
6560
- if (event.notification.event === 'fulfillmentShipped') {
6561
- const fulfillmentId =
6562
- event.notification.fulfillmentId ?? event.data.fulfillmentId
6563
- if (fulfillmentId) await updateFulfillmentWorkflow(fulfillmentId)
6564
- }
6847
+ async fulfillmentShipped({ event, idempotencyKey }) {
6848
+ await processOnce(idempotencyKey, async () => {
6849
+ const fulfillmentId =
6850
+ event.notification.fulfillmentId ?? event.data.fulfillmentId
6851
+ if (fulfillmentId) await updateFulfillmentWorkflow(fulfillmentId)
6565
6852
  })
6853
+ },
6854
+ })
6566
6855
 
6567
- if (!processed) return
6568
- }, {
6856
+ export async function POST(request: Request) {
6857
+ return handleWebhook(request, commerceNotificationHandler, {
6569
6858
  secret: getWebhookSecret(),
6570
6859
  })
6571
6860
  }
@@ -6573,11 +6862,11 @@ export async function POST(request: Request) {
6573
6862
 
6574
6863
  Back \`processOnce()\` with durable storage such as a database unique key or queue idempotency store; do not use process-local memory for webhook idempotency.
6575
6864
 
6576
- ## Headless Commerce Email Workers
6865
+ ## Commerce Notification Workers
6577
6866
 
6578
- For tenant-owned transactional email, use \`commerce.notification\` as the trigger and build a signed worker with \`createCommerceEmailWebhookHandler()\`. 01.software owns event timing, delivery retries, signing, and idempotency signals; the tenant worker owns template rendering, provider credentials, extra order/customer fetches via \`createServerClient\`, and final delivery through a tenant provider such as Resend.
6867
+ For new tenant-owned commerce side effects, use \`commerce.notification\` as the trigger and build a signed worker with \`createCommerceNotificationWebhookHandler()\`. Existing email workers may keep \`createCommerceEmailWebhookHandler()\` as a compatibility alias, but the general helper name should be used in new guidance. 01.software owns event timing, delivery retries, signing, and idempotency signals; the tenant worker owns email, external PG calls, extra order/customer fetches via \`createServerClient\`, and final side effects.
6579
6868
 
6580
- Use \`getCommerceNotificationIdempotencyKey(event)\` or the \`idempotencyKey\` passed by \`createCommerceEmailWebhookHandler()\`, then guard provider sends with durable \`processOnce(idempotencyKey, ...)\` storage. The webhook payload is PII-light and is not enough for recipient data, so fetch recipient/template context with server SDK credentials. In the v1 headless path, do not store tenant ESP secrets in 01.software and do not ask 01.software to send directly through the tenant provider.
6869
+ Use \`getCommerceNotificationIdempotencyKey(event)\` or the \`idempotencyKey\` passed by \`createCommerceNotificationWebhookHandler()\`, then guard side effects with durable \`processOnce(idempotencyKey, ...)\` storage. \`notification.intentId + notification.dedupeKey\` is semantic idempotency. \`deliveryId\` is delivery-attempt observability only.
6581
6870
 
6582
6871
  ## Webhook Payload Structure
6583
6872
 
@@ -6630,9 +6919,11 @@ Canonical example (public operational identifiers only; no PII, payment/provider
6630
6919
  Use \`notification.intentId\` plus \`notification.dedupeKey\` for semantic idempotency. \`deliveryId\` is per delivery attempt / observability and may not be stable across semantic retries.
6631
6920
  Some normalized deliveries may include \`data.source\` or \`change\` metadata, but handlers should treat those fields as optional. Route from \`notification.orderId\`, \`notification.fulfillmentId\`, \`notification.returnId\`, or the matching typed \`data.*Id\` field.
6632
6921
 
6922
+ For CMS/Admin cancellation side effects, route \`commerce.notification/orderCanceled\` workers per the public webhooks guide (**orderCanceled external PG refund handoff**). Use \`orders/update\` only for cache refreshes and local projections. Detailed trusted refetch, PG refund classification, and refund reporting contracts live in that guide\u2014not in this generic webhook resource.
6923
+
6633
6924
  V1 source subscription semantics:
6634
6925
 
6635
- - \`orderPaid\` and \`orderDelivered\` are delivered through \`orders\`-scoped endpoints.
6926
+ - \`orderPaid\`, \`orderCanceled\`, and \`orderDelivered\` are delivered through \`orders\`-scoped endpoints.
6636
6927
  - \`fulfillmentShipped\` is delivered through \`fulfillments\`-scoped endpoints.
6637
6928
  - \`returnRequested\` and \`returnCompleted\` are delivered through \`returns\`-scoped endpoints.
6638
6929
  - Empty, unscoped, and all-collection endpoints do not receive v1 semantic commerce notifications.
@@ -6731,7 +7022,7 @@ Configure webhook URLs in the 01.software console under Tenant Settings > Webhoo
6731
7022
  }
6732
7023
 
6733
7024
  // src/resources/(docs)/product-detail.ts
6734
- var metadata51 = {
7025
+ var metadata52 = {
6735
7026
  name: "docs-product-detail",
6736
7027
  title: "Product Detail Helper",
6737
7028
  description: "01.software SDK commerce.product.detail helper guide"
@@ -6841,7 +7132,7 @@ function runtimeAnnotationsFor(meta) {
6841
7132
  openWorldHint: policy.annotationPolicy.openWorld
6842
7133
  };
6843
7134
  }
6844
- function registerTool(server, schema39, meta, handler21) {
7135
+ function registerTool(server, schema40, meta, handler21) {
6845
7136
  let registered = REGISTERED_TOOLS_BY_SERVER.get(server);
6846
7137
  if (!registered) {
6847
7138
  registered = /* @__PURE__ */ new Set();
@@ -6852,7 +7143,7 @@ function registerTool(server, schema39, meta, handler21) {
6852
7143
  meta.name,
6853
7144
  {
6854
7145
  description: meta.description,
6855
- inputSchema: schema39,
7146
+ inputSchema: schema40,
6856
7147
  annotations: runtimeAnnotationsFor(meta)
6857
7148
  },
6858
7149
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -6902,13 +7193,13 @@ function registerTool(server, schema39, meta, handler21) {
6902
7193
  }
6903
7194
  );
6904
7195
  }
6905
- function registerPrompt(server, schema39, meta, handler21) {
7196
+ function registerPrompt(server, schema40, meta, handler21) {
6906
7197
  server.registerPrompt(
6907
7198
  meta.name,
6908
7199
  {
6909
7200
  title: meta.title,
6910
7201
  description: meta.description,
6911
- argsSchema: schema39
7202
+ argsSchema: schema40
6912
7203
  },
6913
7204
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6914
7205
  (params) => ({
@@ -6968,245 +7259,251 @@ function createServer(options = {}) {
6968
7259
  server,
6969
7260
  schema8,
6970
7261
  metadata8,
6971
- updateFulfillment
7262
+ prepareFulfillmentOrder
6972
7263
  );
6973
7264
  registerTool(
6974
7265
  server,
6975
7266
  schema9,
6976
7267
  metadata9,
6977
- updateTransaction
7268
+ updateFulfillment
6978
7269
  );
6979
7270
  registerTool(
6980
7271
  server,
6981
7272
  schema10,
6982
7273
  metadata10,
6983
- confirmPayment
7274
+ updateTransaction
6984
7275
  );
6985
- registerTool(server, schema11, metadata11, cancelOrder);
6986
7276
  registerTool(
6987
7277
  server,
6988
- schema12,
6989
- metadata12,
6990
- createReturn
7278
+ schema11,
7279
+ metadata11,
7280
+ confirmPayment
6991
7281
  );
7282
+ registerTool(server, schema12, metadata12, cancelOrder);
6992
7283
  registerTool(
6993
7284
  server,
6994
7285
  schema13,
6995
7286
  metadata13,
6996
- updateReturn
7287
+ createReturn
6997
7288
  );
6998
7289
  registerTool(
6999
7290
  server,
7000
7291
  schema14,
7001
7292
  metadata14,
7002
- returnWithRefund
7293
+ updateReturn
7003
7294
  );
7004
- registerTool(server, schema15, metadata15, addCartItem);
7005
7295
  registerTool(
7006
7296
  server,
7007
- schema16,
7008
- metadata16,
7009
- updateCartItem
7297
+ schema15,
7298
+ metadata15,
7299
+ returnWithRefund
7010
7300
  );
7301
+ registerTool(server, schema16, metadata16, addCartItem);
7011
7302
  registerTool(
7012
7303
  server,
7013
7304
  schema17,
7014
7305
  metadata17,
7015
- removeCartItem
7306
+ updateCartItem
7016
7307
  );
7017
7308
  registerTool(
7018
7309
  server,
7019
7310
  schema18,
7020
7311
  metadata18,
7021
- applyDiscount
7312
+ removeCartItem
7022
7313
  );
7023
7314
  registerTool(
7024
7315
  server,
7025
7316
  schema19,
7026
7317
  metadata19,
7027
- removeDiscount
7318
+ applyDiscount
7028
7319
  );
7029
- registerTool(server, schema20, metadata20, clearCart);
7030
7320
  registerTool(
7031
7321
  server,
7032
- schema21,
7033
- metadata21,
7034
- validateDiscount
7322
+ schema20,
7323
+ metadata20,
7324
+ removeDiscount
7035
7325
  );
7326
+ registerTool(server, schema21, metadata21, clearCart);
7036
7327
  registerTool(
7037
7328
  server,
7038
7329
  schema22,
7039
7330
  metadata22,
7040
- calculateShipping
7331
+ validateDiscount
7041
7332
  );
7042
- registerTool(server, schema23, metadata23, stockCheck);
7043
7333
  registerTool(
7044
7334
  server,
7045
- schema24,
7046
- metadata24,
7047
- productDetail
7335
+ schema23,
7336
+ metadata23,
7337
+ calculateShipping
7048
7338
  );
7339
+ registerTool(server, schema24, metadata24, stockCheck);
7049
7340
  registerTool(
7050
7341
  server,
7051
7342
  schema25,
7052
7343
  metadata25,
7344
+ productDetail
7345
+ );
7346
+ registerTool(
7347
+ server,
7348
+ schema26,
7349
+ metadata26,
7053
7350
  productUpsert
7054
7351
  );
7055
7352
  }
7056
- registerTool(
7057
- server,
7058
- schema26,
7059
- metadata26,
7060
- getCollectionSchemaTool
7061
- );
7062
7353
  registerTool(
7063
7354
  server,
7064
7355
  schema27,
7065
7356
  metadata27,
7066
- handler
7357
+ getCollectionSchemaTool
7067
7358
  );
7068
7359
  registerTool(
7069
7360
  server,
7070
7361
  schema28,
7071
7362
  metadata28,
7072
- handler2
7363
+ handler
7073
7364
  );
7074
7365
  registerTool(
7075
7366
  server,
7076
7367
  schema29,
7077
7368
  metadata29,
7078
- listConfigurableFields
7369
+ handler2
7079
7370
  );
7080
7371
  registerTool(
7081
7372
  server,
7082
7373
  schema30,
7083
7374
  metadata30,
7084
- updateFieldConfig
7375
+ listConfigurableFields
7085
7376
  );
7086
7377
  registerTool(
7087
7378
  server,
7088
7379
  schema31,
7089
7380
  metadata31,
7090
- handler3
7381
+ updateFieldConfig
7091
7382
  );
7092
7383
  registerTool(
7093
7384
  server,
7094
7385
  schema32,
7095
7386
  metadata32,
7096
- handler4
7387
+ handler3
7097
7388
  );
7098
7389
  registerTool(
7099
7390
  server,
7100
7391
  schema33,
7101
7392
  metadata33,
7102
- handler5
7393
+ handler4
7103
7394
  );
7104
7395
  registerTool(
7105
7396
  server,
7106
7397
  schema34,
7107
7398
  metadata34,
7108
- handler6
7399
+ handler5
7109
7400
  );
7110
- registerPrompt(
7401
+ registerTool(
7111
7402
  server,
7112
7403
  schema35,
7113
7404
  metadata35,
7114
- sdkUsageGuide
7405
+ handler6
7115
7406
  );
7116
7407
  registerPrompt(
7117
7408
  server,
7118
7409
  schema36,
7119
7410
  metadata36,
7120
- collectionQueryHelp
7411
+ sdkUsageGuide
7121
7412
  );
7122
7413
  registerPrompt(
7123
7414
  server,
7124
7415
  schema37,
7125
7416
  metadata37,
7126
- orderFlowGuide
7417
+ collectionQueryHelp
7127
7418
  );
7128
7419
  registerPrompt(
7129
7420
  server,
7130
7421
  schema38,
7131
7422
  metadata38,
7423
+ orderFlowGuide
7424
+ );
7425
+ registerPrompt(
7426
+ server,
7427
+ schema39,
7428
+ metadata39,
7132
7429
  featureSetupGuide
7133
7430
  );
7134
7431
  registerStaticResource(
7135
7432
  server,
7136
7433
  mcpResourceUri("app-config"),
7137
- metadata39,
7434
+ metadata40,
7138
7435
  handler7
7139
7436
  );
7140
7437
  registerStaticResource(
7141
7438
  server,
7142
7439
  mcpResourceUri("collections-schema"),
7143
- metadata40,
7440
+ metadata41,
7144
7441
  handler8
7145
7442
  );
7146
7443
  registerStaticResource(
7147
7444
  server,
7148
7445
  mcpResourceUri("docs-getting-started"),
7149
- metadata41,
7446
+ metadata42,
7150
7447
  handler9
7151
7448
  );
7152
7449
  registerStaticResource(
7153
7450
  server,
7154
7451
  mcpResourceUri("docs-guides"),
7155
- metadata42,
7452
+ metadata43,
7156
7453
  handler10
7157
7454
  );
7158
7455
  registerStaticResource(
7159
7456
  server,
7160
7457
  mcpResourceUri("docs-api"),
7161
- metadata43,
7458
+ metadata44,
7162
7459
  handler11
7163
7460
  );
7164
7461
  registerStaticResource(
7165
7462
  server,
7166
7463
  mcpResourceUri("docs-query-builder"),
7167
- metadata44,
7464
+ metadata45,
7168
7465
  handler12
7169
7466
  );
7170
7467
  registerStaticResource(
7171
7468
  server,
7172
7469
  mcpResourceUri("docs-react-query"),
7173
- metadata45,
7470
+ metadata46,
7174
7471
  handler13
7175
7472
  );
7176
7473
  registerStaticResource(
7177
7474
  server,
7178
7475
  mcpResourceUri("docs-server-api"),
7179
- metadata46,
7476
+ metadata47,
7180
7477
  handler14
7181
7478
  );
7182
7479
  registerStaticResource(
7183
7480
  server,
7184
7481
  mcpResourceUri("docs-customer-auth"),
7185
- metadata47,
7482
+ metadata48,
7186
7483
  handler15
7187
7484
  );
7188
7485
  registerStaticResource(
7189
7486
  server,
7190
7487
  mcpResourceUri("docs-browser-vs-server"),
7191
- metadata48,
7488
+ metadata49,
7192
7489
  handler16
7193
7490
  );
7194
7491
  registerStaticResource(
7195
7492
  server,
7196
7493
  mcpResourceUri("docs-file-upload"),
7197
- metadata49,
7494
+ metadata50,
7198
7495
  handler17
7199
7496
  );
7200
7497
  registerStaticResource(
7201
7498
  server,
7202
7499
  mcpResourceUri("docs-webhook"),
7203
- metadata50,
7500
+ metadata51,
7204
7501
  handler18
7205
7502
  );
7206
7503
  registerStaticResource(
7207
7504
  server,
7208
7505
  mcpResourceUri("docs-product-detail"),
7209
- metadata51,
7506
+ metadata52,
7210
7507
  handler19
7211
7508
  );
7212
7509
  return server;