@01.software/cli 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
 
7
7
  // src/lib/client.ts
8
8
  import {
9
- CollectionClient,
9
+ ServerCollectionClient,
10
10
  ServerCommerceClient,
11
11
  TenantIntrospectionApi
12
12
  } from "@01.software/sdk/server";
@@ -491,11 +491,7 @@ function resolveClientCredentials(apiKeyFlag) {
491
491
  if (!publishableKey || !secretKey) {
492
492
  throw credentialError({
493
493
  message: t("AuthenticationRequired"),
494
- steps: [
495
- t("RunLoginToAuthenticate"),
496
- t("PassApiKey"),
497
- t("SetEnvVars")
498
- ]
494
+ steps: [t("RunLoginToAuthenticate"), t("PassApiKey"), t("SetEnvVars")]
499
495
  });
500
496
  }
501
497
  if (!isValidBearerToken(secretKey)) {
@@ -510,7 +506,7 @@ function resolveClientOrThrow(apiKeyFlag) {
510
506
  const { publishableKey, secretKey } = resolveClientCredentials(apiKeyFlag);
511
507
  const serverOptions = { publishableKey, secretKey };
512
508
  return {
513
- collections: new CollectionClient(
509
+ collections: new ServerCollectionClient(
514
510
  publishableKey,
515
511
  secretKey,
516
512
  void 0,
@@ -536,13 +532,13 @@ import { readFileSync as readFileSync2 } from "fs";
536
532
  import { basename } from "path";
537
533
 
538
534
  // src/lib/collections.ts
539
- import { COLLECTIONS } from "@01.software/sdk";
535
+ import { SERVER_COLLECTIONS } from "@01.software/sdk";
540
536
  function validateCollection(name) {
541
- if (COLLECTIONS.includes(name)) {
537
+ if (SERVER_COLLECTIONS.includes(name)) {
542
538
  return name;
543
539
  }
544
540
  const normalized = name.replace(/-/g, "").toLowerCase();
545
- const suggestions = COLLECTIONS.filter((collection) => {
541
+ const suggestions = SERVER_COLLECTIONS.filter((collection) => {
546
542
  const candidate = collection.replace(/-/g, "").toLowerCase();
547
543
  return candidate.startsWith(normalized) || normalized.startsWith(candidate) || normalized.length >= 3 && candidate.includes(normalized);
548
544
  }).slice(0, 5);
@@ -808,79 +804,677 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
808
804
  });
809
805
  }
810
806
 
811
- // src/commands/order.ts
807
+ // ../contracts/src/tenant/index.ts
812
808
  import { z } from "zod";
813
- var idSchema = z.union([z.string().min(1), z.number()]).transform(String);
814
- var customerSnapshotSchema = z.object({
815
- email: z.string().email("Invalid email format"),
816
- name: z.string().optional(),
817
- phone: z.string().optional()
809
+ var tenantFieldConfigStateSchema = z.object({
810
+ hiddenFields: z.array(z.string()),
811
+ isHidden: z.boolean()
812
+ }).strict();
813
+ var tenantContextQuerySchema = z.object({
814
+ counts: z.literal("true").optional()
815
+ }).strict();
816
+ var tenantContextToolInputSchema = z.object({
817
+ includeCounts: z.boolean().optional().default(false).describe(
818
+ "Include per-collection document counts and config status (bypasses cache, slower)"
819
+ )
820
+ }).strict();
821
+ var tenantContextResponseSchema = z.object({
822
+ tenant: z.object({
823
+ id: z.string(),
824
+ name: z.string(),
825
+ plan: z.string(),
826
+ planSource: z.string().optional(),
827
+ authoritative: z.boolean().optional(),
828
+ capabilityVersion: z.string().optional()
829
+ }).strict(),
830
+ features: z.array(z.string()),
831
+ collections: z.object({
832
+ active: z.array(z.string()),
833
+ inactive: z.array(z.string())
834
+ }).strict(),
835
+ fieldConfigs: z.record(z.string(), tenantFieldConfigStateSchema),
836
+ counts: z.record(z.string(), z.number()).optional(),
837
+ config: z.object({
838
+ webhookConfigured: z.boolean()
839
+ }).strict().optional()
840
+ }).strict();
841
+ var tenantFeatureProgressFeatureSchema = z.enum(["ecommerce"]);
842
+ var tenantFeatureProgressInputSchema = z.object({
843
+ feature: tenantFeatureProgressFeatureSchema.describe(
844
+ "Feature to inspect for tenant implementation readiness"
845
+ ),
846
+ includeEvidence: z.boolean().optional().default(false).describe("Include sanitized counts and static surface evidence")
847
+ }).strict();
848
+ var tenantFeatureProgressStatusSchema = z.enum([
849
+ "ready",
850
+ "attention",
851
+ "blocked"
852
+ ]);
853
+ var tenantFeatureProgressItemStateSchema = z.enum([
854
+ "complete",
855
+ "incomplete",
856
+ "blocked",
857
+ "attention",
858
+ "optional",
859
+ "unknown",
860
+ "manual",
861
+ "not-applicable"
862
+ ]);
863
+ var tenantFeatureProgressSeveritySchema = z.enum([
864
+ "required",
865
+ "recommended",
866
+ "optional"
867
+ ]);
868
+ var tenantFeatureProgressEvidenceValueSchema = z.union([
869
+ z.string(),
870
+ z.number(),
871
+ z.boolean(),
872
+ z.null()
873
+ ]);
874
+ var tenantFeatureProgressItemSchema = z.object({
875
+ id: z.string(),
876
+ title: z.string(),
877
+ state: tenantFeatureProgressItemStateSchema,
878
+ severity: tenantFeatureProgressSeveritySchema,
879
+ summary: z.string(),
880
+ evidence: z.record(z.string(), tenantFeatureProgressEvidenceValueSchema).optional()
818
881
  }).strict();
819
- var shippingAddressSchema = z.object({
820
- postalCode: z.string().optional(),
821
- address: z.string().optional(),
822
- detailAddress: z.string().optional(),
823
- deliveryMessage: z.string().optional(),
824
- recipientName: z.string().optional(),
825
- phone: z.string().optional()
882
+ var tenantFeatureProgressGroupSchema = z.object({
883
+ id: z.string(),
884
+ title: z.string(),
885
+ summary: z.string().optional(),
886
+ items: z.array(tenantFeatureProgressItemSchema)
826
887
  }).strict();
827
- var orderItemSchema = z.object({
828
- product: idSchema,
829
- variant: idSchema,
830
- option: idSchema,
831
- quantity: z.number().int().positive("quantity must be a positive integer"),
832
- unitPrice: z.number().optional(),
833
- totalPrice: z.number().optional()
888
+ var tenantFeatureProgressResponseSchema = z.object({
889
+ schemaVersion: z.literal(1),
890
+ feature: tenantFeatureProgressFeatureSchema,
891
+ status: tenantFeatureProgressStatusSchema,
892
+ generatedAt: z.string(),
893
+ tenant: z.object({
894
+ id: z.string(),
895
+ name: z.string(),
896
+ plan: z.string()
897
+ }).strict(),
898
+ capability: z.object({
899
+ effectiveFeatures: z.array(z.string()),
900
+ planBlocked: z.array(z.string()),
901
+ closureAdded: z.array(z.string())
902
+ }).strict(),
903
+ summary: z.object({
904
+ complete: z.number().int().nonnegative(),
905
+ total: z.number().int().nonnegative(),
906
+ blocking: z.number().int().nonnegative(),
907
+ manual: z.number().int().nonnegative(),
908
+ unknown: z.number().int().nonnegative()
909
+ }).strict(),
910
+ groups: z.array(tenantFeatureProgressGroupSchema)
834
911
  }).strict();
835
- var orderItemsSchema = z.array(orderItemSchema).min(1, "At least one order item is required").max(100, "Maximum 100 items per order");
836
- var orderStatusSchema = z.enum([
912
+ var COLLECTION_SCHEMA_CONTRACT_VERSION = 1;
913
+ var collectionSchemaEndpointParamsSchema = z.object({
914
+ collectionSlug: z.string().min(1, "collectionSlug is required")
915
+ }).strict();
916
+ var collectionFieldOptionSchema = z.object({
917
+ label: z.string(),
918
+ value: z.string()
919
+ }).strict();
920
+ var collectionFieldSchema = z.lazy(
921
+ () => z.object({
922
+ name: z.string(),
923
+ path: z.string(),
924
+ type: z.string(),
925
+ required: z.literal(true).optional(),
926
+ unique: z.literal(true).optional(),
927
+ hasMany: z.literal(true).optional(),
928
+ relationTo: z.union([z.string(), z.array(z.string())]).optional(),
929
+ options: z.array(collectionFieldOptionSchema).optional(),
930
+ hidden: z.literal(true).optional(),
931
+ systemManaged: z.literal(true).optional(),
932
+ writable: z.boolean().optional(),
933
+ fields: z.array(collectionFieldSchema).optional()
934
+ }).strict()
935
+ );
936
+ var collectionSchemaResponseSchema = z.object({
937
+ contractVersion: z.literal(COLLECTION_SCHEMA_CONTRACT_VERSION),
938
+ mode: z.literal("effective"),
939
+ collection: z.object({
940
+ slug: z.string(),
941
+ timestamps: z.boolean(),
942
+ alwaysActive: z.boolean(),
943
+ feature: z.string().nullable(),
944
+ systemFields: z.array(z.string()),
945
+ visibility: z.object({
946
+ collectionHidden: z.boolean(),
947
+ hiddenFields: z.array(z.string())
948
+ }).strict(),
949
+ fields: z.array(collectionFieldSchema)
950
+ }).strict()
951
+ }).strict();
952
+
953
+ // ../contracts/src/ecommerce/index.ts
954
+ import { z as z3 } from "zod";
955
+
956
+ // ../contracts/src/ecommerce/product-upsert.ts
957
+ import { z as z2 } from "zod";
958
+ var IdSchema = z2.union([z2.string(), z2.number()]).transform(String);
959
+ var RemovedLegacyMediaFieldSchema = z2.unknown().optional();
960
+ var productFieldShape = {
961
+ id: IdSchema.optional(),
962
+ title: z2.string().min(1).optional(),
963
+ subtitle: z2.string().optional().nullable(),
964
+ description: z2.string().optional().nullable(),
965
+ status: z2.string().optional(),
966
+ slug: z2.string().optional(),
967
+ primaryMediaItemId: IdSchema.optional().nullable(),
968
+ thumbnail: IdSchema.optional().nullable(),
969
+ images: z2.array(IdSchema).optional(),
970
+ mediaSets: RemovedLegacyMediaFieldSchema,
971
+ vendor: z2.string().optional().nullable(),
972
+ productType: z2.string().optional().nullable(),
973
+ brand: IdSchema.optional().nullable(),
974
+ shippingPolicy: IdSchema.optional().nullable(),
975
+ weight: z2.number().int().min(0).optional().nullable(),
976
+ minOrderQuantity: z2.number().int().min(1).optional().nullable(),
977
+ maxOrderQuantity: z2.number().int().min(1).optional().nullable(),
978
+ isFeatured: z2.boolean().optional(),
979
+ publishedAt: z2.string().optional().nullable(),
980
+ categories: z2.array(IdSchema).optional(),
981
+ tags: z2.array(IdSchema).optional(),
982
+ metadata: z2.unknown().optional()
983
+ };
984
+ var PRODUCT_UPSERT_PRODUCT_FIELDS = Object.keys(
985
+ productFieldShape
986
+ );
987
+ var ProductFieldsSchema = z2.object(productFieldShape).passthrough();
988
+ var OptionValueObjectSchema = z2.object({
989
+ id: IdSchema.optional(),
990
+ value: z2.string().min(1, "Option value `value` is required"),
991
+ slug: z2.string().optional(),
992
+ swatch: z2.object({
993
+ type: z2.enum(["color", "media"]).optional().nullable(),
994
+ color: z2.string().optional().nullable(),
995
+ mediaItemId: IdSchema.optional().nullable()
996
+ }).optional().nullable(),
997
+ thumbnail: RemovedLegacyMediaFieldSchema,
998
+ images: RemovedLegacyMediaFieldSchema,
999
+ metadata: z2.unknown().optional()
1000
+ });
1001
+ var OptionValueInputSchema = OptionValueObjectSchema.passthrough().superRefine(
1002
+ (value, ctx) => {
1003
+ if (Object.prototype.hasOwnProperty.call(value, "swatchColor")) {
1004
+ ctx.addIssue({
1005
+ code: "custom",
1006
+ message: "Option value field `swatchColor` was removed. Use nested `swatch.color` instead.",
1007
+ path: ["swatchColor"]
1008
+ });
1009
+ }
1010
+ }
1011
+ );
1012
+ var OptionInputSchema = z2.object({
1013
+ id: IdSchema.optional(),
1014
+ title: z2.string().min(1, "Option `title` is required"),
1015
+ slug: z2.string().optional(),
1016
+ values: z2.array(OptionValueInputSchema).min(1, "Each option must have at least one value")
1017
+ });
1018
+ var VariantOptionValueObjectSchema = z2.object({
1019
+ valueSlug: z2.string().optional(),
1020
+ valueId: IdSchema.optional(),
1021
+ value: z2.string().optional()
1022
+ }).refine((data) => Boolean(data.valueSlug ?? data.valueId ?? data.value), {
1023
+ message: "Variant option value object requires valueSlug, valueId, or value"
1024
+ });
1025
+ var VariantInputSchema = z2.object({
1026
+ id: IdSchema.optional(),
1027
+ optionValues: z2.union([
1028
+ z2.record(
1029
+ z2.string(),
1030
+ z2.union([z2.string(), VariantOptionValueObjectSchema])
1031
+ ),
1032
+ z2.array(IdSchema)
1033
+ ]).optional(),
1034
+ sku: z2.string().optional().nullable(),
1035
+ title: z2.string().optional().nullable(),
1036
+ price: z2.number().min(0),
1037
+ compareAtPrice: z2.number().min(0).optional().nullable(),
1038
+ stock: z2.number().int().min(0).optional(),
1039
+ isUnlimited: z2.boolean().optional(),
1040
+ weight: z2.number().int().min(0).optional().nullable(),
1041
+ requiresShipping: z2.boolean().optional(),
1042
+ barcode: z2.string().optional().nullable(),
1043
+ externalId: z2.string().optional().nullable(),
1044
+ isActive: z2.boolean().optional(),
1045
+ images: z2.array(IdSchema).optional(),
1046
+ thumbnail: RemovedLegacyMediaFieldSchema,
1047
+ featuredMediaItemId: RemovedLegacyMediaFieldSchema,
1048
+ metadata: z2.unknown().optional()
1049
+ });
1050
+ var ProductUpsertObjectSchema = z2.object({
1051
+ /** Required on graph edit when the server graph is non-empty (`productId` set); optional for first seed on an empty graph. */
1052
+ graphRevision: z2.string().optional(),
1053
+ productId: IdSchema.optional(),
1054
+ product: ProductFieldsSchema.optional(),
1055
+ options: z2.array(OptionInputSchema).max(10).optional().default([]),
1056
+ variants: z2.array(VariantInputSchema).max(500).optional().default([])
1057
+ });
1058
+ var ProductUpsertSchema = ProductUpsertObjectSchema.superRefine(
1059
+ (data, ctx) => {
1060
+ const nestedProductId = data.product?.id;
1061
+ if (data.productId != null && nestedProductId != null && String(data.productId) !== String(nestedProductId)) {
1062
+ ctx.addIssue({
1063
+ code: "custom",
1064
+ message: "productId must match product.id when both are set on graph upsert.",
1065
+ path: ["productId"]
1066
+ });
1067
+ }
1068
+ const productId = data.productId ?? nestedProductId;
1069
+ const isEdit = productId != null;
1070
+ if (!isEdit && data.productId != null) {
1071
+ ctx.addIssue({
1072
+ code: "custom",
1073
+ message: "productId is not allowed when creating a product.",
1074
+ path: ["productId"]
1075
+ });
1076
+ }
1077
+ if (!isEdit && !data.product?.title) {
1078
+ ctx.addIssue({
1079
+ code: "custom",
1080
+ message: "Product `title` is required when creating a new product.",
1081
+ path: ["product", "title"]
1082
+ });
1083
+ }
1084
+ if (isEdit && data.product) {
1085
+ for (const key of Object.keys(data.product)) {
1086
+ if (key !== "id") {
1087
+ ctx.addIssue({
1088
+ code: "custom",
1089
+ message: "Existing product graph upsert accepts only product identity. Save document fields through Payload.",
1090
+ path: ["product", key]
1091
+ });
1092
+ }
1093
+ }
1094
+ }
1095
+ }
1096
+ );
1097
+
1098
+ // ../contracts/src/ecommerce/index.ts
1099
+ var transactionStatusSchema = z3.enum([
837
1100
  "pending",
838
1101
  "paid",
839
1102
  "failed",
1103
+ "canceled"
1104
+ ]);
1105
+ var financialStatusSchema = z3.enum([
1106
+ "pending",
1107
+ "paid",
840
1108
  "canceled",
1109
+ "partially_refunded",
1110
+ "refunded"
1111
+ ]);
1112
+ var orderDisplayFinancialStatusSchema = z3.enum([
1113
+ "pending",
1114
+ "paid",
1115
+ "partially_refunded",
1116
+ "refunded",
1117
+ "voided"
1118
+ ]);
1119
+ var confirmationStatusSchema = z3.enum(["unconfirmed", "confirmed"]);
1120
+ var fulfillmentOrderStatusSchema = z3.enum([
1121
+ "open",
1122
+ "in_progress",
1123
+ "on_hold",
1124
+ "canceled",
1125
+ "closed"
1126
+ ]);
1127
+ var shipmentStatusSchema = z3.enum([
1128
+ "pending",
1129
+ "shipped",
1130
+ "delivered",
1131
+ "canceled",
1132
+ "failed"
1133
+ ]);
1134
+ var orderDisplayFulfillmentStatusSchema = z3.enum([
1135
+ "unfulfilled",
1136
+ "in_progress",
1137
+ "on_hold",
1138
+ "shipped",
1139
+ "fulfilled",
1140
+ "canceled"
1141
+ ]);
1142
+ var orderReturnStatusSchema = z3.enum([
1143
+ "no_return",
1144
+ "return_requested",
1145
+ "in_progress",
1146
+ "returned"
1147
+ ]);
1148
+ var orderStatusSchema = z3.enum([
1149
+ "pending",
1150
+ "paid",
1151
+ "canceled",
1152
+ "refunded",
1153
+ "preparing",
1154
+ "shipped",
1155
+ "delivered",
1156
+ "confirmed",
1157
+ "return_requested",
1158
+ "return_processing",
1159
+ "returned"
1160
+ ]);
1161
+ var entityIdSchema = z3.union([z3.string().min(1), z3.number()]).transform(String);
1162
+ var createOrderItemSchema = z3.object({
1163
+ // `product` and `option` are storefront-optional: the create-order
1164
+ // endpoint derives the product from the variant's parent and snapshots
1165
+ // option selection from the variant.
1166
+ product: entityIdSchema.optional(),
1167
+ variant: entityIdSchema,
1168
+ option: entityIdSchema.optional(),
1169
+ quantity: z3.number().int().positive("quantity must be a positive integer"),
1170
+ unitPrice: z3.number().optional(),
1171
+ totalPrice: z3.number().optional()
1172
+ }).strict();
1173
+ var createOrderSchema = z3.object({
1174
+ pgPaymentId: z3.string().min(1).optional(),
1175
+ orderNumber: z3.string().min(1, "orderNumber is required"),
1176
+ customer: entityIdSchema.optional(),
1177
+ customerSnapshot: z3.object({
1178
+ name: z3.string().optional(),
1179
+ email: z3.string().email("Invalid email format"),
1180
+ phone: z3.string().optional()
1181
+ }).strict(),
1182
+ shippingAddress: z3.object({
1183
+ postalCode: z3.string().optional(),
1184
+ address: z3.string().optional(),
1185
+ detailAddress: z3.string().optional(),
1186
+ deliveryMessage: z3.string().optional(),
1187
+ recipientName: z3.string().optional(),
1188
+ phone: z3.string().optional()
1189
+ }).strict(),
1190
+ orderItems: z3.array(createOrderItemSchema).min(1, "At least one order item is required").max(100, "Maximum 100 items per order"),
1191
+ totalAmount: z3.number().nonnegative("totalAmount must be non-negative"),
1192
+ shippingAmount: z3.number().min(0).optional(),
1193
+ discountCode: z3.string().optional()
1194
+ }).strict();
1195
+ var updateTransactionSchema = z3.object({
1196
+ pgPaymentId: z3.string().min(1, "pgPaymentId is required").describe("PG payment ID (required)"),
1197
+ status: transactionStatusSchema.describe(
1198
+ "New transaction status (required)"
1199
+ ),
1200
+ paymentMethod: z3.string().optional().describe("Payment method (optional)"),
1201
+ receiptUrl: z3.string().optional().describe("Receipt URL (optional)"),
1202
+ paymentKey: z3.string().min(1).optional().describe("Provider payment key for verified paid confirmation"),
1203
+ amount: z3.number().int().positive().optional().describe("Provider-confirmed amount for verified paid confirmation")
1204
+ }).strict();
1205
+ var providerSlugSchema = z3.string().trim().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/, "pgProvider must be lowercase slug");
1206
+ var confirmPaymentSchema = z3.object({
1207
+ orderNumber: z3.string().min(1).optional(),
1208
+ pgPaymentId: z3.string().min(1, "pgPaymentId is required").describe("Provider payment identifier stored on the transaction"),
1209
+ pgProvider: providerSlugSchema.describe(
1210
+ "Payment provider slug, e.g. toss, portone, stripe"
1211
+ ),
1212
+ pgOrderId: z3.string().min(1).optional(),
1213
+ amount: z3.number().int().nonnegative("amount must be non-negative").describe("Provider-confirmed amount in minor units"),
1214
+ currency: z3.string().min(1).optional(),
1215
+ paymentMethod: z3.string().optional(),
1216
+ receiptUrl: z3.string().url().optional(),
1217
+ approvedAt: z3.string().optional(),
1218
+ providerStatus: z3.string().optional(),
1219
+ providerEventId: z3.string().min(1).optional(),
1220
+ confirmationSource: z3.enum([
1221
+ "provider_webhook",
1222
+ "provider_lookup",
1223
+ "provider_api_confirm",
1224
+ "manual_server"
1225
+ ]).optional(),
1226
+ paymentKey: z3.string().min(1).optional().describe(
1227
+ "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."
1228
+ ),
1229
+ metadata: z3.record(z3.string(), z3.unknown()).optional()
1230
+ }).strict();
1231
+ var returnReasonSchema = z3.enum([
1232
+ "change_of_mind",
1233
+ "defective",
1234
+ "wrong_delivery",
1235
+ "damaged",
1236
+ "other"
1237
+ ]);
1238
+ var restockActionSchema = z3.enum(["return_to_stock", "discard"]);
1239
+ var returnWithRefundItemSchema = z3.object({
1240
+ orderItem: z3.union([z3.string().min(1), z3.number()]).transform(String),
1241
+ quantity: z3.number().int().positive("quantity must be a positive integer"),
1242
+ restockAction: restockActionSchema.default("return_to_stock"),
1243
+ restockingFee: z3.number().min(0, "restockingFee must be non-negative").optional().describe("Restocking fee charged for this line (ADR 0005 \xA7Gap 1)")
1244
+ }).strict();
1245
+ var returnWithRefundSchema = z3.object({
1246
+ orderNumber: z3.string().min(1, "orderNumber is required").describe("Order number (required)"),
1247
+ reason: returnReasonSchema.optional().describe("Return reason (optional)"),
1248
+ reasonDetail: z3.string().optional().describe("Detailed reason text (optional)"),
1249
+ 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)"),
1250
+ refundAmount: z3.number().min(0, "refundAmount must be non-negative").describe("Refund amount (required, min 0)"),
1251
+ returnShippingFee: z3.number().min(0, "returnShippingFee must be non-negative").optional().describe(
1252
+ "Return shipping fee charged to the customer (ADR 0005 \xA7Gap 1)"
1253
+ ),
1254
+ initialShippingRefundAmount: z3.number().min(0, "initialShippingRefundAmount must be non-negative").optional().describe("Initial order shipping amount refunded to the customer"),
1255
+ initialShippingRefundOverrideNote: z3.string().min(1).optional().describe(
1256
+ "Operator audit note required when overriding policy suggestion"
1257
+ ),
1258
+ pgPaymentId: z3.string().min(1, "pgPaymentId is required").describe("PG payment ID for refund (required)"),
1259
+ paymentKey: z3.string().min(1).optional().describe("Provider payment key for verified refund"),
1260
+ refundReceiptUrl: z3.string().optional().describe("Refund receipt URL (optional)")
1261
+ }).strict();
1262
+ var createReturnSchema = z3.object({
1263
+ orderNumber: z3.string().min(1, "orderNumber is required").describe("Order number (required)"),
1264
+ reason: returnReasonSchema.optional().describe("Return reason (optional)"),
1265
+ reasonDetail: z3.string().optional().describe("Detailed reason text (optional)"),
1266
+ 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)"),
1267
+ refundAmount: z3.number().min(0, "refundAmount must be non-negative").describe(
1268
+ "Line refund amount before initial shipping refund (required, min 0)"
1269
+ ),
1270
+ returnShippingFee: z3.number().min(0, "returnShippingFee must be non-negative").optional().describe("Return shipping fee charged to the customer"),
1271
+ initialShippingRefundAmount: z3.number().min(0, "initialShippingRefundAmount must be non-negative").optional().describe("Initial order shipping amount refunded to the customer"),
1272
+ initialShippingRefundOverrideNote: z3.string().min(1).optional().describe(
1273
+ "Operator audit note required when overriding policy suggestion"
1274
+ )
1275
+ }).strict();
1276
+ var cancelReasonCodeSchema = z3.enum([
1277
+ "customer",
1278
+ "inventory",
1279
+ "fraud",
1280
+ "declined",
1281
+ "staff",
1282
+ "other"
1283
+ ]);
1284
+ var idempotencyKeySchema = z3.string().trim().min(1, "idempotencyKey is required").max(255, "idempotencyKey must be 255 characters or fewer").regex(
1285
+ /^[\x21-\x7E]+$/,
1286
+ "idempotencyKey must contain only printable header-safe characters"
1287
+ );
1288
+ var cancelOrderSchema = z3.object({
1289
+ orderNumber: z3.string().min(1, "orderNumber is required").describe("Order number to cancel"),
1290
+ reasonCode: cancelReasonCodeSchema.default("other").describe("Operator-selected cancel reason code"),
1291
+ reasonDetail: z3.string().trim().max(2e3, "reasonDetail must be 2000 characters or fewer").optional().describe("Internal cancellation detail stored on the order")
1292
+ }).strict();
1293
+ var cancelOrderResponseBaseSchema = {
1294
+ orderId: z3.string().min(1)
1295
+ };
1296
+ var unpaidLocalCancelCommittedResponseFields = {
1297
+ refundedAmount: z3.literal(0),
1298
+ providerRefunded: z3.literal(false)
1299
+ };
1300
+ var paidLocalCancelCommittedResponseFields = {
1301
+ transactionId: z3.string().min(1),
1302
+ refundedAmount: z3.literal(0),
1303
+ providerRefunded: z3.literal(false),
1304
+ refundPending: z3.literal(true)
1305
+ };
1306
+ var legacyProviderRefundResponseFields = {
1307
+ transactionId: z3.string().min(1),
1308
+ refundedAmount: z3.number().int().positive(),
1309
+ refundSeq: z3.number().int().positive(),
1310
+ providerRefunded: z3.literal(true)
1311
+ };
1312
+ var alreadyCanceledResponseFields = {
1313
+ refundedAmount: z3.number().int().nonnegative(),
1314
+ providerRefunded: z3.literal(false)
1315
+ };
1316
+ var alreadyCanceledRefundPendingResponseFields = {
1317
+ transactionId: z3.string().min(1),
1318
+ refundedAmount: z3.number().int().nonnegative(),
1319
+ providerRefunded: z3.literal(false),
1320
+ refundPending: z3.literal(true)
1321
+ };
1322
+ var cancelOrderReconciliationStatusSchema = z3.enum([
1323
+ "paid",
841
1324
  "preparing",
842
1325
  "shipped",
843
1326
  "delivered",
844
- "confirmed"
1327
+ "confirmed",
1328
+ "return_requested",
1329
+ "return_processing",
1330
+ "returned",
1331
+ "refunded"
1332
+ ]);
1333
+ var cancelOrderResponseSchema = z3.union([
1334
+ z3.object({
1335
+ ...cancelOrderResponseBaseSchema,
1336
+ ...paidLocalCancelCommittedResponseFields,
1337
+ status: z3.literal("canceled"),
1338
+ cancelCommitted: z3.literal(true)
1339
+ }).strict(),
1340
+ z3.object({
1341
+ ...cancelOrderResponseBaseSchema,
1342
+ ...unpaidLocalCancelCommittedResponseFields,
1343
+ status: z3.literal("canceled"),
1344
+ cancelCommitted: z3.literal(true)
1345
+ }).strict(),
1346
+ z3.object({
1347
+ ...cancelOrderResponseBaseSchema,
1348
+ ...alreadyCanceledResponseFields,
1349
+ status: z3.literal("canceled"),
1350
+ cancelCommitted: z3.literal(false),
1351
+ alreadyCanceled: z3.literal(true)
1352
+ }).strict(),
1353
+ z3.object({
1354
+ ...cancelOrderResponseBaseSchema,
1355
+ ...alreadyCanceledRefundPendingResponseFields,
1356
+ status: z3.literal("canceled"),
1357
+ cancelCommitted: z3.literal(false),
1358
+ alreadyCanceled: z3.literal(true)
1359
+ }).strict(),
1360
+ z3.object({
1361
+ ...cancelOrderResponseBaseSchema,
1362
+ ...legacyProviderRefundResponseFields,
1363
+ status: cancelOrderReconciliationStatusSchema,
1364
+ cancelCommitted: z3.literal(false),
1365
+ reconciliationRequired: z3.literal(true)
1366
+ }).strict()
845
1367
  ]);
846
- var fulfillmentItemsSchema = z.array(
847
- z.object({
1368
+ var resolveCancelRefundOutcomeSchema = z3.enum(["succeeded", "failed"]);
1369
+ var resolveCancelRefundSchema = z3.object({
1370
+ orderNumber: z3.string().min(1, "orderNumber is required").describe("Order number whose pending cancel refund is being resolved"),
1371
+ idempotencyKey: idempotencyKeySchema.describe(
1372
+ "Stable key for this PG refund result report"
1373
+ ),
1374
+ outcome: resolveCancelRefundOutcomeSchema.describe(
1375
+ "PG refund result reported by the storefront or BFF"
1376
+ ),
1377
+ refundedAmount: z3.number().int("refundedAmount must be an integer minor-unit amount").nonnegative("refundedAmount must be nonnegative"),
1378
+ pgProvider: z3.string().trim().min(1, "pgProvider is required").regex(
1379
+ /^[a-z0-9][a-z0-9_-]*$/,
1380
+ "pgProvider must be a lowercase provider slug"
1381
+ ),
1382
+ pgRefundId: z3.string().trim().min(1).optional()
1383
+ }).strict().superRefine((value, ctx) => {
1384
+ if (value.outcome === "succeeded" && value.refundedAmount <= 0) {
1385
+ ctx.addIssue({
1386
+ code: z3.ZodIssueCode.custom,
1387
+ path: ["refundedAmount"],
1388
+ message: "refundedAmount must be positive when outcome is succeeded"
1389
+ });
1390
+ }
1391
+ if (value.outcome === "succeeded" && !value.pgRefundId) {
1392
+ ctx.addIssue({
1393
+ code: z3.ZodIssueCode.custom,
1394
+ path: ["pgRefundId"],
1395
+ message: "pgRefundId is required when outcome is succeeded"
1396
+ });
1397
+ }
1398
+ if (value.outcome === "failed" && value.refundedAmount !== 0) {
1399
+ ctx.addIssue({
1400
+ code: z3.ZodIssueCode.custom,
1401
+ path: ["refundedAmount"],
1402
+ message: "refundedAmount must be 0 when outcome is failed"
1403
+ });
1404
+ }
1405
+ });
1406
+ var resolveCancelRefundResponseSchema = z3.union([
1407
+ z3.object({
1408
+ orderId: z3.string().min(1),
1409
+ transactionId: z3.string().min(1),
1410
+ refundTransactionId: z3.string().min(1),
1411
+ refundedAmount: z3.number().int().positive(),
1412
+ refundStatus: z3.literal("succeeded"),
1413
+ transactionStatus: z3.literal("refunded")
1414
+ }).strict(),
1415
+ z3.object({
1416
+ orderId: z3.string().min(1),
1417
+ transactionId: z3.string().min(1),
1418
+ refundTransactionId: z3.string().min(1),
1419
+ refundedAmount: z3.literal(0),
1420
+ refundStatus: z3.literal("failed"),
1421
+ transactionStatus: z3.literal("paid")
1422
+ }).strict()
1423
+ ]);
1424
+
1425
+ // src/commands/order.ts
1426
+ import { z as z4 } from "zod";
1427
+ var idSchema = z4.union([z4.string().min(1), z4.number()]).transform(String);
1428
+ var customerSnapshotSchema = z4.object({
1429
+ email: z4.string().email("Invalid email format"),
1430
+ name: z4.string().optional(),
1431
+ phone: z4.string().optional()
1432
+ }).strict();
1433
+ var orderStatusSchema2 = z4.enum(["confirmed"]);
1434
+ var fulfillmentStatusSchema = z4.enum(["shipped", "delivered", "failed"]);
1435
+ var updateFulfillmentSchema = z4.object({
1436
+ fulfillmentId: idSchema,
1437
+ status: fulfillmentStatusSchema.optional(),
1438
+ carrier: z4.string().min(1).optional(),
1439
+ trackingNumber: z4.string().min(1).optional()
1440
+ }).refine(
1441
+ (value) => value.status !== void 0 || value.carrier !== void 0 || value.trackingNumber !== void 0,
1442
+ {
1443
+ message: "status, carrier, or trackingNumber is required"
1444
+ }
1445
+ );
1446
+ var fulfillmentItemsSchema = z4.array(
1447
+ z4.object({
848
1448
  orderItem: idSchema,
849
- quantity: z.number().int().positive("quantity must be a positive integer")
1449
+ quantity: z4.number().int().positive("quantity must be a positive integer")
850
1450
  }).strict()
851
1451
  ).min(1, "At least one fulfillment item is required").max(100, "Maximum 100 items per fulfillment");
852
1452
  function registerOrderCommands(program2, getClient2, getFormat2) {
853
1453
  const order = program2.command("order").description("Order management");
854
- order.command("create").description("Create a new order").option("--payment-id <id>", "Payment ID").requiredOption("--order-number <num>", "Order number").requiredOption("--email <email>", "Customer email").option("--customer <id>", "Customer ID").option("--name <name>", "Customer name").option("--phone <phone>", "Customer phone").requiredOption("--shipping-address <json>", "Shipping address (JSON)").requiredOption("--products <json>", "Order products array (JSON)").requiredOption("--total-amount <n>", "Total amount", parseFloat).option("--dry-run", "Validate inputs without executing").action(async (opts) => {
1454
+ order.command("create").description("Create a new order").option("--payment-id <id>", "Payment ID").requiredOption("--order-number <num>", "Order number").requiredOption("--email <email>", "Customer email").option("--customer <id>", "Customer ID").option("--name <name>", "Customer name").option("--phone <phone>", "Customer phone").requiredOption("--shipping-address <json>", "Shipping address (JSON)").requiredOption("--products <json>", "Order products array (JSON)").requiredOption("--total-amount <n>", "Total amount", parseFloat).option("--shipping-amount <n>", "Shipping amount", parseFloat).option("--discount-code <code>", "Discount code").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
855
1455
  try {
856
- const shippingAddress = parseWithSchema(
857
- parseJson(opts.shippingAddress, "shipping-address"),
858
- "shipping-address",
859
- shippingAddressSchema
860
- );
861
- const orderItems = parseWithSchema(
862
- parseJsonArray(opts.products, "products"),
863
- "products",
864
- orderItemsSchema
865
- );
866
- const totalAmount = parseWithSchema(
867
- opts.totalAmount,
868
- "total-amount",
869
- z.number().nonnegative("totalAmount must be non-negative")
870
- );
871
- const data = {
872
- pgPaymentId: opts.paymentId,
873
- orderNumber: opts.orderNumber,
874
- customerSnapshot: {
875
- email: opts.email,
876
- name: opts.name,
877
- phone: opts.phone
1456
+ const data = parseWithSchema(
1457
+ {
1458
+ pgPaymentId: opts.paymentId,
1459
+ orderNumber: opts.orderNumber,
1460
+ customerSnapshot: {
1461
+ email: opts.email,
1462
+ name: opts.name,
1463
+ phone: opts.phone
1464
+ },
1465
+ customer: opts.customer,
1466
+ shippingAddress: parseJson(
1467
+ opts.shippingAddress,
1468
+ "shipping-address"
1469
+ ),
1470
+ orderItems: parseJsonArray(opts.products, "products"),
1471
+ totalAmount: opts.totalAmount,
1472
+ shippingAmount: opts.shippingAmount,
1473
+ discountCode: opts.discountCode
878
1474
  },
879
- customer: opts.customer,
880
- shippingAddress,
881
- orderItems,
882
- totalAmount
883
- };
1475
+ "order",
1476
+ createOrderSchema
1477
+ );
884
1478
  if (opts.dryRun) {
885
1479
  printResult(
886
1480
  { dryRun: true, valid: true, action: "order create", data },
@@ -889,10 +1483,7 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
889
1483
  return;
890
1484
  }
891
1485
  const client = getClient2();
892
- const result = await client.commerce.orders.create({
893
- ...data,
894
- orderItems
895
- });
1486
+ const result = await client.commerce.orders.create(data);
896
1487
  printResult(result, getFormat2());
897
1488
  } catch (e) {
898
1489
  exitWithError(e);
@@ -901,16 +1492,22 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
901
1492
  order.command("get <orderNumber>").description("Get an order by order number").action(async (orderNumber) => {
902
1493
  try {
903
1494
  const client = getClient2();
904
- const { docs: [order2] } = await client.collections.from("orders").find({ where: { orderNumber: { equals: orderNumber } }, limit: 1, depth: 1 });
1495
+ const {
1496
+ docs: [order2]
1497
+ } = await client.collections.from("orders").find({
1498
+ where: { orderNumber: { equals: orderNumber } },
1499
+ limit: 1,
1500
+ depth: 1
1501
+ });
905
1502
  if (!order2) throw new Error("Order not found");
906
1503
  printResult(order2, getFormat2());
907
1504
  } catch (e) {
908
1505
  exitWithError(e);
909
1506
  }
910
1507
  });
911
- order.command("update <orderNumber>").description("Update order status").requiredOption("--status <status>", "New status").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
1508
+ order.command("update <orderNumber>").description("Confirm a delivered order purchase").requiredOption("--status <status>", "New status (confirmed only)").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
912
1509
  try {
913
- const status = parseWithSchema(opts.status, "status", orderStatusSchema);
1510
+ const status = parseWithSchema(opts.status, "status", orderStatusSchema2);
914
1511
  const data = { orderNumber, status };
915
1512
  if (opts.dryRun) {
916
1513
  printResult(
@@ -926,6 +1523,34 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
926
1523
  exitWithError(e);
927
1524
  }
928
1525
  });
1526
+ order.command("cancel <orderNumber>").description("Cancel an eligible order").option(
1527
+ "--reason-code <code>",
1528
+ "Cancel reason (customer, inventory, fraud, declined, staff, other)"
1529
+ ).option("--reason-detail <text>", "Internal cancellation detail").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
1530
+ try {
1531
+ const data = parseWithSchema(
1532
+ {
1533
+ orderNumber,
1534
+ ...opts.reasonCode ? { reasonCode: opts.reasonCode } : {},
1535
+ ...opts.reasonDetail ? { reasonDetail: opts.reasonDetail } : {}
1536
+ },
1537
+ "cancel",
1538
+ cancelOrderSchema
1539
+ );
1540
+ if (opts.dryRun) {
1541
+ printResult(
1542
+ { dryRun: true, valid: true, action: "order cancel", data },
1543
+ getFormat2()
1544
+ );
1545
+ return;
1546
+ }
1547
+ const client = getClient2();
1548
+ const result = await client.commerce.orders.cancelOrder(data);
1549
+ printResult(result, getFormat2());
1550
+ } catch (e) {
1551
+ exitWithError(e);
1552
+ }
1553
+ });
929
1554
  order.command("checkout").description("Convert a cart to an order").requiredOption("--cart-id <id>", "Cart ID").option("--payment-id <id>", "Payment ID (optional for free orders)").requiredOption("--order-number <num>", "Order number").requiredOption("--customer <json>", "Customer snapshot (JSON)").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
930
1555
  try {
931
1556
  const customerSnapshot = parseWithSchema(
@@ -956,18 +1581,35 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
956
1581
  exitWithError(e);
957
1582
  }
958
1583
  });
959
- order.command("fulfill <orderNumber>").description("Create a fulfillment for an order").requiredOption("--items <json>", "Fulfillment items array (JSON)").option("--carrier <name>", "Shipping carrier").option("--tracking-number <num>", "Tracking number").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
1584
+ order.command("prepare <orderNumber>").description("Move paid order fulfillment work to preparation").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
960
1585
  try {
961
- const items = parseWithSchema(
1586
+ const data = { orderNumber };
1587
+ if (opts.dryRun) {
1588
+ printResult(
1589
+ { dryRun: true, valid: true, action: "order prepare", data },
1590
+ getFormat2()
1591
+ );
1592
+ return;
1593
+ }
1594
+ const client = getClient2();
1595
+ const result = await client.commerce.orders.prepareFulfillmentOrder(data);
1596
+ printResult(result, getFormat2());
1597
+ } catch (e) {
1598
+ exitWithError(e);
1599
+ }
1600
+ });
1601
+ order.command("fulfill <orderNumber>").description("Create a shipment for a prepared order").option("--items <json>", "Fulfillment items array (JSON)").option("--carrier <name>", "Shipping carrier").option("--tracking-number <num>", "Tracking number").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
1602
+ try {
1603
+ const items = opts.items ? parseWithSchema(
962
1604
  parseJsonArray(opts.items, "items"),
963
1605
  "items",
964
1606
  fulfillmentItemsSchema
965
- );
1607
+ ) : void 0;
966
1608
  const data = {
967
1609
  orderNumber,
968
- items,
969
- carrier: opts.carrier,
970
- trackingNumber: opts.trackingNumber
1610
+ ...opts.carrier ? { carrier: opts.carrier } : {},
1611
+ ...opts.trackingNumber ? { trackingNumber: opts.trackingNumber } : {},
1612
+ ...items ? { items } : {}
971
1613
  };
972
1614
  if (opts.dryRun) {
973
1615
  printResult(
@@ -979,62 +1621,88 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
979
1621
  const client = getClient2();
980
1622
  const result = await client.commerce.orders.createFulfillment({
981
1623
  ...data,
982
- items
1624
+ ...items ? {
1625
+ items
1626
+ } : {}
983
1627
  });
984
1628
  printResult(result, getFormat2());
985
1629
  } catch (e) {
986
1630
  exitWithError(e);
987
1631
  }
988
1632
  });
1633
+ order.command("update-fulfillment <fulfillmentId>").description("Update shipment status or tracking information").option("--status <status>", "Shipment status (shipped, delivered, failed)").option("--carrier <name>", "Shipping carrier").option("--tracking-number <num>", "Tracking number").option("--dry-run", "Validate inputs without executing").action(async (fulfillmentId, opts) => {
1634
+ try {
1635
+ const data = parseWithSchema(
1636
+ {
1637
+ fulfillmentId,
1638
+ ...opts.status ? { status: opts.status } : {},
1639
+ ...opts.carrier ? { carrier: opts.carrier } : {},
1640
+ ...opts.trackingNumber ? { trackingNumber: opts.trackingNumber } : {}
1641
+ },
1642
+ "fulfillment",
1643
+ updateFulfillmentSchema
1644
+ );
1645
+ if (opts.dryRun) {
1646
+ printResult(
1647
+ {
1648
+ dryRun: true,
1649
+ valid: true,
1650
+ action: "order update-fulfillment",
1651
+ data
1652
+ },
1653
+ getFormat2()
1654
+ );
1655
+ return;
1656
+ }
1657
+ const client = getClient2();
1658
+ const result = await client.commerce.orders.updateFulfillment(data);
1659
+ printResult(result, getFormat2());
1660
+ } catch (e) {
1661
+ exitWithError(e);
1662
+ }
1663
+ });
989
1664
  }
990
1665
 
991
1666
  // src/commands/return.ts
992
- import { z as z2 } from "zod";
993
- var idSchema2 = z2.union([z2.string().min(1), z2.number()]).transform(String);
994
- var returnReasonSchema = z2.enum(["change_of_mind", "defective", "wrong_delivery", "damaged", "other"]).optional();
995
- var returnItemsSchema = z2.array(
996
- z2.object({
997
- orderItem: idSchema2,
998
- quantity: z2.number().int().positive("quantity must be a positive integer"),
999
- restockAction: z2.enum(["return_to_stock", "discard"]).default("return_to_stock")
1000
- }).strict()
1001
- ).min(1, "At least one return item is required").max(100, "Too many return items");
1002
- var returnStatusSchema = z2.enum([
1667
+ import { z as z5 } from "zod";
1668
+ var returnStatusSchema = z5.enum([
1003
1669
  "processing",
1004
1670
  "approved",
1005
1671
  "rejected",
1006
1672
  "completed"
1007
1673
  ]);
1008
- var refundAmountSchema = z2.number().nonnegative("refundAmount must be non-negative");
1009
1674
  function registerReturnCommands(program2, getClient2, getFormat2) {
1010
1675
  const ret = program2.command("return").description("Return management");
1011
1676
  ret.command("create <orderNumber>").description("Create a return request").requiredOption("--products <json>", "Return products array (JSON)").requiredOption("--refund-amount <n>", "Refund amount", parseFloat).option(
1677
+ "--return-shipping-fee <n>",
1678
+ "Return shipping fee charged to the customer",
1679
+ parseFloat
1680
+ ).option(
1681
+ "--initial-shipping-refund-amount <n>",
1682
+ "Initial order shipping refund amount",
1683
+ parseFloat
1684
+ ).option(
1685
+ "--initial-shipping-refund-note <text>",
1686
+ "Audit note for manual initial shipping refund override"
1687
+ ).option(
1012
1688
  "--reason <reason>",
1013
1689
  "Return reason (change_of_mind, defective, wrong_delivery, damaged, other)"
1014
1690
  ).option("--reason-detail <text>", "Detailed reason").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
1015
1691
  try {
1016
- const returnItems = parseWithSchema(
1017
- parseJsonArray(opts.products, "products"),
1018
- "products",
1019
- returnItemsSchema
1020
- );
1021
- const refundAmount = parseWithSchema(
1022
- opts.refundAmount,
1023
- "refund-amount",
1024
- refundAmountSchema
1025
- );
1026
- const reason = parseWithSchema(
1027
- opts.reason,
1028
- "reason",
1029
- returnReasonSchema
1692
+ const data = parseWithSchema(
1693
+ {
1694
+ orderNumber,
1695
+ returnItems: parseJsonArray(opts.products, "products"),
1696
+ refundAmount: opts.refundAmount,
1697
+ returnShippingFee: opts.returnShippingFee,
1698
+ reason: opts.reason,
1699
+ reasonDetail: opts.reasonDetail,
1700
+ initialShippingRefundAmount: opts.initialShippingRefundAmount,
1701
+ initialShippingRefundOverrideNote: opts.initialShippingRefundNote
1702
+ },
1703
+ "return",
1704
+ createReturnSchema
1030
1705
  );
1031
- const data = {
1032
- orderNumber,
1033
- returnItems,
1034
- refundAmount,
1035
- reason,
1036
- reasonDetail: opts.reasonDetail
1037
- };
1038
1706
  if (opts.dryRun) {
1039
1707
  printResult(
1040
1708
  { dryRun: true, valid: true, action: "return create", data },
@@ -1045,7 +1713,7 @@ function registerReturnCommands(program2, getClient2, getFormat2) {
1045
1713
  const client = getClient2();
1046
1714
  const result = await client.commerce.orders.createReturn({
1047
1715
  ...data,
1048
- returnItems
1716
+ returnItems: data.returnItems
1049
1717
  });
1050
1718
  printResult(result, getFormat2());
1051
1719
  } catch (e) {
@@ -1057,7 +1725,11 @@ function registerReturnCommands(program2, getClient2, getFormat2) {
1057
1725
  "New status (processing, approved, rejected, completed)"
1058
1726
  ).option("--dry-run", "Validate inputs without executing").action(async (returnId, opts) => {
1059
1727
  try {
1060
- const status = parseWithSchema(opts.status, "status", returnStatusSchema);
1728
+ const status = parseWithSchema(
1729
+ opts.status,
1730
+ "status",
1731
+ returnStatusSchema
1732
+ );
1061
1733
  const data = { returnId, status };
1062
1734
  if (opts.dryRun) {
1063
1735
  printResult(
@@ -1073,32 +1745,36 @@ function registerReturnCommands(program2, getClient2, getFormat2) {
1073
1745
  exitWithError(e);
1074
1746
  }
1075
1747
  });
1076
- ret.command("refund <orderNumber>").description("Return with refund").requiredOption("--products <json>", "Return products array (JSON)").requiredOption("--refund-amount <n>", "Refund amount", parseFloat).requiredOption("--payment-id <id>", "Payment ID").option("--reason <reason>", "Return reason").option("--reason-detail <text>", "Detailed reason").option("--refund-receipt-url <url>", "Refund receipt URL").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
1748
+ ret.command("refund <orderNumber>").description("Return with refund").requiredOption("--products <json>", "Return products array (JSON)").requiredOption("--refund-amount <n>", "Refund amount", parseFloat).requiredOption("--payment-id <id>", "Payment ID").option(
1749
+ "--return-shipping-fee <n>",
1750
+ "Return shipping fee charged to the customer",
1751
+ parseFloat
1752
+ ).option(
1753
+ "--initial-shipping-refund-amount <n>",
1754
+ "Initial order shipping refund amount",
1755
+ parseFloat
1756
+ ).option(
1757
+ "--initial-shipping-refund-note <text>",
1758
+ "Audit note for manual initial shipping refund override"
1759
+ ).option("--reason <reason>", "Return reason").option("--reason-detail <text>", "Detailed reason").option("--refund-receipt-url <url>", "Refund receipt URL").option("--payment-key <key>", "Provider payment key").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
1077
1760
  try {
1078
- const returnItems = parseWithSchema(
1079
- parseJsonArray(opts.products, "products"),
1080
- "products",
1081
- returnItemsSchema
1082
- );
1083
- const refundAmount = parseWithSchema(
1084
- opts.refundAmount,
1085
- "refund-amount",
1086
- refundAmountSchema
1087
- );
1088
- const reason = parseWithSchema(
1089
- opts.reason,
1090
- "reason",
1091
- returnReasonSchema
1761
+ const data = parseWithSchema(
1762
+ {
1763
+ orderNumber,
1764
+ returnItems: parseJsonArray(opts.products, "products"),
1765
+ refundAmount: opts.refundAmount,
1766
+ returnShippingFee: opts.returnShippingFee,
1767
+ pgPaymentId: opts.paymentId,
1768
+ reason: opts.reason,
1769
+ reasonDetail: opts.reasonDetail,
1770
+ refundReceiptUrl: opts.refundReceiptUrl,
1771
+ paymentKey: opts.paymentKey,
1772
+ initialShippingRefundAmount: opts.initialShippingRefundAmount,
1773
+ initialShippingRefundOverrideNote: opts.initialShippingRefundNote
1774
+ },
1775
+ "return",
1776
+ returnWithRefundSchema
1092
1777
  );
1093
- const data = {
1094
- orderNumber,
1095
- returnItems,
1096
- refundAmount,
1097
- pgPaymentId: opts.paymentId,
1098
- reason,
1099
- reasonDetail: opts.reasonDetail,
1100
- refundReceiptUrl: opts.refundReceiptUrl
1101
- };
1102
1778
  if (opts.dryRun) {
1103
1779
  printResult(
1104
1780
  { dryRun: true, valid: true, action: "return refund", data },
@@ -1109,7 +1785,7 @@ function registerReturnCommands(program2, getClient2, getFormat2) {
1109
1785
  const client = getClient2();
1110
1786
  const result = await client.commerce.orders.returnWithRefund({
1111
1787
  ...data,
1112
- returnItems
1788
+ returnItems: data.returnItems
1113
1789
  });
1114
1790
  printResult(result, getFormat2());
1115
1791
  } catch (e) {
@@ -1190,6 +1866,60 @@ function registerCartCommands(program2, getClient2, getFormat2) {
1190
1866
  exitWithError(e);
1191
1867
  }
1192
1868
  });
1869
+ cart.command("clear <cartId>").description("Remove all items from a cart").option("--dry-run", "Validate inputs without executing").action(async (cartId, opts) => {
1870
+ try {
1871
+ if (opts.dryRun) {
1872
+ printResult(
1873
+ { dryRun: true, valid: true, action: "cart clear", data: { cartId } },
1874
+ getFormat2()
1875
+ );
1876
+ return;
1877
+ }
1878
+ const client = getClient2();
1879
+ const result = await client.commerce.cart.clear({ cartId });
1880
+ printResult(result, getFormat2());
1881
+ } catch (e) {
1882
+ exitWithError(e);
1883
+ }
1884
+ });
1885
+ cart.command("apply-discount <cartId>").description("Apply a discount code to a cart").requiredOption("--code <code>", "Discount code").option("--dry-run", "Validate inputs without executing").action(async (cartId, opts) => {
1886
+ try {
1887
+ const data = { cartId, discountCode: opts.code };
1888
+ if (opts.dryRun) {
1889
+ printResult(
1890
+ { dryRun: true, valid: true, action: "cart apply-discount", data },
1891
+ getFormat2()
1892
+ );
1893
+ return;
1894
+ }
1895
+ const client = getClient2();
1896
+ const result = await client.commerce.cart.applyDiscount(data);
1897
+ printResult(result, getFormat2());
1898
+ } catch (e) {
1899
+ exitWithError(e);
1900
+ }
1901
+ });
1902
+ cart.command("remove-discount <cartId>").description("Remove the discount from a cart").option("--dry-run", "Validate inputs without executing").action(async (cartId, opts) => {
1903
+ try {
1904
+ if (opts.dryRun) {
1905
+ printResult(
1906
+ {
1907
+ dryRun: true,
1908
+ valid: true,
1909
+ action: "cart remove-discount",
1910
+ data: { cartId }
1911
+ },
1912
+ getFormat2()
1913
+ );
1914
+ return;
1915
+ }
1916
+ const client = getClient2();
1917
+ const result = await client.commerce.cart.removeDiscount({ cartId });
1918
+ printResult(result, getFormat2());
1919
+ } catch (e) {
1920
+ exitWithError(e);
1921
+ }
1922
+ });
1193
1923
  }
1194
1924
 
1195
1925
  // src/commands/stock.ts
@@ -1211,19 +1941,50 @@ function registerStockCommands(program2, getClient2, getFormat2) {
1211
1941
  }
1212
1942
 
1213
1943
  // src/commands/transaction.ts
1944
+ import { z as z6 } from "zod";
1945
+ var transactionAmountSchema = z6.object({
1946
+ amount: z6.string().regex(/^[1-9]\d*$/, "amount must be a positive integer").transform(Number)
1947
+ });
1948
+ var confirmPaymentAmountSchema = z6.object({
1949
+ amount: z6.string().regex(/^(0|[1-9]\d*)$/, "amount must be a non-negative integer").transform(Number)
1950
+ });
1951
+ var idempotencyKeyOptionSchema = z6.object({
1952
+ idempotencyKey: idempotencyKeySchema
1953
+ });
1954
+ function parseTransactionAmount(value) {
1955
+ if (value === void 0) return void 0;
1956
+ return parseWithSchema({ amount: value }, "amount", transactionAmountSchema).amount;
1957
+ }
1958
+ function parseConfirmPaymentAmount(value) {
1959
+ return parseWithSchema({ amount: value }, "amount", confirmPaymentAmountSchema).amount;
1960
+ }
1961
+ function parseIdempotencyKey(value) {
1962
+ if (value === void 0) return void 0;
1963
+ return parseWithSchema(
1964
+ { idempotencyKey: value },
1965
+ "idempotencyKey",
1966
+ idempotencyKeyOptionSchema
1967
+ ).idempotencyKey;
1968
+ }
1214
1969
  function registerTransactionCommands(program2, getClient2, getFormat2) {
1215
1970
  const tx = program2.command("transaction").description("Transaction management");
1216
1971
  tx.command("update").description("Update transaction status").requiredOption("--payment-id <id>", "Payment ID").requiredOption(
1217
1972
  "--status <status>",
1218
1973
  "New status (pending, paid, failed, canceled)"
1219
- ).requiredOption("--payment-method <method>", "Payment method").requiredOption("--receipt-url <url>", "Receipt URL").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
1974
+ ).option("--payment-method <method>", "Payment method").option("--receipt-url <url>", "Receipt URL").option("--payment-key <key>", "Provider payment key").option("--amount <n>", "Provider-confirmed amount").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
1220
1975
  try {
1221
- const data = {
1222
- pgPaymentId: opts.paymentId,
1223
- status: opts.status,
1224
- paymentMethod: opts.paymentMethod,
1225
- receiptUrl: opts.receiptUrl
1226
- };
1976
+ const data = parseWithSchema(
1977
+ {
1978
+ pgPaymentId: opts.paymentId,
1979
+ status: opts.status,
1980
+ paymentMethod: opts.paymentMethod,
1981
+ receiptUrl: opts.receiptUrl,
1982
+ paymentKey: opts.paymentKey,
1983
+ amount: parseTransactionAmount(opts.amount)
1984
+ },
1985
+ "transaction",
1986
+ updateTransactionSchema
1987
+ );
1227
1988
  if (opts.dryRun) {
1228
1989
  printResult(
1229
1990
  { dryRun: true, valid: true, action: "transaction update", data },
@@ -1238,6 +1999,132 @@ function registerTransactionCommands(program2, getClient2, getFormat2) {
1238
1999
  exitWithError(e);
1239
2000
  }
1240
2001
  });
2002
+ tx.command("confirm-payment").description("Confirm a provider-verified payment for an order").requiredOption("--payment-id <id>", "Provider payment identifier (pgPaymentId)").requiredOption(
2003
+ "--provider <slug>",
2004
+ "Payment provider slug (toss, portone, stripe, ...)"
2005
+ ).requiredOption(
2006
+ "--amount <n>",
2007
+ "Provider-confirmed amount in minor units"
2008
+ ).option("--order-number <num>", "Order number").option("--pg-order-id <id>", "Provider order id").option("--currency <code>", "Currency code").option("--payment-method <method>", "Payment method").option("--receipt-url <url>", "Receipt URL").option("--approved-at <ts>", "Provider approval timestamp").option("--provider-status <status>", "Provider status").option("--provider-event-id <id>", "Provider event id (idempotency)").option("--idempotency-key <key>", "Idempotency key header override").option(
2009
+ "--confirmation-source <src>",
2010
+ "provider_webhook | provider_lookup | provider_api_confirm | manual_server"
2011
+ ).option("--payment-key <key>", "Provider payment key").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
2012
+ try {
2013
+ const data = parseWithSchema(
2014
+ {
2015
+ pgPaymentId: opts.paymentId,
2016
+ pgProvider: opts.provider,
2017
+ amount: parseConfirmPaymentAmount(opts.amount),
2018
+ ...opts.orderNumber ? { orderNumber: opts.orderNumber } : {},
2019
+ ...opts.pgOrderId ? { pgOrderId: opts.pgOrderId } : {},
2020
+ ...opts.currency ? { currency: opts.currency } : {},
2021
+ ...opts.paymentMethod ? { paymentMethod: opts.paymentMethod } : {},
2022
+ ...opts.receiptUrl ? { receiptUrl: opts.receiptUrl } : {},
2023
+ ...opts.approvedAt ? { approvedAt: opts.approvedAt } : {},
2024
+ ...opts.providerStatus ? { providerStatus: opts.providerStatus } : {},
2025
+ ...opts.providerEventId ? { providerEventId: opts.providerEventId } : {},
2026
+ ...opts.confirmationSource ? { confirmationSource: opts.confirmationSource } : {},
2027
+ ...opts.paymentKey ? { paymentKey: opts.paymentKey } : {}
2028
+ },
2029
+ "confirm-payment",
2030
+ confirmPaymentSchema
2031
+ );
2032
+ const sdkParams = {
2033
+ ...data,
2034
+ ...opts.idempotencyKey !== void 0 ? { idempotencyKey: parseIdempotencyKey(opts.idempotencyKey) } : {}
2035
+ };
2036
+ if (opts.dryRun) {
2037
+ printResult(
2038
+ {
2039
+ dryRun: true,
2040
+ valid: true,
2041
+ action: "transaction confirm-payment",
2042
+ data: sdkParams
2043
+ },
2044
+ getFormat2()
2045
+ );
2046
+ return;
2047
+ }
2048
+ const client = getClient2();
2049
+ const result = await client.commerce.orders.confirmPayment(
2050
+ sdkParams
2051
+ );
2052
+ printResult(result, getFormat2());
2053
+ } catch (e) {
2054
+ exitWithError(e);
2055
+ }
2056
+ });
2057
+ }
2058
+
2059
+ // src/commands/product.ts
2060
+ function registerProductCommands(program2, getClient2, getFormat2) {
2061
+ const product = program2.command("product").description("Product management");
2062
+ product.command("upsert").description("Create or update a product graph (options, values, variants)").requiredOption("--input <json>", "Product upsert input (JSON)").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
2063
+ try {
2064
+ const data = parseWithSchema(
2065
+ parseJson(opts.input, "input"),
2066
+ "input",
2067
+ ProductUpsertSchema
2068
+ );
2069
+ if (opts.dryRun) {
2070
+ printResult(
2071
+ { dryRun: true, valid: true, action: "product upsert", data },
2072
+ getFormat2()
2073
+ );
2074
+ return;
2075
+ }
2076
+ const client = getClient2();
2077
+ const result = await client.commerce.product.upsert(
2078
+ data
2079
+ );
2080
+ printResult(result, getFormat2());
2081
+ } catch (e) {
2082
+ exitWithError(e);
2083
+ }
2084
+ });
2085
+ }
2086
+
2087
+ // src/commands/discount.ts
2088
+ function registerDiscountCommands(program2, getClient2, getFormat2) {
2089
+ const discount = program2.command("discount").description("Discount management");
2090
+ discount.command("validate").description("Validate a discount code against an order amount").requiredOption("--code <code>", "Discount code").requiredOption(
2091
+ "--order-amount <n>",
2092
+ "Order amount",
2093
+ (v) => parseInt(v, 10)
2094
+ ).action(async (opts) => {
2095
+ try {
2096
+ const client = getClient2();
2097
+ const result = await client.commerce.discounts.validate({
2098
+ code: opts.code,
2099
+ orderAmount: opts.orderAmount
2100
+ });
2101
+ printResult(result, getFormat2());
2102
+ } catch (e) {
2103
+ exitWithError(e);
2104
+ }
2105
+ });
2106
+ }
2107
+
2108
+ // src/commands/shipping.ts
2109
+ function registerShippingCommands(program2, getClient2, getFormat2) {
2110
+ const shipping = program2.command("shipping").description("Shipping calculation");
2111
+ shipping.command("calculate").description("Calculate shipping for an order amount").requiredOption(
2112
+ "--order-amount <n>",
2113
+ "Order amount",
2114
+ (v) => parseInt(v, 10)
2115
+ ).option("--shipping-policy-id <id>", "Shipping policy ID").option("--postal-code <code>", "Destination postal code").action(async (opts) => {
2116
+ try {
2117
+ const client = getClient2();
2118
+ const result = await client.commerce.shipping.calculate({
2119
+ orderAmount: opts.orderAmount,
2120
+ ...opts.shippingPolicyId ? { shippingPolicyId: opts.shippingPolicyId } : {},
2121
+ ...opts.postalCode ? { postalCode: opts.postalCode } : {}
2122
+ });
2123
+ printResult(result, getFormat2());
2124
+ } catch (e) {
2125
+ exitWithError(e);
2126
+ }
2127
+ });
1241
2128
  }
1242
2129
 
1243
2130
  // src/commands/auth.ts
@@ -1332,7 +2219,7 @@ async function exchangeCode(code) {
1332
2219
  }
1333
2220
  }
1334
2221
  function startAuthServer(options) {
1335
- return new Promise((resolve3, reject) => {
2222
+ return new Promise((resolve2, reject) => {
1336
2223
  const server = createServer((req, res) => {
1337
2224
  if (!req.url) {
1338
2225
  res.writeHead(400).end();
@@ -1407,7 +2294,7 @@ Logged in successfully!`));
1407
2294
  );
1408
2295
  cleanup(4);
1409
2296
  }, TIMEOUT_MS);
1410
- resolve3({ port: addr.port, cleanup });
2297
+ resolve2({ port: addr.port, cleanup });
1411
2298
  });
1412
2299
  server.on("error", (err) => {
1413
2300
  reject(err);
@@ -1546,25 +2433,17 @@ ${loginUrl}`));
1546
2433
  }
1547
2434
 
1548
2435
  // src/commands/schema.ts
1549
- import { COLLECTIONS as COLLECTIONS2 } from "@01.software/sdk";
2436
+ import { SERVER_COLLECTIONS as SERVER_COLLECTIONS2 } from "@01.software/sdk";
1550
2437
  function registerSchemaCommands(program2, getClient2, getFormat2) {
1551
2438
  const schema = program2.command("schema").description("Collection schema introspection");
1552
2439
  schema.command("list").description("List available collections").action(() => {
1553
- printResult(COLLECTIONS2, getFormat2());
2440
+ printResult(SERVER_COLLECTIONS2, getFormat2());
1554
2441
  });
1555
2442
  schema.command("show <collection>").description("Show collection field schema").action(async (collection) => {
1556
2443
  try {
1557
- if (!COLLECTIONS2.includes(collection)) {
1558
- const normalized = collection.replace(/-/g, "").toLowerCase();
1559
- const suggestions = COLLECTIONS2.filter((c) => {
1560
- const cn = c.replace(/-/g, "").toLowerCase();
1561
- return cn.startsWith(normalized) || normalized.startsWith(cn) || normalized.length >= 3 && cn.includes(normalized);
1562
- }).slice(0, 5);
1563
- const hint = suggestions.length > 0 ? `Did you mean: ${suggestions.join(", ")}?` : 'Run "01 schema list" for available collections.';
1564
- throw new Error(`Unknown collection "${collection}". ${hint}`);
1565
- }
2444
+ const col = validateCollection(collection);
1566
2445
  const client = getClient2();
1567
- const result = await client.tenant.collectionSchema(collection);
2446
+ const result = await client.tenant.collectionSchema(col);
1568
2447
  printResult(result, getFormat2());
1569
2448
  } catch (e) {
1570
2449
  exitWithError(e);
@@ -1572,152 +2451,6 @@ function registerSchemaCommands(program2, getClient2, getFormat2) {
1572
2451
  });
1573
2452
  }
1574
2453
 
1575
- // ../contracts/src/tenant/index.ts
1576
- import { z as z3 } from "zod";
1577
- var tenantFieldConfigStateSchema = z3.object({
1578
- hiddenFields: z3.array(z3.string()),
1579
- isHidden: z3.boolean()
1580
- }).strict();
1581
- var tenantContextQuerySchema = z3.object({
1582
- counts: z3.literal("true").optional()
1583
- }).strict();
1584
- var tenantContextToolInputSchema = z3.object({
1585
- includeCounts: z3.boolean().optional().default(false).describe(
1586
- "Include per-collection document counts and config status (bypasses cache, slower)"
1587
- )
1588
- }).strict();
1589
- var tenantContextResponseSchema = z3.object({
1590
- tenant: z3.object({
1591
- id: z3.string(),
1592
- name: z3.string(),
1593
- plan: z3.string(),
1594
- planSource: z3.string().optional(),
1595
- authoritative: z3.boolean().optional(),
1596
- capabilityVersion: z3.string().optional()
1597
- }).strict(),
1598
- features: z3.array(z3.string()),
1599
- collections: z3.object({
1600
- active: z3.array(z3.string()),
1601
- inactive: z3.array(z3.string())
1602
- }).strict(),
1603
- fieldConfigs: z3.record(z3.string(), tenantFieldConfigStateSchema),
1604
- counts: z3.record(z3.string(), z3.number()).optional(),
1605
- config: z3.object({
1606
- webhookConfigured: z3.boolean()
1607
- }).strict().optional()
1608
- }).strict();
1609
- var tenantFeatureProgressFeatureSchema = z3.enum(["ecommerce"]);
1610
- var tenantFeatureProgressInputSchema = z3.object({
1611
- feature: tenantFeatureProgressFeatureSchema.describe(
1612
- "Feature to inspect for tenant implementation readiness"
1613
- ),
1614
- includeEvidence: z3.boolean().optional().default(false).describe("Include sanitized counts and static surface evidence")
1615
- }).strict();
1616
- var tenantFeatureProgressStatusSchema = z3.enum([
1617
- "ready",
1618
- "attention",
1619
- "blocked"
1620
- ]);
1621
- var tenantFeatureProgressItemStateSchema = z3.enum([
1622
- "complete",
1623
- "incomplete",
1624
- "blocked",
1625
- "attention",
1626
- "optional",
1627
- "unknown",
1628
- "manual",
1629
- "not-applicable"
1630
- ]);
1631
- var tenantFeatureProgressSeveritySchema = z3.enum([
1632
- "required",
1633
- "recommended",
1634
- "optional"
1635
- ]);
1636
- var tenantFeatureProgressEvidenceValueSchema = z3.union([
1637
- z3.string(),
1638
- z3.number(),
1639
- z3.boolean(),
1640
- z3.null()
1641
- ]);
1642
- var tenantFeatureProgressItemSchema = z3.object({
1643
- id: z3.string(),
1644
- title: z3.string(),
1645
- state: tenantFeatureProgressItemStateSchema,
1646
- severity: tenantFeatureProgressSeveritySchema,
1647
- summary: z3.string(),
1648
- evidence: z3.record(z3.string(), tenantFeatureProgressEvidenceValueSchema).optional()
1649
- }).strict();
1650
- var tenantFeatureProgressGroupSchema = z3.object({
1651
- id: z3.string(),
1652
- title: z3.string(),
1653
- summary: z3.string().optional(),
1654
- items: z3.array(tenantFeatureProgressItemSchema)
1655
- }).strict();
1656
- var tenantFeatureProgressResponseSchema = z3.object({
1657
- schemaVersion: z3.literal(1),
1658
- feature: tenantFeatureProgressFeatureSchema,
1659
- status: tenantFeatureProgressStatusSchema,
1660
- generatedAt: z3.string(),
1661
- tenant: z3.object({
1662
- id: z3.string(),
1663
- name: z3.string(),
1664
- plan: z3.string()
1665
- }).strict(),
1666
- capability: z3.object({
1667
- effectiveFeatures: z3.array(z3.string()),
1668
- planBlocked: z3.array(z3.string()),
1669
- closureAdded: z3.array(z3.string())
1670
- }).strict(),
1671
- summary: z3.object({
1672
- complete: z3.number().int().nonnegative(),
1673
- total: z3.number().int().nonnegative(),
1674
- blocking: z3.number().int().nonnegative(),
1675
- manual: z3.number().int().nonnegative(),
1676
- unknown: z3.number().int().nonnegative()
1677
- }).strict(),
1678
- groups: z3.array(tenantFeatureProgressGroupSchema)
1679
- }).strict();
1680
- var COLLECTION_SCHEMA_CONTRACT_VERSION = 1;
1681
- var collectionSchemaEndpointParamsSchema = z3.object({
1682
- collectionSlug: z3.string().min(1, "collectionSlug is required")
1683
- }).strict();
1684
- var collectionFieldOptionSchema = z3.object({
1685
- label: z3.string(),
1686
- value: z3.string()
1687
- }).strict();
1688
- var collectionFieldSchema = z3.lazy(
1689
- () => z3.object({
1690
- name: z3.string(),
1691
- path: z3.string(),
1692
- type: z3.string(),
1693
- required: z3.literal(true).optional(),
1694
- unique: z3.literal(true).optional(),
1695
- hasMany: z3.literal(true).optional(),
1696
- relationTo: z3.union([z3.string(), z3.array(z3.string())]).optional(),
1697
- options: z3.array(collectionFieldOptionSchema).optional(),
1698
- hidden: z3.literal(true).optional(),
1699
- systemManaged: z3.literal(true).optional(),
1700
- writable: z3.boolean().optional(),
1701
- fields: z3.array(collectionFieldSchema).optional()
1702
- }).strict()
1703
- );
1704
- var collectionSchemaResponseSchema = z3.object({
1705
- contractVersion: z3.literal(COLLECTION_SCHEMA_CONTRACT_VERSION),
1706
- mode: z3.literal("effective"),
1707
- collection: z3.object({
1708
- slug: z3.string(),
1709
- timestamps: z3.boolean(),
1710
- alwaysActive: z3.boolean(),
1711
- feature: z3.string().nullable(),
1712
- systemFields: z3.array(z3.string()),
1713
- visibility: z3.object({
1714
- collectionHidden: z3.boolean(),
1715
- hiddenFields: z3.array(z3.string())
1716
- }).strict(),
1717
- fields: z3.array(collectionFieldSchema)
1718
- }).strict()
1719
- }).strict();
1720
-
1721
2454
  // src/commands/feature.ts
1722
2455
  function flattenProgress(progress) {
1723
2456
  return progress.groups.flatMap(
@@ -1757,98 +2490,8 @@ function registerFeatureCommands(program2, getClient2, getFormat2) {
1757
2490
  });
1758
2491
  }
1759
2492
 
1760
- // src/commands/mcp.ts
1761
- import { resolve, dirname } from "path";
1762
- import { existsSync as existsSync2 } from "fs";
1763
- import { spawn } from "child_process";
1764
- import { fileURLToPath } from "url";
1765
- var __dirname = dirname(fileURLToPath(import.meta.url));
1766
- function getStdioEntryCandidates(baseDir = __dirname) {
1767
- const candidates = [
1768
- {
1769
- label: "packaged CLI artifact",
1770
- path: resolve(baseDir, "mcp/stdio.js")
1771
- }
1772
- ];
1773
- const roots = ["../../../..", "../../..", "../.."];
1774
- const entries = [
1775
- {
1776
- label: "monorepo build output",
1777
- path: "apps/mcp/dist/stdio.js"
1778
- },
1779
- {
1780
- label: "xmcp build output",
1781
- path: "apps/mcp/.xmcp/stdio.js"
1782
- }
1783
- ];
1784
- for (const entry of entries) {
1785
- for (const root of roots) {
1786
- candidates.push({
1787
- label: entry.label,
1788
- path: resolve(baseDir, root, entry.path)
1789
- });
1790
- }
1791
- }
1792
- return candidates;
1793
- }
1794
- function findStdioEntry(baseDir = __dirname) {
1795
- for (const candidate of getStdioEntryCandidates(baseDir)) {
1796
- if (existsSync2(candidate.path)) return candidate.path;
1797
- }
1798
- return null;
1799
- }
1800
- function formatMissingStdioEntryMessage(baseDir = __dirname) {
1801
- const checked = getStdioEntryCandidates(baseDir).map((candidate) => ` - ${candidate.label}: ${candidate.path}`).join("\n");
1802
- return [
1803
- "MCP stdio entry not found.",
1804
- "Checked:",
1805
- checked,
1806
- "Fix:",
1807
- " - Monorepo checkout: run pnpm --filter mcp build.",
1808
- " - Published CLI: reinstall or update @01.software/cli so dist/mcp/stdio.js is included."
1809
- ].join("\n");
1810
- }
1811
- function createMcpEnv(baseEnv, client) {
1812
- const env = {
1813
- ...baseEnv,
1814
- SOFTWARE_PUBLISHABLE_KEY: client.publishableKey,
1815
- SOFTWARE_SECRET_KEY: client.secretKey
1816
- };
1817
- delete env.SOFTWARE_TENANT_ID;
1818
- return env;
1819
- }
1820
- function registerMcpCommands(program2) {
1821
- program2.command("mcp").description("Start local MCP stdio server for trusted server-key workflows").addHelpText(
1822
- "after",
1823
- `
1824
- Prerequisites:
1825
- Run 01 login, or set SOFTWARE_PUBLISHABLE_KEY and SOFTWARE_SECRET_KEY.
1826
- Local stdio exposes the full MCP tool surface; HTTP OAuth MCP uses the
1827
- narrower remote surface documented in the web integration guide.
1828
- In a monorepo checkout, build the stdio artifact first:
1829
- pnpm --filter mcp build
1830
- `
1831
- ).action(() => {
1832
- const client = resolveClient(program2.opts().apiKey);
1833
- const stdioEntry = findStdioEntry();
1834
- if (!stdioEntry) {
1835
- exitWithError(new Error(formatMissingStdioEntryMessage()));
1836
- }
1837
- const child = spawn(process.execPath, [stdioEntry], {
1838
- env: createMcpEnv(process.env, client),
1839
- stdio: ["inherit", "inherit", "inherit"]
1840
- });
1841
- child.on("error", (err) => {
1842
- exitWithError(new Error(`Failed to start MCP server: ${err.message}`));
1843
- });
1844
- child.on("exit", (code) => {
1845
- process.exit(code ?? 0);
1846
- });
1847
- });
1848
- }
1849
-
1850
2493
  // src/commands/agent.ts
1851
- import { COLLECTIONS as COLLECTIONS3 } from "@01.software/sdk";
2494
+ import { SERVER_COLLECTIONS as SERVER_COLLECTIONS3 } from "@01.software/sdk";
1852
2495
 
1853
2496
  // src/lib/agent-output.ts
1854
2497
  var PLAN_AGENT_ERROR_CODES = /* @__PURE__ */ new Set([
@@ -2012,7 +2655,7 @@ function hashAgentPlanEnvelope(input) {
2012
2655
  }
2013
2656
 
2014
2657
  // src/lib/agent-plan-id.ts
2015
- import { resolve as resolve2, sep } from "path";
2658
+ import { resolve, sep } from "path";
2016
2659
  var PLAN_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2017
2660
  function assertValidPlanId(planId) {
2018
2661
  if (!PLAN_ID_PATTERN.test(planId)) {
@@ -2021,8 +2664,8 @@ function assertValidPlanId(planId) {
2021
2664
  }
2022
2665
  function safePlanPath(planDir, planId) {
2023
2666
  assertValidPlanId(planId);
2024
- const resolvedDir = resolve2(planDir);
2025
- const resolvedPath = resolve2(resolvedDir, `${planId}.json`);
2667
+ const resolvedDir = resolve(planDir);
2668
+ const resolvedPath = resolve(resolvedDir, `${planId}.json`);
2026
2669
  if (resolvedPath !== resolvedDir && !resolvedPath.startsWith(`${resolvedDir}${sep}`)) {
2027
2670
  throw agentPlanError("INVALID_INPUT", "Invalid plan token.");
2028
2671
  }
@@ -2633,7 +3276,10 @@ function parseWhere(value) {
2633
3276
  }
2634
3277
  throw invalidInput2("--where must be a JSON object", "where", value);
2635
3278
  }
2636
- var AGENT_READ_OPERATIONS = ["query", "get"];
3279
+ var AGENT_READ_OPERATIONS = [
3280
+ "query",
3281
+ "get"
3282
+ ];
2637
3283
  var AGENT_PLAN_OPERATIONS = [
2638
3284
  "plan:create",
2639
3285
  "plan:update",
@@ -2641,7 +3287,7 @@ var AGENT_PLAN_OPERATIONS = [
2641
3287
  ];
2642
3288
  function buildAgentManifest() {
2643
3289
  const collections = {};
2644
- for (const collection of COLLECTIONS3) {
3290
+ for (const collection of SERVER_COLLECTIONS3) {
2645
3291
  const operations = isAgentPlanCollection(collection) ? [...AGENT_READ_OPERATIONS, ...AGENT_PLAN_OPERATIONS] : [...AGENT_READ_OPERATIONS];
2646
3292
  collections[collection] = {
2647
3293
  operations,
@@ -2670,7 +3316,9 @@ function registerAgentCommands(program2, getClient2) {
2670
3316
  );
2671
3317
  configureAgentParser2(
2672
3318
  agent.command("manifest").description("Print the Agent CLI protocol manifest").option("--pretty", "Print 2-space indented JSON").action((opts) => {
2673
- printAgentSuccess(buildAgentManifest(), { pretty: Boolean(opts.pretty) });
3319
+ printAgentSuccess(buildAgentManifest(), {
3320
+ pretty: Boolean(opts.pretty)
3321
+ });
2674
3322
  })
2675
3323
  );
2676
3324
  configureAgentParser2(
@@ -2741,9 +3389,11 @@ registerReturnCommands(program, getClient, getFormat);
2741
3389
  registerCartCommands(program, getClient, getFormat);
2742
3390
  registerStockCommands(program, getClient, getFormat);
2743
3391
  registerTransactionCommands(program, getClient, getFormat);
3392
+ registerProductCommands(program, getClient, getFormat);
3393
+ registerDiscountCommands(program, getClient, getFormat);
3394
+ registerShippingCommands(program, getClient, getFormat);
2744
3395
  registerSchemaCommands(program, getClient, getFormat);
2745
3396
  registerFeatureCommands(program, getClient, getFormat);
2746
- registerMcpCommands(program);
2747
3397
  registerAuthCommands(program);
2748
3398
  program.parse();
2749
3399
  //# sourceMappingURL=index.js.map