@zeroxyz/cli 0.0.26 → 0.0.27

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.
Files changed (2) hide show
  1. package/dist/index.js +114 -37
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/app.ts
4
- import { Command as Command11 } from "commander";
4
+ import { Command as Command12 } from "commander";
5
5
 
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@zeroxyz/cli",
9
- version: "0.0.26",
9
+ version: "0.0.27",
10
10
  type: "module",
11
11
  bin: {
12
12
  zero: "dist/index.js",
@@ -1167,9 +1167,14 @@ var isTextContentType = (contentType) => {
1167
1167
  if (ct === "application/x-www-form-urlencoded") return true;
1168
1168
  return false;
1169
1169
  };
1170
- var detectPaymentRequirement = (headers, status) => {
1171
- if (status !== 402) return null;
1172
- const x402Header = headers.get("payment-required") ?? headers.get("x-payment-required");
1170
+ var looksLikeX402V1Body = (body) => {
1171
+ if (!body || typeof body !== "object") return false;
1172
+ const b = body;
1173
+ return b.x402Version === 1 && Array.isArray(b.accepts) && b.accepts.length > 0;
1174
+ };
1175
+ var detectPaymentRequirement = async (response) => {
1176
+ if (response.status !== 402) return null;
1177
+ const x402Header = response.headers.get("payment-required") ?? response.headers.get("x-payment-required");
1173
1178
  if (x402Header) {
1174
1179
  try {
1175
1180
  const decoded = JSON.parse(
@@ -1180,10 +1185,20 @@ var detectPaymentRequirement = (headers, status) => {
1180
1185
  return { protocol: "x402", raw: { encoded: x402Header } };
1181
1186
  }
1182
1187
  }
1183
- const wwwAuth = headers.get("www-authenticate");
1188
+ const wwwAuth = response.headers.get("www-authenticate");
1184
1189
  if (wwwAuth?.toLowerCase().includes("payment")) {
1185
1190
  return { protocol: "mpp", raw: { "www-authenticate": wwwAuth } };
1186
1191
  }
1192
+ try {
1193
+ const text = await response.clone().text();
1194
+ if (text) {
1195
+ const parsed = JSON.parse(text);
1196
+ if (looksLikeX402V1Body(parsed)) {
1197
+ return { protocol: "x402", raw: parsed };
1198
+ }
1199
+ }
1200
+ } catch {
1201
+ }
1187
1202
  return { protocol: "unknown", raw: {} };
1188
1203
  };
1189
1204
  var fetchCommand = (appContext) => new Command3("fetch").description("Fetch a capability URL with automatic payment handling").argument("<url>", "URL to fetch").option(
@@ -1258,10 +1273,7 @@ var fetchCommand = (appContext) => new Command3("fetch").description("Fetch a ca
1258
1273
  try {
1259
1274
  log(`Calling ${url}...`);
1260
1275
  const response = await fetch(url, requestInit);
1261
- const paymentReq = detectPaymentRequirement(
1262
- response.headers,
1263
- response.status
1264
- );
1276
+ const paymentReq = await detectPaymentRequirement(response);
1265
1277
  if (paymentReq) {
1266
1278
  log(
1267
1279
  `Payment required (${paymentReq.protocol}) \u2014 preparing payment...`
@@ -1809,7 +1821,7 @@ var installSkills = (home) => {
1809
1821
  }
1810
1822
  return installed;
1811
1823
  };
1812
- var initCommand = (appContext) => new Command5("init").description("Initialize Zero CLI for usage").option("--force", "Overwrite existing configuration").action(async (options) => {
1824
+ var runInit = async (appContext, options = {}) => {
1813
1825
  appContext.services.analyticsService.capture("init_started", {
1814
1826
  force: options.force ?? false
1815
1827
  });
@@ -1920,16 +1932,18 @@ To remove them, run: zero init cleanup`
1920
1932
  conflicting_skills_found: conflictingSkills.length,
1921
1933
  force: options.force ?? false
1922
1934
  });
1935
+ return { walletAddress, walletCreated };
1923
1936
  } catch (err) {
1924
1937
  appContext.services.analyticsService.capture("init_failed", {
1925
1938
  step: currentStep,
1926
- error: truncateError(
1927
- err instanceof Error ? err.message : String(err)
1928
- ),
1939
+ error: truncateError(err instanceof Error ? err.message : String(err)),
1929
1940
  force: options.force ?? false
1930
1941
  });
1931
1942
  throw err;
1932
1943
  }
1944
+ };
1945
+ var initCommand = (appContext) => new Command5("init").description("Initialize Zero CLI for usage").option("--force", "Overwrite existing configuration").action(async (options) => {
1946
+ await runInit(appContext, options);
1933
1947
  }).addCommand(
1934
1948
  new Command5("cleanup").description(
1935
1949
  "Remove deprecated skills (zam, tempo) that conflict with Zero"
@@ -2455,10 +2469,71 @@ var walletCommand = (appContext) => {
2455
2469
  return cmd;
2456
2470
  };
2457
2471
 
2472
+ // src/commands/welcome-command.ts
2473
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
2474
+ import { homedir as homedir4 } from "os";
2475
+ import { join as join4 } from "path";
2476
+ import { Command as Command11 } from "commander";
2477
+ import open2 from "open";
2478
+ import { getAddress } from "viem";
2479
+ import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
2480
+ var readPrivateKey = () => {
2481
+ const configPath = join4(homedir4(), ".zero", "config.json");
2482
+ if (!existsSync4(configPath)) return null;
2483
+ try {
2484
+ const config = JSON.parse(readFileSync6(configPath, "utf8"));
2485
+ if (typeof config.privateKey === "string") {
2486
+ return config.privateKey;
2487
+ }
2488
+ } catch {
2489
+ return null;
2490
+ }
2491
+ return null;
2492
+ };
2493
+ var welcomeCommand = (appContext) => new Command11("welcome").description("Claim your $5 welcome bonus.").action(async () => {
2494
+ const { analyticsService } = appContext.services;
2495
+ analyticsService.capture("welcome_started", {});
2496
+ try {
2497
+ let privateKey = readPrivateKey();
2498
+ if (!privateKey) {
2499
+ await runInit(appContext);
2500
+ privateKey = readPrivateKey();
2501
+ if (!privateKey) {
2502
+ throw new Error("Wallet initialization failed");
2503
+ }
2504
+ }
2505
+ const account = privateKeyToAccount3(privateKey);
2506
+ const walletAddress = getAddress(account.address);
2507
+ const walletSignature = await account.signMessage({
2508
+ message: walletAddress
2509
+ });
2510
+ const url = new URL("/welcome", appContext.env.ZERO_WEB_URL);
2511
+ url.searchParams.set("wallet", walletAddress);
2512
+ url.searchParams.set("walletSignature", walletSignature);
2513
+ console.log(
2514
+ `Opening ${url.toString()}
2515
+
2516
+ If your browser didn't open, paste the URL above.`
2517
+ );
2518
+ await open2(url.toString());
2519
+ analyticsService.capture("welcome_link_opened", {
2520
+ // biome-ignore lint/style/useNamingConvention: snake_case for analytics
2521
+ wallet_address: walletAddress
2522
+ });
2523
+ } catch (err) {
2524
+ analyticsService.capture("welcome_failed", {
2525
+ error: truncateError(
2526
+ err instanceof Error ? err.message : String(err)
2527
+ )
2528
+ });
2529
+ throw err;
2530
+ }
2531
+ });
2532
+
2458
2533
  // src/app.ts
2459
2534
  var createApp = (appContext) => {
2460
2535
  const { analyticsService } = appContext.services;
2461
- const program = new Command11().name("zero").description("Zero CLI \u2014 Search engine and payment platform for AI agents").version(package_default.version, "-v, --version").exitOverride().hook("preAction", async (_thisCommand, actionCommand) => {
2536
+ const program = new Command12().name("zero").description("Zero CLI \u2014 Search engine and payment platform for AI agents").version(package_default.version, "-v, --version").exitOverride().hook("preAction", async (_thisCommand, actionCommand) => {
2462
2537
  const agentFlag = actionCommand.opts().agent;
2463
2538
  if (typeof agentFlag === "string" && agentFlag.trim().length > 0) {
2464
2539
  analyticsService.setAgentHost(agentFlag.trim());
@@ -2481,6 +2556,7 @@ var createApp = (appContext) => {
2481
2556
  program.addCommand(walletCommand(appContext));
2482
2557
  program.addCommand(configCommand(appContext));
2483
2558
  program.addCommand(termsCommand(appContext));
2559
+ program.addCommand(welcomeCommand(appContext));
2484
2560
  return program;
2485
2561
  };
2486
2562
 
@@ -2488,6 +2564,7 @@ var createApp = (appContext) => {
2488
2564
  import z4 from "zod";
2489
2565
  var envSchema = z4.object({
2490
2566
  ZERO_API_URL: z4.string().default("https://api.zero.xyz"),
2567
+ ZERO_WEB_URL: z4.string().default("https://zero.xyz"),
2491
2568
  ZERO_PRIVATE_KEY: z4.string().optional(),
2492
2569
  ZERO_ENV: z4.enum(["development", "production"]).default("production")
2493
2570
  });
@@ -2503,14 +2580,14 @@ var getEnv = () => {
2503
2580
 
2504
2581
  // src/app/app-services.ts
2505
2582
  import { randomUUID as randomUUID2 } from "crypto";
2506
- import { existsSync as existsSync6, readFileSync as readFileSync8 } from "fs";
2507
- import { homedir as homedir4 } from "os";
2508
- import { join as join5 } from "path";
2509
- import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
2583
+ import { existsSync as existsSync7, readFileSync as readFileSync9 } from "fs";
2584
+ import { homedir as homedir5 } from "os";
2585
+ import { join as join6 } from "path";
2586
+ import { privateKeyToAccount as privateKeyToAccount4 } from "viem/accounts";
2510
2587
 
2511
2588
  // src/services/analytics-service.ts
2512
2589
  import { randomUUID } from "crypto";
2513
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
2590
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
2514
2591
  import { dirname as dirname2 } from "path";
2515
2592
  import { PostHog } from "posthog-node";
2516
2593
  var POSTHOG_API_KEY = "phc_B2vLyNxAf2mnqvdPQajf4d4b2iXc35dep2ZrvebMJLuX";
@@ -2532,8 +2609,8 @@ var AnalyticsService = class {
2532
2609
  let telemetryEnabled = true;
2533
2610
  let persistedAnonId;
2534
2611
  try {
2535
- if (existsSync4(opts.configPath)) {
2536
- const config = JSON.parse(readFileSync6(opts.configPath, "utf8"));
2612
+ if (existsSync5(opts.configPath)) {
2613
+ const config = JSON.parse(readFileSync7(opts.configPath, "utf8"));
2537
2614
  if (config.telemetry === false) {
2538
2615
  telemetryEnabled = false;
2539
2616
  }
@@ -2558,7 +2635,7 @@ var AnalyticsService = class {
2558
2635
  try {
2559
2636
  const dir = dirname2(opts.configPath);
2560
2637
  mkdirSync4(dir, { recursive: true });
2561
- const existing = existsSync4(opts.configPath) ? JSON.parse(readFileSync6(opts.configPath, "utf8")) : {};
2638
+ const existing = existsSync5(opts.configPath) ? JSON.parse(readFileSync7(opts.configPath, "utf8")) : {};
2562
2639
  writeFileSync4(
2563
2640
  opts.configPath,
2564
2641
  JSON.stringify({ ...existing, anonId: newAnonId }, null, 2)
@@ -2594,7 +2671,7 @@ var AnalyticsService = class {
2594
2671
  if (anonId === walletAddress) return;
2595
2672
  let aliasedTo;
2596
2673
  try {
2597
- const config = JSON.parse(readFileSync6(configPath, "utf8"));
2674
+ const config = JSON.parse(readFileSync7(configPath, "utf8"));
2598
2675
  if (typeof config.aliasedTo === "string") {
2599
2676
  aliasedTo = config.aliasedTo;
2600
2677
  }
@@ -2603,7 +2680,7 @@ var AnalyticsService = class {
2603
2680
  if (aliasedTo === walletAddress) return;
2604
2681
  this.posthog.alias({ distinctId: walletAddress, alias: anonId });
2605
2682
  try {
2606
- const config = existsSync4(configPath) ? JSON.parse(readFileSync6(configPath, "utf8")) : {};
2683
+ const config = existsSync5(configPath) ? JSON.parse(readFileSync7(configPath, "utf8")) : {};
2607
2684
  writeFileSync4(
2608
2685
  configPath,
2609
2686
  JSON.stringify({ ...config, aliasedTo: walletAddress }, null, 2)
@@ -2646,12 +2723,12 @@ var AnalyticsService = class {
2646
2723
  };
2647
2724
 
2648
2725
  // src/services/state-service.ts
2649
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
2650
- import { join as join4 } from "path";
2726
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
2727
+ import { join as join5 } from "path";
2651
2728
  var StateService = class {
2652
2729
  constructor(zeroDir) {
2653
2730
  this.zeroDir = zeroDir;
2654
- this.lastSearchPath = join4(zeroDir, "last_search.json");
2731
+ this.lastSearchPath = join5(zeroDir, "last_search.json");
2655
2732
  }
2656
2733
  lastSearchPath;
2657
2734
  saveLastSearch = (data) => {
@@ -2660,8 +2737,8 @@ var StateService = class {
2660
2737
  };
2661
2738
  loadLastSearch = () => {
2662
2739
  try {
2663
- if (!existsSync5(this.lastSearchPath)) return null;
2664
- const raw = readFileSync7(this.lastSearchPath, "utf8");
2740
+ if (!existsSync6(this.lastSearchPath)) return null;
2741
+ const raw = readFileSync8(this.lastSearchPath, "utf8");
2665
2742
  return JSON.parse(raw);
2666
2743
  } catch {
2667
2744
  return null;
@@ -2709,12 +2786,12 @@ var detectAgentHost = (env = process.env) => {
2709
2786
  var CLI_VERSION = package_default.version;
2710
2787
  var getServices = (env) => {
2711
2788
  let privateKey = env.ZERO_PRIVATE_KEY ? env.ZERO_PRIVATE_KEY : null;
2712
- const zeroDir = join5(homedir4(), ".zero");
2713
- const configPath = join5(zeroDir, "config.json");
2789
+ const zeroDir = join6(homedir5(), ".zero");
2790
+ const configPath = join6(zeroDir, "config.json");
2714
2791
  if (!privateKey) {
2715
2792
  try {
2716
- if (existsSync6(configPath)) {
2717
- const config = JSON.parse(readFileSync8(configPath, "utf8"));
2793
+ if (existsSync7(configPath)) {
2794
+ const config = JSON.parse(readFileSync9(configPath, "utf8"));
2718
2795
  if (typeof config.privateKey === "string") {
2719
2796
  privateKey = config.privateKey;
2720
2797
  }
@@ -2722,11 +2799,11 @@ var getServices = (env) => {
2722
2799
  } catch {
2723
2800
  }
2724
2801
  }
2725
- const account = privateKey ? privateKeyToAccount3(privateKey) : null;
2802
+ const account = privateKey ? privateKeyToAccount4(privateKey) : null;
2726
2803
  let lowBalanceWarning = 1;
2727
2804
  try {
2728
- if (existsSync6(configPath)) {
2729
- const config = JSON.parse(readFileSync8(configPath, "utf8"));
2805
+ if (existsSync7(configPath)) {
2806
+ const config = JSON.parse(readFileSync9(configPath, "utf8"));
2730
2807
  if (typeof config.lowBalanceWarning === "number") {
2731
2808
  lowBalanceWarning = config.lowBalanceWarning;
2732
2809
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxyz/cli",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "zero": "dist/index.js",