tenjin-cli 0.1.0-alpha.1 → 0.1.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +33 -0
- package/README.md +167 -16
- package/dist/{_esm-ZH2J4QEH.js → _esm-C5CRWCYU.js} +2 -2
- package/dist/_esm-FEASBWRP.js +881 -0
- package/dist/buy-EE6SEXP6.js +1598 -0
- package/dist/buy-EE6SEXP6.js.map +1 -0
- package/dist/candidate-ERMSYYQZ.js +127 -0
- package/dist/candidate-ERMSYYQZ.js.map +1 -0
- package/dist/{ccip-UCLT5VOW.js → ccip-NQXCEK2U.js} +6 -5
- package/dist/ccip-XR5NE5QK.js +19 -0
- package/dist/chunk-2I4QTOLB.js +11 -0
- package/dist/chunk-2I4QTOLB.js.map +1 -0
- package/dist/chunk-3OV7E5G5.js +18 -0
- package/dist/chunk-3OV7E5G5.js.map +1 -0
- package/dist/chunk-4ONXEEQL.js +152 -0
- package/dist/chunk-4ONXEEQL.js.map +1 -0
- package/dist/chunk-5CLSD5YN.js +209 -0
- package/dist/chunk-5CLSD5YN.js.map +1 -0
- package/dist/chunk-662MSGZB.js +286 -0
- package/dist/chunk-662MSGZB.js.map +1 -0
- package/dist/chunk-7KUW4MJD.js +59 -0
- package/dist/chunk-7KUW4MJD.js.map +1 -0
- package/dist/{doctor-3QBYN46N.js → chunk-AWPAWHNX.js} +88 -93
- package/dist/chunk-AWPAWHNX.js.map +1 -0
- package/dist/chunk-CYOF7ROH.js +70 -0
- package/dist/chunk-CYOF7ROH.js.map +1 -0
- package/dist/chunk-DXTQ3CSI.js +171 -0
- package/dist/chunk-DXTQ3CSI.js.map +1 -0
- package/dist/{chunk-EZROUI5U.js → chunk-ESPNTPQ2.js} +80 -8
- package/dist/chunk-ESPNTPQ2.js.map +1 -0
- package/dist/chunk-FJPLRISB.js +79 -0
- package/dist/chunk-FJPLRISB.js.map +1 -0
- package/dist/chunk-GO75V3NZ.js +160 -0
- package/dist/chunk-GO75V3NZ.js.map +1 -0
- package/dist/chunk-HIVZG55D.js +204 -0
- package/dist/chunk-HIVZG55D.js.map +1 -0
- package/dist/chunk-HSDCI7OV.js +7806 -0
- package/dist/chunk-HSDCI7OV.js.map +1 -0
- package/dist/chunk-JPHG2JW3.js +96 -0
- package/dist/chunk-JPHG2JW3.js.map +1 -0
- package/dist/{chunk-ZPZFPVDN.js → chunk-MUBUQVC3.js} +1 -1
- package/dist/chunk-MUBUQVC3.js.map +1 -0
- package/dist/{chunk-T4LKNY7T.js → chunk-NCE5NSN6.js} +166 -11
- package/dist/chunk-NCE5NSN6.js.map +1 -0
- package/dist/{chunk-YG2DO46P.js → chunk-OYMYCW7J.js} +18 -3
- package/dist/{chunk-YG2DO46P.js.map → chunk-OYMYCW7J.js.map} +1 -1
- package/dist/{chunk-Q53IYV2G.js → chunk-QVX5MWJZ.js} +20 -17
- package/dist/{chunk-Q53IYV2G.js.map → chunk-QVX5MWJZ.js.map} +1 -1
- package/dist/{chunk-CUWUHTIL.js → chunk-RBJPAZFI.js} +16 -202
- package/dist/chunk-RBJPAZFI.js.map +1 -0
- package/dist/chunk-RRN3YTK7.js +6199 -0
- package/dist/chunk-RRN3YTK7.js.map +1 -0
- package/dist/chunk-RY4XKNV3.js +140 -0
- package/dist/chunk-RY4XKNV3.js.map +1 -0
- package/dist/chunk-S3IGX57D.js +14682 -0
- package/dist/chunk-S3IGX57D.js.map +1 -0
- package/dist/chunk-TLCMMYLY.js +126 -0
- package/dist/chunk-TLCMMYLY.js.map +1 -0
- package/dist/{chunk-IPOWB3G3.js → chunk-UGX7YPX2.js} +3314 -306
- package/dist/chunk-UGX7YPX2.js.map +1 -0
- package/dist/chunk-UO22YNY4.js +69 -0
- package/dist/chunk-UO22YNY4.js.map +1 -0
- package/dist/{config-CEFTL5ZL.js → chunk-XHC6FCGZ.js} +115 -18
- package/dist/chunk-XHC6FCGZ.js.map +1 -0
- package/dist/chunk-XJIW7USF.js +217 -0
- package/dist/chunk-XJIW7USF.js.map +1 -0
- package/dist/{chunk-BRJHUQSY.js → chunk-YALGASEU.js} +1548 -1452
- package/dist/chunk-YALGASEU.js.map +1 -0
- package/dist/{chunk-DXPYFVKG.js → chunk-YN5SHIXQ.js} +6 -6
- package/dist/chunk-YN5SHIXQ.js.map +1 -0
- package/dist/chunk-Z52RA3NC.js +137 -0
- package/dist/chunk-Z52RA3NC.js.map +1 -0
- package/dist/{chunk-EXBMF5X7.js → chunk-Z6MFJV5Z.js} +151 -19
- package/dist/chunk-Z6MFJV5Z.js.map +1 -0
- package/dist/chunk-ZABPQJ3M.js +83 -0
- package/dist/chunk-ZABPQJ3M.js.map +1 -0
- package/dist/{chunk-LPRVHM7P.js → chunk-ZMHYXMO6.js} +1655 -114
- package/dist/chunk-ZMHYXMO6.js.map +1 -0
- package/dist/{chunk-3IMLRUZE.js → chunk-ZXTAQYNA.js} +6 -2
- package/dist/{cli-WA65NP4Y.js → cli-SBXI5AMS.js} +177 -177
- package/dist/cli-SBXI5AMS.js.map +1 -0
- package/dist/config-VELDKLHY.js +21 -0
- package/dist/doctor-T3KWNNP2.js +20 -0
- package/dist/doctor-T3KWNNP2.js.map +1 -0
- package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js +18 -0
- package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/inspect-LMKOXE4Y.js +96 -0
- package/dist/inspect-LMKOXE4Y.js.map +1 -0
- package/dist/install-LEX3ENQ6.js +387 -0
- package/dist/install-LEX3ENQ6.js.map +1 -0
- package/dist/lookup-ZPN2Q67N.js +129 -0
- package/dist/lookup-ZPN2Q67N.js.map +1 -0
- package/dist/{mine.wasm-GQECMSGN.js → mine.wasm-6PIT3DK6.js} +2 -2
- package/dist/outcome-N7TAK6WR.js +66 -0
- package/dist/outcome-N7TAK6WR.js.map +1 -0
- package/dist/publish-BKBQQAW4.js +1478 -0
- package/dist/publish-BKBQQAW4.js.map +1 -0
- package/dist/{secp256k1-BEZS642W.js → secp256k1-N3ZHU7LB.js} +5 -4
- package/dist/secp256k1-N3ZHU7LB.js.map +1 -0
- package/dist/usdc-JIAJW4SV.js +22 -0
- package/dist/usdc-JIAJW4SV.js.map +1 -0
- package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js +14 -0
- package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js.map +1 -0
- package/dist/{wallet-XD576HF3.js → wallet-CWEMYVIH.js} +28 -22
- package/dist/{wallet-XD576HF3.js.map → wallet-CWEMYVIH.js.map} +1 -1
- package/dist/wallet-PA54CRBL.js +30 -0
- package/dist/wallet-PA54CRBL.js.map +1 -0
- package/package.json +19 -16
- package/skills/tenjin/SKILL.md +199 -0
- package/skills/tenjin-publish/SKILL.md +111 -0
- package/skills/tenjin-search/SKILL.md +133 -0
- package/dist/chunk-BRJHUQSY.js.map +0 -1
- package/dist/chunk-CUWUHTIL.js.map +0 -1
- package/dist/chunk-DXPYFVKG.js.map +0 -1
- package/dist/chunk-EXBMF5X7.js.map +0 -1
- package/dist/chunk-EZROUI5U.js.map +0 -1
- package/dist/chunk-IPOWB3G3.js.map +0 -1
- package/dist/chunk-LPRVHM7P.js.map +0 -1
- package/dist/chunk-T4LKNY7T.js.map +0 -1
- package/dist/chunk-ZPZFPVDN.js.map +0 -1
- package/dist/cli-WA65NP4Y.js.map +0 -1
- package/dist/config-CEFTL5ZL.js.map +0 -1
- package/dist/doctor-3QBYN46N.js.map +0 -1
- package/dist/usdc-44R6XZF2.js +0 -18
- package/dist/wallet-ELBTBMXO.js +0 -20
- /package/dist/{_esm-ZH2J4QEH.js.map → _esm-C5CRWCYU.js.map} +0 -0
- /package/dist/{ccip-UCLT5VOW.js.map → _esm-FEASBWRP.js.map} +0 -0
- /package/dist/{chunk-3IMLRUZE.js.map → ccip-NQXCEK2U.js.map} +0 -0
- /package/dist/{secp256k1-BEZS642W.js.map → ccip-XR5NE5QK.js.map} +0 -0
- /package/dist/{usdc-44R6XZF2.js.map → chunk-ZXTAQYNA.js.map} +0 -0
- /package/dist/{wallet-ELBTBMXO.js.map → config-VELDKLHY.js.map} +0 -0
- /package/dist/{mine.wasm-GQECMSGN.js.map → mine.wasm-6PIT3DK6.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/cryptoNode.ts","../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/utils.ts","../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/_u64.ts"],"sourcesContent":["/**\n * Internal webcrypto alias.\n * We prefer WebCrypto aka globalThis.crypto, which exists in node.js 16+.\n * Falls back to Node.js built-in crypto for Node.js <=v14.\n * See utils.ts for details.\n * @module\n */\n// @ts-ignore\nimport * as nc from 'node:crypto';\nexport const crypto: any =\n nc && typeof nc === 'object' && 'webcrypto' in nc\n ? (nc.webcrypto as any)\n : nc && typeof nc === 'object' && 'randomBytes' in nc\n ? nc\n : undefined;\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\n\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n/** Asserts something is positive integer. */\nexport function anumber(n: number): void {\n if (!Number.isSafeInteger(n) || n < 0) throw new Error('positive integer expected, got ' + n);\n}\n\n/** Asserts something is Uint8Array. */\nexport function abytes(b: Uint8Array | undefined, ...lengths: number[]): void {\n if (!isBytes(b)) throw new Error('Uint8Array expected');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);\n}\n\n/** Asserts something is hash */\nexport function ahash(h: IHash): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new Error('Hash should be wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n}\n\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out: any, instance: any): void {\n abytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error('digestInto() expects output buffer of length at least ' + min);\n }\n}\n\n/** Generic type encompassing 8/16/32-byte arrays - but not 64-byte. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays: TypedArray[]): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n\n/** The rotate left (circular left shift) operation for uint32 */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/** The byte swap operation for uint32 */\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n);\n\n/** @deprecated */\nexport const byteSwapIfBE: typeof swap8IfBE = swap8IfBE;\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr: Uint32Array): Uint32Array {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr;\n}\n\nexport const swap32IfBE: (u: Uint32Array) => Uint32Array = isLE\n ? (u: Uint32Array) => u\n : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * Call of async fn will return Promise, which will be fullfiled only on\n * next scheduler queue processing step and this is exactly what we need.\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/** Returns control to thread each 'tick' ms to avoid blocking. */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(Uint8Array.from([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\n/** Accepted input of hash functions. Strings are converted to byte arrays. */\nexport type Input = string | Uint8Array;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: Input): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n/**\n * Helper for KDFs: consumes uint8array or string.\n * When string is passed, does utf8 decoding, using TextDecoder.\n */\nexport function kdfInputToBytes(data: KDFInput): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n\n/** Copies several Uint8Arrays into one. */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new Error('options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Hash interface. */\nexport type IHash = {\n (data: Uint8Array): Uint8Array;\n blockLen: number;\n outputLen: number;\n create: any;\n};\n\n/** For runtime check if class implements interface */\nexport abstract class Hash<T extends Hash<T>> {\n abstract blockLen: number; // Bytes per block\n abstract outputLen: number; // Bytes in output\n abstract update(buf: Input): this;\n // Writes digest into buf\n abstract digestInto(buf: Uint8Array): void;\n abstract digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n abstract destroy(): void;\n /**\n * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()`\n * when no options are passed.\n * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal\n * buffers are overwritten => causes buffer overwrite which is used for digest in some cases.\n * There are no guarantees for clean-up because it's impossible in JS.\n */\n abstract _cloneInto(to?: T): T;\n // Safe version that clones internal state\n abstract clone(): T;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\n/** Hash function */\nexport type CHash = ReturnType<typeof createHasher>;\n/** Hash function with output */\nexport type CHashO = ReturnType<typeof createOptHasher>;\n/** XOF with output */\nexport type CHashXO = ReturnType<typeof createXOFer>;\n\n/** Wraps hash function, creating an interface on top of it */\nexport function createHasher<T extends Hash<T>>(\n hashCons: () => Hash<T>\n): {\n (msg: Input): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(): Hash<T>;\n} {\n const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\n\nexport function createOptHasher<H extends Hash<H>, T extends Object>(\n hashCons: (opts?: T) => Hash<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts?: T): Hash<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts?: T) => hashCons(opts);\n return hashC;\n}\n\nexport function createXOFer<H extends HashXOF<H>, T extends Object>(\n hashCons: (opts?: T) => HashXOF<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts?: T): HashXOF<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts?: T) => hashCons(opts);\n return hashC;\n}\nexport const wrapConstructor: typeof createHasher = createHasher;\nexport const wrapConstructorWithOpts: typeof createOptHasher = createOptHasher;\nexport const wrapXOFConstructorWithOpts: typeof createXOFer = createXOFer;\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n // Legacy Node.js compatibility\n if (crypto && typeof crypto.randomBytes === 'function') {\n return Uint8Array.from(crypto.randomBytes(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n","/**\n * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.\n * @todo re-check https://issues.chromium.org/issues/42212588\n * @module\n */\nconst U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);\nconst _32n = /* @__PURE__ */ BigInt(32);\n\nfunction fromBig(\n n: bigint,\n le = false\n): {\n h: number;\n l: number;\n} {\n if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };\n return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };\n}\n\nfunction split(lst: bigint[], le = false): Uint32Array[] {\n const len = lst.length;\n let Ah = new Uint32Array(len);\n let Al = new Uint32Array(len);\n for (let i = 0; i < len; i++) {\n const { h, l } = fromBig(lst[i], le);\n [Ah[i], Al[i]] = [h, l];\n }\n return [Ah, Al];\n}\n\nconst toBig = (h: number, l: number): bigint => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);\n// for Shift in [0, 32)\nconst shrSH = (h: number, _l: number, s: number): number => h >>> s;\nconst shrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in [1, 32)\nconst rotrSH = (h: number, l: number, s: number): number => (h >>> s) | (l << (32 - s));\nconst rotrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotrBH = (h: number, l: number, s: number): number => (h << (64 - s)) | (l >>> (s - 32));\nconst rotrBL = (h: number, l: number, s: number): number => (h >>> (s - 32)) | (l << (64 - s));\n// Right rotate for shift===32 (just swaps l&h)\nconst rotr32H = (_h: number, l: number): number => l;\nconst rotr32L = (h: number, _l: number): number => h;\n// Left rotate for Shift in [1, 32)\nconst rotlSH = (h: number, l: number, s: number): number => (h << s) | (l >>> (32 - s));\nconst rotlSL = (h: number, l: number, s: number): number => (l << s) | (h >>> (32 - s));\n// Left rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotlBH = (h: number, l: number, s: number): number => (l << (s - 32)) | (h >>> (64 - s));\nconst rotlBL = (h: number, l: number, s: number): number => (h << (s - 32)) | (l >>> (64 - s));\n\n// JS uses 32-bit signed integers for bitwise operations which means we cannot\n// simple take carry out of low bit sum by shift, we need to use division.\nfunction add(\n Ah: number,\n Al: number,\n Bh: number,\n Bl: number\n): {\n h: number;\n l: number;\n} {\n const l = (Al >>> 0) + (Bl >>> 0);\n return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };\n}\n// Addition with more than 2 elements\nconst add3L = (Al: number, Bl: number, Cl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);\nconst add3H = (low: number, Ah: number, Bh: number, Ch: number): number =>\n (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;\nconst add4L = (Al: number, Bl: number, Cl: number, Dl: number): number =>\n (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);\nconst add4H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number): number =>\n (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;\nconst add5L = (Al: number, Bl: number, Cl: number, Dl: number, El: number): number =>\n (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);\nconst add5H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number): number =>\n (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;\n\n// prettier-ignore\nexport {\n add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig\n};\n// prettier-ignore\nconst u64: { fromBig: typeof fromBig; split: typeof split; toBig: (h: number, l: number) => bigint; shrSH: (h: number, _l: number, s: number) => number; shrSL: (h: number, l: number, s: number) => number; rotrSH: (h: number, l: number, s: number) => number; rotrSL: (h: number, l: number, s: number) => number; rotrBH: (h: number, l: number, s: number) => number; rotrBL: (h: number, l: number, s: number) => number; rotr32H: (_h: number, l: number) => number; rotr32L: (h: number, _l: number) => number; rotlSH: (h: number, l: number, s: number) => number; rotlSL: (h: number, l: number, s: number) => number; rotlBH: (h: number, l: number, s: number) => number; rotlBL: (h: number, l: number, s: number) => number; add: typeof add; add3L: (Al: number, Bl: number, Cl: number) => number; add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; } = {\n fromBig, split, toBig,\n shrSH, shrSL,\n rotrSH, rotrSL, rotrBH, rotrBL,\n rotr32H, rotr32L,\n rotlSH, rotlSL, rotlBH, rotlBL,\n add, add3L, add3H, add4L, add4H, add5H, add5L,\n};\nexport default u64;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ATOMIC_RE,
|
|
4
|
+
UUID_RE
|
|
5
|
+
} from "./chunk-3OV7E5G5.js";
|
|
6
|
+
import {
|
|
7
|
+
CLIENT_HEADER,
|
|
8
|
+
httpRequest,
|
|
9
|
+
trimSlash
|
|
10
|
+
} from "./chunk-4ONXEEQL.js";
|
|
11
|
+
import {
|
|
12
|
+
CliError,
|
|
13
|
+
external_exports
|
|
14
|
+
} from "./chunk-OYMYCW7J.js";
|
|
15
|
+
|
|
16
|
+
// src/lib/agent-api.ts
|
|
17
|
+
var FRESH_WITHIN_RE = /^P(\d+)[DWMY]$/;
|
|
18
|
+
var CANONICAL_KEY_RE = /^[a-z][a-z0-9_]{0,31}$/;
|
|
19
|
+
function buildLookupRequest(input) {
|
|
20
|
+
const question = input.question.trim();
|
|
21
|
+
if (question.length === 0 || question.length > 512) {
|
|
22
|
+
throw new CliError("USAGE", "question must be 1 to 512 characters", {
|
|
23
|
+
fix: "Pass a non-empty question under 512 characters."
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (input.freshWithin !== void 0) {
|
|
27
|
+
const digits = FRESH_WITHIN_RE.exec(input.freshWithin)?.[1];
|
|
28
|
+
if (digits === void 0 || Number(digits) === 0) {
|
|
29
|
+
throw new CliError("USAGE", `Invalid --fresh-within: ${JSON.stringify(input.freshWithin)}`, {
|
|
30
|
+
fix: "Use a nonzero ISO-like window P<n>[DWMY], e.g. P30D, P2W, P1Y."
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (input.maxPrice !== void 0 && !ATOMIC_RE.test(input.maxPrice)) {
|
|
35
|
+
throw new CliError("USAGE", `Invalid --max-price: ${JSON.stringify(input.maxPrice)}`, {
|
|
36
|
+
fix: "Pass an atomic USDC integer, e.g. 100000 for $0.10."
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const limit = input.limit ?? 5;
|
|
40
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 10) {
|
|
41
|
+
throw new CliError("USAGE", `Invalid --limit: ${JSON.stringify(input.limit)}`, {
|
|
42
|
+
fix: "Pass an integer between 1 and 10."
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (input.appliesTo !== void 0) {
|
|
46
|
+
const keys = Object.keys(input.appliesTo);
|
|
47
|
+
if (keys.length > 8) {
|
|
48
|
+
throw new CliError("USAGE", "Too many --applies-to keys (max 8).");
|
|
49
|
+
}
|
|
50
|
+
for (const [key, values] of Object.entries(input.appliesTo)) {
|
|
51
|
+
if (!CANONICAL_KEY_RE.test(key)) {
|
|
52
|
+
throw new CliError("USAGE", `Invalid appliesTo key: ${JSON.stringify(key)}`, {
|
|
53
|
+
fix: "Keys must be canonical lowercase identifiers, e.g. products=Vercel."
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (values.length === 0) {
|
|
57
|
+
throw new CliError("USAGE", `appliesTo key ${JSON.stringify(key)} has no values`, {
|
|
58
|
+
fix: "Give each --applies-to key at least one value."
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (values.length > 20) {
|
|
62
|
+
throw new CliError("USAGE", `Too many --applies-to values for ${key} (max 20).`);
|
|
63
|
+
}
|
|
64
|
+
for (const value of values) {
|
|
65
|
+
if (value.length === 0 || value.length > 120) {
|
|
66
|
+
throw new CliError(
|
|
67
|
+
"USAGE",
|
|
68
|
+
`Invalid --applies-to value for ${key}: must be 1 to 120 characters.`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
schemaVersion: 1,
|
|
76
|
+
question,
|
|
77
|
+
...input.freshWithin !== void 0 ? { freshWithin: input.freshWithin } : {},
|
|
78
|
+
...input.maxPrice !== void 0 ? { maxPrice: input.maxPrice } : {},
|
|
79
|
+
...input.appliesTo !== void 0 ? { appliesTo: input.appliesTo } : {},
|
|
80
|
+
limit
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
var lookupCandidateSchema = external_exports.object({
|
|
84
|
+
resourceId: external_exports.string().regex(UUID_RE, "resourceId must be a uuid"),
|
|
85
|
+
url: external_exports.string(),
|
|
86
|
+
title: external_exports.string(),
|
|
87
|
+
artifactType: external_exports.string(),
|
|
88
|
+
price: external_exports.string().regex(ATOMIC_RE, "price must be an atomic integer string"),
|
|
89
|
+
asOf: external_exports.string().nullable(),
|
|
90
|
+
validUntil: external_exports.string().nullable(),
|
|
91
|
+
temporalMode: external_exports.string(),
|
|
92
|
+
appliesTo: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())),
|
|
93
|
+
questionsAnswered: external_exports.array(external_exports.string()),
|
|
94
|
+
tasksSupported: external_exports.array(external_exports.string()),
|
|
95
|
+
scope: external_exports.string().nullable(),
|
|
96
|
+
exclusions: external_exports.string().nullable(),
|
|
97
|
+
matchReasons: external_exports.array(external_exports.string()),
|
|
98
|
+
estimatedTokens: external_exports.number(),
|
|
99
|
+
creator: external_exports.object({ handle: external_exports.string() }).passthrough()
|
|
100
|
+
}).passthrough();
|
|
101
|
+
var lookupResponseSchema = external_exports.object({
|
|
102
|
+
schemaVersion: external_exports.literal(1),
|
|
103
|
+
lookupId: external_exports.string().regex(UUID_RE, "lookupId must be a uuid"),
|
|
104
|
+
decision: external_exports.enum(["CANDIDATES", "MISS"]),
|
|
105
|
+
calibration: external_exports.string(),
|
|
106
|
+
candidates: external_exports.array(lookupCandidateSchema).optional()
|
|
107
|
+
});
|
|
108
|
+
function apiFailure(url, result) {
|
|
109
|
+
const code = result.kind === "network" || result.kind === "timeout" ? "NETWORK_ERROR" : "API_UNREACHABLE";
|
|
110
|
+
return new CliError(code, `${url}: ${result.message}`, {
|
|
111
|
+
fix: "Check --base-url and your network, then retry."
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function rateLimitError(url, header) {
|
|
115
|
+
const retryAfter = header("retry-after");
|
|
116
|
+
const seconds = retryAfter !== void 0 ? Number(retryAfter) : void 0;
|
|
117
|
+
return new CliError("RATE_LIMITED", `${url}: rate limited by the server.`, {
|
|
118
|
+
fix: seconds !== void 0 && Number.isFinite(seconds) ? `Retry after ${seconds}s.` : "Back off and retry shortly.",
|
|
119
|
+
details: {
|
|
120
|
+
...seconds !== void 0 && Number.isFinite(seconds) ? { retryAfterSeconds: seconds } : {}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function serverErrorMessage(json) {
|
|
125
|
+
if (typeof json === "object" && json !== null) {
|
|
126
|
+
const rec = json;
|
|
127
|
+
const err = rec.error;
|
|
128
|
+
if (typeof err === "string") return err;
|
|
129
|
+
if (typeof err === "object" && err !== null) {
|
|
130
|
+
const m = err.message;
|
|
131
|
+
if (typeof m === "string") return m;
|
|
132
|
+
}
|
|
133
|
+
if (typeof rec.message === "string") return rec.message;
|
|
134
|
+
}
|
|
135
|
+
return void 0;
|
|
136
|
+
}
|
|
137
|
+
async function postLookup(body, opts) {
|
|
138
|
+
const url = `${trimSlash(opts.baseUrl)}/api/agent/lookup`;
|
|
139
|
+
const res = await httpRequest(url, {
|
|
140
|
+
method: "POST",
|
|
141
|
+
timeoutMs: opts.timeoutMs,
|
|
142
|
+
headers: {
|
|
143
|
+
"x-tenjin-client": CLIENT_HEADER,
|
|
144
|
+
...opts.evalCohort === true ? { "x-tenjin-eval-cohort": "1" } : {}
|
|
145
|
+
},
|
|
146
|
+
jsonBody: body,
|
|
147
|
+
fetchImpl: opts.fetchImpl
|
|
148
|
+
});
|
|
149
|
+
if (!res.ok) throw apiFailure(url, res);
|
|
150
|
+
if (res.status === 429) throw rateLimitError(url, (n) => res.header(n));
|
|
151
|
+
if (res.status !== 200) {
|
|
152
|
+
throw new CliError(
|
|
153
|
+
"API_UNREACHABLE",
|
|
154
|
+
serverErrorMessage(res.json) ?? `Lookup failed (${res.status})`,
|
|
155
|
+
{
|
|
156
|
+
fix: "Retry; if it persists the lookup endpoint may be unavailable.",
|
|
157
|
+
details: res.json
|
|
158
|
+
}
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
const parsed = lookupResponseSchema.safeParse(res.json);
|
|
162
|
+
if (!parsed.success) {
|
|
163
|
+
throw new CliError("CONTRACT_MISMATCH", "Lookup response did not match the expected contract", {
|
|
164
|
+
fix: "Update tenjin-cli; the server contract may have changed.",
|
|
165
|
+
details: parsed.error.issues
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return truncateResponse(parsed.data);
|
|
169
|
+
}
|
|
170
|
+
var CAND_BOUNDS = {
|
|
171
|
+
title: 200,
|
|
172
|
+
scope: 240,
|
|
173
|
+
exclusions: 240,
|
|
174
|
+
listItems: 4,
|
|
175
|
+
listItemChars: 160,
|
|
176
|
+
matchReasons: 3,
|
|
177
|
+
matchReasonChars: 80,
|
|
178
|
+
appliesToKeys: 6,
|
|
179
|
+
appliesToValues: 5,
|
|
180
|
+
appliesToValueChars: 80
|
|
181
|
+
};
|
|
182
|
+
function truncateResponse(res) {
|
|
183
|
+
if (res.candidates === void 0) return res;
|
|
184
|
+
return { ...res, candidates: res.candidates.map(truncateCandidate) };
|
|
185
|
+
}
|
|
186
|
+
function truncateCandidate(c) {
|
|
187
|
+
const cap = (s, n) => s.length > n ? s.slice(0, n) : s;
|
|
188
|
+
const capList = (list, items, chars) => list.slice(0, items).map((s) => cap(s, chars));
|
|
189
|
+
const appliesTo = {};
|
|
190
|
+
for (const key of Object.keys(c.appliesTo).slice(0, CAND_BOUNDS.appliesToKeys)) {
|
|
191
|
+
appliesTo[cap(key, CAND_BOUNDS.appliesToValueChars)] = capList(
|
|
192
|
+
c.appliesTo[key] ?? [],
|
|
193
|
+
CAND_BOUNDS.appliesToValues,
|
|
194
|
+
CAND_BOUNDS.appliesToValueChars
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
...c,
|
|
199
|
+
title: cap(c.title, CAND_BOUNDS.title),
|
|
200
|
+
scope: c.scope === null ? null : cap(c.scope, CAND_BOUNDS.scope),
|
|
201
|
+
exclusions: c.exclusions === null ? null : cap(c.exclusions, CAND_BOUNDS.exclusions),
|
|
202
|
+
questionsAnswered: capList(
|
|
203
|
+
c.questionsAnswered,
|
|
204
|
+
CAND_BOUNDS.listItems,
|
|
205
|
+
CAND_BOUNDS.listItemChars
|
|
206
|
+
),
|
|
207
|
+
tasksSupported: capList(c.tasksSupported, CAND_BOUNDS.listItems, CAND_BOUNDS.listItemChars),
|
|
208
|
+
matchReasons: capList(c.matchReasons, CAND_BOUNDS.matchReasons, CAND_BOUNDS.matchReasonChars),
|
|
209
|
+
appliesTo
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
var OUTCOME_STATUSES = [
|
|
213
|
+
"used",
|
|
214
|
+
"partially_used",
|
|
215
|
+
"rejected",
|
|
216
|
+
"regenerated",
|
|
217
|
+
"purchase_declined"
|
|
218
|
+
];
|
|
219
|
+
var OUTCOME_STATUS_VALUES = OUTCOME_STATUSES;
|
|
220
|
+
var CONTENT_HASH_RE = /^sha256:[0-9a-f]{64}$/;
|
|
221
|
+
function buildOutcomeItem(input) {
|
|
222
|
+
if (!OUTCOME_STATUS_VALUES.includes(input.status)) {
|
|
223
|
+
throw new CliError("USAGE", `Invalid outcome status: ${JSON.stringify(input.status)}`, {
|
|
224
|
+
fix: `Use one of: ${OUTCOME_STATUSES.join(", ")}.`
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
if (input.resourceId !== void 0 && !UUID_RE.test(input.resourceId)) {
|
|
228
|
+
throw new CliError("USAGE", `Invalid --resource id: ${JSON.stringify(input.resourceId)}`, {
|
|
229
|
+
fix: "Pass the resourceId (a uuid) from a lookup candidate."
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
if (input.contentHash !== void 0 && !CONTENT_HASH_RE.test(input.contentHash)) {
|
|
233
|
+
throw new CliError("USAGE", `Invalid content hash: ${JSON.stringify(input.contentHash)}`, {
|
|
234
|
+
fix: 'A content hash is "sha256:<64 hex>".'
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
status: input.status,
|
|
239
|
+
...input.resourceId !== void 0 ? { resourceId: input.resourceId } : {},
|
|
240
|
+
...input.contentHash !== void 0 ? { contentHash: input.contentHash } : {}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
var LOOKUP_ID_RE = UUID_RE;
|
|
244
|
+
async function postOutcomes(lookupId, items, opts) {
|
|
245
|
+
if (!LOOKUP_ID_RE.test(lookupId)) {
|
|
246
|
+
throw new CliError("USAGE", `Invalid lookup id: ${JSON.stringify(lookupId)}`, {
|
|
247
|
+
fix: "Pass the lookupId from a prior lookup (or use --last)."
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (items.length === 0 || items.length > 10) {
|
|
251
|
+
throw new CliError("USAGE", "An outcome report carries 1 to 10 items", {
|
|
252
|
+
fix: "Report between 1 and 10 outcomes per call."
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
const url = `${trimSlash(opts.baseUrl)}/api/agent/lookups/${lookupId}/outcomes`;
|
|
256
|
+
const res = await httpRequest(url, {
|
|
257
|
+
method: "POST",
|
|
258
|
+
timeoutMs: opts.timeoutMs,
|
|
259
|
+
headers: { "x-tenjin-client": CLIENT_HEADER },
|
|
260
|
+
jsonBody: items.length === 1 ? items[0] : items,
|
|
261
|
+
fetchImpl: opts.fetchImpl
|
|
262
|
+
});
|
|
263
|
+
if (!res.ok) throw apiFailure(url, res);
|
|
264
|
+
if (res.status === 429) throw rateLimitError(url, (n) => res.header(n));
|
|
265
|
+
if (res.status !== 202) {
|
|
266
|
+
throw new CliError(
|
|
267
|
+
"API_UNREACHABLE",
|
|
268
|
+
serverErrorMessage(res.json) ?? `Outcome report failed (${res.status})`,
|
|
269
|
+
{
|
|
270
|
+
fix: "Check the status vocabulary and lookup id, then retry.",
|
|
271
|
+
details: res.json
|
|
272
|
+
}
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
const accepted = typeof res.json === "object" && res.json !== null && "accepted" in res.json ? Number(res.json.accepted) : items.length;
|
|
276
|
+
return { accepted: Number.isFinite(accepted) ? accepted : items.length };
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export {
|
|
280
|
+
buildLookupRequest,
|
|
281
|
+
rateLimitError,
|
|
282
|
+
postLookup,
|
|
283
|
+
buildOutcomeItem,
|
|
284
|
+
postOutcomes
|
|
285
|
+
};
|
|
286
|
+
//# sourceMappingURL=chunk-662MSGZB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/agent-api.ts"],"sourcesContent":["import { z } from 'zod';\nimport { CliError } from './errors';\nimport { httpRequest, type HttpResult } from './http';\nimport { CLIENT_HEADER } from './client-meta';\nimport { ATOMIC_RE, UUID_RE } from './ids';\nimport { trimSlash } from './url';\n\n/**\n * The lookup + outcome HTTP contract (A2, tenjin#370). Request building and\n * response validation live here; the wire shape is validated defensively, an\n * unknown `schemaVersion` degrades to a parse refusal rather than a guess, and\n * unrecognized candidate fields are ignored (forward-compatible), per spec 10.\n *\n * These endpoints are anonymous: no wallet, no SIWX. The only header of note is\n * `X-Tenjin-Client`, which attributes a later purchase back to the lookup flow.\n */\n\nconst FRESH_WITHIN_RE = /^P(\\d+)[DWMY]$/;\nconst CANONICAL_KEY_RE = /^[a-z][a-z0-9_]{0,31}$/;\n\n/** Client-side lookup request (mirrors lib/lookup.ts lookupRequestSchema bounds\n * so a malformed flag fails locally as USAGE, before a round trip). */\nexport interface LookupInput {\n question: string;\n freshWithin?: string;\n maxPrice?: string;\n appliesTo?: Record<string, string[]>;\n limit?: number;\n}\n\nexport interface LookupRequestBody {\n schemaVersion: 1;\n question: string;\n freshWithin?: string;\n maxPrice?: string;\n appliesTo?: Record<string, string[]>;\n limit: number;\n}\n\nexport function buildLookupRequest(input: LookupInput): LookupRequestBody {\n const question = input.question.trim();\n if (question.length === 0 || question.length > 512) {\n throw new CliError('USAGE', 'question must be 1 to 512 characters', {\n fix: 'Pass a non-empty question under 512 characters.',\n });\n }\n if (input.freshWithin !== undefined) {\n // The server rejects ANY zero-valued duration (P0D, P0W, P00M, ...), so a\n // zero window fails here as USAGE instead of a remote 400.\n const digits = FRESH_WITHIN_RE.exec(input.freshWithin)?.[1];\n if (digits === undefined || Number(digits) === 0) {\n throw new CliError('USAGE', `Invalid --fresh-within: ${JSON.stringify(input.freshWithin)}`, {\n fix: 'Use a nonzero ISO-like window P<n>[DWMY], e.g. P30D, P2W, P1Y.',\n });\n }\n }\n if (input.maxPrice !== undefined && !ATOMIC_RE.test(input.maxPrice)) {\n throw new CliError('USAGE', `Invalid --max-price: ${JSON.stringify(input.maxPrice)}`, {\n fix: 'Pass an atomic USDC integer, e.g. 100000 for $0.10.',\n });\n }\n const limit = input.limit ?? 5;\n if (!Number.isInteger(limit) || limit < 1 || limit > 10) {\n throw new CliError('USAGE', `Invalid --limit: ${JSON.stringify(input.limit)}`, {\n fix: 'Pass an integer between 1 and 10.',\n });\n }\n if (input.appliesTo !== undefined) {\n // Mirror the server's strictObject bounds (<=8 keys, <=20 values/key,\n // 1..120 chars/value) so a bad filter fails locally, never as a remote 400.\n const keys = Object.keys(input.appliesTo);\n if (keys.length > 8) {\n throw new CliError('USAGE', 'Too many --applies-to keys (max 8).');\n }\n for (const [key, values] of Object.entries(input.appliesTo)) {\n if (!CANONICAL_KEY_RE.test(key)) {\n throw new CliError('USAGE', `Invalid appliesTo key: ${JSON.stringify(key)}`, {\n fix: 'Keys must be canonical lowercase identifiers, e.g. products=Vercel.',\n });\n }\n if (values.length === 0) {\n throw new CliError('USAGE', `appliesTo key ${JSON.stringify(key)} has no values`, {\n fix: 'Give each --applies-to key at least one value.',\n });\n }\n if (values.length > 20) {\n throw new CliError('USAGE', `Too many --applies-to values for ${key} (max 20).`);\n }\n for (const value of values) {\n if (value.length === 0 || value.length > 120) {\n throw new CliError(\n 'USAGE',\n `Invalid --applies-to value for ${key}: must be 1 to 120 characters.`,\n );\n }\n }\n }\n }\n return {\n schemaVersion: 1,\n question,\n ...(input.freshWithin !== undefined ? { freshWithin: input.freshWithin } : {}),\n ...(input.maxPrice !== undefined ? { maxPrice: input.maxPrice } : {}),\n ...(input.appliesTo !== undefined ? { appliesTo: input.appliesTo } : {}),\n limit,\n };\n}\n\n// Response schemas. `.passthrough()` on the candidate keeps unknown future fields\n// instead of stripping them (forward-compatible), while still requiring the\n// contract fields this CLI reads. `decision` is uppercase on the wire.\nexport const lookupCandidateSchema = z\n .object({\n resourceId: z.string().regex(UUID_RE, 'resourceId must be a uuid'),\n url: z.string(),\n title: z.string(),\n artifactType: z.string(),\n price: z.string().regex(ATOMIC_RE, 'price must be an atomic integer string'),\n asOf: z.string().nullable(),\n validUntil: z.string().nullable(),\n temporalMode: z.string(),\n appliesTo: z.record(z.string(), z.array(z.string())),\n questionsAnswered: z.array(z.string()),\n tasksSupported: z.array(z.string()),\n scope: z.string().nullable(),\n exclusions: z.string().nullable(),\n matchReasons: z.array(z.string()),\n estimatedTokens: z.number(),\n creator: z.object({ handle: z.string() }).passthrough(),\n })\n .passthrough();\n\nexport type LookupCandidate = z.infer<typeof lookupCandidateSchema>;\n\nexport const lookupResponseSchema = z.object({\n schemaVersion: z.literal(1),\n lookupId: z.string().regex(UUID_RE, 'lookupId must be a uuid'),\n decision: z.enum(['CANDIDATES', 'MISS']),\n calibration: z.string(),\n candidates: z.array(lookupCandidateSchema).optional(),\n});\n\nexport type LookupResponse = z.infer<typeof lookupResponseSchema>;\n\nexport interface AgentApiOptions {\n baseUrl: string;\n timeoutMs: number;\n fetchImpl?: typeof fetch;\n /** Spec 09 §3 evaluation-cohort opt-in: sends X-Tenjin-Eval-Cohort: 1. */\n evalCohort?: boolean;\n}\n\n/** Turn a non-2xx / transport HttpResult into the CLI error contract. */\nfunction apiFailure(url: string, result: Exclude<HttpResult, { ok: true }>): CliError {\n const code =\n result.kind === 'network' || result.kind === 'timeout' ? 'NETWORK_ERROR' : 'API_UNREACHABLE';\n return new CliError(code, `${url}: ${result.message}`, {\n fix: 'Check --base-url and your network, then retry.',\n });\n}\n\n/** 429 with Retry-After: a recoverable pause, not an outage; agents branch on it. */\nexport function rateLimitError(\n url: string,\n header: (name: string) => string | undefined,\n): CliError {\n const retryAfter = header('retry-after');\n const seconds = retryAfter !== undefined ? Number(retryAfter) : undefined;\n return new CliError('RATE_LIMITED', `${url}: rate limited by the server.`, {\n fix:\n seconds !== undefined && Number.isFinite(seconds)\n ? `Retry after ${seconds}s.`\n : 'Back off and retry shortly.',\n details: {\n ...(seconds !== undefined && Number.isFinite(seconds) ? { retryAfterSeconds: seconds } : {}),\n },\n });\n}\n\nfunction serverErrorMessage(json: unknown): string | undefined {\n if (typeof json === 'object' && json !== null) {\n const rec = json as Record<string, unknown>;\n const err = rec.error;\n if (typeof err === 'string') return err;\n if (typeof err === 'object' && err !== null) {\n const m = (err as Record<string, unknown>).message;\n if (typeof m === 'string') return m;\n }\n if (typeof rec.message === 'string') return rec.message;\n }\n return undefined;\n}\n\nexport async function postLookup(\n body: LookupRequestBody,\n opts: AgentApiOptions,\n): Promise<LookupResponse> {\n const url = `${trimSlash(opts.baseUrl)}/api/agent/lookup`;\n const res = await httpRequest(url, {\n method: 'POST',\n timeoutMs: opts.timeoutMs,\n headers: {\n 'x-tenjin-client': CLIENT_HEADER,\n ...(opts.evalCohort === true ? { 'x-tenjin-eval-cohort': '1' } : {}),\n },\n jsonBody: body,\n fetchImpl: opts.fetchImpl,\n });\n if (!res.ok) throw apiFailure(url, res);\n if (res.status === 429) throw rateLimitError(url, (n) => res.header(n));\n if (res.status !== 200) {\n throw new CliError(\n 'API_UNREACHABLE',\n serverErrorMessage(res.json) ?? `Lookup failed (${res.status})`,\n {\n fix: 'Retry; if it persists the lookup endpoint may be unavailable.',\n details: res.json,\n },\n );\n }\n const parsed = lookupResponseSchema.safeParse(res.json);\n if (!parsed.success) {\n throw new CliError('CONTRACT_MISMATCH', 'Lookup response did not match the expected contract', {\n fix: 'Update tenjin-cli; the server contract may have changed.',\n details: parsed.error.issues,\n });\n }\n return truncateResponse(parsed.data);\n}\n\n/**\n * The server bounds every card string (response budget ~1k tokens, spec 09);\n * re-apply the same caps defensively so a misbehaving server cannot blow up an\n * agent transcript through the CLI (spec 10 response-size discipline).\n */\nconst CAND_BOUNDS = {\n title: 200,\n scope: 240,\n exclusions: 240,\n listItems: 4,\n listItemChars: 160,\n matchReasons: 3,\n matchReasonChars: 80,\n appliesToKeys: 6,\n appliesToValues: 5,\n appliesToValueChars: 80,\n} as const;\n\nfunction truncateResponse(res: LookupResponse): LookupResponse {\n if (res.candidates === undefined) return res;\n return { ...res, candidates: res.candidates.map(truncateCandidate) };\n}\n\nfunction truncateCandidate(c: LookupCandidate): LookupCandidate {\n const cap = (s: string, n: number): string => (s.length > n ? s.slice(0, n) : s);\n const capList = (list: string[], items: number, chars: number): string[] =>\n list.slice(0, items).map((s) => cap(s, chars));\n const appliesTo: Record<string, string[]> = {};\n for (const key of Object.keys(c.appliesTo).slice(0, CAND_BOUNDS.appliesToKeys)) {\n appliesTo[cap(key, CAND_BOUNDS.appliesToValueChars)] = capList(\n c.appliesTo[key] ?? [],\n CAND_BOUNDS.appliesToValues,\n CAND_BOUNDS.appliesToValueChars,\n );\n }\n return {\n ...c,\n title: cap(c.title, CAND_BOUNDS.title),\n scope: c.scope === null ? null : cap(c.scope, CAND_BOUNDS.scope),\n exclusions: c.exclusions === null ? null : cap(c.exclusions, CAND_BOUNDS.exclusions),\n questionsAnswered: capList(\n c.questionsAnswered,\n CAND_BOUNDS.listItems,\n CAND_BOUNDS.listItemChars,\n ),\n tasksSupported: capList(c.tasksSupported, CAND_BOUNDS.listItems, CAND_BOUNDS.listItemChars),\n matchReasons: capList(c.matchReasons, CAND_BOUNDS.matchReasons, CAND_BOUNDS.matchReasonChars),\n appliesTo,\n };\n}\n\nconst OUTCOME_STATUSES = [\n 'used',\n 'partially_used',\n 'rejected',\n 'regenerated',\n 'purchase_declined',\n] as const;\nexport type OutcomeStatus = (typeof OUTCOME_STATUSES)[number];\nexport const OUTCOME_STATUS_VALUES: readonly string[] = OUTCOME_STATUSES;\n\nconst CONTENT_HASH_RE = /^sha256:[0-9a-f]{64}$/;\n\nexport interface OutcomeInput {\n status: string;\n resourceId?: string;\n contentHash?: string;\n}\n\nexport interface OutcomeBodyItem {\n status: OutcomeStatus;\n resourceId?: string;\n contentHash?: string;\n}\n\nexport function buildOutcomeItem(input: OutcomeInput): OutcomeBodyItem {\n if (!OUTCOME_STATUS_VALUES.includes(input.status)) {\n throw new CliError('USAGE', `Invalid outcome status: ${JSON.stringify(input.status)}`, {\n fix: `Use one of: ${OUTCOME_STATUSES.join(', ')}.`,\n });\n }\n if (input.resourceId !== undefined && !UUID_RE.test(input.resourceId)) {\n throw new CliError('USAGE', `Invalid --resource id: ${JSON.stringify(input.resourceId)}`, {\n fix: 'Pass the resourceId (a uuid) from a lookup candidate.',\n });\n }\n if (input.contentHash !== undefined && !CONTENT_HASH_RE.test(input.contentHash)) {\n throw new CliError('USAGE', `Invalid content hash: ${JSON.stringify(input.contentHash)}`, {\n fix: 'A content hash is \"sha256:<64 hex>\".',\n });\n }\n return {\n status: input.status as OutcomeStatus,\n ...(input.resourceId !== undefined ? { resourceId: input.resourceId } : {}),\n ...(input.contentHash !== undefined ? { contentHash: input.contentHash } : {}),\n };\n}\n\nconst LOOKUP_ID_RE = UUID_RE;\n\nexport async function postOutcomes(\n lookupId: string,\n items: OutcomeBodyItem[],\n opts: AgentApiOptions,\n): Promise<{ accepted: number }> {\n if (!LOOKUP_ID_RE.test(lookupId)) {\n throw new CliError('USAGE', `Invalid lookup id: ${JSON.stringify(lookupId)}`, {\n fix: 'Pass the lookupId from a prior lookup (or use --last).',\n });\n }\n if (items.length === 0 || items.length > 10) {\n throw new CliError('USAGE', 'An outcome report carries 1 to 10 items', {\n fix: 'Report between 1 and 10 outcomes per call.',\n });\n }\n const url = `${trimSlash(opts.baseUrl)}/api/agent/lookups/${lookupId}/outcomes`;\n const res = await httpRequest(url, {\n method: 'POST',\n timeoutMs: opts.timeoutMs,\n headers: { 'x-tenjin-client': CLIENT_HEADER },\n jsonBody: items.length === 1 ? items[0] : items,\n fetchImpl: opts.fetchImpl,\n });\n if (!res.ok) throw apiFailure(url, res);\n if (res.status === 429) throw rateLimitError(url, (n) => res.header(n));\n // 202 is the only success; the body is a uniform { accepted } regardless of\n // whether the lookupId existed (no existence oracle, by design).\n if (res.status !== 202) {\n throw new CliError(\n 'API_UNREACHABLE',\n serverErrorMessage(res.json) ?? `Outcome report failed (${res.status})`,\n {\n fix: 'Check the status vocabulary and lookup id, then retry.',\n details: res.json,\n },\n );\n }\n const accepted =\n typeof res.json === 'object' && res.json !== null && 'accepted' in res.json\n ? Number((res.json as { accepted: unknown }).accepted)\n : items.length;\n return { accepted: Number.isFinite(accepted) ? accepted : items.length };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
findStoredCandidate
|
|
4
|
+
} from "./chunk-JPHG2JW3.js";
|
|
5
|
+
import {
|
|
6
|
+
UUID_RE
|
|
7
|
+
} from "./chunk-3OV7E5G5.js";
|
|
8
|
+
import {
|
|
9
|
+
CliError
|
|
10
|
+
} from "./chunk-OYMYCW7J.js";
|
|
11
|
+
|
|
12
|
+
// src/lib/resource-ref.ts
|
|
13
|
+
function assertOnBaseOrigin(url, baseUrl, what) {
|
|
14
|
+
let target;
|
|
15
|
+
let base;
|
|
16
|
+
try {
|
|
17
|
+
target = new URL(url);
|
|
18
|
+
base = new URL(baseUrl);
|
|
19
|
+
} catch {
|
|
20
|
+
throw new CliError("USAGE", `Invalid ${what}: ${JSON.stringify(url)}`, {
|
|
21
|
+
fix: "Pass an absolute https URL on the configured base URL."
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (target.origin !== base.origin) {
|
|
25
|
+
throw new CliError(
|
|
26
|
+
"USAGE",
|
|
27
|
+
`${what} origin ${target.origin} does not match the configured base URL ${base.origin}.`,
|
|
28
|
+
{
|
|
29
|
+
fix: "The CLI signs SIWX and payments only for the configured base URL. Pass --base-url if you meant a different deployment."
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function resolveResourceRef(arg, dataDir, baseUrl) {
|
|
35
|
+
const trimmed = arg.trim();
|
|
36
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
37
|
+
assertOnBaseOrigin(trimmed, baseUrl, "resource URL");
|
|
38
|
+
return { url: trimmed };
|
|
39
|
+
}
|
|
40
|
+
if (UUID_RE.test(trimmed)) {
|
|
41
|
+
const candidate = await findStoredCandidate(dataDir, trimmed);
|
|
42
|
+
if (candidate === null) {
|
|
43
|
+
throw new CliError("RESOURCE_NOT_FOUND", `No local lookup knows resource ${trimmed}.`, {
|
|
44
|
+
fix: "Run `tenjin lookup` to surface it first, or pass the full read URL."
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
assertOnBaseOrigin(candidate.url, baseUrl, "stored candidate URL");
|
|
48
|
+
return { url: candidate.url, resourceId: trimmed };
|
|
49
|
+
}
|
|
50
|
+
throw new CliError("USAGE", `Not a resource URL or id: ${JSON.stringify(arg)}`, {
|
|
51
|
+
fix: "Pass a full https read URL (a candidate `url`) or a resourceId uuid."
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
assertOnBaseOrigin,
|
|
57
|
+
resolveResourceRef
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=chunk-7KUW4MJD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/resource-ref.ts"],"sourcesContent":["import { CliError } from './errors';\nimport { findStoredCandidate } from './lookup-store';\nimport { UUID_RE } from './ids';\n\n/**\n * Resolve a `<resource-url-or-id>` CLI argument to the payable read URL. A full\n * http(s) URL must live on the configured base URL's origin; a bare uuid is a\n * resourceId, resolved to its URL through the local lookup store (the read route\n * is keyed by handle/slug, so an id alone cannot build the URL). Anything else is\n * a usage error with a clear fix.\n *\n * The origin pin is a MONEY-PATH trust boundary, not pedantry: `buy` sends a\n * wallet-signed SIWX header (a bearer credential scoped to the configured\n * domain) and an EIP-3009 payment authorization to whatever host the resolved\n * URL names. An off-origin URL, whether typed by hand or planted in a lookup\n * candidate, would hand both to that host. Nothing signed may leave for a host\n * the user did not configure.\n */\n\nexport interface ResourceRef {\n url: string;\n resourceId?: string;\n}\n\n/** Throws USAGE unless `url` parses and shares the base URL's origin. */\nexport function assertOnBaseOrigin(url: string, baseUrl: string, what: string): void {\n let target: URL;\n let base: URL;\n try {\n target = new URL(url);\n base = new URL(baseUrl);\n } catch {\n throw new CliError('USAGE', `Invalid ${what}: ${JSON.stringify(url)}`, {\n fix: 'Pass an absolute https URL on the configured base URL.',\n });\n }\n if (target.origin !== base.origin) {\n throw new CliError(\n 'USAGE',\n `${what} origin ${target.origin} does not match the configured base URL ${base.origin}.`,\n {\n fix: 'The CLI signs SIWX and payments only for the configured base URL. Pass --base-url if you meant a different deployment.',\n },\n );\n }\n}\n\nexport async function resolveResourceRef(\n arg: string,\n dataDir: string,\n baseUrl: string,\n): Promise<ResourceRef> {\n const trimmed = arg.trim();\n if (/^https?:\\/\\//i.test(trimmed)) {\n assertOnBaseOrigin(trimmed, baseUrl, 'resource URL');\n return { url: trimmed };\n }\n if (UUID_RE.test(trimmed)) {\n const candidate = await findStoredCandidate(dataDir, trimmed);\n if (candidate === null) {\n throw new CliError('RESOURCE_NOT_FOUND', `No local lookup knows resource ${trimmed}.`, {\n fix: 'Run `tenjin lookup` to surface it first, or pass the full read URL.',\n });\n }\n // The stored url was origin-checked at lookup time, but the config can have\n // changed since; re-assert against the CURRENT base URL before any send.\n assertOnBaseOrigin(candidate.url, baseUrl, 'stored candidate URL');\n return { url: candidate.url, resourceId: trimmed };\n }\n throw new CliError('USAGE', `Not a resource URL or id: ${JSON.stringify(arg)}`, {\n fix: 'Pass a full https read URL (a candidate `url`) or a resourceId uuid.',\n });\n}\n"],"mappings":";;;;;;;;;;;;AAyBO,SAAS,mBAAmB,KAAa,SAAiB,MAAoB;AACnF,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,GAAG;AACpB,WAAO,IAAI,IAAI,OAAO;AAAA,EACxB,QAAQ;AACN,UAAM,IAAI,SAAS,SAAS,WAAW,IAAI,KAAK,KAAK,UAAU,GAAG,CAAC,IAAI;AAAA,MACrE,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AACA,MAAI,OAAO,WAAW,KAAK,QAAQ;AACjC,UAAM,IAAI;AAAA,MACR;AAAA,MACA,GAAG,IAAI,WAAW,OAAO,MAAM,2CAA2C,KAAK,MAAM;AAAA,MACrF;AAAA,QACE,KAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,KACA,SACA,SACsB;AACtB,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,gBAAgB,KAAK,OAAO,GAAG;AACjC,uBAAmB,SAAS,SAAS,cAAc;AACnD,WAAO,EAAE,KAAK,QAAQ;AAAA,EACxB;AACA,MAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,UAAM,YAAY,MAAM,oBAAoB,SAAS,OAAO;AAC5D,QAAI,cAAc,MAAM;AACtB,YAAM,IAAI,SAAS,sBAAsB,kCAAkC,OAAO,KAAK;AAAA,QACrF,KAAK;AAAA,MACP,CAAC;AAAA,IACH;AAGA,uBAAmB,UAAU,KAAK,SAAS,sBAAsB;AACjE,WAAO,EAAE,KAAK,UAAU,KAAK,YAAY,QAAQ;AAAA,EACnD;AACA,QAAM,IAAI,SAAS,SAAS,6BAA6B,KAAK,UAAU,GAAG,CAAC,IAAI;AAAA,IAC9E,KAAK;AAAA,EACP,CAAC;AACH;","names":[]}
|