@pliuz/sdk 0.1.0 → 0.2.1

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.
@@ -3,7 +3,7 @@ import { createHash } from 'crypto';
3
3
  // src/gated.ts
4
4
 
5
5
  // src/version.ts
6
- var VERSION = "0.1.0";
6
+ var VERSION = "0.2.1";
7
7
 
8
8
  // src/errors.ts
9
9
  var PliuzError = class extends Error {
@@ -132,6 +132,19 @@ var PliuzApprovalTimeoutError = class extends PliuzError {
132
132
  approvalId;
133
133
  timeoutMs;
134
134
  };
135
+ var PliuzEditNotApplicableError = class extends PliuzError {
136
+ constructor(approvalId, finalArgs) {
137
+ super(
138
+ `approval ${approvalId} was approved with edited args, but they cannot be mapped back to the wrapped function (custom toolArgs mapper without applyFinalArgs, or incompatible shape) \u2014 refusing to execute the original (unapproved) args. Apply e.finalArgs manually.`
139
+ );
140
+ this.approvalId = approvalId;
141
+ this.finalArgs = finalArgs;
142
+ this.name = "PliuzEditNotApplicableError";
143
+ Object.setPrototypeOf(this, new.target.prototype);
144
+ }
145
+ approvalId;
146
+ finalArgs;
147
+ };
135
148
  var STATUS_TO_ERROR = {
136
149
  400: PliuzValidationError,
137
150
  401: PliuzAuthError,
@@ -238,7 +251,7 @@ async function request(opts) {
238
251
  }
239
252
 
240
253
  // src/client.ts
241
- var DEFAULT_BASE_URL = "https://pliuz-dev.vercel.app";
254
+ var DEFAULT_BASE_URL = "https://pliuz.com";
242
255
  var DEFAULT_TIMEOUT_MS = 3e4;
243
256
  var DEFAULT_MAX_RETRIES = 3;
244
257
  var ENV_API_KEY = "PLIUZ_API_KEY";
@@ -435,7 +448,7 @@ function gated(options, fn) {
435
448
  const activeClient = options.client ?? new PliuzClient();
436
449
  const rawArgs = toolArgsMapper(...args);
437
450
  const sendArgs = redactPaths && redactPaths.length > 0 ? applyRedaction(rawArgs, redactPaths) : rawArgs;
438
- const idempotencyKey = idempotencyKeyFor(toolName, sendArgs, options.sessionId);
451
+ const idempotencyKey = idempotencyKeyFor(toolName, rawArgs, options.sessionId);
439
452
  const metadata = {};
440
453
  if (options.policy) metadata.policy = options.policy;
441
454
  const response = await activeClient.createApproval({
@@ -454,6 +467,7 @@ function gated(options, fn) {
454
467
  if (TERMINAL_EXPIRED.has(response.status)) {
455
468
  throw new PliuzApprovalExpiredError(approvalId);
456
469
  }
470
+ let approval = null;
457
471
  if (!TERMINAL_OK.has(response.status)) {
458
472
  const deadline = Date.now() + timeoutMs;
459
473
  while (true) {
@@ -461,20 +475,27 @@ function gated(options, fn) {
461
475
  throw new PliuzApprovalTimeoutError(approvalId, timeoutMs);
462
476
  }
463
477
  await sleep2(pollIntervalMs);
464
- const approval = await activeClient.getApproval(approvalId);
478
+ approval = await activeClient.getApproval(approvalId);
465
479
  if (terminalOrThrow(approval)) break;
466
480
  }
481
+ } else if (response.is_replay) {
482
+ approval = await activeClient.getApproval(approvalId);
483
+ }
484
+ let callArgs = args;
485
+ const finalArgs = approval?.final_args ?? null;
486
+ if (finalArgs) {
487
+ callArgs = resolveEditedArgs(approvalId, rawArgs, finalArgs, args, options);
467
488
  }
468
489
  const started = Date.now();
469
490
  try {
470
- const result = await fn(...args);
491
+ const result = await fn(...callArgs);
471
492
  const latencyMs = Date.now() - started;
472
- void safeReport(activeClient, approvalId, "success", null, latencyMs, result);
493
+ await safeReport(activeClient, approvalId, "success", null, latencyMs, result, redactPaths);
473
494
  return result;
474
495
  } catch (e) {
475
496
  const latencyMs = Date.now() - started;
476
497
  const errMsg = e instanceof Error ? e.message : String(e);
477
- void safeReport(activeClient, approvalId, "error", errMsg.slice(0, 2e3), latencyMs, null);
498
+ await safeReport(activeClient, approvalId, "error", errMsg.slice(0, 2e3), latencyMs, null, redactPaths);
478
499
  throw e;
479
500
  }
480
501
  };
@@ -498,6 +519,30 @@ function canonicalJSON(value) {
498
519
  const keys = Object.keys(obj).sort();
499
520
  return "{" + keys.map((k) => JSON.stringify(k) + ":" + canonicalJSON(obj[k])).join(",") + "}";
500
521
  }
522
+ function mergeFinalArgs(raw, final) {
523
+ if (isPlainRecord(raw) && isPlainRecord(final)) {
524
+ const out = {};
525
+ for (const [k, v] of Object.entries(final)) {
526
+ out[k] = k in raw ? mergeFinalArgs(raw[k], v) : v;
527
+ }
528
+ return out;
529
+ }
530
+ if (final === REDACTED_PLACEHOLDER) return raw;
531
+ return final;
532
+ }
533
+ function isPlainRecord(v) {
534
+ return typeof v === "object" && v !== null && !Array.isArray(v);
535
+ }
536
+ function resolveEditedArgs(approvalId, rawArgs, finalArgs, originalArgs, options) {
537
+ const merged = mergeFinalArgs(rawArgs, finalArgs);
538
+ if (options.applyFinalArgs) {
539
+ return options.applyFinalArgs(merged, originalArgs);
540
+ }
541
+ if (options.toolArgs === void 0 && Array.isArray(merged.args)) {
542
+ return merged.args;
543
+ }
544
+ throw new PliuzEditNotApplicableError(approvalId, merged);
545
+ }
501
546
  function terminalOrThrow(approval) {
502
547
  if (TERMINAL_OK.has(approval.status)) return true;
503
548
  if (TERMINAL_REJECT.has(approval.status)) {
@@ -508,13 +553,14 @@ function terminalOrThrow(approval) {
508
553
  }
509
554
  return false;
510
555
  }
511
- async function safeReport(client, approvalId, status, errorMessage, latencyMs, result) {
556
+ async function safeReport(client, approvalId, status, errorMessage, latencyMs, result, redactPaths) {
512
557
  let excerpt = null;
513
558
  if (result != null) {
559
+ const toDump = redactPaths && redactPaths.length > 0 && isPlainRecord(result) ? applyRedaction(result, redactPaths) : result;
514
560
  try {
515
- excerpt = JSON.stringify(result).slice(0, 2e3);
561
+ excerpt = JSON.stringify(toDump).slice(0, 2e3);
516
562
  } catch {
517
- excerpt = String(result).slice(0, 2e3);
563
+ excerpt = String(toDump).slice(0, 2e3);
518
564
  }
519
565
  }
520
566
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/version.ts","../../src/errors.ts","../../src/_http.ts","../../src/client.ts","../../src/redaction.ts","../../src/gated.ts","../../src/adapters/ai.ts"],"names":["sleep","isPlainObject"],"mappings":"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","file":"ai.js","sourcesContent":["/**\n * Single source of truth for the package version.\n * Kept in sync with `package.json` by release tooling at publish time.\n */\nexport const VERSION = '0.1.0' as const\n","/**\n * Error hierarchy for the Pliuz SDK.\n *\n * All exceptions extend `PliuzError`. HTTP-level failures use `PliuzApiError`\n * subclasses keyed by status code, so callers can do narrow `instanceof` checks:\n *\n * ```ts\n * try {\n * await pliuz.createApproval(...)\n * } catch (e) {\n * if (e instanceof PliuzAuthError) {\n * // refresh API key\n * } else if (e instanceof PliuzPolicyError) {\n * // no policy matched — define a catch-all\n * } else if (e instanceof PliuzApiError) {\n * // other 4xx/5xx\n * }\n * throw e\n * }\n * ```\n */\n\nexport class PliuzError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzError'\n // Maintain proper prototype chain for `instanceof` after transpile (CJS target)\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNetworkError extends PliuzError {\n constructor(message: string, public override readonly cause?: unknown) {\n super(message)\n this.name = 'PliuzNetworkError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzTimeoutError extends PliuzError {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApiError extends PliuzError {\n constructor(\n public readonly statusCode: number,\n public readonly errorCode: string,\n message: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'PliuzApiError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzValidationError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzValidationError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzAuthError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzAuthError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzForbiddenError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzForbiddenError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNotFoundError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzNotFoundError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzConflictError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzConflictError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzPolicyError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzPolicyError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzRateLimitError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzRateLimitError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzServerError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzServerError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n// ---------------------------------------------------------------------------\n// gated() lifecycle errors — raised by the wrapper, NOT by direct client calls.\n// ---------------------------------------------------------------------------\n\nexport class PliuzRejectedError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly reason: string | null) {\n const msg = reason\n ? `approval ${approvalId} was rejected: ${reason}`\n : `approval ${approvalId} was rejected`\n super(msg)\n this.name = 'PliuzRejectedError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalExpiredError extends PliuzError {\n constructor(public readonly approvalId: string) {\n super(`approval ${approvalId} expired before a human decided`)\n this.name = 'PliuzApprovalExpiredError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalTimeoutError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly timeoutMs: number) {\n super(\n `approval ${approvalId} did not resolve within ${timeoutMs}ms ` +\n '(SDK polling timeout — approval may still be pending server-side)',\n )\n this.name = 'PliuzApprovalTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nconst STATUS_TO_ERROR: Record<number, new (s: number, c: string, m: string, d?: Record<string, unknown>) => PliuzApiError> = {\n 400: PliuzValidationError,\n 401: PliuzAuthError,\n 403: PliuzForbiddenError,\n 404: PliuzNotFoundError,\n 409: PliuzConflictError,\n 422: PliuzPolicyError,\n 429: PliuzRateLimitError,\n}\n\nexport function errorForStatus(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n): PliuzApiError {\n if (statusCode >= 500 && statusCode < 600) {\n return new PliuzServerError(statusCode, errorCode, message, details)\n }\n const Cls = STATUS_TO_ERROR[statusCode] ?? PliuzApiError\n return new Cls(statusCode, errorCode, message, details)\n}\n","/**\n * Internal HTTP layer — shared by PliuzClient.\n *\n * Centralizes: header injection, error mapping, exponential-backoff retries\n * for idempotent operations, and JSON parsing.\n *\n * NOT public API — only `PliuzClient` should import from here.\n */\n\nimport { VERSION } from './version.js'\nimport type { ApiErrorBody } from './types.js'\nimport {\n PliuzApiError,\n PliuzNetworkError,\n PliuzTimeoutError,\n errorForStatus,\n} from './errors.js'\n\n// HTTP methods safe to retry without risking duplicate side-effects.\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'])\n\n// Retry-able status codes — server hiccups, NOT client errors.\nconst RETRYABLE_STATUS = new Set([408, 429, 500, 502, 503, 504])\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n url: string\n apiKey: string\n body?: Record<string, unknown> | null\n timeoutMs: number\n maxRetries: number\n retryOnPost?: boolean\n fetchImpl: typeof fetch\n}\n\nfunction userAgent(): string {\n return `pliuz-typescript/${VERSION}`\n}\n\nfunction buildHeaders(apiKey: string): Record<string, string> {\n return {\n 'X-Pliuz-Api-Key': apiKey,\n 'User-Agent': userAgent(),\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n }\n}\n\nfunction backoffMs(attempt: number, baseMs = 500, capMs = 8000): number {\n // Exponential with full jitter (AWS architecture blog formula).\n const expo = Math.min(capMs, baseMs * 2 ** (attempt - 1))\n return Math.floor(Math.random() * expo)\n}\n\nfunction isRetryable(method: string, status: number, retryOnPost: boolean): boolean {\n if (!RETRYABLE_STATUS.has(status)) return false\n if (IDEMPOTENT_METHODS.has(method)) return true\n if (method === 'POST' && retryOnPost) return true\n return false\n}\n\nasync function parseError(response: Response): Promise<PliuzApiError> {\n let body: Partial<ApiErrorBody> = {}\n try {\n body = (await response.json()) as Partial<ApiErrorBody>\n } catch {\n /* non-JSON body — fall through with empty */\n }\n const errorCode = body.error ?? 'unknown_error'\n const message = body.message ?? response.statusText ?? 'Pliuz API error'\n const details = body.details\n return errorForStatus(response.status, errorCode, message, details)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport async function request<T>(opts: RequestOptions): Promise<T> {\n const { method, url, apiKey, body, timeoutMs, maxRetries, retryOnPost = false, fetchImpl } = opts\n const headers = buildHeaders(apiKey)\n\n let lastError: Error | null = null\n\n for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n\n let response: Response\n try {\n response = await fetchImpl(url, {\n method,\n headers,\n body: body == null ? undefined : JSON.stringify(body),\n signal: controller.signal,\n })\n } catch (e) {\n clearTimeout(timer)\n const isTimeout =\n e instanceof Error &&\n (e.name === 'AbortError' || /abort|timeout/i.test(e.message))\n lastError = isTimeout\n ? new PliuzTimeoutError(`Pliuz request timed out after ${timeoutMs}ms`)\n : new PliuzNetworkError(\n `Pliuz network error: ${e instanceof Error ? e.message : String(e)}`,\n e,\n )\n if (attempt > maxRetries) throw lastError\n await sleep(backoffMs(attempt))\n continue\n }\n clearTimeout(timer)\n\n if (response.status >= 200 && response.status < 300) {\n try {\n return (await response.json()) as T\n } catch (e) {\n throw new PliuzApiError(\n response.status,\n 'invalid_json',\n `Pliuz returned non-JSON 2xx body: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n }\n\n if (isRetryable(method, response.status, retryOnPost)) {\n if (attempt > maxRetries) {\n throw await parseError(response)\n }\n await sleep(backoffMs(attempt))\n continue\n }\n\n throw await parseError(response)\n }\n\n // Unreachable — the loop always returns or throws.\n throw lastError ?? new PliuzApiError(0, 'exhausted', 'retry loop exhausted unexpectedly')\n}\n","/**\n * PliuzClient — the SDK entry point.\n *\n * Reads PLIUZ_API_KEY env var by default (Node only). Apply redaction\n * client-side via `applyRedaction` before passing tool_args; the client\n * does NOT redact for you (separation of concerns — the `gated()` wrapper\n * in Fase 7 will wire them together).\n *\n * @example\n * import { PliuzClient, applyRedaction } from '@pliuz/sdk'\n *\n * const pliuz = new PliuzClient() // reads PLIUZ_API_KEY\n *\n * const response = await pliuz.createApproval({\n * tool_name: 'issue_refund',\n * tool_args: applyRedaction(\n * { customer: { ssn: '...', id: 'cus_123' }, amount_cents: 5000 },\n * ['customer.ssn'],\n * ),\n * idempotency_key: 'refund-cus_123-2026-05-21-001',\n * })\n */\n\nimport { request } from './_http.js'\nimport type {\n ApprovalRequest,\n CreateApprovalInput,\n CreateApprovalResponse,\n ExecutionInput,\n ExecutionResult,\n} from './types.js'\n\nexport const DEFAULT_BASE_URL = 'https://pliuz-dev.vercel.app'\nexport const DEFAULT_TIMEOUT_MS = 30_000\nexport const DEFAULT_MAX_RETRIES = 3\nexport const ENV_API_KEY = 'PLIUZ_API_KEY'\nexport const ENV_BASE_URL = 'PLIUZ_BASE_URL'\n\nexport interface PliuzClientOptions {\n /**\n * Pliuz API key (per-agent). Defaults to `process.env.PLIUZ_API_KEY`.\n * NEVER hardcode in source — read from env or a secrets manager.\n */\n apiKey?: string\n\n /**\n * Base URL (no trailing slash). Defaults to `process.env.PLIUZ_BASE_URL`\n * or `https://pliuz-dev.vercel.app`.\n */\n baseUrl?: string\n\n /** Per-request timeout in milliseconds. Default: 30 000. */\n timeoutMs?: number\n\n /** Max retries for transient failures (network / 5xx / 429). Default: 3. */\n maxRetries?: number\n\n /**\n * Custom fetch implementation. Defaults to global `fetch` (Node ≥18).\n * Use for testing (MSW, vitest-fetch-mock) or to inject proxy/keepalive.\n */\n fetch?: typeof fetch\n}\n\nfunction resolveApiKey(explicit: string | undefined): string {\n if (explicit) return explicit\n if (typeof process !== 'undefined' && process.env?.[ENV_API_KEY]) {\n return process.env[ENV_API_KEY]\n }\n throw new Error(`Pliuz API key not provided. Pass apiKey or set $${ENV_API_KEY}.`)\n}\n\nfunction resolveBaseUrl(explicit: string | undefined): string {\n if (explicit) return explicit.replace(/\\/+$/, '')\n if (typeof process !== 'undefined' && process.env?.[ENV_BASE_URL]) {\n return process.env[ENV_BASE_URL].replace(/\\/+$/, '')\n }\n return DEFAULT_BASE_URL\n}\n\nfunction approvalUrl(baseUrl: string, approvalId?: string, suffix?: string): string {\n let path = '/api/v1/approvals'\n if (approvalId) path += `/${encodeURIComponent(approvalId)}`\n if (suffix) path += `/${suffix}`\n return baseUrl + path\n}\n\nexport class PliuzClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PliuzClientOptions = {}) {\n this.apiKey = resolveApiKey(options.apiKey)\n this.baseUrl = resolveBaseUrl(options.baseUrl)\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n\n const fetchImpl = options.fetch ?? globalThis.fetch\n if (!fetchImpl) {\n throw new Error(\n 'No fetch implementation available. Pliuz requires Node ≥18 or a polyfill.',\n )\n }\n this.fetchImpl = fetchImpl\n }\n\n /**\n * Create (or idempotently replay) an approval request.\n *\n * With `idempotency_key`, the call retries on network failure without\n * risk of duplicates (backend dedupes within 24h).\n */\n async createApproval(input: CreateApprovalInput): Promise<CreateApprovalResponse> {\n const body = {\n tool_name: input.tool_name,\n tool_args: input.tool_args,\n context_messages: input.context_messages ?? null,\n originator: input.originator ?? { type: 'system' },\n session_id: input.session_id ?? null,\n client_metadata: input.client_metadata ?? null,\n idempotency_key: input.idempotency_key ?? null,\n }\n return request<CreateApprovalResponse>({\n method: 'POST',\n url: approvalUrl(this.baseUrl),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: Boolean(input.idempotency_key),\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Fetch the current state of an approval request.\n * Used by polling in `gated()` to detect status transitions.\n */\n async getApproval(approvalId: string): Promise<ApprovalRequest> {\n return request<ApprovalRequest>({\n method: 'GET',\n url: approvalUrl(this.baseUrl, approvalId),\n apiKey: this.apiKey,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Close the audit loop by reporting the outcome of the gated action.\n *\n * Single-shot: a second call returns 409 (PliuzConflictError).\n * Only the originating agent can report — others get 403 (PliuzForbiddenError).\n */\n async reportExecution(\n approvalId: string,\n input: ExecutionInput,\n ): Promise<ExecutionResult> {\n const body = {\n status: input.status,\n error: input.error ?? null,\n latency_ms: input.latency_ms ?? null,\n target_response_excerpt: input.target_response_excerpt ?? null,\n }\n return request<ExecutionResult>({\n method: 'POST',\n url: approvalUrl(this.baseUrl, approvalId, 'execution'),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: false,\n fetchImpl: this.fetchImpl,\n })\n }\n}\n","/**\n * Field-level redaction applied client-side BEFORE sending to Pliuz.\n *\n * Non-negotiable architectural decision: sensitive fields (PII, secrets, PHI)\n * must never leave the caller's process in plaintext. The SDK applies\n * redaction on the client side, transmits the redacted payload, and the\n * backend never sees the raw values.\n *\n * ## Path syntax\n *\n * \"customer.ssn\" → payload.customer.ssn\n * \"items[*].card_number\" → every item's card_number\n * \"headers.authorization\" → payload.headers.authorization\n *\n * Limitations (intentional — keep the surface tiny):\n * - No JSONPath wildcards beyond `[*]`\n * - No filter expressions\n * - Missing keys are silently ignored\n */\n\nexport const REDACTED_PLACEHOLDER = '<redacted>' as const\n\ntype PathSegment = { key: string; isArrayWildcard: boolean }\n\n/**\n * Returns a deep copy of `payload` with values at `paths` replaced by\n * `REDACTED_PLACEHOLDER`. Does not mutate the input.\n *\n * @example\n * applyRedaction({ customer: { ssn: '123-45-6789' } }, ['customer.ssn'])\n * // → { customer: { ssn: '<redacted>' } }\n */\nexport function applyRedaction<T extends Record<string, unknown>>(\n payload: T,\n paths: readonly string[] | null | undefined,\n): T {\n if (!paths || paths.length === 0) {\n return deepClone(payload)\n }\n const result = deepClone(payload)\n for (const path of paths) {\n redactPath(result as Record<string, unknown>, parsePath(path))\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\nfunction parsePath(path: string): PathSegment[] {\n if (!path) {\n throw new Error('redaction path cannot be empty')\n }\n\n const segments: PathSegment[] = []\n for (const raw of path.split('.')) {\n if (raw.endsWith('[*]')) {\n const key = raw.slice(0, -3)\n if (!key) {\n throw new Error(`redaction path segment before [*] cannot be empty: ${path}`)\n }\n segments.push({ key, isArrayWildcard: true })\n } else if (raw.includes('[') || raw.includes(']')) {\n throw new Error(`unsupported redaction syntax in '${path}' — only [*] is allowed`)\n } else {\n if (!raw) {\n throw new Error(`redaction path has empty segment: ${path}`)\n }\n segments.push({ key: raw, isArrayWildcard: false })\n }\n }\n return segments\n}\n\nfunction redactPath(node: unknown, segments: PathSegment[]): void {\n if (segments.length === 0) return\n if (!isPlainObject(node)) return\n\n const [head, ...rest] = segments\n if (!head) return\n const { key, isArrayWildcard } = head\n if (!(key in node)) return\n\n if (isArrayWildcard) {\n const target = node[key]\n if (!Array.isArray(target)) return\n if (rest.length === 0) {\n node[key] = target.map(() => REDACTED_PLACEHOLDER)\n return\n }\n for (const item of target) {\n redactPath(item, rest)\n }\n } else {\n if (rest.length === 0) {\n node[key] = REDACTED_PLACEHOLDER\n } else {\n redactPath(node[key], rest)\n }\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\nfunction deepClone<T>(v: T): T {\n // Prefer structuredClone when available (Node 17+). Falls back to JSON\n // for environments without it (e.g. some bundler test setups).\n if (typeof structuredClone === 'function') {\n return structuredClone(v)\n }\n return JSON.parse(JSON.stringify(v)) as T\n}\n","/**\n * The `gated()` wrapper — the headline API of the Pliuz TypeScript SDK.\n *\n * Wraps any function (sync or async) so every call is gated by a Pliuz\n * approval request. The wrapped function always returns `Promise<TResult>`\n * even if the original is synchronous — gating is inherently async because\n * it involves an HTTP call.\n *\n * @example\n * import { gated } from '@pliuz/sdk'\n *\n * const issueRefund = gated(\n * {\n * policy: 'refund',\n * redact: ['customer.ssn'],\n * toolArgs: (customerId: string, amountCents: number) => ({\n * customer_id: customerId,\n * amount_cents: amountCents,\n * }),\n * },\n * async (customerId, amountCents) => stripe.refund(customerId, amountCents),\n * )\n *\n * const result = await issueRefund('cus_123', 5000)\n */\n\nimport { createHash } from 'node:crypto'\n\nimport { PliuzClient } from './client.js'\nimport {\n PliuzApprovalExpiredError,\n PliuzApprovalTimeoutError,\n PliuzRejectedError,\n} from './errors.js'\nimport { applyRedaction } from './redaction.js'\nimport type {\n ApprovalRequest,\n ExecutionStatus,\n Originator,\n} from './types.js'\n\nexport const DEFAULT_GATED_TIMEOUT_MS = 300_000 // 5 min — matches Pliuz default SLA\nexport const DEFAULT_GATED_POLL_INTERVAL_MS = 2000\n\nexport interface GatedOptions<TArgs extends readonly unknown[]> {\n /** Policy slug to bind this gate to. Default: backend resolves by toolName. */\n policy?: string\n\n /** Redaction paths applied to tool_args BEFORE sending. */\n redact?: readonly string[]\n\n /** Override the tool name. Default: `fn.name` (may be empty for anonymous). */\n toolName?: string\n\n /**\n * Map the wrapped function's args into a tool_args object.\n * Default: `(...args) => ({ args })` — wraps all positional args under\n * a single `args` key. Provide a custom mapper for cleaner audit trails.\n */\n toolArgs?: (...args: TArgs) => Record<string, unknown>\n\n /** Max ms to poll for the approval to resolve. Throws on timeout. */\n timeoutMs?: number\n\n /** Ms between GET /approvals/:id polls. */\n pollIntervalMs?: number\n\n /** Reuse an existing PliuzClient. Default: `new PliuzClient()`. */\n client?: PliuzClient\n\n /** Optional context for the human approver. */\n contextMessages?: readonly string[]\n\n /** Optional session id (groups related approvals in the UI). */\n sessionId?: string\n\n /** Optional originator (default: { type: 'system' }). */\n originator?: Originator\n}\n\nconst TERMINAL_OK = new Set<string>(['approved'])\nconst TERMINAL_REJECT = new Set<string>(['rejected'])\nconst TERMINAL_EXPIRED = new Set<string>(['expired'])\n\n/**\n * Wrap a function so every call is gated by Pliuz.\n *\n * The returned function ALWAYS returns a Promise, even if the input is sync.\n * This is intentional — gating necessarily involves async HTTP calls.\n */\nexport function gated<TArgs extends readonly unknown[], TResult>(\n options: GatedOptions<TArgs>,\n fn: (...args: TArgs) => Promise<TResult> | TResult,\n): (...args: TArgs) => Promise<TResult> {\n const toolName = options.toolName ?? (fn.name || 'anonymous')\n const toolArgsMapper =\n options.toolArgs ??\n ((...args: TArgs): Record<string, unknown> => ({ args: args as unknown as unknown[] }))\n const timeoutMs = options.timeoutMs ?? DEFAULT_GATED_TIMEOUT_MS\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_GATED_POLL_INTERVAL_MS\n const redactPaths = options.redact\n\n return async (...args: TArgs): Promise<TResult> => {\n const activeClient = options.client ?? new PliuzClient()\n const rawArgs = toolArgsMapper(...args)\n const sendArgs = redactPaths && redactPaths.length > 0\n ? applyRedaction(rawArgs, redactPaths)\n : rawArgs\n const idempotencyKey = idempotencyKeyFor(toolName, sendArgs, options.sessionId)\n const metadata: Record<string, unknown> = {}\n if (options.policy) metadata.policy = options.policy\n\n const response = await activeClient.createApproval({\n tool_name: toolName,\n tool_args: sendArgs,\n context_messages: options.contextMessages ?? null,\n originator: options.originator,\n session_id: options.sessionId ?? null,\n client_metadata: Object.keys(metadata).length > 0 ? metadata : null,\n idempotency_key: idempotencyKey,\n })\n\n const approvalId = response.id\n\n if (TERMINAL_REJECT.has(response.status)) {\n throw new PliuzRejectedError(approvalId, response.message ?? null)\n }\n if (TERMINAL_EXPIRED.has(response.status)) {\n throw new PliuzApprovalExpiredError(approvalId)\n }\n\n if (!TERMINAL_OK.has(response.status)) {\n // Poll\n const deadline = Date.now() + timeoutMs\n while (true) {\n if (Date.now() >= deadline) {\n throw new PliuzApprovalTimeoutError(approvalId, timeoutMs)\n }\n await sleep(pollIntervalMs)\n const approval = await activeClient.getApproval(approvalId)\n if (terminalOrThrow(approval)) break\n }\n }\n\n // Execute + report\n const started = Date.now()\n try {\n const result = await fn(...args)\n const latencyMs = Date.now() - started\n void safeReport(activeClient, approvalId, 'success', null, latencyMs, result)\n return result\n } catch (e) {\n const latencyMs = Date.now() - started\n const errMsg = e instanceof Error ? e.message : String(e)\n void safeReport(activeClient, approvalId, 'error', errMsg.slice(0, 2000), latencyMs, null)\n throw e\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction idempotencyKeyFor(\n toolName: string,\n toolArgs: Record<string, unknown>,\n sessionId: string | undefined,\n): string {\n const payload = JSON.stringify(\n { tool: toolName, args: toolArgs, session: sessionId ?? null },\n Object.keys({ tool: 0, args: 0, session: 0 }).sort(),\n )\n // Canonicalize via sorted-key JSON stringify for deterministic hash\n const canonical = canonicalJSON({ tool: toolName, args: toolArgs, session: sessionId ?? null })\n void payload // silence unused\n return 'g_' + createHash('sha256').update(canonical).digest('hex').slice(0, 30)\n}\n\nfunction canonicalJSON(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n return JSON.stringify(value)\n }\n if (Array.isArray(value)) {\n return '[' + value.map(canonicalJSON).join(',') + ']'\n }\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return (\n '{' +\n keys.map((k) => JSON.stringify(k) + ':' + canonicalJSON(obj[k])).join(',') +\n '}'\n )\n}\n\nfunction terminalOrThrow(approval: ApprovalRequest): boolean {\n if (TERMINAL_OK.has(approval.status)) return true\n if (TERMINAL_REJECT.has(approval.status)) {\n throw new PliuzRejectedError(approval.id, approval.decision_reason)\n }\n if (TERMINAL_EXPIRED.has(approval.status)) {\n throw new PliuzApprovalExpiredError(approval.id)\n }\n return false\n}\n\nasync function safeReport(\n client: PliuzClient,\n approvalId: string,\n status: ExecutionStatus,\n errorMessage: string | null,\n latencyMs: number,\n result: unknown,\n): Promise<void> {\n let excerpt: string | null = null\n if (result != null) {\n try {\n excerpt = JSON.stringify(result).slice(0, 2000)\n } catch {\n excerpt = String(result).slice(0, 2000)\n }\n }\n try {\n await client.reportExecution(approvalId, {\n status,\n error: errorMessage,\n latency_ms: latencyMs,\n target_response_excerpt: excerpt,\n })\n } catch {\n // Intentionally swallow — if reporting fails the audit log surfaces\n // 'execution unreported' but we don't want to crash the caller's flow.\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Vercel AI SDK adapter for Pliuz.\n *\n * Wraps any Vercel AI SDK `Tool` so its `execute` is gated by a Pliuz\n * approval request. The wrapped tool preserves `description` and\n * `parameters` so the LLM sees the tool identically — only the\n * execution path is gated.\n *\n * Install requires `ai >= 4.0` as a peer dependency.\n *\n * @example\n * import { tool } from 'ai'\n * import { z } from 'zod'\n * import { gatedTool } from '@pliuz/sdk/adapters/ai'\n *\n * const issueRefund = gatedTool(\n * { policy: 'refund', redact: ['customer.ssn'] },\n * tool({\n * description: 'Issue a refund to a customer',\n * parameters: z.object({\n * customer_id: z.string(),\n * amount_cents: z.number().int().positive(),\n * }),\n * execute: async ({ customer_id, amount_cents }) => {\n * return stripe.refund(customer_id, amount_cents)\n * },\n * }),\n * )\n */\n\nimport { gated } from '../gated.js'\nimport type { PliuzClient } from '../client.js'\nimport type { Originator } from '../types.js'\n\n/**\n * Minimal structural type that matches Vercel AI SDK's `Tool<TParams, TResult>`\n * without importing `ai` (it's a peer dep — adapter must work even if absent\n * from a consumer's tsconfig). The shape mirrors the v4 contract.\n */\nexport interface AITool<TInput, TResult> {\n description?: string\n parameters: unknown\n execute?: (input: TInput, options: unknown) => Promise<TResult> | TResult\n [key: string]: unknown\n}\n\n/**\n * Options for `gatedTool`. Mirrors the relevant fields of GatedOptions\n * without the `toolArgs` / `toolName` generic-parametric pieces (the\n * adapter sets toolArgs internally to surface the Vercel-AI input dict\n * directly as the Pliuz tool_args).\n */\nexport interface GatedToolOptions {\n policy?: string\n redact?: readonly string[]\n /**\n * Override the tool name reported to Pliuz. Defaults to the tool's\n * `description` (first 64 chars) or `'ai_tool'` if neither is set.\n */\n toolName?: string\n timeoutMs?: number\n pollIntervalMs?: number\n client?: PliuzClient\n contextMessages?: readonly string[]\n sessionId?: string\n originator?: Originator\n}\n\nexport const ADAPTER_NAME = 'vercel-ai' as const\n\n/**\n * Wrap a Vercel AI SDK tool so its `execute` is gated by Pliuz.\n *\n * If the tool has no `execute` (e.g. client-side tools), this is a\n * no-op — gating only makes sense on the server side.\n */\nexport function gatedTool<TInput, TResult>(\n options: GatedToolOptions,\n tool: AITool<TInput, TResult>,\n): AITool<TInput, TResult> {\n if (typeof tool.execute !== 'function') {\n // Client-side tool — nothing to gate.\n return tool\n }\n\n const toolName =\n options.toolName ??\n (typeof tool.description === 'string' ? tool.description.slice(0, 64) : 'ai_tool')\n\n const originalExecute = tool.execute\n // We bind the Vercel AI 2-arg `(input, options)` execute into a 1-arg\n // closure for `gated()`, which infers TArgs from the wrapped fn. The\n // closure captures `options` per-call via a mutable holder.\n let pendingOptions: unknown = undefined\n\n const gatedExecute1Arg = gated(\n {\n policy: options.policy,\n redact: options.redact,\n timeoutMs: options.timeoutMs,\n pollIntervalMs: options.pollIntervalMs,\n client: options.client,\n contextMessages: options.contextMessages,\n sessionId: options.sessionId,\n originator: options.originator,\n toolName,\n // Surface the Vercel-AI input dict directly as Pliuz tool_args\n // instead of wrapping in `{ args: [input] }` for cleaner audit logs.\n toolArgs: (input: TInput) =>\n isPlainObject(input) ? input : ({ input } as Record<string, unknown>),\n },\n async (input: TInput) => originalExecute(input, pendingOptions),\n )\n\n const wrappedExecute: AITool<TInput, TResult>['execute'] = async (input, opts) => {\n pendingOptions = opts\n return gatedExecute1Arg(input)\n }\n\n return {\n ...tool,\n execute: wrappedExecute,\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n"]}
1
+ {"version":3,"sources":["../../src/version.ts","../../src/errors.ts","../../src/_http.ts","../../src/client.ts","../../src/redaction.ts","../../src/gated.ts","../../src/adapters/ai.ts"],"names":["sleep","isPlainObject"],"mappings":";;;;;AAIO,IAAM,OAAA,GAAU,OAAA;;;ACkBhB,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EACpC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AAEZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,iBAAA,GAAN,cAAgC,UAAA,CAAW;AAAA,EAChD,WAAA,CAAY,SAA0C,KAAA,EAAiB;AACrE,IAAA,KAAA,CAAM,OAAO,CAAA;AADuC,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAEpD,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAJsD,KAAA;AAKxD,CAAA;AAEO,IAAM,iBAAA,GAAN,cAAgC,UAAA,CAAW;AAAA,EAChD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,aAAA,GAAN,cAA4B,UAAA,CAAW;AAAA,EAC5C,WAAA,CACkB,UAAA,EACA,SAAA,EAChB,OAAA,EACgB,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AALG,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAEA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EARkB,UAAA;AAAA,EACA,SAAA;AAAA,EAEA,OAAA;AAMpB,CAAA;AAEO,IAAM,oBAAA,GAAN,cAAmC,aAAA,CAAc;AAAA,EACtD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,cAAA,GAAN,cAA6B,aAAA,CAAc;AAAA,EAChD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,aAAA,CAAc;AAAA,EACpD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,aAAA,CAAc;AAAA,EACpD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,aAAA,CAAc;AAAA,EAClD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,aAAA,CAAc;AAAA,EAClD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAMO,IAAM,kBAAA,GAAN,cAAiC,UAAA,CAAW;AAAA,EACjD,WAAA,CAA4B,YAAoC,MAAA,EAAuB;AACrF,IAAA,MAAM,GAAA,GAAM,SACR,CAAA,SAAA,EAAY,UAAU,kBAAkB,MAAM,CAAA,CAAA,GAC9C,YAAY,UAAU,CAAA,aAAA,CAAA;AAC1B,IAAA,KAAA,CAAM,GAAG,CAAA;AAJiB,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAoC,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAK9D,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAP4B,UAAA;AAAA,EAAoC,MAAA;AAQlE,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,UAAA,CAAW;AAAA,EACxD,YAA4B,UAAA,EAAoB;AAC9C,IAAA,KAAA,CAAM,CAAA,SAAA,EAAY,UAAU,CAAA,+BAAA,CAAiC,CAAA;AADnC,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAE1B,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAJ4B,UAAA;AAK9B,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,UAAA,CAAW;AAAA,EACxD,WAAA,CAA4B,YAAoC,SAAA,EAAmB;AACjF,IAAA,KAAA;AAAA,MACE,CAAA,SAAA,EAAY,UAAU,CAAA,wBAAA,EAA2B,SAAS,CAAA,yEAAA;AAAA,KAE5D;AAJ0B,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAoC,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAK9D,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAP4B,UAAA;AAAA,EAAoC,SAAA;AAQlE,CAAA;AAUO,IAAM,2BAAA,GAAN,cAA0C,UAAA,CAAW;AAAA,EAC1D,WAAA,CACkB,YACA,SAAA,EAChB;AACA,IAAA,KAAA;AAAA,MACE,YAAY,UAAU,CAAA,oPAAA;AAAA,KAIxB;AARgB,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAQhB,IAAA,IAAA,CAAK,IAAA,GAAO,6BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAXkB,UAAA;AAAA,EACA,SAAA;AAWpB,CAAA;AAEA,IAAM,eAAA,GAAuH;AAAA,EAC3H,GAAA,EAAK,oBAAA;AAAA,EACL,GAAA,EAAK,cAAA;AAAA,EACL,GAAA,EAAK,mBAAA;AAAA,EACL,GAAA,EAAK,kBAAA;AAAA,EACL,GAAA,EAAK,kBAAA;AAAA,EACL,GAAA,EAAK,gBAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAEO,SAAS,cAAA,CACd,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACe;AACf,EAAA,IAAI,UAAA,IAAc,GAAA,IAAO,UAAA,GAAa,GAAA,EAAK;AACzC,IAAA,OAAO,IAAI,gBAAA,CAAiB,UAAA,EAAY,SAAA,EAAW,SAAS,OAAO,CAAA;AAAA,EACrE;AACA,EAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,UAAU,CAAA,IAAK,aAAA;AAC3C,EAAA,OAAO,IAAI,GAAA,CAAI,UAAA,EAAY,SAAA,EAAW,SAAS,OAAO,CAAA;AACxD;;;AChOA,IAAM,kBAAA,uBAAyB,GAAA,CAAI,CAAC,OAAO,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,QAAQ,CAAC,CAAA;AAG9E,IAAM,gBAAA,mBAAmB,IAAI,GAAA,CAAI,CAAC,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAa/D,SAAS,SAAA,GAAoB;AAC3B,EAAA,OAAO,oBAAoB,OAAO,CAAA,CAAA;AACpC;AAEA,SAAS,aAAa,MAAA,EAAwC;AAC5D,EAAA,OAAO;AAAA,IACL,iBAAA,EAAmB,MAAA;AAAA,IACnB,cAAc,SAAA,EAAU;AAAA,IACxB,MAAA,EAAQ,kBAAA;AAAA,IACR,cAAA,EAAgB;AAAA,GAClB;AACF;AAEA,SAAS,SAAA,CAAU,OAAA,EAAiB,MAAA,GAAS,GAAA,EAAK,QAAQ,GAAA,EAAc;AAEtE,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,OAAO,MAAA,GAAS,CAAA,KAAM,UAAU,CAAA,CAAE,CAAA;AACxD,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,IAAI,CAAA;AACxC;AAEA,SAAS,WAAA,CAAY,MAAA,EAAgB,MAAA,EAAgB,WAAA,EAA+B;AAClF,EAAA,IAAI,CAAC,gBAAA,CAAiB,GAAA,CAAI,MAAM,GAAG,OAAO,KAAA;AAC1C,EAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,MAAM,CAAA,EAAG,OAAO,IAAA;AAC3C,EAAA,IAAI,MAAA,KAAW,MAAA,IAAU,WAAA,EAAa,OAAO,IAAA;AAC7C,EAAA,OAAO,KAAA;AACT;AAEA,eAAe,WAAW,QAAA,EAA4C;AACpE,EAAA,IAAI,OAA8B,EAAC;AACnC,EAAA,IAAI;AACF,IAAA,IAAA,GAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,EAC9B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,MAAM,SAAA,GAAY,KAAK,KAAA,IAAS,eAAA;AAChC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,QAAA,CAAS,UAAA,IAAc,iBAAA;AACvD,EAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AACrB,EAAA,OAAO,cAAA,CAAe,QAAA,CAAS,MAAA,EAAQ,SAAA,EAAW,SAAS,OAAO,CAAA;AACpE;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAEA,eAAsB,QAAW,IAAA,EAAkC;AACjE,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAQ,IAAA,EAAM,WAAW,UAAA,EAAY,WAAA,GAAc,KAAA,EAAO,SAAA,EAAU,GAAI,IAAA;AAC7F,EAAA,MAAM,OAAA,GAAU,aAAa,MAAM,CAAA;AAEnC,EAAA,IAAI,SAAA,GAA0B,IAAA;AAE9B,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,UAAA,GAAa,GAAG,OAAA,EAAA,EAAW;AAC1D,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAE5D,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,UAAU,GAAA,EAAK;AAAA,QAC9B,MAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAM,IAAA,IAAQ,IAAA,GAAO,KAAA,CAAA,GAAY,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,QACpD,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAAA,IACH,SAAS,CAAA,EAAG;AACV,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,MAAM,SAAA,GACJ,aAAa,KAAA,KACZ,CAAA,CAAE,SAAS,YAAA,IAAgB,gBAAA,CAAiB,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA,CAAA;AAC7D,MAAA,SAAA,GAAY,YACR,IAAI,iBAAA,CAAkB,iCAAiC,SAAS,CAAA,EAAA,CAAI,IACpE,IAAI,iBAAA;AAAA,QACF,wBAAwB,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAAA,QAClE;AAAA,OACF;AACJ,MAAA,IAAI,OAAA,GAAU,YAAY,MAAM,SAAA;AAChC,MAAA,MAAM,KAAA,CAAM,SAAA,CAAU,OAAO,CAAC,CAAA;AAC9B,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAElB,IAAA,IAAI,QAAA,CAAS,MAAA,IAAU,GAAA,IAAO,QAAA,CAAS,SAAS,GAAA,EAAK;AACnD,MAAA,IAAI;AACF,QAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,MAC9B,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,QAAA,CAAS,MAAA;AAAA,UACT,cAAA;AAAA,UACA,qCAAqC,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,SACjF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,MAAA,EAAQ,QAAA,CAAS,MAAA,EAAQ,WAAW,CAAA,EAAG;AACrD,MAAA,IAAI,UAAU,UAAA,EAAY;AACxB,QAAA,MAAM,MAAM,WAAW,QAAQ,CAAA;AAAA,MACjC;AACA,MAAA,MAAM,KAAA,CAAM,SAAA,CAAU,OAAO,CAAC,CAAA;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAM,WAAW,QAAQ,CAAA;AAAA,EACjC;AAGA,EAAA,MAAM,SAAA,IAAa,IAAI,aAAA,CAAc,CAAA,EAAG,aAAa,mCAAmC,CAAA;AAC1F;;;AC1GO,IAAM,gBAAA,GAAmB,mBAAA;AACzB,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAM,WAAA,GAAc,eAAA;AACpB,IAAM,YAAA,GAAe,gBAAA;AA4B5B,SAAS,cAAc,QAAA,EAAsC;AAC3D,EAAA,IAAI,UAAU,OAAO,QAAA;AACrB,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,GAAM,WAAW,CAAA,EAAG;AAChE,IAAA,OAAO,OAAA,CAAQ,IAAI,WAAW,CAAA;AAAA,EAChC;AACA,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gDAAA,EAAmD,WAAW,CAAA,CAAA,CAAG,CAAA;AACnF;AAEA,SAAS,eAAe,QAAA,EAAsC;AAC5D,EAAA,IAAI,QAAA,EAAU,OAAO,QAAA,CAAS,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAChD,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,GAAM,YAAY,CAAA,EAAG;AACjE,IAAA,OAAO,QAAQ,GAAA,CAAI,YAAY,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,gBAAA;AACT;AAEA,SAAS,WAAA,CAAY,OAAA,EAAiB,UAAA,EAAqB,MAAA,EAAyB;AAClF,EAAA,IAAI,IAAA,GAAO,mBAAA;AACX,EAAA,IAAI,UAAA,EAAY,IAAA,IAAQ,CAAA,CAAA,EAAI,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AAC1D,EAAA,IAAI,MAAA,EAAQ,IAAA,IAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAC9B,EAAA,OAAO,OAAA,GAAU,IAAA;AACnB;AAEO,IAAM,cAAN,MAAkB;AAAA,EACN,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EAEjB,WAAA,CAAY,OAAA,GAA8B,EAAC,EAAG;AAC5C,IAAA,IAAA,CAAK,MAAA,GAAS,aAAA,CAAc,OAAA,CAAQ,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAA,GAAU,cAAA,CAAe,OAAA,CAAQ,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,kBAAA;AACtC,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,mBAAA;AAExC,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAC9C,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,KAAA,EAA6D;AAChF,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,gBAAA,EAAkB,MAAM,gBAAA,IAAoB,IAAA;AAAA,MAC5C,UAAA,EAAY,KAAA,CAAM,UAAA,IAAc,EAAE,MAAM,QAAA,EAAS;AAAA,MACjD,UAAA,EAAY,MAAM,UAAA,IAAc,IAAA;AAAA,MAChC,eAAA,EAAiB,MAAM,eAAA,IAAmB,IAAA;AAAA,MAC1C,eAAA,EAAiB,MAAM,eAAA,IAAmB;AAAA,KAC5C;AACA,IAAA,OAAO,OAAA,CAAgC;AAAA,MACrC,MAAA,EAAQ,MAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAAA,MAC7B,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,IAAA;AAAA,MACA,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAA,EAAa,OAAA,CAAQ,KAAA,CAAM,eAAe,CAAA;AAAA,MAC1C,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,UAAA,EAA8C;AAC9D,IAAA,OAAO,OAAA,CAAyB;AAAA,MAC9B,MAAA,EAAQ,KAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAA,EAAS,UAAU,CAAA;AAAA,MACzC,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAA,CACJ,UAAA,EACA,KAAA,EAC0B;AAC1B,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,KAAA,EAAO,MAAM,KAAA,IAAS,IAAA;AAAA,MACtB,UAAA,EAAY,MAAM,UAAA,IAAc,IAAA;AAAA,MAChC,uBAAA,EAAyB,MAAM,uBAAA,IAA2B;AAAA,KAC5D;AACA,IAAA,OAAO,OAAA,CAAyB;AAAA,MAC9B,MAAA,EAAQ,MAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAA,EAAS,YAAY,WAAW,CAAA;AAAA,MACtD,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,IAAA;AAAA,MACA,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAA,EAAa,KAAA;AAAA,MACb,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AACF,CAAA;;;AC/JO,IAAM,oBAAA,GAAuB,YAAA;AAY7B,SAAS,cAAA,CACd,SACA,KAAA,EACG;AACH,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAChC,IAAA,OAAO,UAAU,OAAO,CAAA;AAAA,EAC1B;AACA,EAAA,MAAM,MAAA,GAAS,UAAU,OAAO,CAAA;AAChC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,UAAA,CAAW,MAAA,EAAmC,SAAA,CAAU,IAAI,CAAC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,UAAU,IAAA,EAA6B;AAC9C,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,WAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,EAAG;AACjC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG;AACvB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAC3B,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mDAAA,EAAsD,IAAI,CAAA,CAAE,CAAA;AAAA,MAC9E;AACA,MAAA,QAAA,CAAS,IAAA,CAAK,EAAE,GAAA,EAAK,eAAA,EAAiB,MAAM,CAAA;AAAA,IAC9C,CAAA,MAAA,IAAW,IAAI,QAAA,CAAS,GAAG,KAAK,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,EAAG;AACjD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,IAAI,CAAA,4BAAA,CAAyB,CAAA;AAAA,IACnF,CAAA,MAAO;AACL,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAE,CAAA;AAAA,MAC7D;AACA,MAAA,QAAA,CAAS,KAAK,EAAE,GAAA,EAAK,GAAA,EAAK,eAAA,EAAiB,OAAO,CAAA;AAAA,IACpD;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,UAAA,CAAW,MAAe,QAAA,EAA+B;AAChE,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAC3B,EAAA,IAAI,CAAC,aAAA,CAAc,IAAI,CAAA,EAAG;AAE1B,EAAA,MAAM,CAAC,IAAA,EAAM,GAAG,IAAI,CAAA,GAAI,QAAA;AACxB,EAAA,IAAI,CAAC,IAAA,EAAM;AACX,EAAA,MAAM,EAAE,GAAA,EAAK,eAAA,EAAgB,GAAI,IAAA;AACjC,EAAA,IAAI,EAAE,OAAO,IAAA,CAAA,EAAO;AAEpB,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,MAAM,MAAA,GAAS,KAAK,GAAG,CAAA;AACvB,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC5B,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,MAAM,oBAAoB,CAAA;AACjD,MAAA;AAAA,IACF;AACA,IAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,MAAA,UAAA,CAAW,MAAM,IAAI,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,MAAO;AACL,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,oBAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,EAAG,IAAI,CAAA;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,SAAS,cAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAEA,SAAS,UAAa,CAAA,EAAS;AAG7B,EAAA,IAAI,OAAO,oBAAoB,UAAA,EAAY;AACzC,IAAA,OAAO,gBAAgB,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA;AACrC;;;ACxEO,IAAM,wBAAA,GAA2B,GAAA;AACjC,IAAM,8BAAA,GAAiC,GAAA;AA+C9C,IAAM,WAAA,mBAAc,IAAI,GAAA,CAAY,CAAC,UAAU,CAAC,CAAA;AAChD,IAAM,eAAA,mBAAkB,IAAI,GAAA,CAAY,CAAC,UAAU,CAAC,CAAA;AACpD,IAAM,gBAAA,mBAAmB,IAAI,GAAA,CAAY,CAAC,SAAS,CAAC,CAAA;AAQ7C,SAAS,KAAA,CACd,SACA,EAAA,EACsC;AACtC,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,KAAa,EAAA,CAAG,IAAA,IAAQ,WAAA,CAAA;AACjD,EAAA,MAAM,iBACJ,OAAA,CAAQ,QAAA,KACP,CAAA,GAAI,IAAA,MAA0C,EAAE,IAAA,EAAmC,CAAA,CAAA;AACtF,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,wBAAA;AACvC,EAAA,MAAM,cAAA,GAAiB,QAAQ,cAAA,IAAkB,8BAAA;AACjD,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA;AAE5B,EAAA,OAAO,UAAU,IAAA,KAAkC;AACjD,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,MAAA,IAAU,IAAI,WAAA,EAAY;AACvD,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,GAAG,IAAI,CAAA;AACtC,IAAA,MAAM,QAAA,GAAW,eAAe,WAAA,CAAY,MAAA,GAAS,IACjD,cAAA,CAAe,OAAA,EAAS,WAAW,CAAA,GACnC,OAAA;AAKJ,IAAA,MAAM,cAAA,GAAiB,iBAAA,CAAkB,QAAA,EAAU,OAAA,EAAS,QAAQ,SAAS,CAAA;AAC7E,IAAA,MAAM,WAAoC,EAAC;AAC3C,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,QAAA,CAAS,MAAA,GAAS,OAAA,CAAQ,MAAA;AAE9C,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,cAAA,CAAe;AAAA,MACjD,SAAA,EAAW,QAAA;AAAA,MACX,SAAA,EAAW,QAAA;AAAA,MACX,gBAAA,EAAkB,QAAQ,eAAA,IAAmB,IAAA;AAAA,MAC7C,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,UAAA,EAAY,QAAQ,SAAA,IAAa,IAAA;AAAA,MACjC,iBAAiB,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAE,MAAA,GAAS,IAAI,QAAA,GAAW,IAAA;AAAA,MAC/D,eAAA,EAAiB;AAAA,KAClB,CAAA;AAED,IAAA,MAAM,aAAa,QAAA,CAAS,EAAA;AAE5B,IAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACxC,MAAA,MAAM,IAAI,kBAAA,CAAmB,UAAA,EAAY,QAAA,CAAS,WAAW,IAAI,CAAA;AAAA,IACnE;AACA,IAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACzC,MAAA,MAAM,IAAI,0BAA0B,UAAU,CAAA;AAAA,IAChD;AAEA,IAAA,IAAI,QAAA,GAAmC,IAAA;AACvC,IAAA,IAAI,CAAC,WAAA,CAAY,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AAErC,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC9B,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,IAAI,IAAA,CAAK,GAAA,EAAI,IAAK,QAAA,EAAU;AAC1B,UAAA,MAAM,IAAI,yBAAA,CAA0B,UAAA,EAAY,SAAS,CAAA;AAAA,QAC3D;AACA,QAAA,MAAMA,OAAM,cAAc,CAAA;AAC1B,QAAA,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,CAAY,UAAU,CAAA;AACpD,QAAA,IAAI,eAAA,CAAgB,QAAQ,CAAA,EAAG;AAAA,MACjC;AAAA,IACF,CAAA,MAAA,IAAW,SAAS,SAAA,EAAW;AAG7B,MAAA,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,CAAY,UAAU,CAAA;AAAA,IACtD;AAIA,IAAA,IAAI,QAAA,GAAW,IAAA;AACf,IAAA,MAAM,SAAA,GAAY,UAAU,UAAA,IAAc,IAAA;AAC1C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,QAAA,GAAW,iBAAA,CAAkB,UAAA,EAAY,OAAA,EAAS,SAAA,EAAW,MAAM,OAAO,CAAA;AAAA,IAC5E;AAKA,IAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,GAAG,QAAQ,CAAA;AACnC,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAC/B,MAAA,MAAM,WAAW,YAAA,EAAc,UAAA,EAAY,WAAW,IAAA,EAAM,SAAA,EAAW,QAAQ,WAAW,CAAA;AAC1F,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,CAAA,EAAG;AACV,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAC/B,MAAA,MAAM,SAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACxD,MAAA,MAAM,UAAA,CAAW,YAAA,EAAc,UAAA,EAAY,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,GAAI,CAAA,EAAG,SAAA,EAAW,IAAA,EAAM,WAAW,CAAA;AACvG,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMA,SAAS,iBAAA,CACP,QAAA,EACA,QAAA,EACA,SAAA,EACQ;AACR,EAAgB,IAAA,CAAK,SAAA;AAAA,IACnB,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,QAAA,EAAU,OAAA,EAAS,aAAa,IAAA,EAAK;AAAA,IAC7D,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,IAAA;AAAK;AAGrD,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,QAAA,EAAU,OAAA,EAAS,SAAA,IAAa,IAAA,EAAM,CAAA;AAE9F,EAAA,OAAO,IAAA,GAAO,UAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAChF;AAEA,SAAS,cAAc,KAAA,EAAwB;AAC7C,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC/C,IAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,EAC7B;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,MAAM,KAAA,CAAM,GAAA,CAAI,aAAa,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AAAA,EACpD;AACA,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AACnC,EAAA,OACE,MACA,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,UAAU,CAAC,CAAA,GAAI,GAAA,GAAM,aAAA,CAAc,IAAI,CAAC,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,GACzE,GAAA;AAEJ;AAQA,SAAS,cAAA,CAAe,KAAc,KAAA,EAAyB;AAC7D,EAAA,IAAI,aAAA,CAAc,GAAG,CAAA,IAAK,aAAA,CAAc,KAAK,CAAA,EAAG;AAC9C,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC1C,MAAA,GAAA,CAAI,CAAC,IAAI,CAAA,IAAK,GAAA,GAAM,eAAe,GAAA,CAAI,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,CAAA;AAAA,IAClD;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,KAAU,sBAAsB,OAAO,GAAA;AAC3C,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,cAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAWA,SAAS,iBAAA,CACP,UAAA,EACA,OAAA,EACA,SAAA,EACA,cACA,OAAA,EACO;AACP,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,OAAA,EAAS,SAAS,CAAA;AAChD,EAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,IAAA,OAAO,OAAA,CAAQ,cAAA,CAAe,MAAA,EAAQ,YAAY,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,QAAQ,QAAA,KAAa,MAAA,IAAa,MAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,EAAG;AAChE,IAAA,OAAO,MAAA,CAAO,IAAA;AAAA,EAChB;AACA,EAAA,MAAM,IAAI,2BAAA,CAA4B,UAAA,EAAY,MAAM,CAAA;AAC1D;AAEA,SAAS,gBAAgB,QAAA,EAAoC;AAC3D,EAAA,IAAI,WAAA,CAAY,GAAA,CAAI,QAAA,CAAS,MAAM,GAAG,OAAO,IAAA;AAC7C,EAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACxC,IAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,EAAA,EAAI,SAAS,eAAe,CAAA;AAAA,EACpE;AACA,EAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACzC,IAAA,MAAM,IAAI,yBAAA,CAA0B,QAAA,CAAS,EAAE,CAAA;AAAA,EACjD;AACA,EAAA,OAAO,KAAA;AACT;AAEA,eAAe,WACb,MAAA,EACA,UAAA,EACA,QACA,YAAA,EACA,SAAA,EACA,QACA,WAAA,EACe;AACf,EAAA,IAAI,OAAA,GAAyB,IAAA;AAC7B,EAAA,IAAI,UAAU,IAAA,EAAM;AAIlB,IAAA,MAAM,MAAA,GAAS,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,IAAK,aAAA,CAAc,MAAM,CAAA,GACxE,cAAA,CAAe,MAAA,EAAQ,WAAW,CAAA,GAClC,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,KAAK,SAAA,CAAU,MAAM,CAAA,CAAE,KAAA,CAAM,GAAG,GAAI,CAAA;AAAA,IAChD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,GAAU,MAAA,CAAO,MAAM,CAAA,CAAE,KAAA,CAAM,GAAG,GAAI,CAAA;AAAA,IACxC;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,CAAO,gBAAgB,UAAA,EAAY;AAAA,MACvC,MAAA;AAAA,MACA,KAAA,EAAO,YAAA;AAAA,MACP,UAAA,EAAY,SAAA;AAAA,MACZ,uBAAA,EAAyB;AAAA,KAC1B,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AAAA,EAGR;AACF;AAEA,SAASA,OAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;;;AC7PO,IAAM,YAAA,GAAe;AAQrB,SAAS,SAAA,CACd,SACA,IAAA,EACyB;AACzB,EAAA,IAAI,OAAO,IAAA,CAAK,OAAA,KAAY,UAAA,EAAY;AAEtC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,GACJ,OAAA,CAAQ,QAAA,KACP,OAAO,IAAA,CAAK,WAAA,KAAgB,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,SAAA,CAAA;AAE1E,EAAA,MAAM,kBAAkB,IAAA,CAAK,OAAA;AAI7B,EAAA,IAAI,cAAA,GAA0B,MAAA;AAE9B,EAAA,MAAM,gBAAA,GAAmB,KAAA;AAAA,IACvB;AAAA,MACE,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,gBAAgB,OAAA,CAAQ,cAAA;AAAA,MACxB,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,iBAAiB,OAAA,CAAQ,eAAA;AAAA,MACzB,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,QAAA;AAAA;AAAA;AAAA,MAGA,QAAA,EAAU,CAAC,KAAA,KACTC,cAAAA,CAAc,KAAK,CAAA,GAAI,KAAA,GAAS,EAAE,KAAA;AAAM,KAC5C;AAAA,IACA,OAAO,KAAA,KAAkB,eAAA,CAAgB,KAAA,EAAO,cAAc;AAAA,GAChE;AAEA,EAAA,MAAM,cAAA,GAAqD,OAAO,KAAA,EAAO,IAAA,KAAS;AAChF,IAAA,cAAA,GAAiB,IAAA;AACjB,IAAA,OAAO,iBAAiB,KAAK,CAAA;AAAA,EAC/B,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,OAAA,EAAS;AAAA,GACX;AACF;AAEA,SAASA,eAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE","file":"ai.js","sourcesContent":["/**\n * Single source of truth for the package version.\n * Kept in sync with `package.json` by release tooling at publish time.\n */\nexport const VERSION = '0.2.1' as const\n","/**\n * Error hierarchy for the Pliuz SDK.\n *\n * All exceptions extend `PliuzError`. HTTP-level failures use `PliuzApiError`\n * subclasses keyed by status code, so callers can do narrow `instanceof` checks:\n *\n * ```ts\n * try {\n * await pliuz.createApproval(...)\n * } catch (e) {\n * if (e instanceof PliuzAuthError) {\n * // refresh API key\n * } else if (e instanceof PliuzPolicyError) {\n * // no policy matched — define a catch-all\n * } else if (e instanceof PliuzApiError) {\n * // other 4xx/5xx\n * }\n * throw e\n * }\n * ```\n */\n\nexport class PliuzError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzError'\n // Maintain proper prototype chain for `instanceof` after transpile (CJS target)\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNetworkError extends PliuzError {\n constructor(message: string, public override readonly cause?: unknown) {\n super(message)\n this.name = 'PliuzNetworkError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzTimeoutError extends PliuzError {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApiError extends PliuzError {\n constructor(\n public readonly statusCode: number,\n public readonly errorCode: string,\n message: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'PliuzApiError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzValidationError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzValidationError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzAuthError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzAuthError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzForbiddenError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzForbiddenError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNotFoundError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzNotFoundError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzConflictError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzConflictError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzPolicyError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzPolicyError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzRateLimitError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzRateLimitError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzServerError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzServerError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n// ---------------------------------------------------------------------------\n// gated() lifecycle errors — raised by the wrapper, NOT by direct client calls.\n// ---------------------------------------------------------------------------\n\nexport class PliuzRejectedError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly reason: string | null) {\n const msg = reason\n ? `approval ${approvalId} was rejected: ${reason}`\n : `approval ${approvalId} was rejected`\n super(msg)\n this.name = 'PliuzRejectedError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalExpiredError extends PliuzError {\n constructor(public readonly approvalId: string) {\n super(`approval ${approvalId} expired before a human decided`)\n this.name = 'PliuzApprovalExpiredError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalTimeoutError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly timeoutMs: number) {\n super(\n `approval ${approvalId} did not resolve within ${timeoutMs}ms ` +\n '(SDK polling timeout — approval may still be pending server-side)',\n )\n this.name = 'PliuzApprovalTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n/**\n * A human approved with EDITED args (action='edit') but the SDK cannot map\n * `final_args` back onto the wrapped function's parameters. The SDK refuses\n * to execute the ORIGINAL (unapproved) args — that would make the audit\n * trail lie about what was approved vs executed. Carries `finalArgs` so the\n * caller can apply the edit manually, or pass an `applyFinalArgs` mapper in\n * GatedOptions to handle edits automatically.\n */\nexport class PliuzEditNotApplicableError extends PliuzError {\n constructor(\n public readonly approvalId: string,\n public readonly finalArgs: Record<string, unknown>,\n ) {\n super(\n `approval ${approvalId} was approved with edited args, but they cannot be ` +\n 'mapped back to the wrapped function (custom toolArgs mapper without ' +\n 'applyFinalArgs, or incompatible shape) — refusing to execute the ' +\n 'original (unapproved) args. Apply e.finalArgs manually.',\n )\n this.name = 'PliuzEditNotApplicableError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nconst STATUS_TO_ERROR: Record<number, new (s: number, c: string, m: string, d?: Record<string, unknown>) => PliuzApiError> = {\n 400: PliuzValidationError,\n 401: PliuzAuthError,\n 403: PliuzForbiddenError,\n 404: PliuzNotFoundError,\n 409: PliuzConflictError,\n 422: PliuzPolicyError,\n 429: PliuzRateLimitError,\n}\n\nexport function errorForStatus(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n): PliuzApiError {\n if (statusCode >= 500 && statusCode < 600) {\n return new PliuzServerError(statusCode, errorCode, message, details)\n }\n const Cls = STATUS_TO_ERROR[statusCode] ?? PliuzApiError\n return new Cls(statusCode, errorCode, message, details)\n}\n","/**\n * Internal HTTP layer — shared by PliuzClient.\n *\n * Centralizes: header injection, error mapping, exponential-backoff retries\n * for idempotent operations, and JSON parsing.\n *\n * NOT public API — only `PliuzClient` should import from here.\n */\n\nimport { VERSION } from './version.js'\nimport type { ApiErrorBody } from './types.js'\nimport {\n PliuzApiError,\n PliuzNetworkError,\n PliuzTimeoutError,\n errorForStatus,\n} from './errors.js'\n\n// HTTP methods safe to retry without risking duplicate side-effects.\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'])\n\n// Retry-able status codes — server hiccups, NOT client errors.\nconst RETRYABLE_STATUS = new Set([408, 429, 500, 502, 503, 504])\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n url: string\n apiKey: string\n body?: Record<string, unknown> | null\n timeoutMs: number\n maxRetries: number\n retryOnPost?: boolean\n fetchImpl: typeof fetch\n}\n\nfunction userAgent(): string {\n return `pliuz-typescript/${VERSION}`\n}\n\nfunction buildHeaders(apiKey: string): Record<string, string> {\n return {\n 'X-Pliuz-Api-Key': apiKey,\n 'User-Agent': userAgent(),\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n }\n}\n\nfunction backoffMs(attempt: number, baseMs = 500, capMs = 8000): number {\n // Exponential with full jitter (AWS architecture blog formula).\n const expo = Math.min(capMs, baseMs * 2 ** (attempt - 1))\n return Math.floor(Math.random() * expo)\n}\n\nfunction isRetryable(method: string, status: number, retryOnPost: boolean): boolean {\n if (!RETRYABLE_STATUS.has(status)) return false\n if (IDEMPOTENT_METHODS.has(method)) return true\n if (method === 'POST' && retryOnPost) return true\n return false\n}\n\nasync function parseError(response: Response): Promise<PliuzApiError> {\n let body: Partial<ApiErrorBody> = {}\n try {\n body = (await response.json()) as Partial<ApiErrorBody>\n } catch {\n /* non-JSON body — fall through with empty */\n }\n const errorCode = body.error ?? 'unknown_error'\n const message = body.message ?? response.statusText ?? 'Pliuz API error'\n const details = body.details\n return errorForStatus(response.status, errorCode, message, details)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport async function request<T>(opts: RequestOptions): Promise<T> {\n const { method, url, apiKey, body, timeoutMs, maxRetries, retryOnPost = false, fetchImpl } = opts\n const headers = buildHeaders(apiKey)\n\n let lastError: Error | null = null\n\n for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n\n let response: Response\n try {\n response = await fetchImpl(url, {\n method,\n headers,\n body: body == null ? undefined : JSON.stringify(body),\n signal: controller.signal,\n })\n } catch (e) {\n clearTimeout(timer)\n const isTimeout =\n e instanceof Error &&\n (e.name === 'AbortError' || /abort|timeout/i.test(e.message))\n lastError = isTimeout\n ? new PliuzTimeoutError(`Pliuz request timed out after ${timeoutMs}ms`)\n : new PliuzNetworkError(\n `Pliuz network error: ${e instanceof Error ? e.message : String(e)}`,\n e,\n )\n if (attempt > maxRetries) throw lastError\n await sleep(backoffMs(attempt))\n continue\n }\n clearTimeout(timer)\n\n if (response.status >= 200 && response.status < 300) {\n try {\n return (await response.json()) as T\n } catch (e) {\n throw new PliuzApiError(\n response.status,\n 'invalid_json',\n `Pliuz returned non-JSON 2xx body: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n }\n\n if (isRetryable(method, response.status, retryOnPost)) {\n if (attempt > maxRetries) {\n throw await parseError(response)\n }\n await sleep(backoffMs(attempt))\n continue\n }\n\n throw await parseError(response)\n }\n\n // Unreachable — the loop always returns or throws.\n throw lastError ?? new PliuzApiError(0, 'exhausted', 'retry loop exhausted unexpectedly')\n}\n","/**\n * PliuzClient — the SDK entry point.\n *\n * Reads PLIUZ_API_KEY env var by default (Node only). Apply redaction\n * client-side via `applyRedaction` before passing tool_args; the client\n * does NOT redact for you (separation of concerns — the `gated()` wrapper\n * in Fase 7 will wire them together).\n *\n * @example\n * import { PliuzClient, applyRedaction } from '@pliuz/sdk'\n *\n * const pliuz = new PliuzClient() // reads PLIUZ_API_KEY\n *\n * const response = await pliuz.createApproval({\n * tool_name: 'issue_refund',\n * tool_args: applyRedaction(\n * { customer: { ssn: '...', id: 'cus_123' }, amount_cents: 5000 },\n * ['customer.ssn'],\n * ),\n * idempotency_key: 'refund-cus_123-2026-05-21-001',\n * })\n */\n\nimport { request } from './_http.js'\nimport type {\n ApprovalRequest,\n CreateApprovalInput,\n CreateApprovalResponse,\n ExecutionInput,\n ExecutionResult,\n} from './types.js'\n\nexport const DEFAULT_BASE_URL = 'https://pliuz.com'\nexport const DEFAULT_TIMEOUT_MS = 30_000\nexport const DEFAULT_MAX_RETRIES = 3\nexport const ENV_API_KEY = 'PLIUZ_API_KEY'\nexport const ENV_BASE_URL = 'PLIUZ_BASE_URL'\n\nexport interface PliuzClientOptions {\n /**\n * Pliuz API key (per-agent). Defaults to `process.env.PLIUZ_API_KEY`.\n * NEVER hardcode in source — read from env or a secrets manager.\n */\n apiKey?: string\n\n /**\n * Base URL (no trailing slash). Defaults to `process.env.PLIUZ_BASE_URL`\n * or `https://pliuz.com`.\n */\n baseUrl?: string\n\n /** Per-request timeout in milliseconds. Default: 30 000. */\n timeoutMs?: number\n\n /** Max retries for transient failures (network / 5xx / 429). Default: 3. */\n maxRetries?: number\n\n /**\n * Custom fetch implementation. Defaults to global `fetch` (Node ≥18).\n * Use for testing (MSW, vitest-fetch-mock) or to inject proxy/keepalive.\n */\n fetch?: typeof fetch\n}\n\nfunction resolveApiKey(explicit: string | undefined): string {\n if (explicit) return explicit\n if (typeof process !== 'undefined' && process.env?.[ENV_API_KEY]) {\n return process.env[ENV_API_KEY]\n }\n throw new Error(`Pliuz API key not provided. Pass apiKey or set $${ENV_API_KEY}.`)\n}\n\nfunction resolveBaseUrl(explicit: string | undefined): string {\n if (explicit) return explicit.replace(/\\/+$/, '')\n if (typeof process !== 'undefined' && process.env?.[ENV_BASE_URL]) {\n return process.env[ENV_BASE_URL].replace(/\\/+$/, '')\n }\n return DEFAULT_BASE_URL\n}\n\nfunction approvalUrl(baseUrl: string, approvalId?: string, suffix?: string): string {\n let path = '/api/v1/approvals'\n if (approvalId) path += `/${encodeURIComponent(approvalId)}`\n if (suffix) path += `/${suffix}`\n return baseUrl + path\n}\n\nexport class PliuzClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PliuzClientOptions = {}) {\n this.apiKey = resolveApiKey(options.apiKey)\n this.baseUrl = resolveBaseUrl(options.baseUrl)\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n\n const fetchImpl = options.fetch ?? globalThis.fetch\n if (!fetchImpl) {\n throw new Error(\n 'No fetch implementation available. Pliuz requires Node ≥18 or a polyfill.',\n )\n }\n this.fetchImpl = fetchImpl\n }\n\n /**\n * Create (or idempotently replay) an approval request.\n *\n * With `idempotency_key`, the call retries on network failure without\n * risk of duplicates (backend dedupes within 24h).\n */\n async createApproval(input: CreateApprovalInput): Promise<CreateApprovalResponse> {\n const body = {\n tool_name: input.tool_name,\n tool_args: input.tool_args,\n context_messages: input.context_messages ?? null,\n originator: input.originator ?? { type: 'system' },\n session_id: input.session_id ?? null,\n client_metadata: input.client_metadata ?? null,\n idempotency_key: input.idempotency_key ?? null,\n }\n return request<CreateApprovalResponse>({\n method: 'POST',\n url: approvalUrl(this.baseUrl),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: Boolean(input.idempotency_key),\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Fetch the current state of an approval request.\n * Used by polling in `gated()` to detect status transitions.\n */\n async getApproval(approvalId: string): Promise<ApprovalRequest> {\n return request<ApprovalRequest>({\n method: 'GET',\n url: approvalUrl(this.baseUrl, approvalId),\n apiKey: this.apiKey,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Close the audit loop by reporting the outcome of the gated action.\n *\n * Single-shot: a second call returns 409 (PliuzConflictError).\n * Only the originating agent can report — others get 403 (PliuzForbiddenError).\n */\n async reportExecution(\n approvalId: string,\n input: ExecutionInput,\n ): Promise<ExecutionResult> {\n const body = {\n status: input.status,\n error: input.error ?? null,\n latency_ms: input.latency_ms ?? null,\n target_response_excerpt: input.target_response_excerpt ?? null,\n }\n return request<ExecutionResult>({\n method: 'POST',\n url: approvalUrl(this.baseUrl, approvalId, 'execution'),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: false,\n fetchImpl: this.fetchImpl,\n })\n }\n}\n","/**\n * Field-level redaction applied client-side BEFORE sending to Pliuz.\n *\n * Non-negotiable architectural decision: sensitive fields (PII, secrets, PHI)\n * must never leave the caller's process in plaintext. The SDK applies\n * redaction on the client side, transmits the redacted payload, and the\n * backend never sees the raw values.\n *\n * ## Path syntax\n *\n * \"customer.ssn\" → payload.customer.ssn\n * \"items[*].card_number\" → every item's card_number\n * \"headers.authorization\" → payload.headers.authorization\n *\n * Limitations (intentional — keep the surface tiny):\n * - No JSONPath wildcards beyond `[*]`\n * - No filter expressions\n * - Missing keys are silently ignored\n */\n\nexport const REDACTED_PLACEHOLDER = '<redacted>' as const\n\ntype PathSegment = { key: string; isArrayWildcard: boolean }\n\n/**\n * Returns a deep copy of `payload` with values at `paths` replaced by\n * `REDACTED_PLACEHOLDER`. Does not mutate the input.\n *\n * @example\n * applyRedaction({ customer: { ssn: '123-45-6789' } }, ['customer.ssn'])\n * // → { customer: { ssn: '<redacted>' } }\n */\nexport function applyRedaction<T extends Record<string, unknown>>(\n payload: T,\n paths: readonly string[] | null | undefined,\n): T {\n if (!paths || paths.length === 0) {\n return deepClone(payload)\n }\n const result = deepClone(payload)\n for (const path of paths) {\n redactPath(result as Record<string, unknown>, parsePath(path))\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\nfunction parsePath(path: string): PathSegment[] {\n if (!path) {\n throw new Error('redaction path cannot be empty')\n }\n\n const segments: PathSegment[] = []\n for (const raw of path.split('.')) {\n if (raw.endsWith('[*]')) {\n const key = raw.slice(0, -3)\n if (!key) {\n throw new Error(`redaction path segment before [*] cannot be empty: ${path}`)\n }\n segments.push({ key, isArrayWildcard: true })\n } else if (raw.includes('[') || raw.includes(']')) {\n throw new Error(`unsupported redaction syntax in '${path}' — only [*] is allowed`)\n } else {\n if (!raw) {\n throw new Error(`redaction path has empty segment: ${path}`)\n }\n segments.push({ key: raw, isArrayWildcard: false })\n }\n }\n return segments\n}\n\nfunction redactPath(node: unknown, segments: PathSegment[]): void {\n if (segments.length === 0) return\n if (!isPlainObject(node)) return\n\n const [head, ...rest] = segments\n if (!head) return\n const { key, isArrayWildcard } = head\n if (!(key in node)) return\n\n if (isArrayWildcard) {\n const target = node[key]\n if (!Array.isArray(target)) return\n if (rest.length === 0) {\n node[key] = target.map(() => REDACTED_PLACEHOLDER)\n return\n }\n for (const item of target) {\n redactPath(item, rest)\n }\n } else {\n if (rest.length === 0) {\n node[key] = REDACTED_PLACEHOLDER\n } else {\n redactPath(node[key], rest)\n }\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\nfunction deepClone<T>(v: T): T {\n // Prefer structuredClone when available (Node 17+). Falls back to JSON\n // for environments without it (e.g. some bundler test setups).\n if (typeof structuredClone === 'function') {\n return structuredClone(v)\n }\n return JSON.parse(JSON.stringify(v)) as T\n}\n","/**\n * The `gated()` wrapper — the headline API of the Pliuz TypeScript SDK.\n *\n * Wraps any function (sync or async) so every call is gated by a Pliuz\n * approval request. The wrapped function always returns `Promise<TResult>`\n * even if the original is synchronous — gating is inherently async because\n * it involves an HTTP call.\n *\n * @example\n * import { gated } from '@pliuz/sdk'\n *\n * const issueRefund = gated(\n * {\n * policy: 'refund',\n * redact: ['customer.ssn'],\n * toolArgs: (customerId: string, amountCents: number) => ({\n * customer_id: customerId,\n * amount_cents: amountCents,\n * }),\n * },\n * async (customerId, amountCents) => stripe.refund(customerId, amountCents),\n * )\n *\n * const result = await issueRefund('cus_123', 5000)\n */\n\nimport { createHash } from 'node:crypto'\n\nimport { PliuzClient } from './client.js'\nimport {\n PliuzApprovalExpiredError,\n PliuzApprovalTimeoutError,\n PliuzEditNotApplicableError,\n PliuzRejectedError,\n} from './errors.js'\nimport { applyRedaction, REDACTED_PLACEHOLDER } from './redaction.js'\nimport type {\n ApprovalRequest,\n ExecutionStatus,\n Originator,\n} from './types.js'\n\nexport const DEFAULT_GATED_TIMEOUT_MS = 300_000 // 5 min — matches Pliuz default SLA\nexport const DEFAULT_GATED_POLL_INTERVAL_MS = 2000\n\nexport interface GatedOptions<TArgs extends readonly unknown[]> {\n /** Policy slug to bind this gate to. Default: backend resolves by toolName. */\n policy?: string\n\n /** Redaction paths applied to tool_args BEFORE sending. */\n redact?: readonly string[]\n\n /** Override the tool name. Default: `fn.name` (may be empty for anonymous). */\n toolName?: string\n\n /**\n * Map the wrapped function's args into a tool_args object.\n * Default: `(...args) => ({ args })` — wraps all positional args under\n * a single `args` key. Provide a custom mapper for cleaner audit trails.\n */\n toolArgs?: (...args: TArgs) => Record<string, unknown>\n\n /** Max ms to poll for the approval to resolve. Throws on timeout. */\n timeoutMs?: number\n\n /** Ms between GET /approvals/:id polls. */\n pollIntervalMs?: number\n\n /** Reuse an existing PliuzClient. Default: `new PliuzClient()`. */\n client?: PliuzClient\n\n /** Optional context for the human approver. */\n contextMessages?: readonly string[]\n\n /** Optional session id (groups related approvals in the UI). */\n sessionId?: string\n\n /** Optional originator (default: { type: 'system' }). */\n originator?: Originator\n\n /**\n * Map human-EDITED args (approval decided with action='edit') back onto\n * the wrapped function's argument tuple. Required to honor edits when a\n * custom `toolArgs` mapper is used (the SDK cannot invert an arbitrary\n * mapper). Without it, an edited approval throws\n * PliuzEditNotApplicableError instead of executing the original args.\n */\n applyFinalArgs?: (finalArgs: Record<string, unknown>, originalArgs: TArgs) => TArgs\n}\n\nconst TERMINAL_OK = new Set<string>(['approved'])\nconst TERMINAL_REJECT = new Set<string>(['rejected'])\nconst TERMINAL_EXPIRED = new Set<string>(['expired'])\n\n/**\n * Wrap a function so every call is gated by Pliuz.\n *\n * The returned function ALWAYS returns a Promise, even if the input is sync.\n * This is intentional — gating necessarily involves async HTTP calls.\n */\nexport function gated<TArgs extends readonly unknown[], TResult>(\n options: GatedOptions<TArgs>,\n fn: (...args: TArgs) => Promise<TResult> | TResult,\n): (...args: TArgs) => Promise<TResult> {\n const toolName = options.toolName ?? (fn.name || 'anonymous')\n const toolArgsMapper =\n options.toolArgs ??\n ((...args: TArgs): Record<string, unknown> => ({ args: args as unknown as unknown[] }))\n const timeoutMs = options.timeoutMs ?? DEFAULT_GATED_TIMEOUT_MS\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_GATED_POLL_INTERVAL_MS\n const redactPaths = options.redact\n\n return async (...args: TArgs): Promise<TResult> => {\n const activeClient = options.client ?? new PliuzClient()\n const rawArgs = toolArgsMapper(...args)\n const sendArgs = redactPaths && redactPaths.length > 0\n ? applyRedaction(rawArgs, redactPaths)\n : rawArgs\n // Key over PRE-redaction args: hashing the redacted payload collapses\n // calls that differ only in a redacted field (two transfers to different\n // IBANs) into one key — the second would replay the first's approval.\n // Only the truncated SHA-256 leaves the process, never the raw values.\n const idempotencyKey = idempotencyKeyFor(toolName, rawArgs, options.sessionId)\n const metadata: Record<string, unknown> = {}\n if (options.policy) metadata.policy = options.policy\n\n const response = await activeClient.createApproval({\n tool_name: toolName,\n tool_args: sendArgs,\n context_messages: options.contextMessages ?? null,\n originator: options.originator,\n session_id: options.sessionId ?? null,\n client_metadata: Object.keys(metadata).length > 0 ? metadata : null,\n idempotency_key: idempotencyKey,\n })\n\n const approvalId = response.id\n\n if (TERMINAL_REJECT.has(response.status)) {\n throw new PliuzRejectedError(approvalId, response.message ?? null)\n }\n if (TERMINAL_EXPIRED.has(response.status)) {\n throw new PliuzApprovalExpiredError(approvalId)\n }\n\n let approval: ApprovalRequest | null = null\n if (!TERMINAL_OK.has(response.status)) {\n // Poll\n const deadline = Date.now() + timeoutMs\n while (true) {\n if (Date.now() >= deadline) {\n throw new PliuzApprovalTimeoutError(approvalId, timeoutMs)\n }\n await sleep(pollIntervalMs)\n approval = await activeClient.getApproval(approvalId)\n if (terminalOrThrow(approval)) break\n }\n } else if (response.is_replay) {\n // Replayed already-approved request: a human may have EDITED the args\n // (final_args). Fresh auto-approvals can't carry edits — skip the fetch.\n approval = await activeClient.getApproval(approvalId)\n }\n\n // Honor human edits: execute final_args, NEVER the original args when\n // the approver changed them.\n let callArgs = args\n const finalArgs = approval?.final_args ?? null\n if (finalArgs) {\n callArgs = resolveEditedArgs(approvalId, rawArgs, finalArgs, args, options)\n }\n\n // Execute + report. The report is AWAITED: on serverless (Vercel/Lambda)\n // the runtime freezes once the handler resolves, so a fire-and-forget\n // report is routinely never sent — silently losing the audit loop.\n const started = Date.now()\n try {\n const result = await fn(...callArgs)\n const latencyMs = Date.now() - started\n await safeReport(activeClient, approvalId, 'success', null, latencyMs, result, redactPaths)\n return result\n } catch (e) {\n const latencyMs = Date.now() - started\n const errMsg = e instanceof Error ? e.message : String(e)\n await safeReport(activeClient, approvalId, 'error', errMsg.slice(0, 2000), latencyMs, null, redactPaths)\n throw e\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction idempotencyKeyFor(\n toolName: string,\n toolArgs: Record<string, unknown>,\n sessionId: string | undefined,\n): string {\n const payload = JSON.stringify(\n { tool: toolName, args: toolArgs, session: sessionId ?? null },\n Object.keys({ tool: 0, args: 0, session: 0 }).sort(),\n )\n // Canonicalize via sorted-key JSON stringify for deterministic hash\n const canonical = canonicalJSON({ tool: toolName, args: toolArgs, session: sessionId ?? null })\n void payload // silence unused\n return 'g_' + createHash('sha256').update(canonical).digest('hex').slice(0, 30)\n}\n\nfunction canonicalJSON(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n return JSON.stringify(value)\n }\n if (Array.isArray(value)) {\n return '[' + value.map(canonicalJSON).join(',') + ']'\n }\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return (\n '{' +\n keys.map((k) => JSON.stringify(k) + ':' + canonicalJSON(obj[k])).join(',') +\n '}'\n )\n}\n\n/**\n * Merge human-edited final_args over the original raw args. final_args is\n * authoritative (the edit modal pre-fills the FULL tool_args JSON), except\n * values left as the redaction placeholder — those are echoes of what we\n * sent; restore the original raw value rather than executing '<redacted>'.\n */\nfunction mergeFinalArgs(raw: unknown, final: unknown): unknown {\n if (isPlainRecord(raw) && isPlainRecord(final)) {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(final)) {\n out[k] = k in raw ? mergeFinalArgs(raw[k], v) : v\n }\n return out\n }\n if (final === REDACTED_PLACEHOLDER) return raw\n return final\n}\n\nfunction isPlainRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\n/**\n * Map human-edited args back onto the wrapped function's argument tuple.\n *\n * - custom `applyFinalArgs` mapper → caller decides.\n * - default toolArgs mapper ({ args: [...] }) → use the edited array.\n * - custom toolArgs mapper without applyFinalArgs → PliuzEditNotApplicableError:\n * executing the ORIGINAL args after a human approved something ELSE would\n * make the audit trail misrepresent what was approved vs executed.\n */\nfunction resolveEditedArgs<TArgs extends readonly unknown[]>(\n approvalId: string,\n rawArgs: Record<string, unknown>,\n finalArgs: Record<string, unknown>,\n originalArgs: TArgs,\n options: GatedOptions<TArgs>,\n): TArgs {\n const merged = mergeFinalArgs(rawArgs, finalArgs) as Record<string, unknown>\n if (options.applyFinalArgs) {\n return options.applyFinalArgs(merged, originalArgs)\n }\n if (options.toolArgs === undefined && Array.isArray(merged.args)) {\n return merged.args as unknown as TArgs\n }\n throw new PliuzEditNotApplicableError(approvalId, merged)\n}\n\nfunction terminalOrThrow(approval: ApprovalRequest): boolean {\n if (TERMINAL_OK.has(approval.status)) return true\n if (TERMINAL_REJECT.has(approval.status)) {\n throw new PliuzRejectedError(approval.id, approval.decision_reason)\n }\n if (TERMINAL_EXPIRED.has(approval.status)) {\n throw new PliuzApprovalExpiredError(approval.id)\n }\n return false\n}\n\nasync function safeReport(\n client: PliuzClient,\n approvalId: string,\n status: ExecutionStatus,\n errorMessage: string | null,\n latencyMs: number,\n result: unknown,\n redactPaths: readonly string[] | undefined,\n): Promise<void> {\n let excerpt: string | null = null\n if (result != null) {\n // The caller's redact paths apply to the RESULT too: a tool that\n // receives a redacted SSN often returns it. Without this the excerpt\n // re-leaked exactly the fields marked as never-leave-process.\n const toDump = redactPaths && redactPaths.length > 0 && isPlainRecord(result)\n ? applyRedaction(result, redactPaths)\n : result\n try {\n excerpt = JSON.stringify(toDump).slice(0, 2000)\n } catch {\n excerpt = String(toDump).slice(0, 2000)\n }\n }\n try {\n await client.reportExecution(approvalId, {\n status,\n error: errorMessage,\n latency_ms: latencyMs,\n target_response_excerpt: excerpt,\n })\n } catch {\n // Intentionally swallow — if reporting fails the audit log surfaces\n // 'execution unreported' but we don't want to crash the caller's flow.\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Vercel AI SDK adapter for Pliuz.\n *\n * Wraps any Vercel AI SDK `Tool` so its `execute` is gated by a Pliuz\n * approval request. The wrapped tool preserves `description` and\n * `parameters` so the LLM sees the tool identically — only the\n * execution path is gated.\n *\n * Install requires `ai >= 4.0` as a peer dependency.\n *\n * @example\n * import { tool } from 'ai'\n * import { z } from 'zod'\n * import { gatedTool } from '@pliuz/sdk/adapters/ai'\n *\n * const issueRefund = gatedTool(\n * { policy: 'refund', redact: ['customer.ssn'] },\n * tool({\n * description: 'Issue a refund to a customer',\n * parameters: z.object({\n * customer_id: z.string(),\n * amount_cents: z.number().int().positive(),\n * }),\n * execute: async ({ customer_id, amount_cents }) => {\n * return stripe.refund(customer_id, amount_cents)\n * },\n * }),\n * )\n */\n\nimport { gated } from '../gated.js'\nimport type { PliuzClient } from '../client.js'\nimport type { Originator } from '../types.js'\n\n/**\n * Minimal structural type that matches Vercel AI SDK's `Tool<TParams, TResult>`\n * without importing `ai` (it's a peer dep — adapter must work even if absent\n * from a consumer's tsconfig). The shape mirrors the v4 contract.\n */\nexport interface AITool<TInput, TResult> {\n description?: string\n parameters: unknown\n execute?: (input: TInput, options: unknown) => Promise<TResult> | TResult\n [key: string]: unknown\n}\n\n/**\n * Options for `gatedTool`. Mirrors the relevant fields of GatedOptions\n * without the `toolArgs` / `toolName` generic-parametric pieces (the\n * adapter sets toolArgs internally to surface the Vercel-AI input dict\n * directly as the Pliuz tool_args).\n */\nexport interface GatedToolOptions {\n policy?: string\n redact?: readonly string[]\n /**\n * Override the tool name reported to Pliuz. Defaults to the tool's\n * `description` (first 64 chars) or `'ai_tool'` if neither is set.\n */\n toolName?: string\n timeoutMs?: number\n pollIntervalMs?: number\n client?: PliuzClient\n contextMessages?: readonly string[]\n sessionId?: string\n originator?: Originator\n}\n\nexport const ADAPTER_NAME = 'vercel-ai' as const\n\n/**\n * Wrap a Vercel AI SDK tool so its `execute` is gated by Pliuz.\n *\n * If the tool has no `execute` (e.g. client-side tools), this is a\n * no-op — gating only makes sense on the server side.\n */\nexport function gatedTool<TInput, TResult>(\n options: GatedToolOptions,\n tool: AITool<TInput, TResult>,\n): AITool<TInput, TResult> {\n if (typeof tool.execute !== 'function') {\n // Client-side tool — nothing to gate.\n return tool\n }\n\n const toolName =\n options.toolName ??\n (typeof tool.description === 'string' ? tool.description.slice(0, 64) : 'ai_tool')\n\n const originalExecute = tool.execute\n // We bind the Vercel AI 2-arg `(input, options)` execute into a 1-arg\n // closure for `gated()`, which infers TArgs from the wrapped fn. The\n // closure captures `options` per-call via a mutable holder.\n let pendingOptions: unknown = undefined\n\n const gatedExecute1Arg = gated(\n {\n policy: options.policy,\n redact: options.redact,\n timeoutMs: options.timeoutMs,\n pollIntervalMs: options.pollIntervalMs,\n client: options.client,\n contextMessages: options.contextMessages,\n sessionId: options.sessionId,\n originator: options.originator,\n toolName,\n // Surface the Vercel-AI input dict directly as Pliuz tool_args\n // instead of wrapping in `{ args: [input] }` for cleaner audit logs.\n toolArgs: (input: TInput) =>\n isPlainObject(input) ? input : ({ input } as Record<string, unknown>),\n },\n async (input: TInput) => originalExecute(input, pendingOptions),\n )\n\n const wrappedExecute: AITool<TInput, TResult>['execute'] = async (input, opts) => {\n pendingOptions = opts\n return gatedExecute1Arg(input)\n }\n\n return {\n ...tool,\n execute: wrappedExecute,\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n"]}
@@ -96,7 +96,7 @@ interface ApiErrorBody {
96
96
  * })
97
97
  */
98
98
 
99
- declare const DEFAULT_BASE_URL = "https://pliuz-dev.vercel.app";
99
+ declare const DEFAULT_BASE_URL = "https://pliuz.com";
100
100
  declare const DEFAULT_TIMEOUT_MS = 30000;
101
101
  declare const DEFAULT_MAX_RETRIES = 3;
102
102
  declare const ENV_API_KEY = "PLIUZ_API_KEY";
@@ -109,7 +109,7 @@ interface PliuzClientOptions {
109
109
  apiKey?: string;
110
110
  /**
111
111
  * Base URL (no trailing slash). Defaults to `process.env.PLIUZ_BASE_URL`
112
- * or `https://pliuz-dev.vercel.app`.
112
+ * or `https://pliuz.com`.
113
113
  */
114
114
  baseUrl?: string;
115
115
  /** Per-request timeout in milliseconds. Default: 30 000. */
@@ -96,7 +96,7 @@ interface ApiErrorBody {
96
96
  * })
97
97
  */
98
98
 
99
- declare const DEFAULT_BASE_URL = "https://pliuz-dev.vercel.app";
99
+ declare const DEFAULT_BASE_URL = "https://pliuz.com";
100
100
  declare const DEFAULT_TIMEOUT_MS = 30000;
101
101
  declare const DEFAULT_MAX_RETRIES = 3;
102
102
  declare const ENV_API_KEY = "PLIUZ_API_KEY";
@@ -109,7 +109,7 @@ interface PliuzClientOptions {
109
109
  apiKey?: string;
110
110
  /**
111
111
  * Base URL (no trailing slash). Defaults to `process.env.PLIUZ_BASE_URL`
112
- * or `https://pliuz-dev.vercel.app`.
112
+ * or `https://pliuz.com`.
113
113
  */
114
114
  baseUrl?: string;
115
115
  /** Per-request timeout in milliseconds. Default: 30 000. */
package/dist/index.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  var crypto = require('crypto');
4
4
 
5
5
  // src/version.ts
6
- var VERSION = "0.1.0";
6
+ var VERSION = "0.2.1";
7
7
 
8
8
  // src/errors.ts
9
9
  var PliuzError = class extends Error {
@@ -132,6 +132,19 @@ var PliuzApprovalTimeoutError = class extends PliuzError {
132
132
  approvalId;
133
133
  timeoutMs;
134
134
  };
135
+ var PliuzEditNotApplicableError = class extends PliuzError {
136
+ constructor(approvalId, finalArgs) {
137
+ super(
138
+ `approval ${approvalId} was approved with edited args, but they cannot be mapped back to the wrapped function (custom toolArgs mapper without applyFinalArgs, or incompatible shape) \u2014 refusing to execute the original (unapproved) args. Apply e.finalArgs manually.`
139
+ );
140
+ this.approvalId = approvalId;
141
+ this.finalArgs = finalArgs;
142
+ this.name = "PliuzEditNotApplicableError";
143
+ Object.setPrototypeOf(this, new.target.prototype);
144
+ }
145
+ approvalId;
146
+ finalArgs;
147
+ };
135
148
  var STATUS_TO_ERROR = {
136
149
  400: PliuzValidationError,
137
150
  401: PliuzAuthError,
@@ -238,7 +251,7 @@ async function request(opts) {
238
251
  }
239
252
 
240
253
  // src/client.ts
241
- var DEFAULT_BASE_URL = "https://pliuz-dev.vercel.app";
254
+ var DEFAULT_BASE_URL = "https://pliuz.com";
242
255
  var DEFAULT_TIMEOUT_MS = 3e4;
243
256
  var DEFAULT_MAX_RETRIES = 3;
244
257
  var ENV_API_KEY = "PLIUZ_API_KEY";
@@ -433,7 +446,7 @@ function gated(options, fn) {
433
446
  const activeClient = options.client ?? new PliuzClient();
434
447
  const rawArgs = toolArgsMapper(...args);
435
448
  const sendArgs = redactPaths && redactPaths.length > 0 ? applyRedaction(rawArgs, redactPaths) : rawArgs;
436
- const idempotencyKey = idempotencyKeyFor(toolName, sendArgs, options.sessionId);
449
+ const idempotencyKey = idempotencyKeyFor(toolName, rawArgs, options.sessionId);
437
450
  const metadata = {};
438
451
  if (options.policy) metadata.policy = options.policy;
439
452
  const response = await activeClient.createApproval({
@@ -452,6 +465,7 @@ function gated(options, fn) {
452
465
  if (TERMINAL_EXPIRED.has(response.status)) {
453
466
  throw new PliuzApprovalExpiredError(approvalId);
454
467
  }
468
+ let approval = null;
455
469
  if (!TERMINAL_OK.has(response.status)) {
456
470
  const deadline = Date.now() + timeoutMs;
457
471
  while (true) {
@@ -459,20 +473,27 @@ function gated(options, fn) {
459
473
  throw new PliuzApprovalTimeoutError(approvalId, timeoutMs);
460
474
  }
461
475
  await sleep2(pollIntervalMs);
462
- const approval = await activeClient.getApproval(approvalId);
476
+ approval = await activeClient.getApproval(approvalId);
463
477
  if (terminalOrThrow(approval)) break;
464
478
  }
479
+ } else if (response.is_replay) {
480
+ approval = await activeClient.getApproval(approvalId);
481
+ }
482
+ let callArgs = args;
483
+ const finalArgs = approval?.final_args ?? null;
484
+ if (finalArgs) {
485
+ callArgs = resolveEditedArgs(approvalId, rawArgs, finalArgs, args, options);
465
486
  }
466
487
  const started = Date.now();
467
488
  try {
468
- const result = await fn(...args);
489
+ const result = await fn(...callArgs);
469
490
  const latencyMs = Date.now() - started;
470
- void safeReport(activeClient, approvalId, "success", null, latencyMs, result);
491
+ await safeReport(activeClient, approvalId, "success", null, latencyMs, result, redactPaths);
471
492
  return result;
472
493
  } catch (e) {
473
494
  const latencyMs = Date.now() - started;
474
495
  const errMsg = e instanceof Error ? e.message : String(e);
475
- void safeReport(activeClient, approvalId, "error", errMsg.slice(0, 2e3), latencyMs, null);
496
+ await safeReport(activeClient, approvalId, "error", errMsg.slice(0, 2e3), latencyMs, null, redactPaths);
476
497
  throw e;
477
498
  }
478
499
  };
@@ -496,6 +517,30 @@ function canonicalJSON(value) {
496
517
  const keys = Object.keys(obj).sort();
497
518
  return "{" + keys.map((k) => JSON.stringify(k) + ":" + canonicalJSON(obj[k])).join(",") + "}";
498
519
  }
520
+ function mergeFinalArgs(raw, final) {
521
+ if (isPlainRecord(raw) && isPlainRecord(final)) {
522
+ const out = {};
523
+ for (const [k, v] of Object.entries(final)) {
524
+ out[k] = k in raw ? mergeFinalArgs(raw[k], v) : v;
525
+ }
526
+ return out;
527
+ }
528
+ if (final === REDACTED_PLACEHOLDER) return raw;
529
+ return final;
530
+ }
531
+ function isPlainRecord(v) {
532
+ return typeof v === "object" && v !== null && !Array.isArray(v);
533
+ }
534
+ function resolveEditedArgs(approvalId, rawArgs, finalArgs, originalArgs, options) {
535
+ const merged = mergeFinalArgs(rawArgs, finalArgs);
536
+ if (options.applyFinalArgs) {
537
+ return options.applyFinalArgs(merged, originalArgs);
538
+ }
539
+ if (options.toolArgs === void 0 && Array.isArray(merged.args)) {
540
+ return merged.args;
541
+ }
542
+ throw new PliuzEditNotApplicableError(approvalId, merged);
543
+ }
499
544
  function terminalOrThrow(approval) {
500
545
  if (TERMINAL_OK.has(approval.status)) return true;
501
546
  if (TERMINAL_REJECT.has(approval.status)) {
@@ -506,13 +551,14 @@ function terminalOrThrow(approval) {
506
551
  }
507
552
  return false;
508
553
  }
509
- async function safeReport(client, approvalId, status, errorMessage, latencyMs, result) {
554
+ async function safeReport(client, approvalId, status, errorMessage, latencyMs, result, redactPaths) {
510
555
  let excerpt = null;
511
556
  if (result != null) {
557
+ const toDump = redactPaths && redactPaths.length > 0 && isPlainRecord(result) ? applyRedaction(result, redactPaths) : result;
512
558
  try {
513
- excerpt = JSON.stringify(result).slice(0, 2e3);
559
+ excerpt = JSON.stringify(toDump).slice(0, 2e3);
514
560
  } catch {
515
- excerpt = String(result).slice(0, 2e3);
561
+ excerpt = String(toDump).slice(0, 2e3);
516
562
  }
517
563
  }
518
564
  try {
@@ -542,6 +588,7 @@ exports.PliuzApprovalTimeoutError = PliuzApprovalTimeoutError;
542
588
  exports.PliuzAuthError = PliuzAuthError;
543
589
  exports.PliuzClient = PliuzClient;
544
590
  exports.PliuzConflictError = PliuzConflictError;
591
+ exports.PliuzEditNotApplicableError = PliuzEditNotApplicableError;
545
592
  exports.PliuzError = PliuzError;
546
593
  exports.PliuzForbiddenError = PliuzForbiddenError;
547
594
  exports.PliuzNetworkError = PliuzNetworkError;