@zeroxyz/sdk 0.9.0 → 0.11.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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { Z as ZeroClient, P as PaymentSessionMeta } from './client-Du4zQHef.cjs';
2
- export { A as AccountCredentials, g as Auth, h as AuthDevice, $ as BUG_REPORT_CATEGORIES, x as BalanceOptions, y as BalanceReadError, a9 as BatchReviewResponse, a0 as BugReportCategory, B as BugReports, j as Capabilities, a3 as CapabilityResponse, G as ClientOptions, a1 as CreateBugReportInput, a2 as CreateBugReportResponse, aa as CreateReviewInput, ab as CreateReviewResponse, ac as CreateRunInput, ad as CreateRunResponse, C as Credentials, H as DEFAULT_BASE_URL, I as DEFAULT_MAX_RETRIES, J as DEFAULT_TIMEOUT_MS, a6 as DevicePollResult, a7 as DeviceStartResponse, r as FETCH_SKIP_REASONS, s as FETCH_WARNINGS, F as FetchOptions, b as FetchOutcome, c as FetchResult, z as FundingUrlOptions, a4 as GetCapabilityOptions, V as InternalUserDto, ae as ListRunsParams, af as ListRunsResponse, L as LogEvent, Q as LogLevel, K as Logger, M as MigrateAuthorization, D as MigrateAuthorizationResponse, N as NoCredentials, O as OnSessionRefreshed, k as PayInput, o as PayResult, l as PaymentChain, m as PaymentProtocol, n as PaymentResult, t as Payments, X as PublicUserDto, a5 as ResolveCapabilityResponse, ag as RunDetail, ah as RunListItem, R as Runs, ai as SearchOptions, aj as SearchResponse, ak as SearchResult, S as SessionCredentials, a as SessionCredentialsInput, a8 as SessionExchangeResponse, p as SessionReceiptPayload, d as SignMessageInput, e as SignTransactionInput, f as SignTypedDataInput, T as TEMPO_CHAIN_ID, v as TEMPO_TESTNET_CHAIN_ID, U as UpstreamError, Y as UserWalletDto, E as Wallet, W as WalletBalance, _ as WelcomeBonusSummary, q as coerceTempoChainId, i as isShortToken, u as paymentHasAnchor, w as tempoChainLabelFromId } from './client-Du4zQHef.cjs';
1
+ import { Z as ZeroClient, P as PaymentSessionMeta } from './client-DKbrAo9Z.cjs';
2
+ export { A as AccountCredentials, a1 as AgentAuthEndpoints, a2 as AgentClaimAttempt, a3 as AgentRegistration, a4 as AgentSignupResult, a5 as AgentToken, a6 as AgentVerifiedIdentity, a7 as AgentZeroSession, k as Auth, l as AuthAgent, m as AuthDevice, ad as BUG_REPORT_CATEGORIES, B as BalanceChainId, G as BalanceOptions, H as BalanceReadError, an as BatchReviewResponse, ae as BugReportCategory, n as BugReports, o as Capabilities, ah as CapabilityResponse, Q as ClientOptions, a8 as CompleteClaimResult, af as CreateBugReportInput, ag as CreateBugReportResponse, ao as CreateReviewInput, ap as CreateReviewResponse, aq as CreateRunInput, ar as CreateRunResponse, C as Credentials, V as DEFAULT_BASE_URL, X as DEFAULT_MAX_RETRIES, Y as DEFAULT_TIMEOUT_MS, ak as DevicePollResult, al as DeviceStartResponse, w as FETCH_SKIP_REASONS, x as FETCH_WARNINGS, F as FetchOptions, d as FetchOutcome, e as FetchResult, I as FundingUrlOptions, ai as GetCapabilityOptions, J as ImportWalletOptions, a9 as InternalUserDto, as as ListRunsParams, at as ListRunsResponse, _ as LogEvent, a0 as LogLevel, $ as Logger, N as NoCredentials, O as OnSessionRefreshed, p as PayInput, t as PayResult, q as PaymentChain, r as PaymentProtocol, s as PaymentResult, y as Payments, aa as PublicUserDto, K as RemoveWalletOptions, aj as ResolveCapabilityResponse, au as RunDetail, av as RunListItem, R as Runs, aw as SearchOptions, ax as SearchResponse, ay as SearchResult, S as SessionCredentials, a as SessionCredentialsInput, am as SessionExchangeResponse, u as SessionReceiptPayload, L as SetPrimaryWalletOptions, g as SignMessageInput, h as SignTransactionInput, j as SignTypedDataInput, T as TEMPO_CHAIN_ID, D as TEMPO_TESTNET_CHAIN_ID, U as USDC_BASE, b as USDC_DECIMALS, c as USDC_TEMPO, f as UpstreamError, ab as UserWalletDto, M as Wallet, W as WalletBalance, ac as WelcomeBonusSummary, v as coerceTempoChainId, i as isShortToken, z as paymentHasAnchor, E as tempoChainLabelFromId } from './client-DKbrAo9Z.cjs';
3
3
  import { Address, LocalAccount } from 'viem';
4
4
  import { z } from 'zod';
5
5
 
@@ -29,6 +29,17 @@ type AuthErrorCode = Extract<ZeroErrorCode, "auth_error" | "auth_session_expired
29
29
  declare class ZeroAuthError extends ZeroError {
30
30
  constructor(code: AuthErrorCode, message: string, options?: ZeroErrorOptions);
31
31
  }
32
+ type AgentAuthErrorInit = {
33
+ status: number;
34
+ body?: unknown;
35
+ cause?: unknown;
36
+ };
37
+ declare class ZeroAgentAuthError extends ZeroError {
38
+ readonly status: number;
39
+ readonly body: unknown;
40
+ constructor(message: string, init: AgentAuthErrorInit);
41
+ get serverCode(): string | null;
42
+ }
32
43
  declare class ZeroPaymentError extends ZeroError {
33
44
  constructor(message: string, options?: ZeroErrorOptions);
34
45
  }
@@ -198,6 +209,101 @@ declare const preferHealthy: <T extends {
198
209
  availabilityStatus?: AvailabilityStatus | null;
199
210
  }>(items: readonly T[]) => T[];
200
211
 
212
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
213
+ type AgentHost = string;
214
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
215
+ declare const detectAgentHost: (env?: NodeJS.ProcessEnv) => AgentHost;
216
+
217
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
218
+ declare const formatReviewCount: (count: number) => string;
219
+
220
+ /**
221
+ * Convert a cents string (4-decimal precision per the API's `microsToCents`)
222
+ * to a dollar-amount string with enough decimal places that sub-cent
223
+ * token-metered charges don't silently round to zero or get overstated.
224
+ *
225
+ * Precision ladder (matches `services/web/src/app/c/[slug]/page.tsx`):
226
+ * value >= 1 → toFixed(2) — normal dollar amounts ("5.00")
227
+ * value >= 0.01 → toFixed(3) — sub-dollar ("0.500")
228
+ * value >= 0.001 → toFixed(4) — sub-cent ("0.0050")
229
+ * value >= 0.0001 → toFixed(5) — sub-millicent ("0.00050")
230
+ * else → toFixed(6) — micro-dollar floor ("0.000005")
231
+ *
232
+ * Honest signal beats pretty zeros. We accept the ugly trailing decimals
233
+ * because the alternative — `.toFixed(4)` flooring at $0.0001 — silently
234
+ * misreports per-token LLM charges as ~2× their actual cost (or as zero).
235
+ *
236
+ * All price-rendering surfaces (CLI, web, SDK consumers) should use this
237
+ * function so the same capability never shows a different price depending
238
+ * on which surface the agent uses.
239
+ */
240
+ declare const centsToDollars: (cents: string) => string;
241
+ /**
242
+ * Human-readable label for a search-row cost amount, interpreting the
243
+ * server's sentinel values: `"0"` means the cap is free, `"unknown"` means
244
+ * the upstream advertised dynamic/per-token pricing without revealing a
245
+ * concrete number. Any other value is a decimal USD amount per call.
246
+ *
247
+ * The sentinel interpretation is part of the server contract — every
248
+ * consumer (CLI, MCP plugin, QA harness) must map them the same way or an
249
+ * agent sees "$unknown" for a variable-priced cap on one surface and
250
+ * "variable pricing" on another.
251
+ */
252
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
253
+ declare const formatCostLabel: (amount: string) => string;
254
+
255
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
256
+ type RatingBadgeInput = {
257
+ successRate: string;
258
+ reviews: number;
259
+ stars?: string | null;
260
+ state?: "unrated" | "rated";
261
+ };
262
+ /**
263
+ * One-line rating badge: `★ 4.1/5 (91% success, 42 reviews)` when a star
264
+ * score exists, `91% success · 42 reviews` otherwise, `unrated` when the cap
265
+ * has no rating yet. Shared so all consumers render the same rating for the
266
+ * same capability.
267
+ */
268
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
269
+ declare const formatRatingBadge: (rating: RatingBadgeInput) => string;
270
+
271
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
272
+ declare const formatRelativeTimestamp: (iso: string | null | undefined) => string;
273
+
274
+ /**
275
+ * Deterministic structural walk of a JSON value → JSON-schema-ish draft.
276
+ *
277
+ * Used to send anonymized shape information (field names + types, no values)
278
+ * to the server after a capability execution. Mirrors the server-side
279
+ * inference in services/api.
280
+ */
281
+ declare const inferSchema: (value: unknown, depth?: number) => Record<string, unknown>;
282
+ declare const tryParseJson: (text: string) => unknown;
283
+
284
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
285
+ declare const redactUrl: (raw: string) => string;
286
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
287
+ declare const truncateError: (raw: string) => string;
288
+
289
+ declare const schemaTypeLabel: (node: JsonSchemaNode) => string;
290
+ declare const constraintHint: (node: JsonSchemaNode) => string | null;
291
+ declare const paramAttrs: (node: JsonSchemaNode, required: boolean) => string;
292
+
293
+ declare const schemaType: (node: JsonSchemaNode | null) => string | undefined;
294
+ declare const coerceToType: (value: unknown, type: string | undefined) => unknown;
295
+ declare const sampleValueFor: (fieldName: string, propSchema: unknown, depth?: number) => unknown;
296
+ declare const placeholderFor: (fieldName: string, propSchema: unknown) => string;
297
+
298
+ /**
299
+ * Match a fetched URL against a urlTemplate like `/users/{handle}`.
300
+ * `{name}` placeholders match a single non-`/` segment. Everything else is
301
+ * regex-escaped so dots in hosts can't act as wildcards. Mirrors the
302
+ * server-side `templateToRegex` in capability-service.ts so CLI and SDK
303
+ * consumers agree on what counts as a match.
304
+ */
305
+ declare const urlMatchesTemplate: (url: string, template: string) => boolean;
306
+
201
307
  declare const SDK_VERSION: string;
202
308
 
203
- export { AVAILABILITY_BADGES, type AvailabilityBadge, type AvailabilityStatus, type JsonSchemaNode, PaymentSessionMeta, type Rating, SDK_VERSION, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, type ZeroErrorCode, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, createManagedAccount, extractInputEnvelope, normalizeTransportEnvelopeRequest, preferHealthy, sortByHealth, unwrapTransportEnvelope };
309
+ export { AVAILABILITY_BADGES, type AgentHost, type AvailabilityBadge, type AvailabilityStatus, type JsonSchemaNode, PaymentSessionMeta, type Rating, type RatingBadgeInput, SDK_VERSION, ZeroAgentAuthError, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, type ZeroErrorCode, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, centsToDollars, coerceToType, constraintHint, createManagedAccount, detectAgentHost, extractInputEnvelope, formatCostLabel, formatRatingBadge, formatRelativeTimestamp, formatReviewCount, inferSchema, normalizeTransportEnvelopeRequest, paramAttrs, placeholderFor, preferHealthy, redactUrl, sampleValueFor, schemaType, schemaTypeLabel, sortByHealth, truncateError, tryParseJson, unwrapTransportEnvelope, urlMatchesTemplate };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Z as ZeroClient, P as PaymentSessionMeta } from './client-Du4zQHef.js';
2
- export { A as AccountCredentials, g as Auth, h as AuthDevice, $ as BUG_REPORT_CATEGORIES, x as BalanceOptions, y as BalanceReadError, a9 as BatchReviewResponse, a0 as BugReportCategory, B as BugReports, j as Capabilities, a3 as CapabilityResponse, G as ClientOptions, a1 as CreateBugReportInput, a2 as CreateBugReportResponse, aa as CreateReviewInput, ab as CreateReviewResponse, ac as CreateRunInput, ad as CreateRunResponse, C as Credentials, H as DEFAULT_BASE_URL, I as DEFAULT_MAX_RETRIES, J as DEFAULT_TIMEOUT_MS, a6 as DevicePollResult, a7 as DeviceStartResponse, r as FETCH_SKIP_REASONS, s as FETCH_WARNINGS, F as FetchOptions, b as FetchOutcome, c as FetchResult, z as FundingUrlOptions, a4 as GetCapabilityOptions, V as InternalUserDto, ae as ListRunsParams, af as ListRunsResponse, L as LogEvent, Q as LogLevel, K as Logger, M as MigrateAuthorization, D as MigrateAuthorizationResponse, N as NoCredentials, O as OnSessionRefreshed, k as PayInput, o as PayResult, l as PaymentChain, m as PaymentProtocol, n as PaymentResult, t as Payments, X as PublicUserDto, a5 as ResolveCapabilityResponse, ag as RunDetail, ah as RunListItem, R as Runs, ai as SearchOptions, aj as SearchResponse, ak as SearchResult, S as SessionCredentials, a as SessionCredentialsInput, a8 as SessionExchangeResponse, p as SessionReceiptPayload, d as SignMessageInput, e as SignTransactionInput, f as SignTypedDataInput, T as TEMPO_CHAIN_ID, v as TEMPO_TESTNET_CHAIN_ID, U as UpstreamError, Y as UserWalletDto, E as Wallet, W as WalletBalance, _ as WelcomeBonusSummary, q as coerceTempoChainId, i as isShortToken, u as paymentHasAnchor, w as tempoChainLabelFromId } from './client-Du4zQHef.js';
1
+ import { Z as ZeroClient, P as PaymentSessionMeta } from './client-DKbrAo9Z.js';
2
+ export { A as AccountCredentials, a1 as AgentAuthEndpoints, a2 as AgentClaimAttempt, a3 as AgentRegistration, a4 as AgentSignupResult, a5 as AgentToken, a6 as AgentVerifiedIdentity, a7 as AgentZeroSession, k as Auth, l as AuthAgent, m as AuthDevice, ad as BUG_REPORT_CATEGORIES, B as BalanceChainId, G as BalanceOptions, H as BalanceReadError, an as BatchReviewResponse, ae as BugReportCategory, n as BugReports, o as Capabilities, ah as CapabilityResponse, Q as ClientOptions, a8 as CompleteClaimResult, af as CreateBugReportInput, ag as CreateBugReportResponse, ao as CreateReviewInput, ap as CreateReviewResponse, aq as CreateRunInput, ar as CreateRunResponse, C as Credentials, V as DEFAULT_BASE_URL, X as DEFAULT_MAX_RETRIES, Y as DEFAULT_TIMEOUT_MS, ak as DevicePollResult, al as DeviceStartResponse, w as FETCH_SKIP_REASONS, x as FETCH_WARNINGS, F as FetchOptions, d as FetchOutcome, e as FetchResult, I as FundingUrlOptions, ai as GetCapabilityOptions, J as ImportWalletOptions, a9 as InternalUserDto, as as ListRunsParams, at as ListRunsResponse, _ as LogEvent, a0 as LogLevel, $ as Logger, N as NoCredentials, O as OnSessionRefreshed, p as PayInput, t as PayResult, q as PaymentChain, r as PaymentProtocol, s as PaymentResult, y as Payments, aa as PublicUserDto, K as RemoveWalletOptions, aj as ResolveCapabilityResponse, au as RunDetail, av as RunListItem, R as Runs, aw as SearchOptions, ax as SearchResponse, ay as SearchResult, S as SessionCredentials, a as SessionCredentialsInput, am as SessionExchangeResponse, u as SessionReceiptPayload, L as SetPrimaryWalletOptions, g as SignMessageInput, h as SignTransactionInput, j as SignTypedDataInput, T as TEMPO_CHAIN_ID, D as TEMPO_TESTNET_CHAIN_ID, U as USDC_BASE, b as USDC_DECIMALS, c as USDC_TEMPO, f as UpstreamError, ab as UserWalletDto, M as Wallet, W as WalletBalance, ac as WelcomeBonusSummary, v as coerceTempoChainId, i as isShortToken, z as paymentHasAnchor, E as tempoChainLabelFromId } from './client-DKbrAo9Z.js';
3
3
  import { Address, LocalAccount } from 'viem';
4
4
  import { z } from 'zod';
5
5
 
@@ -29,6 +29,17 @@ type AuthErrorCode = Extract<ZeroErrorCode, "auth_error" | "auth_session_expired
29
29
  declare class ZeroAuthError extends ZeroError {
30
30
  constructor(code: AuthErrorCode, message: string, options?: ZeroErrorOptions);
31
31
  }
32
+ type AgentAuthErrorInit = {
33
+ status: number;
34
+ body?: unknown;
35
+ cause?: unknown;
36
+ };
37
+ declare class ZeroAgentAuthError extends ZeroError {
38
+ readonly status: number;
39
+ readonly body: unknown;
40
+ constructor(message: string, init: AgentAuthErrorInit);
41
+ get serverCode(): string | null;
42
+ }
32
43
  declare class ZeroPaymentError extends ZeroError {
33
44
  constructor(message: string, options?: ZeroErrorOptions);
34
45
  }
@@ -198,6 +209,101 @@ declare const preferHealthy: <T extends {
198
209
  availabilityStatus?: AvailabilityStatus | null;
199
210
  }>(items: readonly T[]) => T[];
200
211
 
212
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
213
+ type AgentHost = string;
214
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
215
+ declare const detectAgentHost: (env?: NodeJS.ProcessEnv) => AgentHost;
216
+
217
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
218
+ declare const formatReviewCount: (count: number) => string;
219
+
220
+ /**
221
+ * Convert a cents string (4-decimal precision per the API's `microsToCents`)
222
+ * to a dollar-amount string with enough decimal places that sub-cent
223
+ * token-metered charges don't silently round to zero or get overstated.
224
+ *
225
+ * Precision ladder (matches `services/web/src/app/c/[slug]/page.tsx`):
226
+ * value >= 1 → toFixed(2) — normal dollar amounts ("5.00")
227
+ * value >= 0.01 → toFixed(3) — sub-dollar ("0.500")
228
+ * value >= 0.001 → toFixed(4) — sub-cent ("0.0050")
229
+ * value >= 0.0001 → toFixed(5) — sub-millicent ("0.00050")
230
+ * else → toFixed(6) — micro-dollar floor ("0.000005")
231
+ *
232
+ * Honest signal beats pretty zeros. We accept the ugly trailing decimals
233
+ * because the alternative — `.toFixed(4)` flooring at $0.0001 — silently
234
+ * misreports per-token LLM charges as ~2× their actual cost (or as zero).
235
+ *
236
+ * All price-rendering surfaces (CLI, web, SDK consumers) should use this
237
+ * function so the same capability never shows a different price depending
238
+ * on which surface the agent uses.
239
+ */
240
+ declare const centsToDollars: (cents: string) => string;
241
+ /**
242
+ * Human-readable label for a search-row cost amount, interpreting the
243
+ * server's sentinel values: `"0"` means the cap is free, `"unknown"` means
244
+ * the upstream advertised dynamic/per-token pricing without revealing a
245
+ * concrete number. Any other value is a decimal USD amount per call.
246
+ *
247
+ * The sentinel interpretation is part of the server contract — every
248
+ * consumer (CLI, MCP plugin, QA harness) must map them the same way or an
249
+ * agent sees "$unknown" for a variable-priced cap on one surface and
250
+ * "variable pricing" on another.
251
+ */
252
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
253
+ declare const formatCostLabel: (amount: string) => string;
254
+
255
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
256
+ type RatingBadgeInput = {
257
+ successRate: string;
258
+ reviews: number;
259
+ stars?: string | null;
260
+ state?: "unrated" | "rated";
261
+ };
262
+ /**
263
+ * One-line rating badge: `★ 4.1/5 (91% success, 42 reviews)` when a star
264
+ * score exists, `91% success · 42 reviews` otherwise, `unrated` when the cap
265
+ * has no rating yet. Shared so all consumers render the same rating for the
266
+ * same capability.
267
+ */
268
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
269
+ declare const formatRatingBadge: (rating: RatingBadgeInput) => string;
270
+
271
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
272
+ declare const formatRelativeTimestamp: (iso: string | null | undefined) => string;
273
+
274
+ /**
275
+ * Deterministic structural walk of a JSON value → JSON-schema-ish draft.
276
+ *
277
+ * Used to send anonymized shape information (field names + types, no values)
278
+ * to the server after a capability execution. Mirrors the server-side
279
+ * inference in services/api.
280
+ */
281
+ declare const inferSchema: (value: unknown, depth?: number) => Record<string, unknown>;
282
+ declare const tryParseJson: (text: string) => unknown;
283
+
284
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
285
+ declare const redactUrl: (raw: string) => string;
286
+ /** @internal Zero-surface helper — not part of the supported partner contract. */
287
+ declare const truncateError: (raw: string) => string;
288
+
289
+ declare const schemaTypeLabel: (node: JsonSchemaNode) => string;
290
+ declare const constraintHint: (node: JsonSchemaNode) => string | null;
291
+ declare const paramAttrs: (node: JsonSchemaNode, required: boolean) => string;
292
+
293
+ declare const schemaType: (node: JsonSchemaNode | null) => string | undefined;
294
+ declare const coerceToType: (value: unknown, type: string | undefined) => unknown;
295
+ declare const sampleValueFor: (fieldName: string, propSchema: unknown, depth?: number) => unknown;
296
+ declare const placeholderFor: (fieldName: string, propSchema: unknown) => string;
297
+
298
+ /**
299
+ * Match a fetched URL against a urlTemplate like `/users/{handle}`.
300
+ * `{name}` placeholders match a single non-`/` segment. Everything else is
301
+ * regex-escaped so dots in hosts can't act as wildcards. Mirrors the
302
+ * server-side `templateToRegex` in capability-service.ts so CLI and SDK
303
+ * consumers agree on what counts as a match.
304
+ */
305
+ declare const urlMatchesTemplate: (url: string, template: string) => boolean;
306
+
201
307
  declare const SDK_VERSION: string;
202
308
 
203
- export { AVAILABILITY_BADGES, type AvailabilityBadge, type AvailabilityStatus, type JsonSchemaNode, PaymentSessionMeta, type Rating, SDK_VERSION, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, type ZeroErrorCode, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, createManagedAccount, extractInputEnvelope, normalizeTransportEnvelopeRequest, preferHealthy, sortByHealth, unwrapTransportEnvelope };
309
+ export { AVAILABILITY_BADGES, type AgentHost, type AvailabilityBadge, type AvailabilityStatus, type JsonSchemaNode, PaymentSessionMeta, type Rating, type RatingBadgeInput, SDK_VERSION, ZeroAgentAuthError, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, type ZeroErrorCode, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, centsToDollars, coerceToType, constraintHint, createManagedAccount, detectAgentHost, extractInputEnvelope, formatCostLabel, formatRatingBadge, formatRelativeTimestamp, formatReviewCount, inferSchema, normalizeTransportEnvelopeRequest, paramAttrs, placeholderFor, preferHealthy, redactUrl, sampleValueFor, schemaType, schemaTypeLabel, sortByHealth, truncateError, tryParseJson, unwrapTransportEnvelope, urlMatchesTemplate };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- export { Auth, AuthDevice, BUG_REPORT_CATEGORIES, BugReports, Capabilities, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, FETCH_SKIP_REASONS, FETCH_WARNINGS, Payments, Runs, SDK_VERSION, TEMPO_CHAIN_ID, TEMPO_TESTNET_CHAIN_ID, Wallet, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, coerceTempoChainId, createManagedAccount, extractInputEnvelope, isShortToken, normalizeTransportEnvelopeRequest, paymentHasAnchor, tempoChainLabelFromId, unwrapTransportEnvelope } from './chunk-T6JT5NV5.js';
1
+ import { asSchemaNode } from './chunk-T77VVLOM.js';
2
+ export { Auth, AuthAgent, AuthDevice, BUG_REPORT_CATEGORIES, BugReports, Capabilities, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, FETCH_SKIP_REASONS, FETCH_WARNINGS, Payments, Runs, SDK_VERSION, TEMPO_CHAIN_ID, TEMPO_TESTNET_CHAIN_ID, USDC_BASE, USDC_DECIMALS, USDC_TEMPO, Wallet, ZeroAgentAuthError, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, coerceTempoChainId, createManagedAccount, extractInputEnvelope, isShortToken, normalizeTransportEnvelopeRequest, paymentHasAnchor, tempoChainLabelFromId, unwrapTransportEnvelope } from './chunk-T77VVLOM.js';
2
3
 
3
4
  // src/status.ts
4
5
  var AVAILABILITY_BADGES = {
@@ -21,6 +22,235 @@ var sortByHealth = (items) => [...items].sort(
21
22
  );
22
23
  var preferHealthy = sortByHealth;
23
24
 
24
- export { AVAILABILITY_BADGES, preferHealthy, sortByHealth };
25
+ // src/utils/agent-host.ts
26
+ var detectAgentHost = (env = process.env) => {
27
+ if (env.ZERO_AGENT) return env.ZERO_AGENT;
28
+ if (env.CLAUDECODE === "1") return "claude-code";
29
+ if (env.CURSOR_TRACE_ID) return "cursor";
30
+ if (env.TERM_PROGRAM === "vscode") return "vscode";
31
+ return "unknown";
32
+ };
33
+
34
+ // src/utils/format-count.ts
35
+ var formatReviewCount = (count) => {
36
+ if (count >= 1e3) return `${(count / 1e3).toFixed(1)}k`;
37
+ return count.toString();
38
+ };
39
+
40
+ // src/utils/format-price.ts
41
+ var centsToDollars = (cents) => {
42
+ const value = Number.parseFloat(cents) / 100;
43
+ if (!Number.isFinite(value) || value === 0) return "0.00";
44
+ if (value < 1e-4) return value.toFixed(6);
45
+ if (value < 1e-3) return value.toFixed(5);
46
+ if (value < 0.01) return value.toFixed(4);
47
+ if (value < 1) return value.toFixed(3);
48
+ return value.toFixed(2);
49
+ };
50
+ var formatCostLabel = (amount) => {
51
+ if (amount === "0") return "Free";
52
+ if (amount === "unknown") return "variable pricing";
53
+ return `$${amount}/call`;
54
+ };
55
+
56
+ // src/utils/format-rating.ts
57
+ var formatRatingBadge = (rating) => {
58
+ if (rating.state === "unrated") return "unrated";
59
+ const successPct = `${Math.round(Number.parseFloat(rating.successRate) * 100)}%`;
60
+ const reviews = formatReviewCount(rating.reviews);
61
+ if (rating.stars) {
62
+ return `\u2605 ${rating.stars}/5 (${successPct} success, ${reviews} reviews)`;
63
+ }
64
+ return `${successPct} success \xB7 ${reviews} reviews`;
65
+ };
66
+
67
+ // src/utils/format-time.ts
68
+ var formatRelativeTimestamp = (iso) => {
69
+ if (!iso) return "never";
70
+ const then = new Date(iso).getTime();
71
+ if (Number.isNaN(then)) return "never";
72
+ const diffSec = Math.max(0, Math.round((Date.now() - then) / 1e3));
73
+ if (diffSec < 60) return `${diffSec}s ago`;
74
+ const diffMin = Math.round(diffSec / 60);
75
+ if (diffMin < 60) return `${diffMin}m ago`;
76
+ const diffHr = Math.round(diffMin / 60);
77
+ if (diffHr < 24) return `${diffHr}h ago`;
78
+ const diffDay = Math.round(diffHr / 24);
79
+ if (diffDay < 30) return `${diffDay}d ago`;
80
+ const diffMo = Math.round(diffDay / 30);
81
+ if (diffMo < 12) return `${diffMo}mo ago`;
82
+ return `${Math.round(diffMo / 12)}y ago`;
83
+ };
84
+
85
+ // src/utils/infer-schema.ts
86
+ var inferSchema = (value, depth = 0) => {
87
+ if (depth > 6) return { type: typeOf(value) };
88
+ if (value === null) return { type: "null" };
89
+ if (Array.isArray(value)) {
90
+ const itemSchemas = value.slice(0, 3).map((v) => inferSchema(v, depth + 1));
91
+ return {
92
+ type: "array",
93
+ items: itemSchemas[0] ?? { type: "unknown" }
94
+ };
95
+ }
96
+ if (typeof value === "object") {
97
+ const obj = value;
98
+ const properties = {};
99
+ const required = [];
100
+ for (const [k, v] of Object.entries(obj)) {
101
+ properties[k] = inferSchema(v, depth + 1);
102
+ required.push(k);
103
+ }
104
+ return { type: "object", properties, required };
105
+ }
106
+ return { type: typeOf(value) };
107
+ };
108
+ var typeOf = (v) => {
109
+ if (v === null) return "null";
110
+ if (Array.isArray(v)) return "array";
111
+ return typeof v;
112
+ };
113
+ var tryParseJson = (text) => {
114
+ try {
115
+ return JSON.parse(text);
116
+ } catch {
117
+ return null;
118
+ }
119
+ };
120
+
121
+ // src/utils/redact.ts
122
+ var ERROR_MAX = 500;
123
+ var redactUrl = (raw) => {
124
+ try {
125
+ const parsed = new URL(raw);
126
+ return `${parsed.origin}${parsed.pathname}`;
127
+ } catch {
128
+ return raw;
129
+ }
130
+ };
131
+ var truncateError = (raw) => raw.length > ERROR_MAX ? `${raw.slice(0, ERROR_MAX)}\u2026` : raw;
132
+
133
+ // src/utils/schema-describe.ts
134
+ var schemaTypeLabel = (node) => {
135
+ const t = node.type;
136
+ if (typeof t === "string") return t;
137
+ if (Array.isArray(t)) {
138
+ const parts = t.filter((x) => typeof x === "string");
139
+ return parts.length > 0 ? parts.join(" | ") : "any";
140
+ }
141
+ return "any";
142
+ };
143
+ var constraintHint = (node) => {
144
+ const num = (k) => typeof node[k] === "number" ? node[k] : void 0;
145
+ const hints = [];
146
+ const min = num("minimum");
147
+ const max = num("maximum");
148
+ if (min !== void 0 && max !== void 0)
149
+ hints.push(`range: ${min}..${max}`);
150
+ else if (min !== void 0) hints.push(`min: ${min}`);
151
+ else if (max !== void 0) hints.push(`max: ${max}`);
152
+ const exMin = num("exclusiveMinimum");
153
+ const exMax = num("exclusiveMaximum");
154
+ if (exMin !== void 0) hints.push(`> ${exMin}`);
155
+ if (exMax !== void 0) hints.push(`< ${exMax}`);
156
+ const minLen = num("minLength");
157
+ const maxLen = num("maxLength");
158
+ if (minLen !== void 0 && maxLen !== void 0)
159
+ hints.push(`length: ${minLen}..${maxLen}`);
160
+ else if (maxLen !== void 0) hints.push(`maxLength: ${maxLen}`);
161
+ else if (minLen !== void 0) hints.push(`minLength: ${minLen}`);
162
+ const minItems = num("minItems");
163
+ const maxItems = num("maxItems");
164
+ if (minItems !== void 0 && maxItems !== void 0)
165
+ hints.push(`items: ${minItems}..${maxItems}`);
166
+ else if (maxItems !== void 0) hints.push(`maxItems: ${maxItems}`);
167
+ else if (minItems !== void 0) hints.push(`minItems: ${minItems}`);
168
+ if (typeof node.pattern === "string") hints.push(`pattern: ${node.pattern}`);
169
+ return hints.length > 0 ? hints.join(", ") : null;
170
+ };
171
+ var paramAttrs = (node, required) => {
172
+ const attrs = [schemaTypeLabel(node)];
173
+ if (required) attrs.push("required");
174
+ if (node.const !== void 0)
175
+ attrs.push(`const: ${JSON.stringify(node.const)}`);
176
+ if (node.default !== void 0)
177
+ attrs.push(`default: ${JSON.stringify(node.default)}`);
178
+ if (Array.isArray(node.enum))
179
+ attrs.push(`one of: ${node.enum.map((v) => String(v)).join(" | ")}`);
180
+ if (typeof node.format === "string") attrs.push(`format: ${node.format}`);
181
+ const hint = constraintHint(node);
182
+ if (hint) attrs.push(hint);
183
+ return attrs.join(", ");
184
+ };
185
+
186
+ // src/utils/schema-sample.ts
187
+ var schemaType = (node) => {
188
+ const t = node?.type;
189
+ if (typeof t === "string") return t;
190
+ if (Array.isArray(t)) {
191
+ const first = t.find((x) => typeof x === "string" && x !== "null");
192
+ return typeof first === "string" ? first : void 0;
193
+ }
194
+ return void 0;
195
+ };
196
+ var coerceToType = (value, type) => {
197
+ if (typeof value !== "string") return value;
198
+ if (type === "number" || type === "integer") {
199
+ const n = Number(value);
200
+ return value.trim() !== "" && Number.isFinite(n) ? n : value;
201
+ }
202
+ if (type === "boolean") {
203
+ if (value === "true") return true;
204
+ if (value === "false") return false;
205
+ }
206
+ return value;
207
+ };
208
+ var MAX_SCHEMA_DEPTH = 5;
209
+ var sampleValueFor = (fieldName, propSchema, depth = 0) => {
210
+ const node = asSchemaNode(propSchema);
211
+ const type = schemaType(node);
212
+ const enumFirst = Array.isArray(node?.enum) && node.enum.length > 0 ? node.enum[0] : void 0;
213
+ const fixed = node?.const ?? node?.example ?? node?.default ?? enumFirst;
214
+ if (fixed !== void 0 && fixed !== null) {
215
+ return coerceToType(fixed, type);
216
+ }
217
+ if (node && depth < MAX_SCHEMA_DEPTH) {
218
+ const props = asSchemaNode(node.properties);
219
+ if (props && (type === "object" || type === void 0)) {
220
+ const obj = {};
221
+ for (const [k, sub] of Object.entries(props)) {
222
+ obj[k] = sampleValueFor(k, sub, depth + 1);
223
+ }
224
+ return obj;
225
+ }
226
+ if (type === "array") {
227
+ const items = asSchemaNode(node.items);
228
+ return items ? [sampleValueFor(fieldName, items, depth + 1)] : [];
229
+ }
230
+ }
231
+ switch (type) {
232
+ case "number":
233
+ case "integer":
234
+ return 0;
235
+ case "boolean":
236
+ return false;
237
+ case "array":
238
+ return [];
239
+ case "object":
240
+ return {};
241
+ default:
242
+ return `<${fieldName.toUpperCase()}>`;
243
+ }
244
+ };
245
+ var placeholderFor = (fieldName, propSchema) => String(sampleValueFor(fieldName, propSchema));
246
+
247
+ // src/utils/url-template.ts
248
+ var urlMatchesTemplate = (url, template) => {
249
+ const escaped = template.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
250
+ const withCaptures = escaped.replace(/\\\{[^/\\}]+\\\}/g, "[^/]+");
251
+ return new RegExp(`^${withCaptures}$`).test(url);
252
+ };
253
+
254
+ export { AVAILABILITY_BADGES, centsToDollars, coerceToType, constraintHint, detectAgentHost, formatCostLabel, formatRatingBadge, formatRelativeTimestamp, formatReviewCount, inferSchema, paramAttrs, placeholderFor, preferHealthy, redactUrl, sampleValueFor, schemaType, schemaTypeLabel, sortByHealth, truncateError, tryParseJson, urlMatchesTemplate };
25
255
  //# sourceMappingURL=index.js.map
26
256
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/status.ts"],"names":[],"mappings":";;;AAoCO,IAAM,mBAAA,GAAsB;AAAA,EAClC,SAAS,EAAE,MAAA,EAAQ,UAAK,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA,EAAU;AAAA,EACzD,SAAS,EAAE,MAAA,EAAQ,KAAK,KAAA,EAAO,QAAA,EAAU,OAAO,SAAA,EAAU;AAAA,EAC1D,MAAM,EAAE,MAAA,EAAQ,UAAK,KAAA,EAAO,KAAA,EAAO,OAAO,MAAA;AAC3C;AAGA,IAAM,WAAA,GAAkD;AAAA,EACvD,OAAA,EAAS,CAAA;AAAA,EACT,OAAA,EAAS,CAAA;AAAA,EACT,IAAA,EAAM;AACP,CAAA;AAEA,IAAM,SAAS,CAAC,MAAA;AAAA;AAAA;AAAA,EAGf,MAAA,IAAU,IAAA,GAAO,WAAA,CAAY,OAAA,GAAU,YAAY,MAAM;AAAA,CAAA;AAUnD,IAAM,eAAe,CAG3B,KAAA,KAEA,CAAC,GAAG,KAAK,CAAA,CAAE,IAAA;AAAA,EACV,CAAC,GAAG,CAAA,KAAM,MAAA,CAAO,EAAE,kBAAkB,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,kBAAkB;AACrE;AAMM,IAAM,aAAA,GAAgB","file":"index.js","sourcesContent":["/**\n * Capability availability status — the single, consolidated health signal\n * Zero surfaces to clients (ZERO-89 / ZERO-92).\n *\n * - `healthy` — proven live and executable; safe to call.\n * - `unknown` — insufficient evidence either way; usable as a fallback.\n * - `down` — confirmed dead / failing; avoid.\n *\n * Preference rule for agents: PREFER `healthy`. Fall back to `unknown` only\n * when nothing `healthy` fits the task. Avoid `down`. This is the same rule the\n * server-side visibility filter enforces, surfaced here so agents and UIs can\n * rank consistently.\n */\nexport type AvailabilityStatus = \"healthy\" | \"unknown\" | \"down\";\n\n/** A renderable badge for an {@link AvailabilityStatus}. */\nexport type AvailabilityBadge = {\n\t/** A short glyph suitable for terminals/UI (✓ / ? / ✗). */\n\tsymbol: string;\n\t/**\n\t * A color *name* (not ANSI/hex) — this SDK is environment-agnostic, so\n\t * consumers map the name to whatever their renderer needs.\n\t */\n\tcolor: \"green\" | \"yellow\" | \"red\";\n\t/** Human-readable label. */\n\tlabel: string;\n};\n\n/**\n * Badge metadata for each {@link AvailabilityStatus}. Exhaustively keyed via\n * `satisfies` so adding/removing a status value is a compile error here.\n *\n * - healthy → green check\n * - unknown → yellow question\n * - down → red cross\n */\nexport const AVAILABILITY_BADGES = {\n\thealthy: { symbol: \"✓\", color: \"green\", label: \"Healthy\" },\n\tunknown: { symbol: \"?\", color: \"yellow\", label: \"Unknown\" },\n\tdown: { symbol: \"✗\", color: \"red\", label: \"Down\" },\n} as const satisfies Record<AvailabilityStatus, AvailabilityBadge>;\n\n// Lower rank sorts first: healthy ahead of unknown ahead of down.\nconst STATUS_RANK: Record<AvailabilityStatus, number> = {\n\thealthy: 0,\n\tunknown: 1,\n\tdown: 2,\n};\n\nconst rankOf = (status: AvailabilityStatus | null | undefined): number =>\n\t// Missing/null status is treated as `unknown` — \"we don't know\" ranks\n\t// above a confirmed `down` but below a proven `healthy`.\n\tstatus == null ? STATUS_RANK.unknown : STATUS_RANK[status];\n\n/**\n * Stable-sort capabilities by health: `healthy` > `unknown` > `down`.\n *\n * Agents should PREFER `healthy` and fall back to `unknown` only when nothing\n * `healthy` fits; `down` is last. A missing/null status is ranked as\n * `unknown`. Returns a NEW array — the input is not mutated. Items of equal\n * rank keep their original relative order (stable).\n */\nexport const sortByHealth = <\n\tT extends { availabilityStatus?: AvailabilityStatus | null },\n>(\n\titems: readonly T[],\n): T[] =>\n\t[...items].sort(\n\t\t(a, b) => rankOf(a.availabilityStatus) - rankOf(b.availabilityStatus),\n\t);\n\n/**\n * Alias for {@link sortByHealth}. The preference rule is \"prefer healthy, fall\n * back to unknown\" — applying it to a list means sorting healthy-first.\n */\nexport const preferHealthy = sortByHealth;\n"]}
1
+ {"version":3,"sources":["../src/status.ts","../src/utils/agent-host.ts","../src/utils/format-count.ts","../src/utils/format-price.ts","../src/utils/format-rating.ts","../src/utils/format-time.ts","../src/utils/infer-schema.ts","../src/utils/redact.ts","../src/utils/schema-describe.ts","../src/utils/schema-sample.ts","../src/utils/url-template.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Capability availability status — the single, consolidated health signal\n * Zero surfaces to clients (ZERO-89 / ZERO-92).\n *\n * - `healthy` — proven live and executable; safe to call.\n * - `unknown` — insufficient evidence either way; usable as a fallback.\n * - `down` — confirmed dead / failing; avoid.\n *\n * Preference rule for agents: PREFER `healthy`. Fall back to `unknown` only\n * when nothing `healthy` fits the task. Avoid `down`. This is the same rule the\n * server-side visibility filter enforces, surfaced here so agents and UIs can\n * rank consistently.\n */\nexport type AvailabilityStatus = \"healthy\" | \"unknown\" | \"down\";\n\n/** A renderable badge for an {@link AvailabilityStatus}. */\nexport type AvailabilityBadge = {\n\t/** A short glyph suitable for terminals/UI (✓ / ? / ✗). */\n\tsymbol: string;\n\t/**\n\t * A color *name* (not ANSI/hex) — this SDK is environment-agnostic, so\n\t * consumers map the name to whatever their renderer needs.\n\t */\n\tcolor: \"green\" | \"yellow\" | \"red\";\n\t/** Human-readable label. */\n\tlabel: string;\n};\n\n/**\n * Badge metadata for each {@link AvailabilityStatus}. Exhaustively keyed via\n * `satisfies` so adding/removing a status value is a compile error here.\n *\n * - healthy → green check\n * - unknown → yellow question\n * - down → red cross\n */\nexport const AVAILABILITY_BADGES = {\n\thealthy: { symbol: \"✓\", color: \"green\", label: \"Healthy\" },\n\tunknown: { symbol: \"?\", color: \"yellow\", label: \"Unknown\" },\n\tdown: { symbol: \"✗\", color: \"red\", label: \"Down\" },\n} as const satisfies Record<AvailabilityStatus, AvailabilityBadge>;\n\n// Lower rank sorts first: healthy ahead of unknown ahead of down.\nconst STATUS_RANK: Record<AvailabilityStatus, number> = {\n\thealthy: 0,\n\tunknown: 1,\n\tdown: 2,\n};\n\nconst rankOf = (status: AvailabilityStatus | null | undefined): number =>\n\t// Missing/null status is treated as `unknown` — \"we don't know\" ranks\n\t// above a confirmed `down` but below a proven `healthy`.\n\tstatus == null ? STATUS_RANK.unknown : STATUS_RANK[status];\n\n/**\n * Stable-sort capabilities by health: `healthy` > `unknown` > `down`.\n *\n * Agents should PREFER `healthy` and fall back to `unknown` only when nothing\n * `healthy` fits; `down` is last. A missing/null status is ranked as\n * `unknown`. Returns a NEW array — the input is not mutated. Items of equal\n * rank keep their original relative order (stable).\n */\nexport const sortByHealth = <\n\tT extends { availabilityStatus?: AvailabilityStatus | null },\n>(\n\titems: readonly T[],\n): T[] =>\n\t[...items].sort(\n\t\t(a, b) => rankOf(a.availabilityStatus) - rankOf(b.availabilityStatus),\n\t);\n\n/**\n * Alias for {@link sortByHealth}. The preference rule is \"prefer healthy, fall\n * back to unknown\" — applying it to a list means sorting healthy-first.\n */\nexport const preferHealthy = sortByHealth;\n","// Detect which agent host is invoking the SDK at runtime.\n//\n// Resolution is deliberately stateless — no persisted config. Anything\n// long-lived risks going stale when an agent moves between sandboxes.\n//\n// Resolution order (highest priority first):\n// 1. ZERO_AGENT env var (per-invocation prefix or per-session export)\n// 2. Host-specific env signals (CLAUDECODE=1, CURSOR_TRACE_ID,\n// TERM_PROGRAM=vscode) that the host sets per-session\n// 3. \"unknown\"\n//\n// Canonical names: claude-code, cursor, vscode, claude-web, codex, opencode.\n// Arbitrary strings are accepted (self-identified); dashboards group by value.\n\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport type AgentHost = string;\n\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport const detectAgentHost = (\n\tenv: NodeJS.ProcessEnv = process.env,\n): AgentHost => {\n\tif (env.ZERO_AGENT) return env.ZERO_AGENT;\n\tif (env.CLAUDECODE === \"1\") return \"claude-code\";\n\tif (env.CURSOR_TRACE_ID) return \"cursor\";\n\tif (env.TERM_PROGRAM === \"vscode\") return \"vscode\";\n\treturn \"unknown\";\n};\n","// Compact number formatter for review/run counts. Collapses ≥1000 to one\n// decimal \"k\" (e.g. 1234 → \"1.2k\") so result lists stay scannable.\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport const formatReviewCount = (count: number): string => {\n\tif (count >= 1000) return `${(count / 1000).toFixed(1)}k`;\n\treturn count.toString();\n};\n","/**\n * Convert a cents string (4-decimal precision per the API's `microsToCents`)\n * to a dollar-amount string with enough decimal places that sub-cent\n * token-metered charges don't silently round to zero or get overstated.\n *\n * Precision ladder (matches `services/web/src/app/c/[slug]/page.tsx`):\n * value >= 1 → toFixed(2) — normal dollar amounts (\"5.00\")\n * value >= 0.01 → toFixed(3) — sub-dollar (\"0.500\")\n * value >= 0.001 → toFixed(4) — sub-cent (\"0.0050\")\n * value >= 0.0001 → toFixed(5) — sub-millicent (\"0.00050\")\n * else → toFixed(6) — micro-dollar floor (\"0.000005\")\n *\n * Honest signal beats pretty zeros. We accept the ugly trailing decimals\n * because the alternative — `.toFixed(4)` flooring at $0.0001 — silently\n * misreports per-token LLM charges as ~2× their actual cost (or as zero).\n *\n * All price-rendering surfaces (CLI, web, SDK consumers) should use this\n * function so the same capability never shows a different price depending\n * on which surface the agent uses.\n */\nexport const centsToDollars = (cents: string): string => {\n\tconst value = Number.parseFloat(cents) / 100;\n\tif (!Number.isFinite(value) || value === 0) return \"0.00\";\n\tif (value < 0.0001) return value.toFixed(6);\n\tif (value < 0.001) return value.toFixed(5);\n\tif (value < 0.01) return value.toFixed(4);\n\tif (value < 1) return value.toFixed(3);\n\treturn value.toFixed(2);\n};\n\n/**\n * Human-readable label for a search-row cost amount, interpreting the\n * server's sentinel values: `\"0\"` means the cap is free, `\"unknown\"` means\n * the upstream advertised dynamic/per-token pricing without revealing a\n * concrete number. Any other value is a decimal USD amount per call.\n *\n * The sentinel interpretation is part of the server contract — every\n * consumer (CLI, MCP plugin, QA harness) must map them the same way or an\n * agent sees \"$unknown\" for a variable-priced cap on one surface and\n * \"variable pricing\" on another.\n */\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport const formatCostLabel = (amount: string): string => {\n\tif (amount === \"0\") return \"Free\";\n\tif (amount === \"unknown\") return \"variable pricing\";\n\treturn `$${amount}/call`;\n};\n","import { formatReviewCount } from \"./format-count\";\n\n// Structural subset of the API's rating shape shared by search rows and the\n// capability detail response. `score` (present on the full Rating) isn't\n// needed to render the badge, so it's not required here.\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport type RatingBadgeInput = {\n\tsuccessRate: string;\n\treviews: number;\n\tstars?: string | null;\n\tstate?: \"unrated\" | \"rated\";\n};\n\n/**\n * One-line rating badge: `★ 4.1/5 (91% success, 42 reviews)` when a star\n * score exists, `91% success · 42 reviews` otherwise, `unrated` when the cap\n * has no rating yet. Shared so all consumers render the same rating for the\n * same capability.\n */\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport const formatRatingBadge = (rating: RatingBadgeInput): string => {\n\tif (rating.state === \"unrated\") return \"unrated\";\n\tconst successPct = `${Math.round(Number.parseFloat(rating.successRate) * 100)}%`;\n\tconst reviews = formatReviewCount(rating.reviews);\n\tif (rating.stars) {\n\t\treturn `★ ${rating.stars}/5 (${successPct} success, ${reviews} reviews)`;\n\t}\n\treturn `${successPct} success · ${reviews} reviews`;\n};\n","// Converts an ISO timestamp (or null/undefined) to a compact relative string\n// (\"5m ago\", \"3d ago\", \"never\"). No terminal I/O — safe for any consumer.\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport const formatRelativeTimestamp = (\n\tiso: string | null | undefined,\n): string => {\n\tif (!iso) return \"never\";\n\tconst then = new Date(iso).getTime();\n\tif (Number.isNaN(then)) return \"never\";\n\tconst diffSec = Math.max(0, Math.round((Date.now() - then) / 1000));\n\tif (diffSec < 60) return `${diffSec}s ago`;\n\tconst diffMin = Math.round(diffSec / 60);\n\tif (diffMin < 60) return `${diffMin}m ago`;\n\tconst diffHr = Math.round(diffMin / 60);\n\tif (diffHr < 24) return `${diffHr}h ago`;\n\tconst diffDay = Math.round(diffHr / 24);\n\tif (diffDay < 30) return `${diffDay}d ago`;\n\tconst diffMo = Math.round(diffDay / 30);\n\tif (diffMo < 12) return `${diffMo}mo ago`;\n\treturn `${Math.round(diffMo / 12)}y ago`;\n};\n","/**\n * Deterministic structural walk of a JSON value → JSON-schema-ish draft.\n *\n * Used to send anonymized shape information (field names + types, no values)\n * to the server after a capability execution. Mirrors the server-side\n * inference in services/api.\n */\nexport const inferSchema = (\n\tvalue: unknown,\n\tdepth = 0,\n): Record<string, unknown> => {\n\tif (depth > 6) return { type: typeOf(value) };\n\tif (value === null) return { type: \"null\" };\n\tif (Array.isArray(value)) {\n\t\tconst itemSchemas = value.slice(0, 3).map((v) => inferSchema(v, depth + 1));\n\t\treturn {\n\t\t\ttype: \"array\",\n\t\t\titems: itemSchemas[0] ?? { type: \"unknown\" },\n\t\t};\n\t}\n\tif (typeof value === \"object\") {\n\t\tconst obj = value as Record<string, unknown>;\n\t\tconst properties: Record<string, unknown> = {};\n\t\tconst required: string[] = [];\n\t\tfor (const [k, v] of Object.entries(obj)) {\n\t\t\tproperties[k] = inferSchema(v, depth + 1);\n\t\t\trequired.push(k);\n\t\t}\n\t\treturn { type: \"object\", properties, required };\n\t}\n\treturn { type: typeOf(value) };\n};\n\nconst typeOf = (v: unknown): string => {\n\tif (v === null) return \"null\";\n\tif (Array.isArray(v)) return \"array\";\n\treturn typeof v;\n};\n\nexport const tryParseJson = (text: string): unknown => {\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\treturn null;\n\t}\n};\n","// PII-reduction helpers for analytics and logging. These constants and\n// functions apply the same policy regardless of which surface (CLI, MCP,\n// raw SDK) is building the event payload.\n\nconst ERROR_MAX = 500;\n\n// Strip query string + hash from a URL. Keeps protocol + host + pathname so\n// events can still be attributed to the right endpoint, but drops any\n// `?api_key=...` / user-supplied params that might be PII.\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport const redactUrl = (raw: string): string => {\n\ttry {\n\t\tconst parsed = new URL(raw);\n\t\treturn `${parsed.origin}${parsed.pathname}`;\n\t} catch {\n\t\treturn raw;\n\t}\n};\n\n// Error messages are low-risk (usually stack traces / HTTP bodies) but can\n// leak absolute paths or inline data. Hard-cap at 500 chars.\n/** @internal Zero-surface helper — not part of the supported partner contract. */\nexport const truncateError = (raw: string): string =>\n\traw.length > ERROR_MAX ? `${raw.slice(0, ERROR_MAX)}…` : raw;\n","import type { JsonSchemaNode } from \"../input-envelope\";\n\n// Human/agent-readable type label, preserving unions (e.g. \"string | null\").\nexport const schemaTypeLabel = (node: JsonSchemaNode): string => {\n\tconst t = node.type;\n\tif (typeof t === \"string\") return t;\n\tif (Array.isArray(t)) {\n\t\tconst parts = t.filter((x): x is string => typeof x === \"string\");\n\t\treturn parts.length > 0 ? parts.join(\" | \") : \"any\";\n\t}\n\treturn \"any\";\n};\n\n// Compact constraint hints (numeric range, exclusive bounds, string/array\n// length, regex pattern) — every constraint the agent must satisfy to avoid a\n// charged 400. Collects ALL applicable hints, not just the first.\nexport const constraintHint = (node: JsonSchemaNode): string | null => {\n\tconst num = (k: string): number | undefined =>\n\t\ttypeof node[k] === \"number\" ? (node[k] as number) : undefined;\n\tconst hints: string[] = [];\n\tconst min = num(\"minimum\");\n\tconst max = num(\"maximum\");\n\tif (min !== undefined && max !== undefined)\n\t\thints.push(`range: ${min}..${max}`);\n\telse if (min !== undefined) hints.push(`min: ${min}`);\n\telse if (max !== undefined) hints.push(`max: ${max}`);\n\tconst exMin = num(\"exclusiveMinimum\");\n\tconst exMax = num(\"exclusiveMaximum\");\n\tif (exMin !== undefined) hints.push(`> ${exMin}`);\n\tif (exMax !== undefined) hints.push(`< ${exMax}`);\n\tconst minLen = num(\"minLength\");\n\tconst maxLen = num(\"maxLength\");\n\tif (minLen !== undefined && maxLen !== undefined)\n\t\thints.push(`length: ${minLen}..${maxLen}`);\n\telse if (maxLen !== undefined) hints.push(`maxLength: ${maxLen}`);\n\telse if (minLen !== undefined) hints.push(`minLength: ${minLen}`);\n\tconst minItems = num(\"minItems\");\n\tconst maxItems = num(\"maxItems\");\n\tif (minItems !== undefined && maxItems !== undefined)\n\t\thints.push(`items: ${minItems}..${maxItems}`);\n\telse if (maxItems !== undefined) hints.push(`maxItems: ${maxItems}`);\n\telse if (minItems !== undefined) hints.push(`minItems: ${minItems}`);\n\tif (typeof node.pattern === \"string\") hints.push(`pattern: ${node.pattern}`);\n\treturn hints.length > 0 ? hints.join(\", \") : null;\n};\n\n// The single-field attrs line: type, required, const (exact value the agent\n// MUST send), default, enum, format, and numeric/length constraints.\nexport const paramAttrs = (node: JsonSchemaNode, required: boolean): string => {\n\tconst attrs: string[] = [schemaTypeLabel(node)];\n\tif (required) attrs.push(\"required\");\n\tif (node.const !== undefined)\n\t\tattrs.push(`const: ${JSON.stringify(node.const)}`);\n\tif (node.default !== undefined)\n\t\tattrs.push(`default: ${JSON.stringify(node.default)}`);\n\tif (Array.isArray(node.enum))\n\t\tattrs.push(`one of: ${node.enum.map((v) => String(v)).join(\" | \")}`);\n\tif (typeof node.format === \"string\") attrs.push(`format: ${node.format}`);\n\tconst hint = constraintHint(node);\n\tif (hint) attrs.push(hint);\n\treturn attrs.join(\", \");\n};\n","import { asSchemaNode, type JsonSchemaNode } from \"../input-envelope\";\n\n// JSON Schema `type` may be a string (\"number\") or an array ([\"string\",\"null\"]).\n// Return the first concrete, non-null type.\nexport const schemaType = (node: JsonSchemaNode | null): string | undefined => {\n\tconst t = node?.type;\n\tif (typeof t === \"string\") return t;\n\tif (Array.isArray(t)) {\n\t\tconst first = t.find((x) => typeof x === \"string\" && x !== \"null\");\n\t\treturn typeof first === \"string\" ? first : undefined;\n\t}\n\treturn undefined;\n};\n\n// Coerce a stored example/default to its declared schema type. Some capabilities\n// store typed examples as strings (e.g. boolean `suggest` as \"false\"); without\n// this an agent copies the over-quoted value verbatim and gets a charged HTTP 400.\nexport const coerceToType = (\n\tvalue: unknown,\n\ttype: string | undefined,\n): unknown => {\n\tif (typeof value !== \"string\") return value;\n\tif (type === \"number\" || type === \"integer\") {\n\t\tconst n = Number(value);\n\t\treturn value.trim() !== \"\" && Number.isFinite(n) ? n : value;\n\t}\n\tif (type === \"boolean\") {\n\t\tif (value === \"true\") return true;\n\t\tif (value === \"false\") return false;\n\t}\n\treturn value;\n};\n\nconst MAX_SCHEMA_DEPTH = 5;\n\n// Build a correctly-typed sample value for a field. Prefers const → example/default\n// → first enum option → per-type placeholder. Recurses into nested objects/arrays.\n// Used to render \"Try it:\" request bodies so JSON.stringify emits numbers/booleans\n// unquoted, avoiding the charged HTTP 400s caused by over-quoted values (ZERO-339).\nexport const sampleValueFor = (\n\tfieldName: string,\n\tpropSchema: unknown,\n\tdepth = 0,\n): unknown => {\n\tconst node = asSchemaNode(propSchema);\n\tconst type = schemaType(node);\n\tconst enumFirst =\n\t\tArray.isArray(node?.enum) && node.enum.length > 0\n\t\t\t? node.enum[0]\n\t\t\t: undefined;\n\tconst fixed = node?.const ?? node?.example ?? node?.default ?? enumFirst;\n\tif (fixed !== undefined && fixed !== null) {\n\t\treturn coerceToType(fixed, type);\n\t}\n\tif (node && depth < MAX_SCHEMA_DEPTH) {\n\t\tconst props = asSchemaNode(node.properties);\n\t\tif (props && (type === \"object\" || type === undefined)) {\n\t\t\tconst obj: Record<string, unknown> = {};\n\t\t\tfor (const [k, sub] of Object.entries(props)) {\n\t\t\t\tobj[k] = sampleValueFor(k, sub, depth + 1);\n\t\t\t}\n\t\t\treturn obj;\n\t\t}\n\t\tif (type === \"array\") {\n\t\t\tconst items = asSchemaNode(node.items);\n\t\t\treturn items ? [sampleValueFor(fieldName, items, depth + 1)] : [];\n\t\t}\n\t}\n\tswitch (type) {\n\t\tcase \"number\":\n\t\tcase \"integer\":\n\t\t\treturn 0;\n\t\tcase \"boolean\":\n\t\t\treturn false;\n\t\tcase \"array\":\n\t\t\treturn [];\n\t\tcase \"object\":\n\t\t\treturn {};\n\t\tdefault:\n\t\t\treturn `<${fieldName.toUpperCase()}>`;\n\t}\n};\n\n// String form for URL query params, which are always strings on the wire.\nexport const placeholderFor = (\n\tfieldName: string,\n\tpropSchema: unknown,\n): string => String(sampleValueFor(fieldName, propSchema));\n","/**\n * Match a fetched URL against a urlTemplate like `/users/{handle}`.\n * `{name}` placeholders match a single non-`/` segment. Everything else is\n * regex-escaped so dots in hosts can't act as wildcards. Mirrors the\n * server-side `templateToRegex` in capability-service.ts so CLI and SDK\n * consumers agree on what counts as a match.\n */\nexport const urlMatchesTemplate = (url: string, template: string): boolean => {\n\tconst escaped = template.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\tconst withCaptures = escaped.replace(/\\\\\\{[^/\\\\}]+\\\\\\}/g, \"[^/]+\");\n\treturn new RegExp(`^${withCaptures}$`).test(url);\n};\n"]}
package/dist/testing.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkO7QJMY3Y_cjs = require('./chunk-O7QJMY3Y.cjs');
3
+ var chunkHKF4TRC6_cjs = require('./chunk-HKF4TRC6.cjs');
4
4
 
5
5
  // src/testing/index.ts
6
6
  var FALLBACK_HANDLER = (request) => {
@@ -34,7 +34,7 @@ var respondJson = (body, init) => new Response(JSON.stringify(body), {
34
34
  });
35
35
  var createTestClient = (opts = {}) => {
36
36
  const { routes, ...rest } = opts;
37
- return new chunkO7QJMY3Y_cjs.ZeroClient({
37
+ return new chunkHKF4TRC6_cjs.ZeroClient({
38
38
  ...rest,
39
39
  baseUrl: rest.baseUrl ?? "http://test.zero.local",
40
40
  // Tests should fail fast, not retry-and-mask flakiness.
@@ -1,4 +1,4 @@
1
- import { G as ClientOptions, Z as ZeroClient } from './client-Du4zQHef.cjs';
1
+ import { Q as ClientOptions, Z as ZeroClient } from './client-DKbrAo9Z.cjs';
2
2
  import 'viem';
3
3
  import 'zod';
4
4
 
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { G as ClientOptions, Z as ZeroClient } from './client-Du4zQHef.js';
1
+ import { Q as ClientOptions, Z as ZeroClient } from './client-DKbrAo9Z.js';
2
2
  import 'viem';
3
3
  import 'zod';
4
4
 
package/dist/testing.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ZeroClient } from './chunk-T6JT5NV5.js';
1
+ import { ZeroClient } from './chunk-T77VVLOM.js';
2
2
 
3
3
  // src/testing/index.ts
4
4
  var FALLBACK_HANDLER = (request) => {