@zeroxyz/cli 1.12.1 → 1.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.
Files changed (2) hide show
  1. package/dist/index.js +207 -107
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -78576,7 +78576,7 @@ init_esm_shims();
78576
78576
 
78577
78577
  // package.json
78578
78578
  var package_default = {
78579
- version: "1.12.1"};
78579
+ version: "1.14.0"};
78580
78580
 
78581
78581
  // src/app.ts
78582
78582
  init_esm_shims();
@@ -79584,7 +79584,7 @@ init_esm_shims();
79584
79584
  // ../sdk/dist/index.js
79585
79585
  init_esm_shims();
79586
79586
 
79587
- // ../sdk/dist/chunk-NUBD543C.js
79587
+ // ../sdk/dist/chunk-AAAVBKT3.js
79588
79588
  init_esm_shims();
79589
79589
 
79590
79590
  // ../../node_modules/.pnpm/viem@2.52.2_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_zod@4.3.6/node_modules/viem/_esm/index.js
@@ -144966,7 +144966,7 @@ config(en_default2());
144966
144966
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/index.js
144967
144967
  var zod_default = external_exports3;
144968
144968
 
144969
- // ../sdk/dist/chunk-NUBD543C.js
144969
+ // ../sdk/dist/chunk-AAAVBKT3.js
144970
144970
  var createManagedAccount = (client, address2) => toAccount({
144971
144971
  address: address2,
144972
144972
  async signMessage({ message: message2 }) {
@@ -146778,7 +146778,7 @@ var clientFetch = async (client, url4, opts = {}) => {
146778
146778
  return result;
146779
146779
  };
146780
146780
  var package_default2 = {
146781
- version: "0.8.0"
146781
+ version: "0.9.0"
146782
146782
  };
146783
146783
  var SDK_VERSION2 = package_default2.version;
146784
146784
  var userWalletDtoSchema = external_exports3.object({
@@ -147371,6 +147371,15 @@ var ratingSchema = external_exports3.object({
147371
147371
  stars: external_exports3.string().nullable().optional(),
147372
147372
  state: external_exports3.enum(["unrated", "rated"]).optional()
147373
147373
  });
147374
+ var pricingOptionSchema = external_exports3.object({
147375
+ kind: external_exports3.string(),
147376
+ protocol: external_exports3.string(),
147377
+ network: external_exports3.string().nullable(),
147378
+ amountUsd: external_exports3.string().nullable(),
147379
+ per: external_exports3.string(),
147380
+ confidence: external_exports3.string(),
147381
+ depositUsd: external_exports3.string().optional()
147382
+ });
147374
147383
  var capabilityResponseSchema = external_exports3.object({
147375
147384
  uid: external_exports3.string(),
147376
147385
  slug: external_exports3.string(),
@@ -147395,6 +147404,23 @@ var capabilityResponseSchema = external_exports3.object({
147395
147404
  instructions: external_exports3.string().nullable().optional(),
147396
147405
  displayCostAmount: external_exports3.string(),
147397
147406
  displayCostAsset: external_exports3.string(),
147407
+ // Whether the upstream advertises variable/usage-based pricing, and the raw
147408
+ // hint string (e.g. "$0.01/result"). The server emits both; without them an
147409
+ // agent sees a single scalar with no signal that the price scales with input
147410
+ // (ZERO-199). Optional so an older API deploy still parses.
147411
+ priceDynamic: external_exports3.boolean().optional(),
147412
+ priceHint: external_exports3.string().nullable().optional(),
147413
+ // ZERO-199: the authoritative price classification. Only `proven_free` may be
147414
+ // rendered "Free"; `unknown_unparsed` is a parse miss (never free); a parse
147415
+ // miss must not become "0"→Free. Optional so older deploys still parse.
147416
+ priceStatus: external_exports3.enum([
147417
+ "priced",
147418
+ "proven_free",
147419
+ "free_handshake",
147420
+ "unknown_unparsed",
147421
+ "unprobed"
147422
+ ]).optional(),
147423
+ requiresHandshake: external_exports3.boolean().optional(),
147398
147424
  reviewCount: external_exports3.number(),
147399
147425
  rating: ratingSchema,
147400
147426
  priceObserved: external_exports3.object({
@@ -147417,9 +147443,27 @@ var capabilityResponseSchema = external_exports3.object({
147417
147443
  mode: external_exports3.string(),
147418
147444
  costAmount: external_exports3.string(),
147419
147445
  costPer: external_exports3.string(),
147420
- priority: external_exports3.number()
147446
+ priority: external_exports3.number(),
147447
+ // ZERO-199 rail-union fields (optional; older deploys omit them).
147448
+ asset: external_exports3.string().nullable().optional(),
147449
+ unit: external_exports3.string().optional(),
147450
+ depositMicros: external_exports3.number().nullable().optional(),
147451
+ planRef: external_exports3.string().nullable().optional()
147421
147452
  })
147422
147453
  ).nullable(),
147454
+ // Recommended channel deposit for a `mode='session'` cap (the seller's
147455
+ // advertised `suggestedDeposit`). Without it an agent can't size an MPP
147456
+ // session channel. The server emits it; optional for older-deploy parsing
147457
+ // (ZERO-199).
147458
+ sessionDeposit: external_exports3.object({ amountUsd: external_exports3.string(), asset: external_exports3.string() }).nullable().optional(),
147459
+ // ZERO-199 P-B — the single resolved price. Prefer `pricing.summary`/`kind`
147460
+ // over re-deriving from the legacy fields. Optional so older deploys parse.
147461
+ pricing: external_exports3.object({
147462
+ kind: external_exports3.string(),
147463
+ summary: external_exports3.string(),
147464
+ primary: pricingOptionSchema.nullable(),
147465
+ accepted: external_exports3.array(pricingOptionSchema)
147466
+ }).optional(),
147423
147467
  availabilityStatus: external_exports3.enum(["healthy", "unknown", "down"]).nullable().optional(),
147424
147468
  /**
147425
147469
  * @deprecated The API no longer emits `displayStatus`; it has been replaced
@@ -147840,6 +147884,15 @@ var searchResultSchema = external_exports3.object({
147840
147884
  url: external_exports3.string(),
147841
147885
  urlTemplate: external_exports3.string().nullable().optional(),
147842
147886
  cost: external_exports3.object({ amount: external_exports3.string(), asset: external_exports3.string() }),
147887
+ // ZERO-199 — the server-resolved price. Prefer `pricing.summary` over
147888
+ // deriving a label from `cost.amount` (which flattens usage-priced caps).
147889
+ // Optional: absent on older API deploys.
147890
+ pricing: external_exports3.object({ kind: external_exports3.string(), summary: external_exports3.string() }).optional(),
147891
+ // Payment protocol (x402 | mpp) for this result. The server emits it; the SDK
147892
+ // previously stripped it, leaving an agent unable to tell which handshake to
147893
+ // engage from a search row. Optional/nullable so older deploys still parse
147894
+ // (ZERO-199).
147895
+ protocol: external_exports3.string().nullable().optional(),
147843
147896
  reviewCount: external_exports3.number().optional(),
147844
147897
  rating: ratingSchema,
147845
147898
  // All-time activation count (non-deleted runs), mirroring capabilities.ts.
@@ -149162,24 +149215,73 @@ var formatRelativeTimestamp = (iso) => {
149162
149215
  var formatCost = (capability) => {
149163
149216
  const lines = [];
149164
149217
  const observed = capability.priceObserved;
149165
- if (observed && observed.sampleCount > 0 && observed.varies && observed.minCents && observed.maxCents) {
149218
+ if (capability.pricing?.summary) {
149219
+ lines.push(` Cost: ${capability.pricing.summary}`);
149220
+ if (capability.sessionDeposit) {
149221
+ lines.push(
149222
+ ` Session deposit: $${capability.sessionDeposit.amountUsd} ${capability.sessionDeposit.asset} to open a channel`
149223
+ );
149224
+ }
149225
+ appendFailureChargeWarning(lines, observed);
149226
+ return lines;
149227
+ }
149228
+ if (capability.priceStatus === "free_handshake" || capability.requiresHandshake) {
149229
+ lines.push(` Cost: free \xB7 handshake required`);
149230
+ } else if (observed && observed.sampleCount > 0 && observed.varies && observed.minCents && observed.maxCents) {
149166
149231
  const min = centsToDollars(observed.minCents);
149167
149232
  const max = centsToDollars(observed.maxCents);
149168
149233
  const median = observed.medianCents ? centsToDollars(observed.medianCents) : null;
149169
149234
  const detail = median ? `median $${median}, n=${observed.sampleCount}` : `n=${observed.sampleCount}`;
149170
149235
  lines.push(` Cost: $${min}\u2013$${max}/call (${detail})`);
149236
+ } else if (capability.priceDynamic && capability.priceHint && /\$\d/.test(capability.priceHint)) {
149237
+ const ceiling = observed?.maxCents ? centsToDollars(observed.maxCents) : null;
149238
+ lines.push(
149239
+ ` Cost: ${capability.priceHint} (dynamic${ceiling ? `, up to ~$${ceiling}/call` : ""})`
149240
+ );
149241
+ } else if (capability.priceStatus === "unknown_unparsed" && !(Number(capability.displayCostAmount) > 0) && !paidRailAmount(capability)) {
149242
+ lines.push(` Cost: price unknown`);
149243
+ } else if (capability.priceDynamic) {
149244
+ lines.push(
149245
+ ` Cost: $${capability.displayCostAmount}/call (dynamic \u2014 varies by input)`
149246
+ );
149171
149247
  } else if (capability.displayCostAmount === "0") {
149172
- lines.push(` Cost: Free`);
149248
+ const paid = paidRailAmount(capability);
149249
+ if (paid) lines.push(` Cost: $${paid}/call`);
149250
+ else if (observedMedianUsd(observed))
149251
+ lines.push(` Cost: ~$${observedMedianUsd(observed)}/call (observed)`);
149252
+ else lines.push(` Cost: Free`);
149173
149253
  } else if (capability.displayCostAmount === "unknown") {
149174
- lines.push(` Cost: variable pricing`);
149254
+ const paid = paidRailAmount(capability);
149255
+ if (paid) lines.push(` Cost: $${paid}/call`);
149256
+ else if (observedMedianUsd(observed))
149257
+ lines.push(` Cost: ~$${observedMedianUsd(observed)}/call (observed)`);
149258
+ else lines.push(` Cost: price unknown`);
149175
149259
  } else {
149176
149260
  lines.push(` Cost: $${capability.displayCostAmount}/call`);
149177
149261
  }
149262
+ if (capability.sessionDeposit) {
149263
+ lines.push(
149264
+ ` Session deposit: $${capability.sessionDeposit.amountUsd} ${capability.sessionDeposit.asset} to open a channel`
149265
+ );
149266
+ }
149267
+ appendFailureChargeWarning(lines, observed);
149268
+ return lines;
149269
+ };
149270
+ var appendFailureChargeWarning = (lines, observed) => {
149178
149271
  if (observed?.failureChargeRate != null && observed.failureChargeRate > 0) {
149179
149272
  const pct = Math.round(observed.failureChargeRate * 100);
149180
149273
  lines.push(` \u26A0 ~${pct}% of failed runs still charged the wallet`);
149181
149274
  }
149182
- return lines;
149275
+ };
149276
+ var paidRailAmount = (capability) => {
149277
+ const rail = capability.paymentMethods?.find(
149278
+ (pm) => pm.costAmount != null && !["0", "0.00", "unknown", ""].includes(pm.costAmount)
149279
+ );
149280
+ return rail?.costAmount ?? null;
149281
+ };
149282
+ var observedMedianUsd = (observed) => {
149283
+ if (!observed?.medianCents) return null;
149284
+ return Number(observed.medianCents) > 0 ? centsToDollars(observed.medianCents) : null;
149183
149285
  };
149184
149286
  var formatReviewCount = (count) => {
149185
149287
  if (count >= 1e3) return `${(count / 1e3).toFixed(1)}k`;
@@ -149554,16 +149656,20 @@ var agentStandaloneMcpSchema = zod_default.looseObject({
149554
149656
  var agentStandaloneHooksSchema = zod_default.looseObject({
149555
149657
  // Config file to merge the hook declarations into (relative to $HOME).
149556
149658
  file: zod_default.string(),
149557
- // Names the config schema. The CLI's generic JSON merger handles the shared
149558
- // `{ hooks: { Event: [...] } }` shape (claude-settings, codex-hooks); other
149559
- // formats (e.g. kiro-agent) need their own writer and are skipped until one
149560
- // exists.
149561
- format: zod_default.string(),
149659
+ // Informational name of the config schema. Registration is driven by `merge`
149660
+ // alone; `format` stays in the matrix because pre-1.14 CLIs require it.
149661
+ format: zod_default.string().optional(),
149562
149662
  sessionStart: zod_default.boolean().optional(),
149563
149663
  // Domains to ensure on this host's sandbox network allowlist
149564
149664
  // (sandbox.network.allowedDomains) after merging — e.g. ["*.zero.xyz"] for
149565
149665
  // Claude. Omitted hosts get no allowlist entry.
149566
- network: zod_default.array(zod_default.string()).optional()
149666
+ network: zod_default.array(zod_default.string()).optional(),
149667
+ // The literal hook config fragment to deep-merge into `file`, with
149668
+ // ${ZERO_HOOKS_DIR} standing in for the staged ~/.zero/hooks dir. The CLI
149669
+ // derives which hook scripts to fetch+stage by scanning this fragment for
149670
+ // ${ZERO_HOOKS_DIR}/<name> references. Hosts without a fragment get no hook
149671
+ // registration.
149672
+ merge: zod_default.record(zod_default.string(), zod_default.unknown()).optional()
149567
149673
  });
149568
149674
  var agentStandaloneSchema = zod_default.looseObject({
149569
149675
  // Skill install dirs (relative to $HOME) for the standalone fallback.
@@ -149648,6 +149754,57 @@ var loadAgents = async (webBase, cliVersion) => {
149648
149754
  return { entries: filterMatrix(matrix, cliVersion) };
149649
149755
  };
149650
149756
 
149757
+ // src/util/hook-fragment.ts
149758
+ init_esm_shims();
149759
+ var ZERO_HOOKS_DIR_PLACEHOLDER = "${ZERO_HOOKS_DIR}";
149760
+ var SCRIPT_REF_PATTERN = /\$\{ZERO_HOOKS_DIR\}\/([a-z0-9][a-z0-9-]*\.sh)/g;
149761
+ var isPlainObject3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
149762
+ var fragmentScriptNames = (fragment) => {
149763
+ const names = /* @__PURE__ */ new Set();
149764
+ for (const match of JSON.stringify(fragment).matchAll(SCRIPT_REF_PATTERN)) {
149765
+ if (match[1]) names.add(match[1]);
149766
+ }
149767
+ return [...names];
149768
+ };
149769
+ var substituteHooksDir = (value, hooksDir) => {
149770
+ if (typeof value === "string") {
149771
+ return value.replaceAll(ZERO_HOOKS_DIR_PLACEHOLDER, hooksDir);
149772
+ }
149773
+ if (Array.isArray(value)) {
149774
+ return value.map((item) => substituteHooksDir(item, hooksDir));
149775
+ }
149776
+ if (isPlainObject3(value)) {
149777
+ return Object.fromEntries(
149778
+ Object.entries(value).map(([key, item]) => [
149779
+ key,
149780
+ substituteHooksDir(item, hooksDir)
149781
+ ])
149782
+ );
149783
+ }
149784
+ return value;
149785
+ };
149786
+ var referencesAnyScript = (element, scriptNames) => {
149787
+ const json3 = JSON.stringify(element) ?? "";
149788
+ return scriptNames.some((name) => json3.includes(name));
149789
+ };
149790
+ var mergeHookFragment = (target, fragment, scriptNames) => {
149791
+ for (const [key, incoming] of Object.entries(fragment)) {
149792
+ const existing = target[key];
149793
+ if (Array.isArray(incoming)) {
149794
+ const kept = Array.isArray(existing) ? existing.filter(
149795
+ (element) => !referencesAnyScript(element, scriptNames)
149796
+ ) : [];
149797
+ target[key] = [...kept, ...incoming];
149798
+ } else if (isPlainObject3(incoming)) {
149799
+ const base2 = isPlainObject3(existing) ? existing : {};
149800
+ target[key] = base2;
149801
+ mergeHookFragment(base2, incoming, scriptNames);
149802
+ } else {
149803
+ target[key] = incoming;
149804
+ }
149805
+ }
149806
+ };
149807
+
149651
149808
  // src/util/install-banner.ts
149652
149809
  init_esm_shims();
149653
149810
  var colorsEnabled = () => {
@@ -149815,8 +149972,6 @@ var fallbackReason = (selection, detections, results) => {
149815
149972
  }
149816
149973
  return "no plugin install succeeded";
149817
149974
  };
149818
- var PLUGIN_HOOKS_ROOT = "${CLAUDE_PLUGIN_ROOT}/hooks";
149819
- var SCRIPT_NAME_PATTERN = /\$\{CLAUDE_PLUGIN_ROOT\}\/hooks\/([a-z0-9][a-z0-9-]*\.sh)/;
149820
149975
  var fetchText = async (url4) => {
149821
149976
  const res = await fetch(url4);
149822
149977
  if (!res.ok) {
@@ -149824,15 +149979,6 @@ var fetchText = async (url4) => {
149824
149979
  }
149825
149980
  return await res.text();
149826
149981
  };
149827
- var entryScriptNames = (entry) => {
149828
- const names = [];
149829
- for (const hook of entry.hooks ?? []) {
149830
- if (typeof hook.command !== "string") continue;
149831
- const match = hook.command.match(SCRIPT_NAME_PATTERN);
149832
- if (match?.[1]) names.push(match[1]);
149833
- }
149834
- return names;
149835
- };
149836
149982
  var expandHome = (path3, home) => {
149837
149983
  if (path3 === "~") return home;
149838
149984
  if (path3.startsWith("~/")) return join(home, path3.slice(2));
@@ -149856,20 +150002,11 @@ var installSkill = (skillsDirs, skillMd, verbose) => {
149856
150002
  }
149857
150003
  return installed;
149858
150004
  };
149859
- var installHookScripts = async (home, hooksJson, webBase, verbose) => {
149860
- const names = /* @__PURE__ */ new Set();
149861
- for (const entries of Object.values(hooksJson.hooks)) {
149862
- for (const entry of entries ?? []) {
149863
- for (const name of entryScriptNames(entry)) names.add(name);
149864
- }
149865
- }
149866
- if (names.size === 0) {
149867
- throw new Error("hooks.json declared no recognizable hook scripts");
149868
- }
150005
+ var installHookScripts = async (home, names, webBase, verbose) => {
149869
150006
  const hooksDir = join(home, ".zero", "hooks");
149870
150007
  mkdirSync(hooksDir, { recursive: true });
149871
150008
  return await Promise.all(
149872
- [...names].map(async (name) => {
150009
+ names.map(async (name) => {
149873
150010
  const body = await fetchText(`${webBase}/hooks/${name}`);
149874
150011
  const dest = join(hooksDir, name);
149875
150012
  writeFileSync(dest, body);
@@ -149900,53 +150037,17 @@ var ensureSandboxDomains = (settings, domains, verbose) => {
149900
150037
  }
149901
150038
  }
149902
150039
  };
149903
- var registerHooksInJsonFile = (home, hooksJson, target, verbose) => {
150040
+ var registerHooksInJsonFile = (home, target, verbose) => {
149904
150041
  const hooksDir = join(home, ".zero", "hooks");
149905
150042
  const configPath = join(home, target.relativePath);
150043
+ const scriptNames = fragmentScriptNames(target.fragment);
150044
+ const fragment = substituteHooksDir(target.fragment, hooksDir);
149906
150045
  const result = updateJsonConfigFile(
149907
150046
  configPath,
149908
150047
  (config2) => {
149909
- if (!config2.hooks || typeof config2.hooks !== "object") {
149910
- config2.hooks = {};
149911
- }
149912
- const hooks = config2.hooks;
149913
- for (const [event, entries] of Object.entries(hooksJson.hooks)) {
149914
- for (const entry of entries ?? []) {
149915
- const scripts = entryScriptNames(entry);
149916
- if (scripts.length === 0) {
149917
- if (verbose) {
149918
- stepInfo(`${event}: entry has no plugin hook script \u2014 skipped`);
149919
- }
149920
- continue;
149921
- }
149922
- const rewritten = {
149923
- ...entry,
149924
- hooks: (entry.hooks ?? []).map((hook) => ({
149925
- ...hook,
149926
- command: typeof hook.command === "string" ? hook.command.replaceAll(PLUGIN_HOOKS_ROOT, hooksDir) : hook.command
149927
- }))
149928
- };
149929
- if (!Array.isArray(hooks[event])) hooks[event] = [];
149930
- const list2 = hooks[event];
149931
- const existingIdx = list2.findIndex((existing) => {
149932
- const existingHooks = existing?.hooks;
149933
- if (!Array.isArray(existingHooks)) return false;
149934
- return existingHooks.some(
149935
- (h2) => typeof h2.command === "string" && scripts.some((s) => h2.command.includes(s))
149936
- );
149937
- });
149938
- if (existingIdx >= 0) {
149939
- list2[existingIdx] = rewritten;
149940
- if (verbose) {
149941
- stepInfo(`${event}: ${scripts.join(", ")} entry replaced`);
149942
- }
149943
- } else {
149944
- list2.push(rewritten);
149945
- if (verbose) {
149946
- stepInfo(`${event}: ${scripts.join(", ")} entry appended`);
149947
- }
149948
- }
149949
- }
150048
+ mergeHookFragment(config2, fragment, scriptNames);
150049
+ if (verbose) {
150050
+ stepInfo(`merged hook fragment (${scriptNames.join(", ")})`);
149950
150051
  }
149951
150052
  ensureSandboxDomains(config2, target.network, verbose);
149952
150053
  return true;
@@ -149962,18 +150063,21 @@ var registerHooksInJsonFile = (home, hooksJson, target, verbose) => {
149962
150063
  }
149963
150064
  return true;
149964
150065
  };
149965
- var JSON_HOOK_FORMATS = /* @__PURE__ */ new Set(["claude-settings", "codex-hooks"]);
149966
150066
  var buildHookTargets = (entries) => {
149967
150067
  const byFile = /* @__PURE__ */ new Map();
149968
150068
  for (const entry of entries) {
149969
150069
  const hooks = entry.standalone?.hooks;
149970
- if (!hooks || !JSON_HOOK_FORMATS.has(hooks.format)) continue;
150070
+ if (!hooks?.merge || Object.keys(hooks.merge).length === 0) continue;
149971
150071
  const existing = byFile.get(hooks.file);
149972
150072
  const network = unique([
149973
150073
  ...existing?.network ?? [],
149974
150074
  ...hooks.network ?? []
149975
150075
  ]);
149976
- byFile.set(hooks.file, { relativePath: hooks.file, network });
150076
+ byFile.set(hooks.file, {
150077
+ relativePath: hooks.file,
150078
+ fragment: existing?.fragment ?? hooks.merge,
150079
+ network
150080
+ });
149977
150081
  }
149978
150082
  return [...byFile.values()];
149979
150083
  };
@@ -149987,21 +150091,18 @@ var runStandaloneInit = async (appContext, options = {}) => {
149987
150091
  console.log("");
149988
150092
  const home = homedir();
149989
150093
  const webBase = appContext.env.ZERO_WEB_URL;
149990
- const [skillMd, hooksJsonRaw] = await Promise.all([
149991
- fetchText(`${webBase}/SKILL.md`),
149992
- fetchText(`${webBase}/hooks.json`)
149993
- ]);
149994
- let hooksJson;
149995
- try {
149996
- hooksJson = JSON.parse(hooksJsonRaw);
149997
- } catch {
149998
- throw new Error(`${webBase}/hooks.json is not valid JSON`);
149999
- }
150000
- if (!hooksJson?.hooks || typeof hooksJson.hooks !== "object") {
150001
- throw new Error(`${webBase}/hooks.json has no "hooks" object`);
150094
+ const hookTargets = options.hookTargets ?? [];
150095
+ const hookScriptNames = unique(
150096
+ hookTargets.flatMap((target) => fragmentScriptNames(target.fragment))
150097
+ );
150098
+ if (hookScriptNames.length === 0) {
150099
+ throw new Error(
150100
+ "the agent matrix declared no standalone hook scripts to install"
150101
+ );
150002
150102
  }
150103
+ const skillMd = await fetchText(`${webBase}/SKILL.md`);
150003
150104
  if (verbose) {
150004
- stepInfo(`fetched ${webBase}/SKILL.md and ${webBase}/hooks.json`);
150105
+ stepInfo(`fetched ${webBase}/SKILL.md`);
150005
150106
  }
150006
150107
  options.onStep?.("skill");
150007
150108
  const skillsDirs = unique([
@@ -150016,20 +150117,15 @@ var runStandaloneInit = async (appContext, options = {}) => {
150016
150117
  options.onStep?.("hooks");
150017
150118
  const hookScriptsInstalled = await installHookScripts(
150018
150119
  home,
150019
- hooksJson,
150120
+ hookScriptNames,
150020
150121
  webBase,
150021
150122
  verbose
150022
150123
  );
150023
150124
  stepSuccess("Hook scripts installed", "~/.zero/hooks");
150024
150125
  options.onStep?.("settings");
150025
150126
  const registeredFiles = /* @__PURE__ */ new Set();
150026
- for (const target of options.hookTargets ?? []) {
150027
- const registered = registerHooksInJsonFile(
150028
- home,
150029
- hooksJson,
150030
- target,
150031
- verbose
150032
- );
150127
+ for (const target of hookTargets) {
150128
+ const registered = registerHooksInJsonFile(home, target, verbose);
150033
150129
  if (registered) {
150034
150130
  registeredFiles.add(target.relativePath);
150035
150131
  stepSuccess("Hooks registered", `~/${target.relativePath}`);
@@ -150183,8 +150279,11 @@ var runInit = async (appContext, options = {}) => {
150183
150279
  if (dryRun) {
150184
150280
  stepInfo("would install/update ~/.claude/skills/zero");
150185
150281
  stepInfo("would install/update ~/.agents/skills/zero");
150282
+ const targetFiles = buildHookTargets(entries).map(
150283
+ (target) => `~/${target.relativePath}`
150284
+ );
150186
150285
  stepInfo(
150187
- "would register current standalone hooks in ~/.claude/settings.json and ~/.codex/hooks.json"
150286
+ `would register current standalone hooks in ${targetFiles.join(" and ")}`
150188
150287
  );
150189
150288
  } else {
150190
150289
  standaloneResult = await runStandaloneInit(appContext, {
@@ -150763,7 +150862,8 @@ var formatSearchResults = (results) => {
150763
150862
  const displayDescription = r2.whatItDoes ?? r2.description;
150764
150863
  const ratingBadge = formatRatingBadge(r2.rating);
150765
150864
  const statusBadge = formatStatusBadge(r2.availabilityStatus);
150766
- const costLabel = r2.cost.amount === "0" ? "Free" : r2.cost.amount === "unknown" ? "variable pricing" : `$${r2.cost.amount}/call`;
150865
+ const baseCost = r2.pricing?.summary ?? (r2.cost.amount === "0" ? "Free" : r2.cost.amount === "unknown" ? "variable pricing" : `$${r2.cost.amount}/call`);
150866
+ const costLabel = r2.protocol ? `${baseCost} \xB7 ${r2.protocol}` : baseCost;
150767
150867
  const tokenHint = r2.token ? ` [${r2.token}]` : "";
150768
150868
  return ` ${r2.position}.${tokenHint} ${displayName} \u2014 ${costLabel} \u2014 ${ratingBadge}${statusBadge}
150769
150869
  "${displayDescription}"`;
@@ -152549,7 +152649,7 @@ function isErrorEvent(event) {
152549
152649
  function isEvent(candidate) {
152550
152650
  return "undefined" != typeof Event && isInstanceOf(candidate, Event);
152551
152651
  }
152552
- function isPlainObject3(candidate) {
152652
+ function isPlainObject4(candidate) {
152553
152653
  return isBuiltin(candidate, "Object");
152554
152654
  }
152555
152655
  function isInstanceOf(candidate, base2) {
@@ -155746,7 +155846,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
155746
155846
  };
155747
155847
  const personProperties = {};
155748
155848
  const groupProperties = {};
155749
- for (const [key, value] of Object.entries(eventProperties)) if (isPlainObject3(value) && groups && key in groups) {
155849
+ for (const [key, value] of Object.entries(eventProperties)) if (isPlainObject4(value) && groups && key in groups) {
155750
155850
  const groupProps = {};
155751
155851
  for (const [groupKey, groupValue] of Object.entries(value)) groupProps[String(groupKey)] = String(groupValue);
155752
155852
  groupProperties[String(key)] = groupProps;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxyz/cli",
3
- "version": "1.12.1",
3
+ "version": "1.14.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "zero": "dist/index.js",