@ollie-shop/cli 1.0.1 → 1.1.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
@@ -21,49 +21,98 @@ function HelpCommand() {
21
21
  "<command>",
22
22
  " [options]"
23
23
  ] }) }),
24
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Commands:" }) }),
24
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Interactive Commands:" }) }),
25
25
  /* @__PURE__ */ jsxs(Box, { marginLeft: 2, flexDirection: "column", gap: 0, children: [
26
26
  /* @__PURE__ */ jsxs(Box, { children: [
27
- /* @__PURE__ */ jsx(Box, { width: 16, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "login" }) }),
27
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "login" }) }),
28
28
  /* @__PURE__ */ jsx(Text, { children: "Authenticate with your Ollie Shop account" })
29
29
  ] }),
30
30
  /* @__PURE__ */ jsxs(Box, { children: [
31
- /* @__PURE__ */ jsx(Box, { width: 16, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "start" }) }),
31
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "start" }) }),
32
32
  /* @__PURE__ */ jsx(Text, { children: "Start the development server with hot reload" })
33
+ ] })
34
+ ] }),
35
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Agent Commands:" }) }),
36
+ /* @__PURE__ */ jsxs(Box, { marginLeft: 2, flexDirection: "column", gap: 0, children: [
37
+ /* @__PURE__ */ jsxs(Box, { children: [
38
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "whoami" }) }),
39
+ /* @__PURE__ */ jsx(Text, { children: "Show current user and organization" })
40
+ ] }),
41
+ /* @__PURE__ */ jsxs(Box, { children: [
42
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "store create|list" }) }),
43
+ /* @__PURE__ */ jsx(Text, { children: "Create or list stores" })
44
+ ] }),
45
+ /* @__PURE__ */ jsxs(Box, { children: [
46
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "version create|list" }) }),
47
+ /* @__PURE__ */ jsx(Text, { children: "Create or list versions" })
33
48
  ] }),
34
49
  /* @__PURE__ */ jsxs(Box, { children: [
35
- /* @__PURE__ */ jsx(Box, { width: 16, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "help" }) }),
50
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "component create|list" }) }),
51
+ /* @__PURE__ */ jsx(Text, { children: "Create or list components" })
52
+ ] }),
53
+ /* @__PURE__ */ jsxs(Box, { children: [
54
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "schema" }) }),
55
+ /* @__PURE__ */ jsx(Text, { children: "Introspect resource schemas (JSON Schema)" })
56
+ ] }),
57
+ /* @__PURE__ */ jsxs(Box, { children: [
58
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "init" }) }),
59
+ /* @__PURE__ */ jsx(Text, { children: "Write store/version IDs to ollie.json" })
60
+ ] }),
61
+ /* @__PURE__ */ jsxs(Box, { children: [
62
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "help" }) }),
36
63
  /* @__PURE__ */ jsx(Text, { children: "Show this help message" })
37
64
  ] }),
38
65
  /* @__PURE__ */ jsxs(Box, { children: [
39
- /* @__PURE__ */ jsx(Box, { width: 16, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "version" }) }),
66
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "green", children: "version" }) }),
40
67
  /* @__PURE__ */ jsx(Text, { children: "Show CLI version" })
41
68
  ] })
42
69
  ] }),
43
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Start Options:" }) }),
44
- /* @__PURE__ */ jsx(Box, { marginLeft: 2, flexDirection: "column", gap: 0, children: /* @__PURE__ */ jsxs(Box, { children: [
45
- /* @__PURE__ */ jsx(Box, { width: 20, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "--stage, -s" }) }),
46
- /* @__PURE__ */ jsxs(Text, { children: [
47
- "Config stage (loads ollie.",
48
- "{stage}",
49
- ".json)"
50
- ] })
51
- ] }) }),
52
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Configuration:" }) }),
53
- /* @__PURE__ */ jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [
54
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "ollie.json - Default config (prod)" }),
55
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "ollie.dev.json - Dev stage config" }),
56
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
57
- "ollie.",
58
- "{stage}",
59
- ".json - Custom stage config"
70
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Global Flags:" }) }),
71
+ /* @__PURE__ */ jsxs(Box, { marginLeft: 2, flexDirection: "column", gap: 0, children: [
72
+ /* @__PURE__ */ jsxs(Box, { children: [
73
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "--output json, -o json" }) }),
74
+ /* @__PURE__ */ jsx(Text, { children: "Force JSON output (auto when piped)" })
75
+ ] }),
76
+ /* @__PURE__ */ jsxs(Box, { children: [
77
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "--dry-run" }) }),
78
+ /* @__PURE__ */ jsx(Text, { children: "Validate without executing mutations" })
79
+ ] }),
80
+ /* @__PURE__ */ jsxs(Box, { children: [
81
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "--fields a,b,c" }) }),
82
+ /* @__PURE__ */ jsx(Text, { children: "Limit output fields" })
83
+ ] }),
84
+ /* @__PURE__ */ jsxs(Box, { children: [
85
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
86
+ "--data ",
87
+ `'{...}'`
88
+ ] }) }),
89
+ /* @__PURE__ */ jsx(Text, { children: "Raw JSON payload for mutations" })
90
+ ] }),
91
+ /* @__PURE__ */ jsxs(Box, { children: [
92
+ /* @__PURE__ */ jsx(Box, { width: 24, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "--stage, -s" }) }),
93
+ /* @__PURE__ */ jsxs(Text, { children: [
94
+ "Config stage (loads ollie.",
95
+ "{stage}",
96
+ ".json)"
97
+ ] })
60
98
  ] })
61
99
  ] }),
62
100
  /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Examples:" }) }),
63
101
  /* @__PURE__ */ jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [
64
102
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop login" }),
65
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop start" }),
66
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop start --stage dev" })
103
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop start --stage dev" }),
104
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop whoami -o json" }),
105
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop schema store.create" }),
106
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: '$ ollieshop store create --name "My Store" --platform vtex --platform-store-id mystore' }),
107
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
108
+ "$ ollieshop store create --data",
109
+ " ",
110
+ `'{"name":"My Store","platform":"vtex","platformStoreId":"mystore"}'`,
111
+ " ",
112
+ "-o json"
113
+ ] }),
114
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop version create --store-id UUID --name v1 --active" }),
115
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "$ ollieshop init --store-id UUID --version-id UUID" })
67
116
  ] })
68
117
  ] });
69
118
  }
@@ -227,14 +276,32 @@ async function saveCredentials(token) {
227
276
  };
228
277
  await fs.writeFile(CREDENTIALS_PATH, JSON.stringify(credentials, null, 2));
229
278
  }
279
+ async function getCredentials() {
280
+ try {
281
+ const content = await fs.readFile(CREDENTIALS_PATH, "utf-8");
282
+ return JSON.parse(content);
283
+ } catch {
284
+ return null;
285
+ }
286
+ }
287
+ async function getCurrentUser() {
288
+ const credentials = await getCredentials();
289
+ if (!credentials) return null;
290
+ try {
291
+ const decoded = jwtDecode(credentials.accessToken);
292
+ return decoded.email ? { email: decoded.email } : null;
293
+ } catch {
294
+ return null;
295
+ }
296
+ }
230
297
 
231
298
  // src/commands/login.tsx
232
299
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
233
- function LoginCommand({ args: args2 }) {
300
+ function LoginCommand({ args }) {
234
301
  const { exit } = useApp();
235
302
  const [state, setState] = useState({ status: "idle" });
236
- const portIndex = args2.findIndex((a) => a === "--port" || a === "-p");
237
- const port = portIndex !== -1 ? Number.parseInt(args2[portIndex + 1], 10) : 7777;
303
+ const portIndex = args.findIndex((a) => a === "--port" || a === "-p");
304
+ const port = portIndex !== -1 ? Number.parseInt(args[portIndex + 1], 10) : 7777;
238
305
  useEffect(() => {
239
306
  if (state.status !== "idle") return;
240
307
  setState({ status: "waiting" });
@@ -341,6 +408,17 @@ async function loadConfig(options = {}) {
341
408
  };
342
409
  return OllieConfigSchema.parse(merged);
343
410
  }
411
+ async function saveConfig(config, options = {}) {
412
+ const { cwd = process.cwd(), stage } = options;
413
+ const fileName = getConfigFileName(stage);
414
+ const configPath = path2.join(cwd, fileName);
415
+ const existing = await loadConfigFile(configPath);
416
+ const merged = {
417
+ ...existing,
418
+ ...config
419
+ };
420
+ await fs2.writeFile(configPath, JSON.stringify(merged, null, 2));
421
+ }
344
422
  function resolveStage(cliStage) {
345
423
  return cliStage || process.env.OLLIE_STAGE || void 0;
346
424
  }
@@ -603,6 +681,7 @@ async function startDevServer(ctx, options = {}) {
603
681
  const componentName = pathMatch[1];
604
682
  res.setHeader("Access-Control-Allow-Origin", "*");
605
683
  res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
684
+ res.setHeader("Access-Control-Allow-Private-Network", "true");
606
685
  try {
607
686
  const stream = await createComponentBundle({ cwd, componentName });
608
687
  res.setHeader("Content-Type", "application/zip");
@@ -642,6 +721,7 @@ async function startDevServer(ctx, options = {}) {
642
721
  res.setHeader("Access-Control-Allow-Origin", "*");
643
722
  res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
644
723
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");
724
+ res.setHeader("Access-Control-Allow-Private-Network", "true");
645
725
  let body = "";
646
726
  req.on("data", (chunk) => {
647
727
  body += chunk.toString();
@@ -680,6 +760,7 @@ async function startDevServer(ctx, options = {}) {
680
760
  if (req.method === "OPTIONS") {
681
761
  res.setHeader("Access-Control-Allow-Origin", "*");
682
762
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
763
+ res.setHeader("Access-Control-Allow-Private-Network", "true");
683
764
  const requestedHeaders = req.headers["access-control-request-headers"];
684
765
  res.setHeader(
685
766
  "Access-Control-Allow-Headers",
@@ -700,7 +781,8 @@ async function startDevServer(ctx, options = {}) {
700
781
  (proxyRes) => {
701
782
  const responseHeaders = {
702
783
  ...proxyRes.headers,
703
- "access-control-allow-origin": "*"
784
+ "access-control-allow-origin": "*",
785
+ "access-control-allow-private-network": "true"
704
786
  };
705
787
  res.writeHead(proxyRes.statusCode || 200, responseHeaders);
706
788
  proxyRes.pipe(res);
@@ -760,11 +842,11 @@ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
760
842
  var STUDIO_BASE_URL = "https://admin.ollie.shop/studio";
761
843
  var MAX_LOGS = 10;
762
844
  var PORT = 4e3;
763
- function parseArg(args2, ...flags) {
764
- const index = args2.findIndex((a) => flags.includes(a));
765
- return index !== -1 ? args2[index + 1] : void 0;
845
+ function parseArg(args, ...flags) {
846
+ const index = args.findIndex((a) => flags.includes(a));
847
+ return index !== -1 ? args[index + 1] : void 0;
766
848
  }
767
- function StartCommand({ args: args2 }) {
849
+ function StartCommand({ args }) {
768
850
  const { exit } = useApp2();
769
851
  const [state, setState] = useState2({ status: "initializing" });
770
852
  const [components, setComponents] = useState2([]);
@@ -774,7 +856,7 @@ function StartCommand({ args: args2 }) {
774
856
  const logIdRef = useRef(0);
775
857
  const ctxRef = useRef(null);
776
858
  const stopRef = useRef(null);
777
- const stage = resolveStage(parseArg(args2, "--stage", "-s"));
859
+ const stage = resolveStage(parseArg(args, "--stage", "-s"));
778
860
  const addLog = useCallback((log) => {
779
861
  setLogs((prev) => {
780
862
  const newLog = {
@@ -786,12 +868,12 @@ function StartCommand({ args: args2 }) {
786
868
  });
787
869
  }, []);
788
870
  const handleRequest = useCallback(
789
- (args3) => {
871
+ (args2) => {
790
872
  addLog({
791
- method: args3.method,
792
- path: args3.path,
793
- status: args3.status,
794
- time: args3.timeInMS
873
+ method: args2.method,
874
+ path: args2.path,
875
+ status: args2.status,
876
+ time: args2.timeInMS
795
877
  });
796
878
  },
797
879
  [addLog]
@@ -1061,12 +1143,12 @@ function Footer() {
1061
1143
 
1062
1144
  // src/cli.tsx
1063
1145
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1064
- function App({ command: command2, args: args2 }) {
1065
- switch (command2) {
1146
+ function App({ command, args }) {
1147
+ switch (command) {
1066
1148
  case "login":
1067
- return /* @__PURE__ */ jsx4(LoginCommand, { args: args2 });
1149
+ return /* @__PURE__ */ jsx4(LoginCommand, { args });
1068
1150
  case "start":
1069
- return /* @__PURE__ */ jsx4(StartCommand, { args: args2 });
1151
+ return /* @__PURE__ */ jsx4(StartCommand, { args });
1070
1152
  case "help":
1071
1153
  case "--help":
1072
1154
  case "-h":
@@ -1076,25 +1158,785 @@ function App({ command: command2, args: args2 }) {
1076
1158
  case "-v":
1077
1159
  return /* @__PURE__ */ jsx4(VersionCommand, {});
1078
1160
  default:
1079
- return /* @__PURE__ */ jsx4(UnknownCommand, { command: command2 });
1161
+ return /* @__PURE__ */ jsx4(UnknownCommand, { command });
1080
1162
  }
1081
1163
  }
1082
1164
  function VersionCommand() {
1083
1165
  return /* @__PURE__ */ jsx4(Box4, { children: /* @__PURE__ */ jsx4(Text4, { children: "ollie v0.1.0" }) });
1084
1166
  }
1085
- function UnknownCommand({ command: command2 }) {
1167
+ function UnknownCommand({ command }) {
1086
1168
  return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", gap: 1, children: [
1087
1169
  /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
1088
1170
  "Unknown command: ",
1089
- command2
1171
+ command
1090
1172
  ] }),
1091
1173
  /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Run `ollie help` for available commands." })
1092
1174
  ] });
1093
1175
  }
1094
1176
 
1177
+ // src/core/schema.ts
1178
+ import { z as z2 } from "zod";
1179
+ import { zodToJsonSchema } from "zod-to-json-schema";
1180
+ var PLATFORM_VENDORS = ["vtex", "shopify", "vnda", "custom"];
1181
+ var storeCreateSchema = z2.object({
1182
+ name: z2.string().min(1).describe("Store display name"),
1183
+ platform: z2.enum(PLATFORM_VENDORS).describe("E-commerce platform vendor"),
1184
+ platformStoreId: z2.string().min(1).describe("Platform-specific store identifier (e.g. account name)"),
1185
+ logo: z2.string().url().optional().describe("Store logo URL"),
1186
+ settings: z2.string().optional().describe("JSON settings string")
1187
+ });
1188
+ var storeListSchema = z2.object({}).describe("No parameters required");
1189
+ var versionCreateSchema = z2.object({
1190
+ storeId: z2.string().uuid().describe("Parent store UUID"),
1191
+ name: z2.string().min(1).describe("Version name (e.g. v1, main)"),
1192
+ active: z2.boolean().default(false).describe("Whether version is active"),
1193
+ default: z2.boolean().default(false).describe("Whether this is the default version"),
1194
+ template: z2.string().nullable().default(null).describe("Template name or null")
1195
+ });
1196
+ var versionListSchema = z2.object({
1197
+ storeId: z2.string().uuid().describe("Store UUID to list versions for")
1198
+ });
1199
+ var componentCreateSchema = z2.object({
1200
+ versionId: z2.string().uuid().describe("Parent version UUID"),
1201
+ name: z2.string().min(1).describe("Component name (e.g. FreeShippingBar)"),
1202
+ slot: z2.string().min(1).describe(
1203
+ "Target slot (e.g. cart_header_full_page, shipping_address_details_form)"
1204
+ ),
1205
+ active: z2.boolean().default(true).describe("Whether component is active"),
1206
+ props: z2.record(z2.unknown()).nullable().default(null).describe("Default component props as JSON object")
1207
+ });
1208
+ var componentListSchema = z2.object({
1209
+ storeId: z2.string().uuid().describe("Store UUID"),
1210
+ versionId: z2.string().uuid().optional().describe("Optional version UUID to filter by")
1211
+ });
1212
+ var functionCreateSchema = z2.object({
1213
+ versionId: z2.string().uuid().describe("Parent version UUID"),
1214
+ name: z2.string().min(1).describe("Function name"),
1215
+ trigger: z2.string().min(1).describe("Function trigger (e.g. beforePayment, afterShipping)"),
1216
+ active: z2.boolean().default(true).describe("Whether function is active")
1217
+ });
1218
+ var functionListSchema = z2.object({
1219
+ versionId: z2.string().uuid().describe("Version UUID to list functions for")
1220
+ });
1221
+ var schemas = {
1222
+ store: {
1223
+ create: storeCreateSchema,
1224
+ list: storeListSchema
1225
+ },
1226
+ version: {
1227
+ create: versionCreateSchema,
1228
+ list: versionListSchema
1229
+ },
1230
+ component: {
1231
+ create: componentCreateSchema,
1232
+ list: componentListSchema
1233
+ },
1234
+ function: {
1235
+ create: functionCreateSchema,
1236
+ list: functionListSchema
1237
+ }
1238
+ };
1239
+ function getSchemaNames() {
1240
+ const names = [];
1241
+ for (const [resource, actions] of Object.entries(schemas)) {
1242
+ names.push(resource);
1243
+ for (const action of Object.keys(actions)) {
1244
+ names.push(`${resource}.${action}`);
1245
+ }
1246
+ }
1247
+ return names;
1248
+ }
1249
+ function getJsonSchema(name) {
1250
+ const parts = name.split(".");
1251
+ const resource = parts[0];
1252
+ const action = parts[1];
1253
+ if (!resource || !schemas[resource]) return null;
1254
+ if (action) {
1255
+ const schema = schemas[resource][action];
1256
+ if (!schema) return null;
1257
+ return zodToJsonSchema(schema, { name: `${resource}.${action}` });
1258
+ }
1259
+ const result = {};
1260
+ for (const [actionName, schema] of Object.entries(schemas[resource])) {
1261
+ result[actionName] = zodToJsonSchema(schema, {
1262
+ name: `${resource}.${actionName}`
1263
+ });
1264
+ }
1265
+ return result;
1266
+ }
1267
+
1268
+ // src/core/component.ts
1269
+ async function createComponent(client, input) {
1270
+ const parsed2 = componentCreateSchema.safeParse(input);
1271
+ if (!parsed2.success) {
1272
+ return {
1273
+ error: { message: parsed2.error.issues.map((i) => i.message).join("; ") }
1274
+ };
1275
+ }
1276
+ const { data, error } = await client.from("components").insert({
1277
+ name: parsed2.data.name,
1278
+ slot: parsed2.data.slot,
1279
+ active: parsed2.data.active,
1280
+ version_id: parsed2.data.versionId,
1281
+ props: parsed2.data.props
1282
+ }).select("id").single();
1283
+ if (error) {
1284
+ return { error: { message: error.message } };
1285
+ }
1286
+ return { data: { id: data.id } };
1287
+ }
1288
+ async function listComponents(client, storeId, versionId) {
1289
+ let query = client.from("components").select(
1290
+ "id, name, slot, active, version_id, props, created_at, versions!inner(id, name)"
1291
+ ).eq("versions.store_id", storeId);
1292
+ if (versionId) {
1293
+ query = query.eq("versions.id", versionId);
1294
+ }
1295
+ const { data, error } = await query;
1296
+ if (error) {
1297
+ return { error: { message: error.message } };
1298
+ }
1299
+ return { data: data ?? [] };
1300
+ }
1301
+
1302
+ // src/utils/output.ts
1303
+ function detectOutputFormat(cliOutput) {
1304
+ if (cliOutput === "json" || cliOutput === "j") return "json";
1305
+ if (cliOutput === "pretty") return "pretty";
1306
+ return process.stdout.isTTY ? "pretty" : "json";
1307
+ }
1308
+ function filterFields(data, fields) {
1309
+ if (!fields || fields.length === 0) return data;
1310
+ const result = {};
1311
+ for (const field of fields) {
1312
+ if (field in data) {
1313
+ result[field] = data[field];
1314
+ }
1315
+ }
1316
+ return result;
1317
+ }
1318
+ function outputResult(result, format, fields) {
1319
+ if (format === "json") {
1320
+ let output = result;
1321
+ if (fields && result.data && typeof result.data === "object") {
1322
+ if (Array.isArray(result.data)) {
1323
+ output = {
1324
+ ...result,
1325
+ data: result.data.map(
1326
+ (item) => filterFields(item, fields)
1327
+ )
1328
+ };
1329
+ } else {
1330
+ output = {
1331
+ ...result,
1332
+ data: filterFields(result.data, fields)
1333
+ };
1334
+ }
1335
+ }
1336
+ process.stdout.write(`${JSON.stringify(output)}
1337
+ `);
1338
+ return;
1339
+ }
1340
+ if (result.error) {
1341
+ const errMsg = typeof result.error === "object" && result.error !== null ? result.error.message || JSON.stringify(result.error) : String(result.error);
1342
+ console.error(`\x1B[31mError:\x1B[0m ${errMsg}`);
1343
+ return;
1344
+ }
1345
+ if (Array.isArray(result.data)) {
1346
+ printTable(result.data, fields);
1347
+ } else if (typeof result.data === "object" && result.data !== null) {
1348
+ const filtered = fields ? filterFields(result.data, fields) : result.data;
1349
+ for (const [key, value] of Object.entries(
1350
+ filtered
1351
+ )) {
1352
+ console.log(`\x1B[1m${key}:\x1B[0m ${value}`);
1353
+ }
1354
+ } else {
1355
+ console.log(result.data);
1356
+ }
1357
+ }
1358
+ function printTable(rows, fields) {
1359
+ if (rows.length === 0) {
1360
+ console.log("(no results)");
1361
+ return;
1362
+ }
1363
+ const keys = fields || Object.keys(rows[0]);
1364
+ const widths = {};
1365
+ for (const key of keys) {
1366
+ widths[key] = key.length;
1367
+ for (const row of rows) {
1368
+ const val = String(row[key] ?? "");
1369
+ widths[key] = Math.max(widths[key], val.length);
1370
+ }
1371
+ widths[key] = Math.min(widths[key], 40);
1372
+ }
1373
+ const header = keys.map((k) => k.padEnd(widths[k])).join(" ");
1374
+ console.log(`\x1B[1m${header}\x1B[0m`);
1375
+ console.log(keys.map((k) => "\u2500".repeat(widths[k])).join("\u2500\u2500"));
1376
+ for (const row of rows) {
1377
+ const line = keys.map(
1378
+ (k) => String(row[k] ?? "").padEnd(widths[k]).slice(0, widths[k])
1379
+ ).join(" ");
1380
+ console.log(line);
1381
+ }
1382
+ }
1383
+ function outputDryRun(action, data, format) {
1384
+ if (format === "json") {
1385
+ process.stdout.write(`${JSON.stringify({ dryRun: true, action, data })}
1386
+ `);
1387
+ } else {
1388
+ console.log(`\x1B[33m[dry-run]\x1B[0m Would execute: ${action}`);
1389
+ for (const [key, value] of Object.entries(data)) {
1390
+ console.log(` ${key}: ${JSON.stringify(value)}`);
1391
+ }
1392
+ }
1393
+ }
1394
+
1395
+ // src/utils/parse-args.ts
1396
+ function parseArgs(argv) {
1397
+ const args = argv.slice(2);
1398
+ const command = args[0] || "help";
1399
+ const flags = {};
1400
+ const positional = [];
1401
+ let subcommand;
1402
+ if (args[1] && !args[1].startsWith("-")) {
1403
+ subcommand = args[1];
1404
+ }
1405
+ const startIdx = subcommand ? 2 : 1;
1406
+ for (let i = startIdx; i < args.length; i++) {
1407
+ const arg = args[i];
1408
+ if (arg.startsWith("--")) {
1409
+ const key = arg.slice(2);
1410
+ const next = args[i + 1];
1411
+ if (next && !next.startsWith("-")) {
1412
+ flags[key] = next;
1413
+ i++;
1414
+ } else {
1415
+ flags[key] = true;
1416
+ }
1417
+ } else if (arg.startsWith("-") && arg.length === 2) {
1418
+ const key = arg.slice(1);
1419
+ const next = args[i + 1];
1420
+ if (next && !next.startsWith("-")) {
1421
+ flags[key] = next;
1422
+ i++;
1423
+ } else {
1424
+ flags[key] = true;
1425
+ }
1426
+ } else {
1427
+ positional.push(arg);
1428
+ }
1429
+ }
1430
+ const global = {
1431
+ output: flags.output || flags.o || void 0,
1432
+ dryRun: flags["dry-run"] === true,
1433
+ fields: flags.fields ? String(flags.fields).split(",").map((f) => f.trim()) : void 0,
1434
+ data: flags.data || flags.d || void 0
1435
+ };
1436
+ return { command, subcommand, flags, global, positional };
1437
+ }
1438
+ function getFlag(flags, ...names) {
1439
+ for (const name of names) {
1440
+ const val = flags[name];
1441
+ if (typeof val === "string") return val;
1442
+ }
1443
+ return void 0;
1444
+ }
1445
+ function getBoolFlag(flags, ...names) {
1446
+ for (const name of names) {
1447
+ if (flags[name] === true) return true;
1448
+ }
1449
+ return false;
1450
+ }
1451
+
1452
+ // src/utils/supabase.ts
1453
+ import { createClient } from "@supabase/supabase-js";
1454
+ function requireEnv(name) {
1455
+ const value = process.env[name];
1456
+ if (!value) {
1457
+ throw new Error(
1458
+ `Missing required environment variable: ${name}. Set it in your .env file or shell.`
1459
+ );
1460
+ }
1461
+ return value;
1462
+ }
1463
+ async function getAuthenticatedClient() {
1464
+ const credentials = await getCredentials();
1465
+ if (!credentials) {
1466
+ throw new Error("Not authenticated. Run `ollieshop login` first.");
1467
+ }
1468
+ const supabaseUrl = requireEnv("OLLIE_SUPABASE_URL");
1469
+ const supabaseAnonKey = requireEnv("OLLIE_SUPABASE_ANON_KEY");
1470
+ const client = createClient(supabaseUrl, supabaseAnonKey, {
1471
+ auth: {
1472
+ autoRefreshToken: false,
1473
+ persistSession: false
1474
+ }
1475
+ });
1476
+ await client.auth.setSession({
1477
+ access_token: credentials.accessToken,
1478
+ refresh_token: credentials.refreshToken
1479
+ });
1480
+ return client;
1481
+ }
1482
+ async function getOrganizationId(client) {
1483
+ const { data: org, error } = await client.from("organizations").select("id").order("created_at", { ascending: true }).limit(1).maybeSingle();
1484
+ if (error) {
1485
+ throw new Error(`Failed to get organization: ${error.message}`);
1486
+ }
1487
+ if (!org) {
1488
+ throw new Error(
1489
+ "No organization found for your account. Create one at https://admin.ollie.shop"
1490
+ );
1491
+ }
1492
+ return org.id;
1493
+ }
1494
+
1495
+ // src/utils/validate.ts
1496
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1497
+ var CONTROL_CHAR_REGEX = /[\x00-\x1f\x7f]/;
1498
+ function validateUuid(value, name) {
1499
+ if (!UUID_REGEX.test(value)) {
1500
+ throw new Error(
1501
+ `Invalid ${name}: "${value}". Must be a valid UUID (e.g. 7217542a-d7c6-40d3-a20e-db13b310a781).`
1502
+ );
1503
+ }
1504
+ return value;
1505
+ }
1506
+ function rejectControlChars(value, name) {
1507
+ if (CONTROL_CHAR_REGEX.test(value)) {
1508
+ throw new Error(
1509
+ `Invalid ${name}: contains control characters. Input must be printable text.`
1510
+ );
1511
+ }
1512
+ return value;
1513
+ }
1514
+ function validateEnum(value, allowed, name) {
1515
+ if (!allowed.includes(value)) {
1516
+ throw new Error(
1517
+ `Invalid ${name}: "${value}". Must be one of: ${allowed.join(", ")}`
1518
+ );
1519
+ }
1520
+ return value;
1521
+ }
1522
+ function validateRequired(value, name) {
1523
+ if (!value || value.trim() === "") {
1524
+ throw new Error(`Missing required parameter: --${name}`);
1525
+ }
1526
+ return rejectControlChars(value.trim(), name);
1527
+ }
1528
+
1529
+ // src/commands/component-cmd.ts
1530
+ async function componentCommand(parsed2) {
1531
+ const sub = parsed2.subcommand;
1532
+ if (sub === "create") return componentCreateCommand(parsed2);
1533
+ if (sub === "list" || sub === "ls") return componentListCommand(parsed2);
1534
+ console.error(
1535
+ `Unknown component subcommand: ${sub}. Use: component create | component list`
1536
+ );
1537
+ process.exit(1);
1538
+ }
1539
+ async function componentCreateCommand(parsed2) {
1540
+ const format = detectOutputFormat(parsed2.global.output);
1541
+ try {
1542
+ let input;
1543
+ if (parsed2.global.data) {
1544
+ const raw = JSON.parse(parsed2.global.data);
1545
+ input = {
1546
+ versionId: validateUuid(raw.versionId, "versionId"),
1547
+ name: validateRequired(raw.name, "name"),
1548
+ slot: validateRequired(raw.slot, "slot"),
1549
+ active: raw.active ?? true,
1550
+ props: raw.props ?? null
1551
+ };
1552
+ } else {
1553
+ input = {
1554
+ versionId: validateUuid(
1555
+ validateRequired(getFlag(parsed2.flags, "version-id"), "version-id"),
1556
+ "version-id"
1557
+ ),
1558
+ name: validateRequired(getFlag(parsed2.flags, "name", "n"), "name"),
1559
+ slot: validateRequired(getFlag(parsed2.flags, "slot", "s"), "slot"),
1560
+ active: getBoolFlag(parsed2.flags, "active") || !("active" in parsed2.flags),
1561
+ props: null
1562
+ };
1563
+ }
1564
+ if (parsed2.global.dryRun) {
1565
+ outputDryRun(
1566
+ "component.create",
1567
+ input,
1568
+ format
1569
+ );
1570
+ return;
1571
+ }
1572
+ const client = await getAuthenticatedClient();
1573
+ const result = await createComponent(client, input);
1574
+ outputResult(result, format, parsed2.global.fields);
1575
+ if (result.error) process.exit(1);
1576
+ } catch (err) {
1577
+ outputResult(
1578
+ {
1579
+ error: { message: err instanceof Error ? err.message : String(err) }
1580
+ },
1581
+ format
1582
+ );
1583
+ process.exit(1);
1584
+ }
1585
+ }
1586
+ async function componentListCommand(parsed2) {
1587
+ const format = detectOutputFormat(parsed2.global.output);
1588
+ try {
1589
+ const storeId = validateUuid(
1590
+ validateRequired(getFlag(parsed2.flags, "store-id"), "store-id"),
1591
+ "store-id"
1592
+ );
1593
+ const versionId = getFlag(parsed2.flags, "version-id");
1594
+ if (versionId) validateUuid(versionId, "version-id");
1595
+ const client = await getAuthenticatedClient();
1596
+ const result = await listComponents(client, storeId, versionId);
1597
+ outputResult(result, format, parsed2.global.fields);
1598
+ if (result.error) process.exit(1);
1599
+ } catch (err) {
1600
+ outputResult(
1601
+ {
1602
+ error: { message: err instanceof Error ? err.message : String(err) }
1603
+ },
1604
+ format
1605
+ );
1606
+ process.exit(1);
1607
+ }
1608
+ }
1609
+
1610
+ // src/commands/init-cmd.ts
1611
+ async function initCommand(parsed2) {
1612
+ const format = detectOutputFormat(parsed2.global.output);
1613
+ try {
1614
+ const storeId = validateUuid(
1615
+ validateRequired(getFlag(parsed2.flags, "store-id"), "store-id"),
1616
+ "store-id"
1617
+ );
1618
+ const versionIdRaw = getFlag(parsed2.flags, "version-id");
1619
+ const versionId = versionIdRaw ? validateUuid(versionIdRaw, "version-id") : void 0;
1620
+ const stage = getFlag(parsed2.flags, "stage", "s");
1621
+ await saveConfig(
1622
+ {
1623
+ storeId,
1624
+ ...versionId ? { versionId } : {}
1625
+ },
1626
+ { stage }
1627
+ );
1628
+ const fileName = stage && stage !== "prod" ? `ollie.${stage}.json` : "ollie.json";
1629
+ outputResult(
1630
+ {
1631
+ data: {
1632
+ file: fileName,
1633
+ storeId,
1634
+ ...versionId ? { versionId } : {}
1635
+ }
1636
+ },
1637
+ format,
1638
+ parsed2.global.fields
1639
+ );
1640
+ } catch (err) {
1641
+ outputResult(
1642
+ {
1643
+ error: { message: err instanceof Error ? err.message : String(err) }
1644
+ },
1645
+ format
1646
+ );
1647
+ process.exit(1);
1648
+ }
1649
+ }
1650
+
1651
+ // src/commands/schema-cmd.ts
1652
+ async function schemaCommand(parsed2) {
1653
+ const format = detectOutputFormat(parsed2.global.output);
1654
+ const resourceName = parsed2.subcommand || parsed2.positional[0];
1655
+ if (!resourceName) {
1656
+ const names = getSchemaNames();
1657
+ if (format === "json") {
1658
+ process.stdout.write(`${JSON.stringify({ schemas: names })}
1659
+ `);
1660
+ } else {
1661
+ console.log("\x1B[1mAvailable schemas:\x1B[0m");
1662
+ for (const name of names) {
1663
+ const indent = name.includes(".") ? " " : " ";
1664
+ console.log(`${indent}\x1B[32m${name}\x1B[0m`);
1665
+ }
1666
+ console.log("\nUsage: ollieshop schema <resource[.action]>");
1667
+ }
1668
+ return;
1669
+ }
1670
+ const schema = getJsonSchema(resourceName);
1671
+ if (!schema) {
1672
+ console.error(
1673
+ `Unknown schema: ${resourceName}. Run \`ollieshop schema\` to see available schemas.`
1674
+ );
1675
+ process.exit(1);
1676
+ }
1677
+ process.stdout.write(`${JSON.stringify(schema, null, 2)}
1678
+ `);
1679
+ }
1680
+
1681
+ // src/core/store.ts
1682
+ async function createStore(client, input) {
1683
+ const parsed2 = storeCreateSchema.safeParse(input);
1684
+ if (!parsed2.success) {
1685
+ return {
1686
+ error: { message: parsed2.error.issues.map((i) => i.message).join("; ") }
1687
+ };
1688
+ }
1689
+ const organizationId = await getOrganizationId(client);
1690
+ const { data, error } = await client.from("stores").insert({
1691
+ name: parsed2.data.name,
1692
+ platform: parsed2.data.platform,
1693
+ platform_store_id: parsed2.data.platformStoreId,
1694
+ organization_id: organizationId,
1695
+ logo: parsed2.data.logo ?? null,
1696
+ settings: parsed2.data.settings ?? null
1697
+ }).select("id").single();
1698
+ if (error) {
1699
+ return { error: { message: error.message } };
1700
+ }
1701
+ return { data: { id: data.id } };
1702
+ }
1703
+ async function listStores(client) {
1704
+ const organizationId = await getOrganizationId(client);
1705
+ const { data, error } = await client.from("stores").select(
1706
+ "id, name, platform, platform_store_id, organization_id, logo, settings, created_at"
1707
+ ).eq("organization_id", organizationId).order("created_at", { ascending: false });
1708
+ if (error) {
1709
+ return { error: { message: error.message } };
1710
+ }
1711
+ return { data };
1712
+ }
1713
+
1714
+ // src/commands/store-cmd.ts
1715
+ async function storeCommand(parsed2) {
1716
+ const sub = parsed2.subcommand;
1717
+ if (sub === "create") return storeCreateCommand(parsed2);
1718
+ if (sub === "list" || sub === "ls") return storeListCommand(parsed2);
1719
+ console.error(
1720
+ `Unknown store subcommand: ${sub}. Use: store create | store list`
1721
+ );
1722
+ process.exit(1);
1723
+ }
1724
+ async function storeCreateCommand(parsed2) {
1725
+ const format = detectOutputFormat(parsed2.global.output);
1726
+ try {
1727
+ let input;
1728
+ if (parsed2.global.data) {
1729
+ const raw = JSON.parse(parsed2.global.data);
1730
+ input = {
1731
+ name: validateRequired(raw.name, "name"),
1732
+ platform: validateEnum(raw.platform, PLATFORM_VENDORS, "platform"),
1733
+ platformStoreId: validateRequired(
1734
+ raw.platformStoreId,
1735
+ "platformStoreId"
1736
+ ),
1737
+ logo: raw.logo,
1738
+ settings: raw.settings
1739
+ };
1740
+ } else {
1741
+ input = {
1742
+ name: validateRequired(getFlag(parsed2.flags, "name", "n"), "name"),
1743
+ platform: validateEnum(
1744
+ validateRequired(getFlag(parsed2.flags, "platform", "p"), "platform"),
1745
+ PLATFORM_VENDORS,
1746
+ "platform"
1747
+ ),
1748
+ platformStoreId: validateRequired(
1749
+ getFlag(parsed2.flags, "platform-store-id"),
1750
+ "platform-store-id"
1751
+ ),
1752
+ logo: getFlag(parsed2.flags, "logo"),
1753
+ settings: getFlag(parsed2.flags, "settings")
1754
+ };
1755
+ }
1756
+ if (parsed2.global.dryRun) {
1757
+ outputDryRun("store.create", input, format);
1758
+ return;
1759
+ }
1760
+ const client = await getAuthenticatedClient();
1761
+ const result = await createStore(client, input);
1762
+ outputResult(result, format, parsed2.global.fields);
1763
+ if (result.error) process.exit(1);
1764
+ } catch (err) {
1765
+ outputResult(
1766
+ {
1767
+ error: { message: err instanceof Error ? err.message : String(err) }
1768
+ },
1769
+ format
1770
+ );
1771
+ process.exit(1);
1772
+ }
1773
+ }
1774
+ async function storeListCommand(parsed2) {
1775
+ const format = detectOutputFormat(parsed2.global.output);
1776
+ try {
1777
+ const client = await getAuthenticatedClient();
1778
+ const result = await listStores(client);
1779
+ outputResult(result, format, parsed2.global.fields);
1780
+ if (result.error) process.exit(1);
1781
+ } catch (err) {
1782
+ outputResult(
1783
+ {
1784
+ error: { message: err instanceof Error ? err.message : String(err) }
1785
+ },
1786
+ format
1787
+ );
1788
+ process.exit(1);
1789
+ }
1790
+ }
1791
+
1792
+ // src/core/version.ts
1793
+ async function createVersion(client, input) {
1794
+ const parsed2 = versionCreateSchema.safeParse(input);
1795
+ if (!parsed2.success) {
1796
+ return {
1797
+ error: { message: parsed2.error.issues.map((i) => i.message).join("; ") }
1798
+ };
1799
+ }
1800
+ const { data, error } = await client.from("versions").insert({
1801
+ name: parsed2.data.name,
1802
+ active: parsed2.data.active,
1803
+ default: parsed2.data.default,
1804
+ store_id: parsed2.data.storeId,
1805
+ template: parsed2.data.template
1806
+ }).select("id").single();
1807
+ if (error) {
1808
+ return { error: { message: error.message } };
1809
+ }
1810
+ return { data: { id: data.id } };
1811
+ }
1812
+ async function listVersions(client, storeId) {
1813
+ const { data, error } = await client.from("versions").select("id, name, active, default, store_id, template, created_at").eq("store_id", storeId).order("created_at", { ascending: false });
1814
+ if (error) {
1815
+ return { error: { message: error.message } };
1816
+ }
1817
+ return { data };
1818
+ }
1819
+
1820
+ // src/commands/version-cmd.ts
1821
+ async function versionCommand(parsed2) {
1822
+ const sub = parsed2.subcommand;
1823
+ if (sub === "create") return versionCreateCommand(parsed2);
1824
+ if (sub === "list" || sub === "ls") return versionListCommand(parsed2);
1825
+ console.error(
1826
+ `Unknown version subcommand: ${sub}. Use: version create | version list`
1827
+ );
1828
+ process.exit(1);
1829
+ }
1830
+ async function versionCreateCommand(parsed2) {
1831
+ const format = detectOutputFormat(parsed2.global.output);
1832
+ try {
1833
+ let input;
1834
+ if (parsed2.global.data) {
1835
+ const raw = JSON.parse(parsed2.global.data);
1836
+ input = {
1837
+ storeId: validateUuid(raw.storeId, "storeId"),
1838
+ name: validateRequired(raw.name, "name"),
1839
+ active: raw.active ?? false,
1840
+ default: raw.default ?? false,
1841
+ template: raw.template ?? null
1842
+ };
1843
+ } else {
1844
+ input = {
1845
+ storeId: validateUuid(
1846
+ validateRequired(getFlag(parsed2.flags, "store-id"), "store-id"),
1847
+ "store-id"
1848
+ ),
1849
+ name: validateRequired(getFlag(parsed2.flags, "name", "n"), "name"),
1850
+ active: getBoolFlag(parsed2.flags, "active"),
1851
+ default: getBoolFlag(parsed2.flags, "default"),
1852
+ template: getFlag(parsed2.flags, "template") ?? null
1853
+ };
1854
+ }
1855
+ if (parsed2.global.dryRun) {
1856
+ outputDryRun("version.create", input, format);
1857
+ return;
1858
+ }
1859
+ const client = await getAuthenticatedClient();
1860
+ const result = await createVersion(client, input);
1861
+ outputResult(result, format, parsed2.global.fields);
1862
+ if (result.error) process.exit(1);
1863
+ } catch (err) {
1864
+ outputResult(
1865
+ {
1866
+ error: { message: err instanceof Error ? err.message : String(err) }
1867
+ },
1868
+ format
1869
+ );
1870
+ process.exit(1);
1871
+ }
1872
+ }
1873
+ async function versionListCommand(parsed2) {
1874
+ const format = detectOutputFormat(parsed2.global.output);
1875
+ try {
1876
+ const storeId = validateUuid(
1877
+ validateRequired(getFlag(parsed2.flags, "store-id"), "store-id"),
1878
+ "store-id"
1879
+ );
1880
+ const client = await getAuthenticatedClient();
1881
+ const result = await listVersions(client, storeId);
1882
+ outputResult(result, format, parsed2.global.fields);
1883
+ if (result.error) process.exit(1);
1884
+ } catch (err) {
1885
+ outputResult(
1886
+ {
1887
+ error: { message: err instanceof Error ? err.message : String(err) }
1888
+ },
1889
+ format
1890
+ );
1891
+ process.exit(1);
1892
+ }
1893
+ }
1894
+
1895
+ // src/commands/whoami.ts
1896
+ async function whoamiCommand(parsed2) {
1897
+ const format = detectOutputFormat(parsed2.global.output);
1898
+ const user = await getCurrentUser();
1899
+ if (!user) {
1900
+ outputResult(
1901
+ {
1902
+ error: { message: "Not logged in. Run `ollieshop login`." }
1903
+ },
1904
+ format
1905
+ );
1906
+ process.exit(1);
1907
+ }
1908
+ outputResult(
1909
+ {
1910
+ data: {
1911
+ email: user.email
1912
+ }
1913
+ },
1914
+ format,
1915
+ parsed2.global.fields
1916
+ );
1917
+ }
1918
+
1095
1919
  // src/index.tsx
1096
1920
  import { jsx as jsx5 } from "react/jsx-runtime";
1097
- var args = process.argv.slice(2);
1098
- var command = args[0] || "help";
1099
- var commandArgs = args.slice(1);
1100
- render(/* @__PURE__ */ jsx5(App, { command, args: commandArgs }));
1921
+ var AGENT_COMMANDS = {
1922
+ whoami: whoamiCommand,
1923
+ store: storeCommand,
1924
+ version: versionCommand,
1925
+ component: componentCommand,
1926
+ schema: schemaCommand,
1927
+ init: initCommand
1928
+ };
1929
+ var parsed = parseArgs(process.argv);
1930
+ if (parsed.command in AGENT_COMMANDS) {
1931
+ AGENT_COMMANDS[parsed.command](parsed).catch((err) => {
1932
+ const msg = err instanceof Error ? err.message : String(err);
1933
+ process.stderr.write(`${JSON.stringify({ error: { message: msg } })}
1934
+ `);
1935
+ process.exit(1);
1936
+ });
1937
+ } else {
1938
+ const args = process.argv.slice(2);
1939
+ const command = args[0] || "help";
1940
+ const commandArgs = args.slice(1);
1941
+ render(/* @__PURE__ */ jsx5(App, { command, args: commandArgs }));
1942
+ }