{"version":3,"file":"index.cjs","names":["fs","path","crypto","initializeLogger","path","logger$3","DEFAULT_DATASET_PUSH_BATCH_SIZE","logger$2","logger$1","logger","DEFAULT_FRONTEND_URL","DEFAULT_BASE_URL","trimSlash","logger","logger","fs","readFile","Table","logger","pick","DEFAULT_FRONTEND_URL","trimSlash","execFile","describeError","version","Command","version"],"sources":["../../types/dist/index.mjs","../package.json","../../../node_modules/.pnpm/dotenv@17.4.2/node_modules/dotenv/lib/main.js","../../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/rng.js","../../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/stringify.js","../../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/v4.js","../../client/dist/index.mjs","../src/utils/logger.ts","../src/utils/output.ts","../src/constants.ts","../src/utils/local-project-file.ts","../src/auth/credentials.ts","../src/auth/device.ts","../src/auth/resolve.ts","../src/auth/client.ts","../src/auth/with-client.ts","../src/utils/colors.ts","../src/commands/ask.ts","../src/utils/file.ts","../src/utils/table.ts","../src/commands/dataset/index.ts","../src/utils/debug-session-file.ts","../src/commands/debug/index.ts","../src/commands/login/index.ts","../src/commands/logout/index.ts","../src/commands/project/index.ts","../src/utils/env-file.ts","../src/skill/laminar-skill.ts","../src/skill/fetch-skill.ts","../src/utils/install-skill.ts","../src/commands/setup/index.ts","../src/commands/sql/index.ts","../src/commands/sql/schema.ts","../src/index.ts"],"sourcesContent":["//#region src/debug-session.ts\n/** Directory the debug-session file lives in, relative to the working dir. */\nconst DEBUG_SESSION_DIR = \".lmnr\";\n/** Filename of the debug-session file inside {@link DEBUG_SESSION_DIR}. */\nconst DEBUG_SESSION_FILE = \"debug-session.json\";\n//#endregion\n//#region src/tracing.ts\n/**\n* Tracing levels to conditionally disable tracing.\n*\n* OFF - No tracing is sent.\n* META_ONLY - Only metadata is sent (e.g. tokens, costs, etc.).\n* ALL - All data is sent.\n*/\nlet TracingLevel = /* @__PURE__ */ function(TracingLevel) {\n\tTracingLevel[\"OFF\"] = \"off\";\n\tTracingLevel[\"META_ONLY\"] = \"meta_only\";\n\tTracingLevel[\"ALL\"] = \"all\";\n\treturn TracingLevel;\n}({});\n//#endregion\n//#region src/utils.ts\nconst errorMessage = (error) => error instanceof Error ? error.message : String(error);\n//#endregion\nexport { DEBUG_SESSION_DIR, DEBUG_SESSION_FILE, TracingLevel, errorMessage };\n\n//# sourceMappingURL=index.mjs.map","","const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\n\n// Array of tips to display randomly\nconst TIPS = [\n  '◈ encrypted .env [www.dotenvx.com]',\n  '◈ secrets for agents [www.dotenvx.com]',\n  '⌁ auth for agents [www.vestauth.com]',\n  '⌘ custom filepath { path: \\'/custom/path/.env\\' }',\n  '⌘ enable debugging { debug: true }',\n  '⌘ override existing { override: true }',\n  '⌘ suppress logs { quiet: true }',\n  '⌘ multiple files { path: [\\'.env.local\\', \\'.env\\'] }'\n]\n\n// Get a random tip from the tips array\nfunction _getRandomTip () {\n  return TIPS[Math.floor(Math.random() * TIPS.length)]\n}\n\nfunction parseBoolean (value) {\n  if (typeof value === 'string') {\n    return !['false', '0', 'no', 'off', ''].includes(value.toLowerCase())\n  }\n  return Boolean(value)\n}\n\nfunction supportsAnsi () {\n  return process.stdout.isTTY // && process.env.TERM !== 'dumb'\n}\n\nfunction dim (text) {\n  return supportsAnsi() ? `\\x1b[2m${text}\\x1b[0m` : text\n}\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n  const obj = {}\n\n  // Convert buffer to string\n  let lines = src.toString()\n\n  // Convert line breaks to same format\n  lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n  let match\n  while ((match = LINE.exec(lines)) != null) {\n    const key = match[1]\n\n    // Default undefined or null to empty string\n    let value = (match[2] || '')\n\n    // Remove whitespace\n    value = value.trim()\n\n    // Check if double quoted\n    const maybeQuote = value[0]\n\n    // Remove surrounding quotes\n    value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n    // Expand newlines if double quoted\n    if (maybeQuote === '\"') {\n      value = value.replace(/\\\\n/g, '\\n')\n      value = value.replace(/\\\\r/g, '\\r')\n    }\n\n    // Add to object\n    obj[key] = value\n  }\n\n  return obj\n}\n\nfunction _parseVault (options) {\n  options = options || {}\n\n  const vaultPath = _vaultPath(options)\n  options.path = vaultPath // parse .env.vault\n  const result = DotenvModule.configDotenv(options)\n  if (!result.parsed) {\n    const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n    err.code = 'MISSING_DATA'\n    throw err\n  }\n\n  // handle scenario for comma separated keys - for use with key rotation\n  // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n  const keys = _dotenvKey(options).split(',')\n  const length = keys.length\n\n  let decrypted\n  for (let i = 0; i < length; i++) {\n    try {\n      // Get full key\n      const key = keys[i].trim()\n\n      // Get instructions for decrypt\n      const attrs = _instructions(result, key)\n\n      // Decrypt\n      decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n      break\n    } catch (error) {\n      // last key\n      if (i + 1 >= length) {\n        throw error\n      }\n      // try next key\n    }\n  }\n\n  // Parse decrypted .env string\n  return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n  console.error(`⚠ ${message}`)\n}\n\nfunction _debug (message) {\n  console.log(`┆ ${message}`)\n}\n\nfunction _log (message) {\n  console.log(`◇ ${message}`)\n}\n\nfunction _dotenvKey (options) {\n  // prioritize developer directly setting options.DOTENV_KEY\n  if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n    return options.DOTENV_KEY\n  }\n\n  // secondary infra already contains a DOTENV_KEY environment variable\n  if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n    return process.env.DOTENV_KEY\n  }\n\n  // fallback to empty string\n  return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n  // Parse DOTENV_KEY. Format is a URI\n  let uri\n  try {\n    uri = new URL(dotenvKey)\n  } catch (error) {\n    if (error.code === 'ERR_INVALID_URL') {\n      const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n      err.code = 'INVALID_DOTENV_KEY'\n      throw err\n    }\n\n    throw error\n  }\n\n  // Get decrypt key\n  const key = uri.password\n  if (!key) {\n    const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n    err.code = 'INVALID_DOTENV_KEY'\n    throw err\n  }\n\n  // Get environment\n  const environment = uri.searchParams.get('environment')\n  if (!environment) {\n    const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n    err.code = 'INVALID_DOTENV_KEY'\n    throw err\n  }\n\n  // Get ciphertext payload\n  const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n  const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n  if (!ciphertext) {\n    const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n    err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n    throw err\n  }\n\n  return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n  let possibleVaultPath = null\n\n  if (options && options.path && options.path.length > 0) {\n    if (Array.isArray(options.path)) {\n      for (const filepath of options.path) {\n        if (fs.existsSync(filepath)) {\n          possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n        }\n      }\n    } else {\n      possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n    }\n  } else {\n    possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n  }\n\n  if (fs.existsSync(possibleVaultPath)) {\n    return possibleVaultPath\n  }\n\n  return null\n}\n\nfunction _resolveHome (envPath) {\n  return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n  const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || (options && options.debug))\n  const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n  if (debug || !quiet) {\n    _log('loading env from encrypted .env.vault')\n  }\n\n  const parsed = DotenvModule._parseVault(options)\n\n  let processEnv = process.env\n  if (options && options.processEnv != null) {\n    processEnv = options.processEnv\n  }\n\n  DotenvModule.populate(processEnv, parsed, options)\n\n  return { parsed }\n}\n\nfunction configDotenv (options) {\n  const dotenvPath = path.resolve(process.cwd(), '.env')\n  let encoding = 'utf8'\n  let processEnv = process.env\n  if (options && options.processEnv != null) {\n    processEnv = options.processEnv\n  }\n  let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || (options && options.debug))\n  let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n  if (options && options.encoding) {\n    encoding = options.encoding\n  } else {\n    if (debug) {\n      _debug('no encoding is specified (UTF-8 is used by default)')\n    }\n  }\n\n  let optionPaths = [dotenvPath] // default, look for .env\n  if (options && options.path) {\n    if (!Array.isArray(options.path)) {\n      optionPaths = [_resolveHome(options.path)]\n    } else {\n      optionPaths = [] // reset default\n      for (const filepath of options.path) {\n        optionPaths.push(_resolveHome(filepath))\n      }\n    }\n  }\n\n  // Build the parsed data in a temporary object (because we need to return it).  Once we have the final\n  // parsed data, we will combine it with process.env (or options.processEnv if provided).\n  let lastError\n  const parsedAll = {}\n  for (const path of optionPaths) {\n    try {\n      // Specifying an encoding returns a string instead of a buffer\n      const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n      DotenvModule.populate(parsedAll, parsed, options)\n    } catch (e) {\n      if (debug) {\n        _debug(`failed to load ${path} ${e.message}`)\n      }\n      lastError = e\n    }\n  }\n\n  const populated = DotenvModule.populate(processEnv, parsedAll, options)\n\n  // handle user settings DOTENV_CONFIG_ options inside .env file(s)\n  debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug)\n  quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet)\n\n  if (debug || !quiet) {\n    const keysCount = Object.keys(populated).length\n    const shortPaths = []\n    for (const filePath of optionPaths) {\n      try {\n        const relative = path.relative(process.cwd(), filePath)\n        shortPaths.push(relative)\n      } catch (e) {\n        if (debug) {\n          _debug(`failed to load ${filePath} ${e.message}`)\n        }\n        lastError = e\n      }\n    }\n\n    _log(`injected env (${keysCount}) from ${shortPaths.join(',')} ${dim(`// tip: ${_getRandomTip()}`)}`)\n  }\n\n  if (lastError) {\n    return { parsed: parsedAll, error: lastError }\n  } else {\n    return { parsed: parsedAll }\n  }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n  // fallback to original dotenv if DOTENV_KEY is not set\n  if (_dotenvKey(options).length === 0) {\n    return DotenvModule.configDotenv(options)\n  }\n\n  const vaultPath = _vaultPath(options)\n\n  // dotenvKey exists but .env.vault file does not exist\n  if (!vaultPath) {\n    _warn(`you set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}`)\n\n    return DotenvModule.configDotenv(options)\n  }\n\n  return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n  const key = Buffer.from(keyStr.slice(-64), 'hex')\n  let ciphertext = Buffer.from(encrypted, 'base64')\n\n  const nonce = ciphertext.subarray(0, 12)\n  const authTag = ciphertext.subarray(-16)\n  ciphertext = ciphertext.subarray(12, -16)\n\n  try {\n    const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n    aesgcm.setAuthTag(authTag)\n    return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n  } catch (error) {\n    const isRange = error instanceof RangeError\n    const invalidKeyLength = error.message === 'Invalid key length'\n    const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n    if (isRange || invalidKeyLength) {\n      const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n      err.code = 'INVALID_DOTENV_KEY'\n      throw err\n    } else if (decryptionFailed) {\n      const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n      err.code = 'DECRYPTION_FAILED'\n      throw err\n    } else {\n      throw error\n    }\n  }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n  const debug = Boolean(options && options.debug)\n  const override = Boolean(options && options.override)\n  const populated = {}\n\n  if (typeof parsed !== 'object') {\n    const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n    err.code = 'OBJECT_REQUIRED'\n    throw err\n  }\n\n  // Set process.env\n  for (const key of Object.keys(parsed)) {\n    if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n      if (override === true) {\n        processEnv[key] = parsed[key]\n        populated[key] = parsed[key]\n      }\n\n      if (debug) {\n        if (override === true) {\n          _debug(`\"${key}\" is already defined and WAS overwritten`)\n        } else {\n          _debug(`\"${key}\" is already defined and was NOT overwritten`)\n        }\n      }\n    } else {\n      processEnv[key] = parsed[key]\n      populated[key] = parsed[key]\n    }\n  }\n\n  return populated\n}\n\nconst DotenvModule = {\n  configDotenv,\n  _configVault,\n  _parseVault,\n  config,\n  decrypt,\n  parse,\n  populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","const rnds8 = new Uint8Array(16);\nexport default function rng() {\n    return crypto.getRandomValues(rnds8);\n}\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n    byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n    return (byteToHex[arr[offset + 0]] +\n        byteToHex[arr[offset + 1]] +\n        byteToHex[arr[offset + 2]] +\n        byteToHex[arr[offset + 3]] +\n        '-' +\n        byteToHex[arr[offset + 4]] +\n        byteToHex[arr[offset + 5]] +\n        '-' +\n        byteToHex[arr[offset + 6]] +\n        byteToHex[arr[offset + 7]] +\n        '-' +\n        byteToHex[arr[offset + 8]] +\n        byteToHex[arr[offset + 9]] +\n        '-' +\n        byteToHex[arr[offset + 10]] +\n        byteToHex[arr[offset + 11]] +\n        byteToHex[arr[offset + 12]] +\n        byteToHex[arr[offset + 13]] +\n        byteToHex[arr[offset + 14]] +\n        byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n    const uuid = unsafeStringify(arr, offset);\n    if (!validate(uuid)) {\n        throw TypeError('Stringified UUID is invalid');\n    }\n    return uuid;\n}\nexport default stringify;\n","import rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n    if (!buf && !options && crypto.randomUUID) {\n        return crypto.randomUUID();\n    }\n    return _v4(options, buf, offset);\n}\nfunction _v4(options, buf, offset) {\n    options = options || {};\n    const rnds = options.random ?? options.rng?.() ?? rng();\n    if (rnds.length < 16) {\n        throw new Error('Random bytes length must be >= 16');\n    }\n    rnds[6] = (rnds[6] & 0x0f) | 0x40;\n    rnds[8] = (rnds[8] & 0x3f) | 0x80;\n    if (buf) {\n        offset = offset || 0;\n        if (offset < 0 || offset + 16 > buf.length) {\n            throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n        }\n        for (let i = 0; i < 16; ++i) {\n            buf[offset + i] = rnds[i];\n        }\n        return buf;\n    }\n    return unsafeStringify(rnds);\n}\nexport default v4;\n","import { config } from \"dotenv\";\nimport * as path from \"path\";\nimport pino from \"pino\";\nimport { PinoPretty } from \"pino-pretty\";\nimport { v4 } from \"uuid\";\nimport { errorMessage } from \"@lmnr-ai/types\";\n//#region package.json\nvar version = \"0.8.37\";\n//#endregion\n//#region src/version.ts\nfunction getLangVersion() {\n\tif (typeof process !== \"undefined\" && process.versions && process.versions.node) return `node-${process.versions.node}`;\n\tif (typeof navigator !== \"undefined\" && navigator.userAgent) return `browser-${navigator.userAgent}`;\n\treturn null;\n}\n//#endregion\n//#region src/resources/index.ts\nvar BaseResource = class {\n\tconstructor(baseHttpUrl, auth) {\n\t\tthis.baseHttpUrl = baseHttpUrl;\n\t\tthis.auth = auth;\n\t\tthis.credential = auth.type === \"apiKey\" ? auth.key : auth.token;\n\t}\n\t/** API path prefix: `/v1/cli` for CLI user-token auth, `/v1` otherwise. */\n\tget apiPrefix() {\n\t\treturn this.auth.type === \"userToken\" ? \"/v1/cli\" : \"/v1\";\n\t}\n\theaders() {\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${this.credential}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t\t...this.auth.type === \"userToken\" ? { \"x-lmnr-project-id\": this.auth.projectId } : {}\n\t\t};\n\t}\n\tasync handleError(response) {\n\t\tconst errorMsg = await response.text();\n\t\tthrow new Error(`${response.status} ${errorMsg}`);\n\t}\n};\n//#endregion\n//#region src/resources/browser-events.ts\nvar BrowserEventsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\tasync send({ sessionId, traceId, events }) {\n\t\tconst payload = {\n\t\t\tsessionId,\n\t\t\ttraceId,\n\t\t\tevents,\n\t\t\tsource: getLangVersion() ?? \"javascript\",\n\t\t\tsdkVersion: version\n\t\t};\n\t\tconst jsonString = JSON.stringify(payload);\n\t\tconst compressedStream = new Blob([jsonString], { type: \"application/json\" }).stream().pipeThrough(new CompressionStream(\"gzip\"));\n\t\tconst compressedData = await new Response(compressedStream).arrayBuffer();\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/browser-sessions/events\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t...this.headers(),\n\t\t\t\t\"Content-Encoding\": \"gzip\"\n\t\t\t},\n\t\t\tbody: compressedData\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n//#endregion\n//#region src/resources/cli.ts\n/**\n* User-scoped CLI endpoints that don't target a specific project. Authed by the\n* BetterAuth user JWT (the `credential`); deliberately does NOT send an\n* `x-lmnr-project-id` header (these routes are project discovery, pre-selection).\n*\n* Discovery exception: this resource always hits `/v1/cli/projects` with the\n* bare bearer and overrides `BaseResource.headers()`/`apiPrefix`, so it works\n* even when constructed with a `userToken` auth that has no real project id yet.\n*/\nvar CliResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\t/** Workspaces + projects the authenticated user can access. */\n\tasync listProjects() {\n\t\tconst response = await fetch(`${this.baseHttpUrl}/v1/cli/projects`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${this.credential}`,\n\t\t\t\tAccept: \"application/json\"\n\t\t\t}\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\tconst body = await response.json();\n\t\treturn Array.isArray(body?.projects) ? body.projects : [];\n\t}\n\t/**\n\t* Resolve which project a project API key belongs to. Authed by the user JWT\n\t* (the bearer); the project key travels in the body, NOT in `Authorization`.\n\t* The server verifies the key and that the authenticated user is a member of\n\t* the resolved project. Returns a tri-state probe so callers can distinguish a\n\t* revoked key (401 → `invalid`) from a server/access problem (`unverifiable`).\n\t*/\n\tasync resolveProjectByApiKey(apiKey) {\n\t\tlet response;\n\t\ttry {\n\t\t\tresponse = await fetch(`${this.baseHttpUrl}/v1/cli/project`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${this.credential}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAccept: \"application/json\"\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ apiKey })\n\t\t\t});\n\t\t} catch {\n\t\t\treturn { status: \"unverifiable\" };\n\t\t}\n\t\tif (response.status === 401) return { status: \"invalid\" };\n\t\tif (!response.ok) return { status: \"unverifiable\" };\n\t\tconst body = await response.json().catch(() => null);\n\t\treturn body?.projectId ? {\n\t\t\tstatus: \"ok\",\n\t\t\tprojectId: body.projectId\n\t\t} : { status: \"unverifiable\" };\n\t}\n};\n//#endregion\n//#region src/utils.ts\nfunction initializeLogger(options) {\n\tconst colorize = options?.colorize ?? true;\n\tconst level = options?.level ?? process.env.LMNR_LOG_LEVEL?.toLowerCase()?.trim() ?? \"info\";\n\treturn pino({ level }, PinoPretty({\n\t\tcolorize,\n\t\tminimumLevel: level\n\t}));\n}\nconst logger$4 = initializeLogger();\nconst isStringUUID = (id) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id);\nconst newUUID = () => {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") return crypto.randomUUID();\n\telse return v4();\n};\nconst otelSpanIdToUUID = (spanId) => {\n\tlet id = spanId.toLowerCase();\n\tif (id.startsWith(\"0x\")) id = id.slice(2);\n\tif (id.length !== 16) logger$4.warn(`Span ID ${spanId} is not 16 hex chars long. This is not a valid OpenTelemetry span ID.`);\n\tif (!/^[0-9a-f]+$/.test(id)) {\n\t\tlogger$4.error(`Span ID ${spanId} is not a valid hex string. Generating a random UUID instead.`);\n\t\treturn newUUID();\n\t}\n\treturn id.padStart(32, \"0\").replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/, \"$1-$2-$3-$4-$5\");\n};\nconst otelTraceIdToUUID = (traceId) => {\n\tlet id = traceId.toLowerCase();\n\tif (id.startsWith(\"0x\")) id = id.slice(2);\n\tif (id.length !== 32) logger$4.warn(`Trace ID ${traceId} is not 32 hex chars long. This is not a valid OpenTelemetry trace ID.`);\n\tif (!/^[0-9a-f]+$/.test(id)) {\n\t\tlogger$4.error(`Trace ID ${traceId} is not a valid hex string. Generating a random UUID instead.`);\n\t\treturn newUUID();\n\t}\n\treturn id.replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/, \"$1-$2-$3-$4-$5\");\n};\nconst slicePayload = (value, length) => {\n\tif (value === null || value === void 0) return value;\n\tconst str = JSON.stringify(value);\n\tif (str.length <= length) return value;\n\treturn str.slice(0, length) + \"...\";\n};\nconst loadEnv = (options) => {\n\tconst nodeEnv = process.env.NODE_ENV || \"development\";\n\tconst envDir = process.cwd();\n\tconst envFiles = [\n\t\t\".env\",\n\t\t\".env.local\",\n\t\t`.env.${nodeEnv}`,\n\t\t`.env.${nodeEnv}.local`\n\t];\n\tconst logLevel = process.env.LMNR_LOG_LEVEL ?? \"info\";\n\tconst verbose = [\"debug\", \"trace\"].includes(logLevel.trim().toLowerCase());\n\tconst quiet = options?.quiet ?? !verbose;\n\tconfig({\n\t\tpath: options?.paths ?? envFiles.map((envFile) => path.resolve(envDir, envFile)),\n\t\tquiet\n\t});\n};\n//#endregion\n//#region src/resources/datasets.ts\nconst logger$3 = initializeLogger();\nconst DEFAULT_DATASET_PULL_LIMIT = 100;\nconst DEFAULT_DATASET_PUSH_BATCH_SIZE = 100;\nvar DatasetsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\t/**\n\t* List all datasets.\n\t*\n\t* @returns {Promise<Dataset[]>} Array of datasets\n\t*/\n\tasync listDatasets() {\n\t\tconst response = await fetch(this.baseHttpUrl + this.apiPrefix + \"/datasets\", {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Get a dataset by name.\n\t*\n\t* @param {string} name - Name of the dataset\n\t* @returns {Promise<Dataset[]>} Array of datasets with matching name\n\t*/\n\tasync getDatasetByName(name) {\n\t\tconst params = new URLSearchParams({ name });\n\t\tconst response = await fetch(this.baseHttpUrl + `${this.apiPrefix}/datasets?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Push datapoints to a dataset.\n\t*\n\t* @param {Object} options - Push options\n\t* @param {Datapoint<D, T>[]} options.points - Datapoints to push\n\t* @param {string} [options.name] - Name of the dataset (either name or id must be provided)\n\t* @param {StringUUID} [options.id] - ID of the dataset (either name or id must be provided)\n\t* @param {number} [options.batchSize] - Batch size for pushing (default: 100)\n\t* @param {boolean} [options.createDataset] - Whether to create the dataset if it doesn't exist\n\t* @returns {Promise<PushDatapointsResponse | undefined>}\n\t*/\n\tasync push({ points, name, id, batchSize = DEFAULT_DATASET_PUSH_BATCH_SIZE, createDataset = false }) {\n\t\tif (!name && !id) throw new Error(\"Either name or id must be provided\");\n\t\tif (name && id) throw new Error(\"Only one of name or id must be provided\");\n\t\tif (createDataset && !name) throw new Error(\"Name must be provided when creating a new dataset\");\n\t\tconst identifier = name ? { name } : { datasetId: id };\n\t\tconst totalBatches = Math.ceil(points.length / batchSize);\n\t\tlet response;\n\t\tfor (let i = 0; i < points.length; i += batchSize) {\n\t\t\tconst batchNum = Math.floor(i / batchSize) + 1;\n\t\t\tlogger$3.debug(`Pushing batch ${batchNum} of ${totalBatches}`);\n\t\t\tconst batch = points.slice(i, i + batchSize);\n\t\t\tconst fetchResponse = await fetch(this.baseHttpUrl + this.apiPrefix + \"/datasets/datapoints\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: this.headers(),\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t...identifier,\n\t\t\t\t\tdatapoints: batch.map((point) => ({\n\t\t\t\t\t\tdata: point.data,\n\t\t\t\t\t\ttarget: point.target ?? {},\n\t\t\t\t\t\tmetadata: point.metadata ?? {}\n\t\t\t\t\t})),\n\t\t\t\t\tcreateDataset\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (fetchResponse.status !== 200 && fetchResponse.status !== 201) await this.handleError(fetchResponse);\n\t\t\tresponse = await fetchResponse.json();\n\t\t}\n\t\treturn response;\n\t}\n\t/**\n\t* Pull datapoints from a dataset.\n\t*\n\t* @param {Object} options - Pull options\n\t* @param {string} [options.name] - Name of the dataset (either name or id must be provided)\n\t* @param {StringUUID} [options.id] - ID of the dataset (either name or id must be provided)\n\t* @param {number} [options.limit] - Maximum number of datapoints to return (default: 100)\n\t* @param {number} [options.offset] - Offset for pagination (default: 0)\n\t* @returns {Promise<GetDatapointsResponse<D, T>>}\n\t*/\n\tasync pull({ name, id, limit = DEFAULT_DATASET_PULL_LIMIT, offset = 0 }) {\n\t\tif (!name && !id) throw new Error(\"Either name or id must be provided\");\n\t\tif (name && id) throw new Error(\"Only one of name or id must be provided\");\n\t\tconst paramsObj = {\n\t\t\toffset: offset.toString(),\n\t\t\tlimit: limit.toString()\n\t\t};\n\t\tif (name) paramsObj.name = name;\n\t\telse paramsObj.datasetId = id;\n\t\tconst params = new URLSearchParams(paramsObj);\n\t\tconst response = await fetch(this.baseHttpUrl + `${this.apiPrefix}/datasets/datapoints?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n};\n//#endregion\n//#region src/resources/evals.ts\nconst logger$2 = initializeLogger();\nconst INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH = 16e6;\nvar EvalsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\t/**\n\t* Initialize an evaluation.\n\t*\n\t* @param {string} name - Name of the evaluation\n\t* @param {string} groupName - Group name of the evaluation\n\t* @param {Record<string, any>} metadata - Optional metadata\n\t* @returns {Promise<InitEvaluationResponse>} Response from the evaluation initialization\n\t*/\n\tasync init(name, groupName, metadata) {\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/evals\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\tname: name ?? null,\n\t\t\t\tgroupName: groupName ?? null,\n\t\t\t\tmetadata: metadata ?? null\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n\t/**\n\t* Create a new evaluation and return its ID.\n\t*\n\t* @param {string} [name] - Optional name of the evaluation\n\t* @param {string} [groupName] - An identifier to group evaluations\n\t* @param {Record<string, any>} [metadata] - Optional metadata\n\t* @returns {Promise<StringUUID>} The evaluation ID\n\t*/\n\tasync create(args) {\n\t\treturn (await this.init(args?.name, args?.groupName, args?.metadata)).id;\n\t}\n\t/**\n\t* Create a new evaluation and return its ID.\n\t* @deprecated use `create` instead.\n\t*/\n\tasync createEvaluation(name, groupName, metadata) {\n\t\treturn (await this.init(name, groupName, metadata)).id;\n\t}\n\t/**\n\t* Create a datapoint for an evaluation.\n\t*\n\t* @param {Object} options - Create datapoint options\n\t* @param {string} options.evalId - The evaluation ID\n\t* @param {D} options.data - The input data for the executor\n\t* @param {T} [options.target] - The target/expected output for evaluators\n\t* @param {Record<string, any>} [options.metadata] - Optional metadata\n\t* @param {number} [options.index] - Optional index of the datapoint\n\t* @param {string} [options.traceId] - Optional trace ID\n\t* @returns {Promise<StringUUID>} The datapoint ID\n\t*/\n\tasync createDatapoint({ evalId, data, target, metadata, index, traceId }) {\n\t\tconst datapointId = newUUID();\n\t\tconst partialDatapoint = {\n\t\t\tid: datapointId,\n\t\t\tdata,\n\t\t\ttarget,\n\t\t\tindex: index ?? 0,\n\t\t\ttraceId: traceId ?? newUUID(),\n\t\t\texecutorSpanId: newUUID(),\n\t\t\tmetadata\n\t\t};\n\t\tawait this.saveDatapoints({\n\t\t\tevalId,\n\t\t\tdatapoints: [partialDatapoint]\n\t\t});\n\t\treturn datapointId;\n\t}\n\t/**\n\t* Update a datapoint with evaluation results.\n\t*\n\t* @param {Object} options - Update datapoint options\n\t* @param {string} options.evalId - The evaluation ID\n\t* @param {string} options.datapointId - The datapoint ID\n\t* @param {Record<string, number>} options.scores - The scores\n\t* @param {O} [options.executorOutput] - The executor output\n\t* @returns {Promise<void>}\n\t*/\n\tasync updateDatapoint({ evalId, datapointId, scores, executorOutput }) {\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints/${datapointId}`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\texecutorOutput,\n\t\t\t\tscores\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\t/**\n\t* Save evaluation datapoints.\n\t*\n\t* @param {Object} options - Save datapoints options\n\t* @param {string} options.evalId - ID of the evaluation\n\t* @param {EvaluationDatapoint<D, T, O>[]} options.datapoints - Datapoint to add\n\t* @param {string} [options.groupName] - Group name of the evaluation\n\t* @returns {Promise<void>} Response from the datapoint addition\n\t*/\n\tasync saveDatapoints({ evalId, datapoints, groupName }) {\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\tpoints: datapoints.map((d) => ({\n\t\t\t\t\t...d,\n\t\t\t\t\tdata: slicePayload(d.data, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH),\n\t\t\t\t\ttarget: slicePayload(d.target, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH),\n\t\t\t\t\texecutorOutput: slicePayload(d.executorOutput, INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH)\n\t\t\t\t})),\n\t\t\t\tgroupName: groupName ?? null\n\t\t\t})\n\t\t});\n\t\tif (response.status === 413) return await this.retrySaveDatapoints({\n\t\t\tevalId,\n\t\t\tdatapoints,\n\t\t\tgroupName\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\t/**\n\t* Get evaluation datapoints.\n\t*\n\t* @deprecated Use `client.datasets.pull()` instead.\n\t* @param {Object} options - Get datapoints options\n\t* @param {string} options.datasetName - Name of the dataset\n\t* @param {number} options.offset - Offset at which to start the query\n\t* @param {number} options.limit - Maximum number of datapoints to return\n\t* @returns {Promise<GetDatapointsResponse>} Response from the datapoint retrieval\n\t*/\n\tasync getDatapoints({ datasetName, offset, limit }) {\n\t\tlogger$2.warn(\"evals.getDatapoints() is deprecated. Use client.datasets.pull() instead.\");\n\t\tconst params = new URLSearchParams({\n\t\t\tname: datasetName,\n\t\t\toffset: offset.toString(),\n\t\t\tlimit: limit.toString()\n\t\t});\n\t\tconst response = await fetch(this.baseHttpUrl + `/v1/datasets/datapoints?${params.toString()}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn await response.json();\n\t}\n\tasync retrySaveDatapoints({ evalId, datapoints, groupName, maxRetries = 25, initialLength = INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH }) {\n\t\tlet length = initialLength;\n\t\tlet lastResponse = null;\n\t\tfor (let i = 0; i < maxRetries; i++) {\n\t\t\tlogger$2.debug(`Retrying save datapoints... ${i + 1} of ${maxRetries}, length: ${length}`);\n\t\t\tconst response = await fetch(this.baseHttpUrl + `/v1/evals/${evalId}/datapoints`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: this.headers(),\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tpoints: datapoints.map((d) => ({\n\t\t\t\t\t\t...d,\n\t\t\t\t\t\tdata: slicePayload(d.data, length),\n\t\t\t\t\t\ttarget: slicePayload(d.target, length),\n\t\t\t\t\t\texecutorOutput: slicePayload(d.executorOutput, length)\n\t\t\t\t\t})),\n\t\t\t\t\tgroupName: groupName ?? null\n\t\t\t\t})\n\t\t\t});\n\t\t\tlastResponse = response;\n\t\t\tlength = Math.floor(length / 2);\n\t\t\tif (response.status !== 413) break;\n\t\t}\n\t\tif (lastResponse && !lastResponse.ok) await this.handleError(lastResponse);\n\t}\n};\n//#endregion\n//#region src/resources/evaluators.ts\n/**\n* Resource for creating evaluator scores\n*/\nvar EvaluatorsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\t/**\n\t* Create a score for a span or trace\n\t*\n\t* @param {ScoreOptions} options - Score creation options\n\t* @param {string} options.name - Name of the score\n\t* @param {string} [options.traceId] - The trace ID to score (will be attached to top-level span)\n\t* @param {string} [options.spanId] - The span ID to score\n\t* @param {Record<string, any>} [options.metadata] - Additional metadata\n\t* @param {number} options.score - The score value (float)\n\t* @returns {Promise<void>}\n\t*\n\t* @example\n\t* // Score by trace ID (will attach to root span)\n\t* await evaluators.score({\n\t*   name: \"quality\",\n\t*   traceId: \"trace-id-here\",\n\t*   score: 0.95,\n\t*   metadata: { model: \"gpt-4\" }\n\t* });\n\t*\n\t* @example\n\t* // Score by span ID\n\t* await evaluators.score({\n\t*   name: \"relevance\",\n\t*   spanId: \"span-id-here\",\n\t*   score: 0.87\n\t* });\n\t*/\n\tasync score(options) {\n\t\tconst { name, metadata, score } = options;\n\t\tlet payload;\n\t\tif (\"traceId\" in options && options.traceId) payload = {\n\t\t\tname,\n\t\t\tmetadata,\n\t\t\tscore,\n\t\t\tsource: \"Code\",\n\t\t\ttraceId: isStringUUID(options.traceId) ? options.traceId : otelTraceIdToUUID(options.traceId)\n\t\t};\n\t\telse if (\"spanId\" in options && options.spanId) payload = {\n\t\t\tname,\n\t\t\tmetadata,\n\t\t\tscore,\n\t\t\tsource: \"Code\",\n\t\t\tspanId: isStringUUID(options.spanId) ? options.spanId : otelSpanIdToUUID(options.spanId)\n\t\t};\n\t\telse throw new Error(\"Either 'traceId' or 'spanId' must be provided.\");\n\t\tconst response = await fetch(this.baseHttpUrl + \"/v1/evaluators/score\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n//#endregion\n//#region src/resources/rollout-sessions.ts\nconst logger$1 = initializeLogger();\n/**\n* Map the opaque HIT `response` payload onto a {@link CachedSpan} the provider\n* wrappers can replay. The server-side shape of `response` is not yet frozen\n* (app-server plan 01 leaves it as a `serde_json::Value`), so this stays\n* deliberately tolerant: the whole payload is serialized into `output` (the only\n* field the AI SDK wrapper's `parseCachedSpan` actually reads, via\n* `JSON.parse`), and a `finishReason` is surfaced into `attributes` when the\n* payload carries one. `name`/`input` are irrelevant to replay and left empty.\n*/\nconst toCachedSpan = (response) => {\n\tconst output = typeof response === \"string\" ? response : JSON.stringify(response ?? null);\n\tconst attributes = {};\n\tif (response !== null && typeof response === \"object\" && typeof response.finishReason === \"string\") attributes[\"ai.response.finishReason\"] = response.finishReason;\n\treturn {\n\t\tname: \"\",\n\t\tinput: \"\",\n\t\toutput,\n\t\tattributes\n\t};\n};\nvar RolloutSessionsResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\t/**\n\t* Idempotently register (upsert) a debug session on the backend, keyed on the\n\t* SDK-supplied session id. The backend stores the row so the session is\n\t* visible in the UI; a null/omitted name never clobbers a name set elsewhere.\n\t*\n\t* Returns the backend-resolved `projectId` (derived from the API key) so the\n\t* caller can build the debugger URL; null if the body can't be parsed.\n\t*/\n\tasync register({ sessionId, name }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/rollouts/${sessionId}`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({ name })\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\ttry {\n\t\t\treturn (await response.json()).projectId ?? null;\n\t\t} catch (e) {\n\t\t\tlogger$1.warn(`Failed to parse rollout register response: ${errorMessage(e)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* Rename an existing debug session. Update-only: the backend returns 404 (and\n\t* this throws) when the session id is unknown for the project, so a mistyped\n\t* id surfaces as an error rather than silently creating a session. Creation\n\t* stays the SDK's job via {@link register}.\n\t*/\n\tasync setName({ sessionId, name }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/rollouts/${sessionId}/name`, {\n\t\t\tmethod: \"PATCH\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({ name })\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n\t/**\n\t* Append a block to a debug session (debugger session blocks).\n\t*\n\t* A debug session renders as an ordered list of blocks; this writes one to the\n\t* backend keyed by session id. The CLI uses it for `text` blocks — standalone\n\t* agent notes attached post-factum via `lmnr-cli debug session add-note` — so\n\t* a note is tied to the SESSION, not to a specific trace / evaluation (those\n\t* blocks are written at ingest from `rollout.session_id` metadata).\n\t*\n\t* A 404 (the session is unknown for the project) is logged and swallowed\n\t* unless `failOnNotFound` is set — CLI callers pass it so an exit 0 means the\n\t* block actually landed. Any other non-OK status throws.\n\t*\n\t* Returns the created block id, or null when the response body can't be parsed.\n\t*/\n\tasync addBlock({ sessionId, type, content, failOnNotFound }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/rollouts/${sessionId}/blocks`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\ttype,\n\t\t\t\tcontent\n\t\t\t})\n\t\t});\n\t\tif (response.status === 404) {\n\t\t\tconst message = `Could not add a note: HTTP 404 for session ${sessionId}. Either the session isn't registered in this project (mint one with \\`lmnr-cli debug session new\\`, or run under LMNR_DEBUG=1), or this Laminar server doesn't expose the session-blocks write endpoint (POST /v1/rollouts/{sessionId}/blocks) yet.`;\n\t\t\tif (failOnNotFound) throw new Error(message);\n\t\t\tlogger$1.warn(message);\n\t\t\treturn null;\n\t\t}\n\t\tif (!response.ok) await this.handleError(response);\n\t\ttry {\n\t\t\treturn (await response.json()).id ?? null;\n\t\t} catch (e) {\n\t\t\tlogger$1.warn(`Failed to parse add-block response: ${errorMessage(e)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* List a debug session's blocks in creation order.\n\t*\n\t* Returns every `trace` / `evaluation` / `text` block on the session — the\n\t* same data the debugger UI renders. Used by `lmnr-cli debug session summary`\n\t* to print a chronological digest of the session. Returns an empty array when\n\t* the session has no blocks or the body can't be parsed.\n\t*/\n\tasync listBlocks({ sessionId }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/rollouts/${sessionId}/blocks`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\ttry {\n\t\t\tconst body = await response.json();\n\t\t\treturn (Array.isArray(body) ? body : body.blocks) ?? [];\n\t\t} catch (e) {\n\t\t\tlogger$1.warn(`Failed to parse list-blocks response: ${errorMessage(e)}`);\n\t\t\treturn [];\n\t\t}\n\t}\n\t/**\n\t* Look up the debug-replay cache for a single LLM call (debug-replay v2).\n\t*\n\t* The server is keyed by `inputHash` (hex blake3 of the canonicalized,\n\t* system-stripped input messages). It returns one of three outcomes:\n\t*   - `{ outcome: \"hit\", response }` — a cached response to replay.\n\t*   - `{ outcome: \"miss\" }`          — no entry; caller latches live mode.\n\t*   - `{ outcome: \"live\" }`          — run this call live (COLD degrade).\n\t*\n\t* Error posture: a non-OK response or a transport error degrades to\n\t* `{ kind: \"live\" }` for THIS call only — it never throws and never latches\n\t* the process-wide live flag (only a real MISS does that). This keeps a flaky\n\t* cache backend from turning a replay into a crash.\n\t*/\n\tasync cache({ sessionId, replayTraceId, cacheUntil, inputHash }) {\n\t\tlet response;\n\t\ttry {\n\t\t\tresponse = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/rollouts/${sessionId}/cache`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: this.headers(),\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\treplayTraceId,\n\t\t\t\t\tcacheUntil,\n\t\t\t\t\tinputHash\n\t\t\t\t})\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tlogger$1.warn(`Debug cache lookup failed, running live: ${errorMessage(e)}`);\n\t\t\treturn { kind: \"live\" };\n\t\t}\n\t\tif (!response.ok) {\n\t\t\tlogger$1.warn(`Debug cache lookup returned ${response.status}, running live`);\n\t\t\treturn { kind: \"live\" };\n\t\t}\n\t\tlet body;\n\t\ttry {\n\t\t\tbody = await response.json();\n\t\t} catch (e) {\n\t\t\tlogger$1.warn(`Failed to parse debug cache response, running live: ${errorMessage(e)}`);\n\t\t\treturn { kind: \"live\" };\n\t\t}\n\t\tswitch (body.outcome) {\n\t\t\tcase \"hit\":\n\t\t\t\tif (body.response === null || body.response === void 0) {\n\t\t\t\t\tlogger$1.warn(\"Debug cache HIT had no response payload, running live\");\n\t\t\t\t\treturn { kind: \"live\" };\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"hit\",\n\t\t\t\t\tcached: toCachedSpan(body.response)\n\t\t\t\t};\n\t\t\tcase \"miss\": return { kind: \"miss\" };\n\t\t\tcase \"live\": return { kind: \"live\" };\n\t\t\tdefault:\n\t\t\t\tlogger$1.warn(`Unknown debug cache outcome \"${body.outcome}\", running live`);\n\t\t\t\treturn { kind: \"live\" };\n\t\t}\n\t}\n\tasync delete({ sessionId }) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/rollouts/${sessionId}`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: this.headers()\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n//#endregion\n//#region src/resources/sql.ts\nvar SqlResource = class extends BaseResource {\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\tasync query(sql, parameters = {}) {\n\t\tconst response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/sql/query`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { ...this.headers() },\n\t\t\tbody: JSON.stringify({\n\t\t\t\tquery: sql,\n\t\t\t\tparameters\n\t\t\t})\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn (await response.json()).data;\n\t}\n};\n//#endregion\n//#region src/resources/tags.ts\n/** Resource for tagging traces. */\nvar TagsResource = class extends BaseResource {\n\t/** Resource for tagging traces. */\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\t/**\n\t* Tag a trace with a list of tags. Note that the trace must be ended before\n\t* tagging it. You may want to call `await Laminar.flush()` after the trace\n\t* that you want to tag.\n\t*\n\t* @param {string | StringUUID} trace_id - The trace id to tag.\n\t* @param {string[] | string} tags - The tag or list of tags to add to the trace.\n\t* @returns {Promise<any>} The response from the server.\n\t* @example\n\t* ```javascript\n\t* import { Laminar, observe, LaminarClient } from \"@lmnr-ai/lmnr\";\n\t* Laminar.initialize();\n\t* const client = new LaminarClient();\n\t* let traceId: StringUUID | null = null;\n\t* // Make sure this is called outside of traced context.\n\t* await observe(\n\t*   {\n\t*     name: \"my-trace\",\n\t*   },\n\t*   async () => {\n\t*     traceId = await Laminar.getTraceId();\n\t*     await foo();\n\t*   },\n\t* );\n\t*\n\t* // or make sure the trace is ended by this point.\n\t* await Laminar.flush();\n\t* if (traceId) {\n\t*   await client.tags.tag(traceId, [\"tag1\", \"tag2\"]);\n\t* }\n\t* ```\n\t*/\n\tasync tag(trace_id, tags) {\n\t\tconst traceTags = Array.isArray(tags) ? tags : [tags];\n\t\tconst formattedTraceId = isStringUUID(trace_id) ? trace_id : otelTraceIdToUUID(trace_id);\n\t\tconst url = this.baseHttpUrl + \"/v1/tag\";\n\t\tconst payload = {\n\t\t\t\"traceId\": formattedTraceId,\n\t\t\t\"names\": traceTags\n\t\t};\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\t\tif (!response.ok) await this.handleError(response);\n\t\treturn response.json();\n\t}\n};\n//#endregion\n//#region src/resources/traces.ts\n/** Resource for post-factum operations on existing traces. */\nconst logger = initializeLogger();\nvar TracesResource = class extends BaseResource {\n\t/** Resource for post-factum operations on existing traces. */\n\tconstructor(baseHttpUrl, auth) {\n\t\tsuper(baseHttpUrl, auth);\n\t}\n\t/**\n\t* Push a metadata patch to an existing trace.\n\t*\n\t* The patch is shallow-merged server-side into the trace's existing metadata\n\t* (`existing || patch`, last-write-wins per top-level key). Useful for\n\t* attaching post-factum signals — quality scores, human edits, triage labels —\n\t* to a trace that has already finished. The patch does NOT extend `endTime`\n\t* or change tokens / cost / top span / tags / span names. `numSpans` is\n\t* incremented by 1 (paid by the virtual span that carried the patch through\n\t* the ingestion queue) so the new ClickHouse row beats the prior version on\n\t* `ReplacingMergeTree(numSpans)`. No row is added to the `spans` table.\n\t*\n\t* Compared to `Laminar.setTraceMetadata` (which sets metadata on the\n\t* currently in-flight trace via OpenTelemetry attributes), this method\n\t* operates on a finished trace by trace id, so it must be called after the\n\t* trace has been flushed.\n\t*\n\t* A 404 response (the trace was not found in the project — typically because\n\t* it has not been flushed yet) is logged as a warning and the call returns\n\t* without throwing, since the 404 may be expected when pushing too soon\n\t* after the trace run. Pass `failOnNotFound: true` to throw instead (e.g.\n\t* CLI callers that must report the failure). Any other non-OK status throws.\n\t*\n\t* @param traceId - The trace id to push metadata to. Accepts a UUID string\n\t*   or a 32-char OTel hex trace id.\n\t* @param metadata - The metadata patch. Top-level keys are merged into the\n\t*   trace's existing metadata. Must be non-empty (the server rejects empty\n\t*   patches with 400).\n\t* @param options - `failOnNotFound`: throw on 404 instead of warn-and-return.\n\t* @example\n\t* ```typescript\n\t* import { Laminar, observe, LaminarClient } from \"@lmnr-ai/lmnr\";\n\t* Laminar.initialize();\n\t* const client = new LaminarClient();\n\t*\n\t* let traceId: string | null = null;\n\t* await observe({ name: \"generate\" }, async () => {\n\t*   traceId = await Laminar.getTraceId();\n\t* });\n\t* await Laminar.flush();\n\t*\n\t* if (traceId) {\n\t*   await client.traces.pushMetadata(traceId, {\n\t*     score: 0.85,\n\t*     reviewer: \"alice\",\n\t*     needsReview: false,\n\t*   });\n\t* }\n\t* ```\n\t*/\n\tasync pushMetadata(traceId, metadata, options) {\n\t\tif (!metadata || Object.keys(metadata).length === 0) throw new Error(\"metadata must be a non-empty object\");\n\t\tconst formattedTraceId = isStringUUID(traceId) ? traceId : otelTraceIdToUUID(traceId);\n\t\tconst url = this.baseHttpUrl + this.apiPrefix + \"/traces/metadata\";\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: this.headers(),\n\t\t\tbody: JSON.stringify({\n\t\t\t\ttraceId: formattedTraceId,\n\t\t\t\tmetadata\n\t\t\t})\n\t\t});\n\t\tif (response.status === 404) {\n\t\t\tconst message = `Trace ${formattedTraceId} not found. The trace may not have been flushed yet — call await Laminar.flush() and retry.`;\n\t\t\tif (options?.failOnNotFound) throw new Error(message);\n\t\t\tlogger.warn(message);\n\t\t\treturn;\n\t\t}\n\t\tif (!response.ok) await this.handleError(response);\n\t}\n};\n//#endregion\n//#region src/index.ts\nvar LaminarClient = class LaminarClient {\n\tconstructor({ baseUrl, port, auth, projectApiKey, cliUserProjectId } = {}) {\n\t\tloadEnv();\n\t\tthis.auth = LaminarClient.normalizeAuth(auth, projectApiKey, cliUserProjectId);\n\t\tconst httpPort = port ?? (baseUrl?.match(/:\\d{1,5}$/g) ? parseInt(baseUrl.match(/:\\d{1,5}$/g)[0].slice(1)) : 443);\n\t\tconst baseUrlNoPort = (baseUrl ?? process.env.LMNR_BASE_URL)?.replace(/\\/$/, \"\").replace(/:\\d{1,5}$/g, \"\");\n\t\tthis.baseUrl = `${baseUrlNoPort ?? \"https://api.lmnr.ai\"}:${httpPort}`;\n\t\tthis._browserEvents = new BrowserEventsResource(this.baseUrl, this.auth);\n\t\tthis._cli = new CliResource(this.baseUrl, this.auth);\n\t\tthis._datasets = new DatasetsResource(this.baseUrl, this.auth);\n\t\tthis._evals = new EvalsResource(this.baseUrl, this.auth);\n\t\tthis._evaluators = new EvaluatorsResource(this.baseUrl, this.auth);\n\t\tthis._rolloutSessions = new RolloutSessionsResource(this.baseUrl, this.auth);\n\t\tthis._sql = new SqlResource(this.baseUrl, this.auth);\n\t\tthis._tags = new TagsResource(this.baseUrl, this.auth);\n\t\tthis._traces = new TracesResource(this.baseUrl, this.auth);\n\t}\n\t/**\n\t* Normalize the constructor's auth inputs into a {@link LaminarAuth} union.\n\t* Precedence: an explicit `auth` wins; otherwise the legacy\n\t* `projectApiKey` (+ optional `cliUserProjectId`) is mapped — a present\n\t* `cliUserProjectId` selects the user-token surface, otherwise the project\n\t* key surface. Falls back to `LMNR_PROJECT_API_KEY` as a project key.\n\t*/\n\tstatic normalizeAuth(auth, projectApiKey, cliUserProjectId) {\n\t\tif (auth) return auth;\n\t\tconst key = projectApiKey ?? process.env.LMNR_PROJECT_API_KEY;\n\t\tif (cliUserProjectId) return {\n\t\t\ttype: \"userToken\",\n\t\t\ttoken: key,\n\t\t\tprojectId: cliUserProjectId\n\t\t};\n\t\treturn {\n\t\t\ttype: \"apiKey\",\n\t\t\tkey\n\t\t};\n\t}\n\tget browserEvents() {\n\t\treturn this._browserEvents;\n\t}\n\tget cli() {\n\t\treturn this._cli;\n\t}\n\tget datasets() {\n\t\treturn this._datasets;\n\t}\n\tget evals() {\n\t\treturn this._evals;\n\t}\n\tget evaluators() {\n\t\treturn this._evaluators;\n\t}\n\tget rolloutSessions() {\n\t\treturn this._rolloutSessions;\n\t}\n\tget sql() {\n\t\treturn this._sql;\n\t}\n\tget tags() {\n\t\treturn this._tags;\n\t}\n\tget traces() {\n\t\treturn this._traces;\n\t}\n};\n//#endregion\nexport { LaminarClient, RolloutSessionsResource };\n\n//# sourceMappingURL=index.mjs.map","import pino, { Level } from 'pino';\nimport { PinoPretty } from 'pino-pretty';\n\nexport function initializeLogger(options?: { colorize?: boolean; level?: Level }) {\n  const colorize = options?.colorize ?? true;\n  const level =\n    options?.level ??\n    (process.env.LMNR_LOG_LEVEL?.toLowerCase()?.trim() as Level) ??\n    'info';\n\n  return pino(\n    {\n      level,\n    },\n    PinoPretty({\n      colorize,\n      minimumLevel: level,\n      destination: 2,\n    }),\n  );\n}\n","import { errorMessage } from '@lmnr-ai/types';\n\n/**\n * Write structured JSON to stdout. Use this for machine-readable output\n * when --json is set.\n */\nexport function outputJson(data: unknown): void {\n  console.log(JSON.stringify(data));\n}\n\n/**\n * Write a JSON error to stdout and exit with code 1.\n * Use this in --json mode so agents can parse the failure.\n */\nexport function outputJsonError(error: unknown, exitCode: number = 1): never {\n  console.log(JSON.stringify({\n    error: errorMessage(error),\n  }));\n  process.exit(exitCode);\n}\n","// Default Laminar endpoints, shared across commands. Override per-invocation\n// via the --frontend-url / --base-url flags or the LMNR_FRONTEND_URL /\n// LMNR_BASE_URL env vars; these are the final fallback.\nexport const DEFAULT_FRONTEND_URL = \"https://laminar.sh\";\nexport const DEFAULT_BASE_URL = \"https://api.lmnr.ai\";\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join, parse } from \"node:path\";\n\n/**\n * Directory-scoped project link, written by `setup` to `.lmnr/project.json`.\n * The project the CLI operates on is inferred from the directory you're in\n * (Vercel/Supabase style), overridable with --project-id.\n * Holds the project id plus small display details — never secrets (the API key\n * lives in .env).\n */\nexport interface LocalProjectFile {\n  projectId: string;\n  projectName?: string;\n  workspaceId?: string;\n  workspaceName?: string;\n}\n\nconst LOCAL_LMNR_DIR = \".lmnr\";\nconst LOCAL_LMNR_PROJECT_FILE = \"project.json\";\n\n/**\n * Find the nearest `.lmnr/project.json`, walking up from `startDir` to the\n * filesystem root (so commands work from subdirectories of a linked project).\n * Returns null if none is found.\n */\nexport async function readLocalProjectFile(\n  startDir: string = process.cwd(),\n): Promise<LocalProjectFile | null> {\n  let dir = startDir;\n  const root = parse(dir).root;\n\n  while (true) {\n    const candidate = join(dir, LOCAL_LMNR_DIR, LOCAL_LMNR_PROJECT_FILE);\n    try {\n      const parsed = JSON.parse(await readFile(candidate, \"utf8\")) as LocalProjectFile;\n      if (parsed && typeof parsed.projectId === \"string\" && parsed.projectId.length > 0) {\n        return parsed;\n      }\n    } catch {\n      // Not here (missing / unreadable / malformed) — keep walking up.\n    }\n    const parent = dirname(dir);\n    if (parent === dir || dir === root) break;\n    dir = parent;\n  }\n  return null;\n}\n\n/** Write `.lmnr/project.json` under `dir` (default cwd). Returns the file path. */\nexport async function writeLocalProjectFile(\n  link: LocalProjectFile,\n  dir: string = process.cwd(),\n): Promise<string> {\n  const linkDir = join(dir, LOCAL_LMNR_DIR);\n  await mkdir(linkDir, { recursive: true });\n  const path = join(linkDir, LOCAL_LMNR_PROJECT_FILE);\n  await writeFile(path, JSON.stringify(link, null, 2) + \"\\n\", \"utf8\");\n  return path;\n}\n","import { mkdir, readFile, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport const CREDENTIALS_VERSION = 1;\n\n/**\n * The signed-in user's BetterAuth tokens. The CLI is single-user — one account\n * at a time, so the file is flat (no profiles map / active pointer).\n * Pre-release: version stays 1, no backcompat with any earlier shape.\n * - `sessionToken` is the durable BetterAuth session token (the refresh token).\n * - `accessToken` is the short-lived (15m) EdDSA JWT minted from the session.\n */\nexport interface Credentials {\n  version: 1;\n  issuer: string;\n  // No `baseUrl` here on purpose: the data-API endpoint is resolved fresh on\n  // every command (`--base-url` flag → LMNR_BASE_URL → default) so a self-host\n  // .env change takes effect without re-login. `issuer` (the frontend URL,\n  // used for token refresh) stays cached because refresh has no flag/env.\n  sessionToken: string;\n  accessToken: string;\n  accessTokenExpiresAt: string;\n  sessionExpiresAt?: string;\n  userEmail?: string;\n  userId: string;\n  createdAt: string;\n  lastUsedAt?: string;\n}\n\n// The lmnr config dir: `XDG_CONFIG_HOME` when set, else `%APPDATA%\\lmnr` on\n// Windows and `~/.config/lmnr` elsewhere.\nexport function globalLmnrDirectory(): string {\n  const xdg = process.env.XDG_CONFIG_HOME?.trim();\n  if (xdg && xdg.length > 0) {\n    return join(xdg, \"lmnr\");\n  }\n  const appData = process.env.APPDATA?.trim();\n  if (process.platform === \"win32\" && appData && appData.length > 0) {\n    return join(appData, \"lmnr\");\n  }\n  return join(homedir(), \".config\", \"lmnr\");\n}\n\nexport function credentialsPath(): string {\n  return join(globalLmnrDirectory(), \"credentials.json\");\n}\n\n/**\n * Read the credentials file. Returns null when missing or not the current flat\n * v1 shape (treated as \"not logged in\" — `lmnr-cli login` overwrites).\n */\nexport async function readCredentials(): Promise<Credentials | null> {\n  const path = credentialsPath();\n  let raw: string;\n  try {\n    raw = await readFile(path, \"utf-8\");\n  } catch (e: unknown) {\n    if (isNotFound(e)) return null;\n    throw e;\n  }\n  let parsed: Partial<Credentials>;\n  try {\n    parsed = JSON.parse(raw) as Partial<Credentials>;\n  } catch {\n    return null;\n  }\n  if (parsed.version === CREDENTIALS_VERSION && typeof parsed.sessionToken === \"string\") {\n    return parsed as Credentials;\n  }\n  return null;\n}\n\nexport async function writeCredentials(creds: Credentials): Promise<void> {\n  const path = credentialsPath();\n  const parent = dirname(path);\n  await mkdir(parent, { recursive: true, mode: 0o700 });\n\n  // Preserve a tighter user-set mode (e.g. 0o600) across token-refresh writes;\n  // default 0o600 for new files. The temp adopts this mode and the rename\n  // carries it onto the canonical file.\n  let mode = 0o600;\n  try {\n    const existing = await stat(path);\n    mode = existing.mode & 0o777;\n  } catch (e: unknown) {\n    if (!isNotFound(e)) throw e;\n  }\n\n  // Atomic temp+rename so a crashed write can't corrupt the canonical file.\n  const tmp = `${path}.tmp.${process.pid}.${Date.now()}`;\n  await writeFile(tmp, JSON.stringify(creds, null, 2), { mode, flag: \"wx\" });\n  await rename(tmp, path);\n}\n\nexport async function deleteCredentials(): Promise<boolean> {\n  const path = credentialsPath();\n  try {\n    await stat(path);\n  } catch (e: unknown) {\n    if (isNotFound(e)) return false;\n    throw e;\n  }\n  await rm(path, { force: true });\n  return true;\n}\n\nfunction isNotFound(e: unknown): boolean {\n  return (\n    typeof e === \"object\" &&\n    e !== null &&\n    \"code\" in e &&\n    (e as { code?: string }).code === \"ENOENT\"\n  );\n}\n","// Hand-rolled fetch against BetterAuth's RFC 8628 device-flow endpoints. Login\n// is user-scoped: the device token endpoint returns a session token (the\n// refresh token); the access token is a short-lived JWT minted separately via\n// GET /api/auth/token.\n\nimport {\n  type DeviceCodeResponse,\n  type DeviceTokenResponse,\n  type PollOptions,\n  type SessionUser,\n} from \"./types\";\n\nexport const CLI_CLIENT_ID = \"lmnr-cli\";\nexport const CLI_SCOPE = \"projects:rw\";\n\nconst DEVICE_CODE_ENDPOINT = \"/api/auth/device/code\";\nconst DEVICE_TOKEN_ENDPOINT = \"/api/auth/device/token\";\nconst TOKEN_ENDPOINT = \"/api/auth/token\";\nconst SESSION_ENDPOINT = \"/api/auth/get-session\";\n\ntype PollErrorCode =\n  | \"authorization_pending\"\n  | \"slow_down\"\n  | \"access_denied\"\n  | \"expired_token\"\n  | \"invalid_grant\"\n  | \"invalid_request\"\n  | \"invalid_client\"\n  | \"server_error\";\n\nexport class DeviceFlowError extends Error {\n  constructor(public readonly code: string, message: string) {\n    super(message);\n  }\n}\n\nfunction trimSlash(url: string): string {\n  return url.replace(/\\/+$/, \"\");\n}\n\nexport async function initiateDevice(\n  issuer: string,\n  scope: string = CLI_SCOPE,\n): Promise<DeviceCodeResponse> {\n  const url = `${trimSlash(issuer)}${DEVICE_CODE_ENDPOINT}`;\n  const res = await fetch(url, {\n    method: \"POST\",\n    headers: { \"content-type\": \"application/json\" },\n    body: JSON.stringify({ client_id: CLI_CLIENT_ID, scope }),\n  });\n  if (!res.ok) {\n    const body = (await safeJson(res)) ?? {};\n    throw new DeviceFlowError(\n      typeof body.error === \"string\" ? body.error : `http_${res.status}`,\n      typeof body.error_description === \"string\"\n        ? body.error_description\n        : `Device authorization request failed (${res.status})`,\n    );\n  }\n  return (await res.json()) as DeviceCodeResponse;\n}\n\n/**\n * Poll BetterAuth's native token endpoint until the user approves. Returns the\n * full token response (whose `access_token` is the durable session token).\n */\nexport async function pollDevice(\n  issuer: string,\n  deviceCode: string,\n  opts: PollOptions = {},\n): Promise<DeviceTokenResponse> {\n  let intervalSeconds = Math.max(1, opts.intervalSeconds ?? 5);\n  const timeoutMs = (opts.timeoutSeconds ?? 900) * 1000;\n  const deadline = Date.now() + timeoutMs;\n\n  while (true) {\n    if (Date.now() > deadline) {\n      throw new DeviceFlowError(\"expired_token\", \"Timed out waiting for authorization\");\n    }\n    const url = `${trimSlash(issuer)}${DEVICE_TOKEN_ENDPOINT}`;\n    const res = await fetch(url, {\n      method: \"POST\",\n      headers: { \"content-type\": \"application/json\" },\n      body: JSON.stringify({\n        grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n        device_code: deviceCode,\n        client_id: CLI_CLIENT_ID,\n      }),\n    });\n    if (res.ok) {\n      const body = (await res.json()) as DeviceTokenResponse;\n      if (!body.access_token) {\n        throw new DeviceFlowError(\"server_error\", \"Device token response missing access_token\");\n      }\n      // The browser-selected project (and any future CLI metadata) rides back on\n      // the x-lmnr-metadata response header, NOT the OAuth scope. Attach it so\n      // callers can parse it via parseProjectFromMetadata.\n      body.metadata = res.headers.get(\"x-lmnr-metadata\");\n      return body;\n    }\n    const body = (await safeJson(res)) ?? {};\n    const code = (\n      typeof body.error === \"string\" ? body.error : `http_${res.status}`\n    ) as PollErrorCode;\n    const description = typeof body.error_description === \"string\" ? body.error_description : code;\n    if (code === \"authorization_pending\") {\n      opts.onTick?.();\n      await sleep(intervalSeconds * 1000);\n      continue;\n    }\n    if (code === \"slow_down\") {\n      intervalSeconds += 5;\n      await sleep(intervalSeconds * 1000);\n      continue;\n    }\n    // access_denied / expired_token / invalid_grant / server_error — terminal.\n    throw new DeviceFlowError(code, description);\n  }\n}\n\n/**\n * Mint a fresh 15m EdDSA JWT from a session token. Throws DeviceFlowError\n * \"invalid_grant\" on 401 (session expired/revoked).\n */\nexport async function mintAccessJwt(issuer: string, sessionToken: string): Promise<string> {\n  const url = `${trimSlash(issuer)}${TOKEN_ENDPOINT}`;\n  const res = await fetch(url, {\n    method: \"GET\",\n    headers: { authorization: `Bearer ${sessionToken}` },\n  });\n  if (res.status === 401) {\n    throw new DeviceFlowError(\"invalid_grant\", \"Session expired or revoked\");\n  }\n  if (!res.ok) {\n    const body = (await safeJson(res)) ?? {};\n    throw new DeviceFlowError(\n      typeof body.error === \"string\" ? body.error : `http_${res.status}`,\n      `Failed to mint access token (${res.status})`,\n    );\n  }\n  const body = (await res.json()) as { token?: string };\n  if (!body.token) {\n    throw new DeviceFlowError(\"server_error\", \"Token endpoint response missing token\");\n  }\n  return body.token;\n}\n\n/** Fetch the BetterAuth session for profile metadata (userId, email). */\nexport async function fetchSession(issuer: string, sessionToken: string): Promise<SessionUser> {\n  const url = `${trimSlash(issuer)}${SESSION_ENDPOINT}`;\n  const res = await fetch(url, {\n    method: \"GET\",\n    headers: { authorization: `Bearer ${sessionToken}` },\n  });\n  if (!res.ok) {\n    throw new DeviceFlowError(`http_${res.status}`, `Failed to fetch session (${res.status})`);\n  }\n  const body = (await res.json()) as { user?: { id?: string; email?: string } } | null;\n  const user = body?.user;\n  if (!user?.id) {\n    throw new DeviceFlowError(\"server_error\", \"Session response missing user\");\n  }\n  return { id: user.id, email: user.email ?? \"\" };\n}\n\n/**\n * Decode a JWT's `exp` (seconds since epoch) → ISO string. No signature\n * verification — the CLI trusts a token it just received over TLS. Returns null\n * when the token is malformed or carries no numeric `exp`.\n */\nexport function decodeJwtExp(jwt: string): string | null {\n  const parts = jwt.split(\".\");\n  if (parts.length < 2) return null;\n  try {\n    const json = Buffer.from(parts[1], \"base64url\").toString(\"utf-8\");\n    const payload = JSON.parse(json) as { exp?: unknown };\n    if (typeof payload.exp !== \"number\") return null;\n    return new Date(payload.exp * 1000).toISOString();\n  } catch {\n    return null;\n  }\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Extract the browser-selected projectId from the device-token `x-lmnr-metadata`\n * response header — a JSON string, e.g. `{\"projectId\":\"<uuid>\"}`, forwarded by\n * the server's /device/token route wrapper. Returns null when absent or malformed.\n */\nexport function parseProjectFromMetadata(metadata?: string | null): string | null {\n  if (!metadata) return null;\n  try {\n    const obj = JSON.parse(metadata) as { projectId?: unknown };\n    const pid = obj?.projectId;\n    return typeof pid === \"string\" && UUID_RE.test(pid) ? pid : null;\n  } catch {\n    return null;\n  }\n}\n\nasync function safeJson(res: Response): Promise<Record<string, unknown> | null> {\n  try {\n    return (await res.json()) as Record<string, unknown>;\n  } catch {\n    return null;\n  }\n}\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise((r) => setTimeout(r, ms));\n}\n","import { DEFAULT_BASE_URL } from \"../constants\";\nimport { readLocalProjectFile } from \"../utils/local-project-file\";\nimport { type Credentials, readCredentials, writeCredentials } from \"./credentials\";\nimport { decodeJwtExp, DeviceFlowError, mintAccessJwt } from \"./device\";\nimport { type AuthInputs, type ResolvedAuth } from \"./types\";\n\n// Re-mint the JWT when it's within this window of expiry.\nconst REFRESH_SKEW_MS = 30_000;\n\n/**\n * HTTP port from `LMNR_HTTP_PORT`. The Laminar convention is that `baseUrl`\n * carries NO port and the port is supplied separately (mirrors the SDK's\n * `LMNR_HTTP_PORT` / `LMNR_GRPC_PORT`). Returns undefined when unset/invalid so\n * the client keeps its 443 default for Cloud. An explicit `--port` flag still\n * wins (callers do `opts.port ?? envHttpPort()`).\n */\nexport function envHttpPort(): number | undefined {\n  const raw = process.env.LMNR_HTTP_PORT?.trim();\n  if (!raw) return undefined;\n  const n = Number.parseInt(raw, 10);\n  return Number.isFinite(n) ? n : undefined;\n}\n\n/**\n * Resolve the data-API base URL: `--base-url` flag → `LMNR_BASE_URL` env →\n * default. Intentionally NOT read from credentials.json — the endpoint is not\n * persisted at login, so a self-host `.env` change applies to every command\n * without re-logging-in (and base URL behaves symmetrically with the port).\n */\nexport function resolveBaseUrl(optBaseUrl?: string): string {\n  return optBaseUrl?.trim() || process.env.LMNR_BASE_URL?.trim() || DEFAULT_BASE_URL;\n}\n\n/**\n * CLI auth is **user-token only** — the CLI authenticates as the single\n * signed-in user via the stored BetterAuth session (refreshed access JWT),\n * never via a project API key.\n *\n * Project precedence (directory-scoped): `--project-id` flag > the nearest\n * `.lmnr/project.json` (written by `setup`). The project is NOT stored in\n * credentials.json — that holds only user auth.\n */\nexport async function resolveAuth(opts: AuthInputs): Promise<ResolvedAuth> {\n  const creds = await readCredentials();\n  if (!creds) {\n    throw new Error(\"Not authenticated. Run `lmnr-cli login`.\");\n  }\n\n  let projectId = opts.projectId;\n  if (!projectId || projectId.length === 0) {\n    projectId = (await readLocalProjectFile())?.projectId;\n  }\n  if (!projectId || projectId.length === 0) {\n    throw new Error(\n      \"No project for this directory. Run `lmnr-cli setup` here, \" +\n      \"or pass --project-id <id>.\",\n    );\n  }\n\n  const updated = await refreshIfNeeded(creds);\n  return {\n    bearer: updated.accessToken,\n    baseUrl: resolveBaseUrl(opts.baseUrl),\n    port: opts.port ?? envHttpPort(),\n    projectId,\n  };\n}\n\n/**\n * Resolve only the user-scoped access token (no project) — for discovery\n * endpoints like listing projects, which run BEFORE a project is selected.\n */\nexport async function resolveUserToken(opts: {\n  baseUrl?: string;\n  port?: number;\n}): Promise<{ bearer: string; baseUrl?: string; port?: number }> {\n  const creds = await readCredentials();\n  if (!creds) {\n    throw new Error(\"Not authenticated. Run `lmnr-cli login`.\");\n  }\n  const updated = await refreshIfNeeded(creds);\n  return {\n    bearer: updated.accessToken,\n    baseUrl: resolveBaseUrl(opts.baseUrl),\n    port: opts.port ?? envHttpPort(),\n  };\n}\n\n/**\n * Re-mint the access JWT when it's near expiry and persist it. A 401 from the\n * token endpoint means the session is gone — surface a clear \"run login\" error.\n *\n * Logout race guard: we write credentials ONLY when we actually re-minted. The\n * old code unconditionally rewrote the file (just to bump lastUsedAt) on every\n * command, so a concurrent `logout` that deleted the file mid-flight could have\n * its delete clobbered by this in-flight atomic rename — logout would appear to\n * succeed while tokens remained on disk. For a fresh (not-near-expiry) token we\n * now do no write at all, eliminating that window for the common case.\n */\nexport async function refreshIfNeeded(creds: Credentials): Promise<Credentials> {\n  const expMs = new Date(creds.accessTokenExpiresAt).getTime();\n  const nearExpiry = !Number.isFinite(expMs) || expMs - Date.now() <= REFRESH_SKEW_MS;\n  if (!nearExpiry) {\n    return creds;\n  }\n\n  const next: Credentials = { ...creds };\n  try {\n    const jwt = await mintAccessJwt(creds.issuer, creds.sessionToken);\n    next.accessToken = jwt;\n    next.accessTokenExpiresAt = decodeJwtExp(jwt) ?? new Date().toISOString();\n  } catch (e) {\n    if (e instanceof DeviceFlowError && e.code === \"invalid_grant\") {\n      throw new Error(\"Session expired — run `lmnr-cli login`.\");\n    }\n    throw e;\n  }\n  next.lastUsedAt = new Date().toISOString();\n  await writeCredentials(next);\n  return next;\n}\n","import { LaminarClient } from \"@lmnr-ai/client\";\n\nimport { resolveAuth } from \"./resolve\";\nimport { type AuthInputs } from \"./types\";\n\n/**\n * Build a LaminarClient for CLI commands. Auth is user-token only: the bearer\n * is the stored BetterAuth access JWT (auto-refreshed near expiry) and requests\n * route to `/v1/cli/*` with the resolved project in `x-lmnr-project-id`.\n */\nexport async function buildLaminarClient(opts: AuthInputs): Promise<LaminarClient> {\n  const auth = await resolveAuth(opts);\n  return new LaminarClient({\n    baseUrl: auth.baseUrl,\n    port: auth.port,\n    // User-token auth → routes to /v1/cli/* with the resolved project in the\n    // x-lmnr-project-id header.\n    auth: { type: \"userToken\", token: auth.bearer, projectId: auth.projectId },\n  });\n}\n","import { LaminarClient } from \"@lmnr-ai/client\";\nimport { errorMessage } from \"@lmnr-ai/types\";\nimport type { Command } from \"commander\";\n\nimport { initializeLogger } from \"../utils/logger\";\nimport { outputJsonError } from \"../utils/output\";\nimport { buildLaminarClient } from \"./client\";\nimport { resolveUserToken } from \"./resolve\";\n\nconst logger = initializeLogger();\n\n/**\n * Global options every wrapped command shares (from `cmd.optsWithGlobals()`).\n * `projectId` is consumed by the project-client path; discovery commands ignore\n * it (the user-token surface has no project to scope at discovery time).\n */\nexport interface GlobalOpts {\n  projectId?: string;\n  baseUrl?: string;\n  port?: number;\n  json?: boolean;\n}\n\n/**\n * Map a thrown error to a process exit code. The default is 1; pass a custom\n * mapper to a wrapper to surface distinct machine-readable codes (Phase 6).\n */\nexport type ExitCodeMapper = (error: unknown) => number;\n\nconst defaultExitCode: ExitCodeMapper = () => 1;\n\n/**\n * Pull the commander positionals out of an `.action(...)` argument list.\n * Commander invokes the handler as `(arg1, ..., argN, options, command)`, so\n * the positionals are everything except the trailing `(options, command)`.\n */\nfunction splitCommanderArgs(cmdArgs: unknown[]): {\n  positionals: unknown[];\n  command: Command;\n  opts: GlobalOpts;\n} {\n  const command = cmdArgs.at(-1) as Command;\n  const positionals = cmdArgs.slice(0, -2);\n  const opts = command.optsWithGlobals();\n  return { positionals, command, opts };\n}\n\n/**\n * The error envelope shared by both wrappers: in `--json` mode emit a structured\n * error line and exit with the mapped code; otherwise log and exit. Owning this\n * here lets handlers stay pure `(client, ...args) => work` with no try/catch.\n */\nfunction runWithEnvelope(\n  work: () => Promise<void>,\n  opts: GlobalOpts,\n  exitCodeFor: ExitCodeMapper,\n): Promise<void> {\n  return work().catch((error: unknown) => {\n    const code = exitCodeFor(error);\n    if (opts.json) {\n      // outputJsonError exits with `code` (never returns).\n      outputJsonError(error, code);\n    }\n    logger.error(errorMessage(error));\n    process.exit(code);\n  });\n}\n\n/**\n * The handler shape both wrappers accept: a pure function of the resolved\n * client, the commander positionals, and the parsed options (so it can read\n * `--json` for output mode). All auth resolution + the error envelope live in\n * the wrapper, so handlers contain only the work.\n */\nexport type ClientAction<A extends unknown[]> = (\n  client: LaminarClient,\n  ...args: [...A, GlobalOpts]\n) => Promise<void>;\n\n/**\n * The handler shape {@link withLocalOpts} accepts: a pure function of the\n * commander positionals and the parsed options — no client, for commands that\n * only touch local state (e.g. `.lmnr/*` files) and never call the API.\n */\nexport type LocalAction<A extends unknown[]> = (\n  ...args: [...A, GlobalOpts]\n) => Promise<void>;\n\n/**\n * Wrap a local-only command handler. No auth resolution / client build (the\n * command must not call the API), but the same positionals + options threading\n * and error envelope as the client wrappers, so handlers stay pure.\n */\nexport const withLocalOpts =\n  <A extends unknown[]>(\n    action: LocalAction<A>,\n    exitCodeFor: ExitCodeMapper = defaultExitCode,\n  ) =>\n    async (...cmdArgs: unknown[]): Promise<void> => {\n      const { positionals, opts } = splitCommanderArgs(cmdArgs);\n      await runWithEnvelope(\n        () => action(...(positionals as A), opts),\n        opts,\n        exitCodeFor,\n      );\n    };\n\n/**\n * Wrap a project-scoped command handler. Resolves a user-token\n * {@link LaminarClient} (routes to `/v1/cli/*` with the resolved project),\n * threads the commander positionals + options through, and owns the error\n * envelope.\n *\n * @example\n *   sqlCmd.command(\"query\")\n *     .argument(\"<query>\")\n *     .action(withProjectClient(handleSqlQuery)); // (client, query, opts) => work\n */\nexport const withProjectClient =\n  <A extends unknown[]>(\n    action: ClientAction<A>,\n    exitCodeFor: ExitCodeMapper = defaultExitCode,\n  ) =>\n    async (...cmdArgs: unknown[]): Promise<void> => {\n      const { positionals, opts } = splitCommanderArgs(cmdArgs);\n      await runWithEnvelope(\n        async () => {\n          const client = await buildLaminarClient({\n            projectId: opts.projectId,\n            baseUrl: opts.baseUrl,\n            port: opts.port,\n          });\n          await action(client, ...(positionals as A), opts);\n        },\n        opts,\n        exitCodeFor,\n      );\n    };\n\n/**\n * Wrap a discovery command handler. Resolves a user-token\n * {@link LaminarClient} with NO project (the discovery surface — e.g. listing\n * projects — runs before a project is selected), threads positionals +\n * options, and owns the error envelope.\n */\nexport const withUserToken =\n  <A extends unknown[]>(\n    action: ClientAction<A>,\n    exitCodeFor: ExitCodeMapper = defaultExitCode,\n  ) =>\n    async (...cmdArgs: unknown[]): Promise<void> => {\n      const { positionals, opts } = splitCommanderArgs(cmdArgs);\n      await runWithEnvelope(\n        async () => {\n          const token = await resolveUserToken({\n            baseUrl: opts.baseUrl,\n            port: opts.port,\n          });\n          const client = new LaminarClient({\n            baseUrl: token.baseUrl,\n            // token.port carries the --port flag OR the LMNR_HTTP_PORT fallback\n            // (resolveUserToken applies it); using opts.port here would drop it.\n            port: token.port,\n            // Discovery: no project id yet. CliResource overrides its own\n            // URL/headers, so the empty projectId is never sent.\n            auth: { type: \"userToken\", token: token.bearer, projectId: \"\" },\n          });\n          await action(client, ...(positionals as A), opts);\n        },\n        opts,\n        exitCodeFor,\n      );\n    };\n","import { createColors } from \"picocolors\";\n\n// Decide color support per stream: NO_COLOR (present at any value) disables,\n// FORCE_COLOR (present and not \"0\") forces on, otherwise fall back to that\n// stream's own TTY-ness. We key each stream independently because the CLI writes\n// human status to STDERR (stdout is reserved for the `--json` contract) but ALSO\n// prints a human summary to STDOUT in non-json mode — each should follow its own\n// stream's redirection (e.g. `setup > out.txt` must not get ANSI in the file).\nfunction enabledFor(stream: NodeJS.WriteStream): boolean {\n  if (\"NO_COLOR\" in process.env) return false;\n  if (\"FORCE_COLOR\" in process.env && process.env.FORCE_COLOR !== \"0\") return true;\n  return Boolean(stream.isTTY);\n}\n\n// Human status lines (✓ / ⚠ / errors) → stderr.\nexport const pc = createColors(enabledFor(process.stderr));\n// The non-json human summary (\"Next steps\") → stdout.\nexport const pcOut = createColors(enabledFor(process.stdout));\n\n// Laminar brand orange (#D0754E = rgb(208,117,78)). picocolors only ships the 16\n// ANSI colors, so wrap a truecolor escape ourselves — gated on stderr color\n// support (the brand banner is a stderr line, same as `pc`).\nconst stderrColorEnabled = enabledFor(process.stderr);\nexport const orange = (text: string): string =>\n  stderrColorEnabled ? `\\x1b[38;2;208;117;78m${text}\\x1b[39m` : text;\n","import { resolveAuth } from \"../auth/resolve\";\nimport type { GlobalOpts } from \"../auth/with-client\";\nimport { pc } from \"../utils/colors\";\nimport { outputJson } from \"../utils/output\";\n\n/**\n * One SSE frame from the app-server agent stream (`AgentEvent`, camelCase). Only\n * the fields the CLI consumes are typed; unknown variants are ignored so the\n * stream stays forward-compatible.\n */\ninterface AgentFrame {\n  type: \"conversation\" | \"delta\" | \"thought\" | \"message\" | \"finish\" | \"error\";\n  conversationId?: string;\n  text?: string;\n  message?: { role: string; parts?: { type: string; text?: string; name?: string }[] };\n}\n\n/** `ask`-specific opts on top of the shared globals. `conversation` continues a prior session. */\ntype AskOpts = GlobalOpts & { conversation?: string };\n\n/**\n * `lmnr-cli ask \"<question>\"` — ask the Laminar agent a natural-language question.\n * User-token authed (like the rest of the CLI) against `/v1/cli/agent/chat`, project\n * in the `x-lmnr-project-id` header; streams the answer to stdout (activity to stderr).\n * `--conversation <id>` continues a prior session (its id is echoed on stderr).\n */\nexport const handleAsk = async (query: string, opts: AskOpts): Promise<void> => {\n  const question = query?.trim();\n  if (!question) {\n    throw new Error('Provide a question, e.g. lmnr-cli ask \"why did my latest trace fail?\"');\n  }\n\n  // User-token auth (auto-refreshed) + resolved project — same resolution `withProjectClient` uses.\n  const { bearer, baseUrl, port, projectId } = await resolveAuth(opts);\n\n  // baseUrl carries no port by convention; splice the resolved port onto the URL.\n  const url = new URL(baseUrl.replace(/\\/+$/, \"\"));\n  if (port) url.port = String(port);\n  url.pathname = \"/v1/cli/agent/chat\";\n\n  const res = await fetch(url.toString(), {\n    method: \"POST\",\n    headers: {\n      Authorization: `Bearer ${bearer}`,\n      \"x-lmnr-project-id\": projectId,\n      \"Content-Type\": \"application/json\",\n      // Content negotiation: agents/scripts (`--json`) get one buffered JSON result; humans stream.\n      Accept: opts.json ? \"application/json\" : \"text/event-stream\",\n    },\n    // `--conversation` continues a prior session; omitted → server mints a fresh one and echoes it.\n    body: JSON.stringify({\n      message: question,\n      ...(opts.conversation ? { conversationId: opts.conversation } : {}),\n    }),\n  });\n\n  if (!res.ok || !res.body) {\n    const detail = await res.text().catch(() => \"\");\n    const suffix = detail ? `: ${detail.slice(0, 500)}` : \"\";\n    throw new Error(`Agent request failed (HTTP ${res.status})${suffix}`);\n  }\n\n  // `--json`: the server buffered the run into `{ answer, conversationId, tools }` — no stream\n  // to parse. Emit it verbatim.\n  if (opts.json) {\n    outputJson(await res.json());\n    return;\n  }\n\n  // Human mode: stream-parse the SSE frames — `delta` tokens form the answer (stdout), thoughts +\n  // tool calls surface as activity (stderr), a trailing `error` frame aborts.\n  const reader = res.body.getReader();\n  const decoder = new TextDecoder();\n  let buffer = \"\";\n  let answer = \"\";\n  let streamed = false;\n  let failure: string | undefined;\n  // Resolved server-side; arrives on the leading `conversation` frame (or equals `--conversation`).\n  let conversationId: string | undefined = opts.conversation;\n\n  const onFrame = (data: string): void => {\n    let frame: AgentFrame;\n    try {\n      frame = JSON.parse(data) as AgentFrame;\n    } catch {\n      return; // ignore keep-alives / malformed lines\n    }\n    switch (frame.type) {\n      case \"conversation\":\n        if (frame.conversationId) conversationId = frame.conversationId;\n        break;\n      case \"delta\":\n        // Only a NON-EMPTY delta counts as streamed: an empty token writes nothing but would still\n        // flip `streamed`, suppressing the `message`-frame fallback that carries the full answer.\n        if (typeof frame.text === \"string\" && frame.text.length > 0) {\n          answer += frame.text;\n          process.stdout.write(frame.text);\n          streamed = true;\n        }\n        break;\n      case \"thought\":\n        if (typeof frame.text === \"string\") {\n          process.stderr.write(pc.dim(frame.text));\n        }\n        break;\n      case \"message\": {\n        const parts = frame.message?.parts ?? [];\n        if (frame.message?.role === \"assistant\") {\n          for (const part of parts) {\n            if (part.type === \"toolCall\" && part.name) {\n              process.stderr.write(pc.dim(`\\n  → ${part.name}\\n`));\n            }\n          }\n          // Final assistant text: only used if no deltas streamed it (defensive).\n          const text = parts\n            .filter((p) => p.type === \"text\" && typeof p.text === \"string\")\n            .map((p) => p.text)\n            .join(\"\");\n          if (text) answer = text;\n        }\n        break;\n      }\n      case \"error\": {\n        // The `error` frame's `message` is a string (the `message` frame's is the\n        // ChatMessage object) — read it off the raw payload.\n        const raw = (frame as unknown as { message?: unknown }).message;\n        failure = typeof raw === \"string\" && raw.length > 0 ? raw : \"Agent error\";\n        break;\n      }\n      case \"finish\":\n        break;\n    }\n  };\n\n  const drain = (chunk: string): void => {\n    buffer += chunk;\n    let idx: number;\n    while ((idx = buffer.indexOf(\"\\n\\n\")) !== -1) {\n      const event = buffer.slice(0, idx);\n      buffer = buffer.slice(idx + 2);\n      const dataLine = event.split(\"\\n\").find((l) => l.startsWith(\"data:\"));\n      if (dataLine) onFrame(dataLine.slice(\"data:\".length).trim());\n    }\n  };\n\n  for (;;) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    drain(decoder.decode(value, { stream: true }));\n  }\n  drain(decoder.decode());\n  // Flush a trailing unterminated frame, if any.\n  const tail = buffer.split(\"\\n\").find((l) => l.startsWith(\"data:\"));\n  if (tail) onFrame(tail.slice(\"data:\".length).trim());\n\n  if (failure) throw new Error(failure);\n\n  if (streamed) {\n    process.stdout.write(\"\\n\");\n  } else if (answer.trim()) {\n    process.stdout.write(`${answer.trim()}\\n`);\n  } else {\n    process.stderr.write(pc.dim(\"(the agent returned no answer)\\n\"));\n  }\n\n  // Echo a ready-to-run continuation hint (muted, on stderr so stdout stays the clean answer) —\n  // copy it into the next turn's `--conversation`.\n  if (conversationId) {\n    process.stderr.write(\n      pc.dim(`\\ncontinue with: lmnr-cli ask \"<question>\" --conversation ${conversationId}\\n`),\n    );\n  }\n};\n","import { Datapoint, errorMessage } from '@lmnr-ai/types';\nimport csv from 'csv-parser';\nimport { asString, generateCsv, mkConfig } from 'export-to-csv';\nimport { createReadStream } from 'fs';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nimport { initializeLogger } from './logger';\n\nconst logger = initializeLogger();\n\n/**\n * Check if a file has a supported extension.\n */\nconst isSupportedFile = (file: string): boolean => {\n  const ext = path.extname(file).toLowerCase();\n  return ['.json', '.csv', '.jsonl'].includes(ext);\n};\n\n/**\n * Collect all supported files from the given paths.\n * Handles both files and directories.\n */\nexport const collectFiles = async (\n  paths: string[],\n  recursive: boolean = false,\n): Promise<string[]> => {\n  const collectedFiles: string[] = [];\n\n  for (const filepath of paths) {\n    try {\n      const stats = await fs.stat(filepath);\n\n      if (stats.isFile()) {\n        if (isSupportedFile(filepath)) {\n          collectedFiles.push(filepath);\n        } else {\n          logger.warn(`Skipping unsupported file type: ${filepath}`);\n        }\n      } else if (stats.isDirectory()) {\n        const entries = await fs.readdir(filepath);\n\n        for (const entry of entries) {\n          const fullPath = path.join(filepath, entry);\n          const entryStats = await fs.stat(fullPath);\n\n          if (entryStats.isFile() && isSupportedFile(fullPath)) {\n            collectedFiles.push(fullPath);\n          } else if (recursive && entryStats.isDirectory()) {\n            const subFiles = await collectFiles([fullPath], true);\n            collectedFiles.push(...subFiles);\n          }\n        }\n      }\n    } catch (error) {\n      logger.warn(\n        `Path does not exist or is not accessible: ${filepath}. `\n        + `Error: ${errorMessage(error)}`,\n      );\n    }\n  }\n\n  return collectedFiles;\n};\n\n/**\n * Read a JSON file and return its contents.\n */\nconst readJsonFile = async (filepath: string): Promise<any[]> => {\n  const content = await fs.readFile(filepath, 'utf-8');\n  const parsed = JSON.parse(content);\n  return Array.isArray(parsed) ? parsed : [parsed];\n};\n\n/**\n * Try to parse a string as JSON. If it fails, return the original string.\n */\nconst tryParseJson = (content: string): any => {\n  // Don't try to parse if it's not a string or doesn't look like JSON\n  if (typeof content !== 'string') {\n    return content;\n  }\n\n  // If it doesn't start with { or [, it's probably not JSON\n  const trimmed = content.trim();\n  if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n    return content;\n  }\n\n  try {\n    return JSON.parse(content);\n  } catch (error) {\n    logger.debug(\n      `Error parsing JSON: ${errorMessage(error)}`,\n    );\n    return content;\n  }\n};\n\n/**\n * Parse each field in a CSV row, attempting to convert JSON strings back to objects.\n */\nconst parseCsvRow = (row: Record<string, string>): any => {\n  const parsed: any = {};\n  for (const [key, value] of Object.entries(row)) {\n    parsed[key] = tryParseJson(value);\n  }\n  return parsed;\n};\n\n/**\n * Read a CSV file and return its contents as an array of objects.\n */\nconst readCsvFile = async (filepath: string): Promise<any[]> => new Promise((resolve, reject) => {\n  const results: any[] = [];\n  createReadStream(filepath)\n    .pipe(csv())\n    .on('data', (data) => results.push(parseCsvRow(data)))\n    .on('end', () => resolve(results))\n    .on('error', reject);\n});\n\n/**\n * Read a JSONL file and return its contents as an array of objects.\n */\nasync function readJsonlFile(filepath: string): Promise<any[]> {\n  const content = await fs.readFile(filepath, 'utf-8');\n  const lines = content.split('\\n').filter((line) => line.trim());\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return lines.map((line) => JSON.parse(line));\n}\n\n/**\n * Read a single file and return its contents.\n */\nasync function readFile(filepath: string): Promise<any[]> {\n  const ext = path.extname(filepath).toLowerCase();\n\n  if (ext === '.json') {\n    return readJsonFile(filepath);\n  } else if (ext === '.csv') {\n    return readCsvFile(filepath);\n  } else if (ext === '.jsonl') {\n    return readJsonlFile(filepath);\n  } else {\n    throw new Error(`Unsupported file type: ${ext}`);\n  }\n}\n\n/**\n * Load data from all files in the specified paths.\n */\nexport const loadFromPaths = async <D = any, T = any>(\n  paths: string[],\n  recursive: boolean = false,\n): Promise<Datapoint<D, T>[]> => {\n  const files = await collectFiles(paths, recursive);\n\n  if (files.length === 0) {\n    logger.warn('No supported files found in the specified paths');\n    return [];\n  }\n\n  logger.info(`Found ${files.length} file(s) to read`);\n\n  const result: Datapoint<D, T>[] = [];\n\n  for (const file of files) {\n    try {\n      const data = await readFile(file);\n      result.push(...data);\n      logger.info(`Read ${data.length} record(s) from ${file}`);\n    } catch (error) {\n      logger.error(\n        `Error reading file ${file}: ${errorMessage(error)}`,\n      );\n      throw error;\n    }\n  }\n\n  return result;\n};\n\n/**\n * Write data to a JSON file.\n */\nconst writeJsonFile = async <D, T>(\n  filepath: string,\n  data: Datapoint<D, T>[],\n): Promise<void> => {\n  const content = JSON.stringify(data, null, 2);\n  await fs.writeFile(filepath, content, 'utf-8');\n};\n\n/**\n * Format data as a CSV string.\n */\nconst formatCsv = <D, T>(data: Datapoint<D, T>[]): string => {\n  const formattedData = data.map(item =>\n    Object.fromEntries(Object.entries(item).map(([key, value]) => [key, stringifyForCsv(value)]),\n    ));\n\n  const csvConfig = mkConfig({ useKeysAsHeaders: true });\n  const csvOutput = generateCsv(csvConfig)(formattedData);\n  return asString(csvOutput);\n};\n\n/**\n * Write data to a CSV file.\n */\nconst writeCsvFile = async <D, T>(\n  filepath: string,\n  data: Datapoint<D, T>[],\n): Promise<void> => {\n  if (data.length === 0) {\n    throw new Error('No data to write to CSV');\n  }\n\n  await fs.writeFile(filepath, formatCsv(data), 'utf-8');\n};\n\n/**\n * Write data to a JSONL file.\n */\nconst writeJsonlFile = async <D, T>(\n  filepath: string,\n  data: Datapoint<D, T>[],\n): Promise<void> => {\n  const lines = data.map((item) => JSON.stringify(item)).join('\\n');\n  await fs.writeFile(filepath, lines + '\\n', 'utf-8');\n};\n\n/**\n * Write data to a file based on the file extension.\n */\nexport const writeToFile = async <D, T>(\n  filepath: string,\n  data: Datapoint<D, T>[],\n  format?: 'json' | 'csv' | 'jsonl',\n): Promise<void> => {\n  // Create parent directories if they don't exist\n  const dir = path.dirname(filepath);\n  await fs.mkdir(dir, { recursive: true });\n\n  // Determine the format\n  const ext = format ?? path.extname(filepath).slice(1);\n\n  if (format && format !== path.extname(filepath).slice(1)) {\n    logger.warn(\n      `Output format ${format} does not match file extension ${path.extname(filepath).slice(1)}`,\n    );\n  }\n\n  if (ext === 'json') {\n    await writeJsonFile(filepath, data);\n  } else if (ext === 'csv') {\n    await writeCsvFile(filepath, data);\n  } else if (ext === 'jsonl') {\n    await writeJsonlFile(filepath, data);\n  } else {\n    throw new Error(`Unsupported output format: ${ext}`);\n  }\n};\n\n/**\n * Convert a value to a CSV-safe string.\n * - Strings and numbers pass through\n * - null/undefined become empty strings\n * - Objects and arrays are stringified to JSON\n */\nconst stringifyForCsv = (value: any): string => {\n  if (value === null || value === undefined) {\n    return '';\n  }\n  if (typeof value === 'string') {\n    return value;\n  }\n  if (typeof value === 'number' || typeof value === 'boolean') {\n    return String(value);\n  }\n  // For objects and arrays, stringify to JSON\n  return JSON.stringify(value);\n};\n\n/**\n * Print data to console in the specified format.\n */\nexport const printToConsole = <D, T>(\n  data: Datapoint<D, T>[],\n  format: 'json' | 'csv' | 'jsonl' = 'json',\n) => {\n  if (format === 'json') {\n    console.log(JSON.stringify(data, null, 2));\n  } else if (format === 'csv') {\n    if (data.length === 0) {\n      logger.error('No data to print');\n      return;\n    }\n\n    console.log(formatCsv(data));\n  } else if (format === 'jsonl') {\n    data.forEach((item) => console.log(JSON.stringify(item)));\n  } else {\n    throw new Error(\n      `Unsupported output format: ${String(format)}. `\n      + \"(supported formats: json, csv, jsonl)\",\n    );\n  }\n};\n\n","import Table from \"cli-table3\";\n\nconst DEFAULT_TERMINAL_WIDTH = 80;\nconst PADDING_RIGHT = 2;\n\nconst noBorderChars = {\n  top: \"\", \"top-mid\": \"\", \"top-left\": \"\", \"top-right\": \"\",\n  bottom: \"\", \"bottom-mid\": \"\", \"bottom-left\": \"\", \"bottom-right\": \"\",\n  left: \"\", \"left-mid\": \"\", mid: \"\", \"mid-mid\": \"\",\n  right: \"\", \"right-mid\": \"\", middle: \"\",\n};\n\nfunction getTerminalWidth(): number {\n  return process.stdout.columns || DEFAULT_TERMINAL_WIDTH;\n}\n\n/**\n * Calculate column widths that fit within the terminal width.\n * Distributes available space proportionally based on content width.\n */\nfunction fitColumnWidths(\n  contentWidths: number[],\n  terminalWidth: number,\n): number[] | undefined {\n  // With no borders, overhead is just padding-right per column\n  const overhead = contentWidths.length * PADDING_RIGHT;\n  const totalContentWidth = contentWidths.reduce((sum, w) => sum + w, 0);\n\n  if (totalContentWidth + overhead <= terminalWidth) {\n    return undefined;\n  }\n\n  const availableContent = terminalWidth - overhead;\n  const minColWidth = 5;\n\n  // Return widths including padding, since cli-table3's colWidths includes padding\n  return contentWidths.map((w) =>\n    Math.max(\n      minColWidth + PADDING_RIGHT,\n      Math.floor((w / totalContentWidth) * availableContent) + PADDING_RIGHT,\n    ),\n  );\n}\n\nfunction truncate(str: string, maxLen: number): string {\n  if (maxLen < 1) return str;\n  if (str.length <= maxLen) return str;\n  return str.slice(0, maxLen - 1) + \"\\u2026\";\n}\n\n/**\n * Render a borderless table from column headers and row data.\n * Automatically truncates content when the table exceeds terminal width.\n */\nexport function renderTable(head: string[], rows: string[][]): string {\n  const terminalWidth = getTerminalWidth();\n\n  const contentWidths = head.map((h, i) =>\n    rows.reduce((max, row) => Math.max(max, (row[i] ?? \"\").length), h.length),\n  );\n\n  const colWidths = fitColumnWidths(contentWidths, terminalWidth);\n\n  const truncatedHead = colWidths\n    ? head.map((h, i) => truncate(h, colWidths[i] - PADDING_RIGHT))\n    : head;\n\n  const table = new Table({\n    head: truncatedHead,\n    chars: noBorderChars,\n    style: {\n      \"padding-left\": 0,\n      \"padding-right\": PADDING_RIGHT,\n    },\n    ...(colWidths && { colWidths }),\n  });\n\n  if (colWidths) {\n    for (const row of rows) {\n      table.push(row.map((cell, i) => truncate(cell, colWidths[i] - PADDING_RIGHT)));\n    }\n  } else {\n    for (const row of rows) {\n      table.push(row);\n    }\n  }\n\n  return table.toString();\n}\n","import { LaminarClient } from \"@lmnr-ai/client\";\nimport { Datapoint, type StringUUID } from \"@lmnr-ai/types\";\n\nimport type { GlobalOpts } from \"../../auth/with-client\";\nimport { loadFromPaths, printToConsole, writeToFile } from \"../../utils/file\";\nimport { initializeLogger } from \"../../utils/logger\";\nimport { outputJson } from \"../../utils/output\";\nimport { renderTable } from \"../../utils/table\";\n\nconst logger = initializeLogger();\nconst DEFAULT_DATASET_PULL_BATCH_SIZE = 100;\nconst DEFAULT_DATASET_PUSH_BATCH_SIZE = 100;\n\ninterface DatasetIdentifierOptions extends GlobalOpts {\n  name?: string;\n  id?: StringUUID;\n}\n\n/** Throw on the name/id mutual-exclusion rule. The wrapper renders the error. */\nfunction requireSingleIdentifier(opts: { name?: string; id?: StringUUID }): void {\n  if (!opts.name && !opts.id) {\n    throw new Error(\"Either name or id must be provided\");\n  }\n  if (opts.name && opts.id) {\n    throw new Error(\"Only one of name or id must be provided\");\n  }\n}\n\n/**\n * Pull all data from a dataset in batches.\n */\nconst pullAllData = async <D = any, T = any>(\n  client: LaminarClient,\n  identifier: { name?: string; id?: StringUUID },\n  batchSize: number = DEFAULT_DATASET_PULL_BATCH_SIZE,\n  offset: number = 0,\n  limit?: number,\n): Promise<Datapoint<D, T>[]> => {\n  let hasMore = true;\n  let currentOffset = offset;\n  const stopAt = limit !== undefined ? offset + limit : undefined;\n\n  const result: Datapoint<D, T>[] = [];\n\n  while (hasMore && (stopAt === undefined || currentOffset < stopAt)) {\n    const data = await client.datasets.pull<D, T>({\n      ...identifier,\n      offset: currentOffset,\n      limit: batchSize,\n    });\n\n    result.push(...data.items);\n\n    // Stop if we received no items or fewer items than requested (end of data)\n    if (data.items.length === 0 || data.items.length < batchSize) {\n      hasMore = false;\n    } else if (stopAt !== undefined && currentOffset + batchSize >= stopAt) {\n      hasMore = false;\n    } else if (data.totalCount !== undefined && currentOffset + batchSize >= data.totalCount) {\n      hasMore = false;\n    }\n\n    currentOffset += batchSize;\n  }\n\n  if (limit !== undefined) {\n    return result.slice(0, limit);\n  }\n\n  return result;\n};\n\n/**\n * Handle datasets list command. Pure handler — `withProjectClient` resolves the\n * client and owns the error envelope.\n */\nexport const handleDatasetsList = async (\n  client: LaminarClient,\n  opts: GlobalOpts,\n): Promise<void> => {\n  const datasets = await client.datasets.listDatasets();\n\n  if (opts.json) {\n    outputJson(datasets);\n    return;\n  }\n\n  if (datasets.length === 0) {\n    console.log(\"No datasets found.\");\n    return;\n  }\n\n  const rows = datasets.map((dataset) => {\n    const createdAt = new Date(dataset.createdAt);\n    const createdAtStr = createdAt.toISOString().replace('T', ' ').substring(0, 19);\n    return [dataset.id, createdAtStr, dataset.name];\n  });\n\n  console.log(renderTable(['ID', 'Created At', 'Name'], rows));\n  console.log(`\\nTotal: ${datasets.length} dataset(s)\\n`);\n};\n\n/**\n * Handle datasets push command.\n */\nexport const handleDatasetsPush = async (\n  client: LaminarClient,\n  paths: string[],\n  opts: DatasetIdentifierOptions & {\n    recursive?: boolean;\n    batchSize?: number;\n  },\n): Promise<void> => {\n  requireSingleIdentifier(opts);\n\n  const data = await loadFromPaths(paths, opts.recursive);\n\n  if (data.length === 0) {\n    throw new Error(\"No data to push\");\n  }\n\n  const identifier = opts.name ? { name: opts.name } : { id: opts.id };\n\n  const result = await client.datasets.push({\n    points: data,\n    ...identifier,\n    batchSize: opts.batchSize ?? DEFAULT_DATASET_PUSH_BATCH_SIZE,\n  });\n\n  if (opts.json) {\n    outputJson({ datasetId: result?.datasetId, count: data.length });\n    return;\n  }\n\n  logger.info(`Pushed ${data.length} data points to dataset ${opts.name || opts.id}`);\n};\n\n/**\n * Handle datasets pull command.\n */\nexport const handleDatasetsPull = async (\n  client: LaminarClient,\n  outputPath: string | undefined,\n  opts: DatasetIdentifierOptions & {\n    outputFormat?: 'json' | 'csv' | 'jsonl';\n    batchSize?: number;\n    limit?: number;\n    offset?: number;\n  },\n): Promise<void> => {\n  requireSingleIdentifier(opts);\n\n  const identifier = opts.name ? { name: opts.name } : { id: opts.id };\n\n  const result = await pullAllData(\n    client,\n    identifier,\n    opts.batchSize ?? DEFAULT_DATASET_PULL_BATCH_SIZE,\n    opts.offset ?? 0,\n    opts.limit,\n  );\n\n  if (outputPath) {\n    await writeToFile(outputPath, result, opts.outputFormat);\n    if (opts.json) {\n      outputJson({ path: outputPath, count: result.length });\n    } else {\n      logger.info(`Successfully pulled ${result.length} data points to ${outputPath}`);\n    }\n  } else {\n    if (opts.json) {\n      outputJson(result);\n    } else {\n      printToConsole(result, opts.outputFormat ?? 'json');\n    }\n  }\n};\n\n/**\n * Handle datasets create command.\n */\nexport const handleDatasetsCreate = async (\n  client: LaminarClient,\n  name: string,\n  paths: string[],\n  opts: GlobalOpts & {\n    outputFile: string;\n    outputFormat?: 'json' | 'csv' | 'jsonl';\n    recursive?: boolean;\n    batchSize?: number;\n  },\n): Promise<void> => {\n  // Load data from input files\n  const data = await loadFromPaths(paths, opts.recursive);\n\n  if (data.length === 0) {\n    throw new Error(\"No data to push\");\n  }\n\n  // Push data to create/populate the dataset\n  logger.info(`Pushing ${data.length} data points to dataset '${name}'...`);\n\n  await client.datasets.push({\n    points: data,\n    name,\n    batchSize: opts.batchSize ?? DEFAULT_DATASET_PUSH_BATCH_SIZE,\n    createDataset: true,\n  });\n  logger.info(`Successfully pushed ${data.length} data points to dataset '${name}'`);\n\n  // Pull data back from the dataset\n  logger.info(`Pulling data from dataset '${name}'...`);\n\n  const result = await pullAllData(\n    client,\n    { name },\n    opts.batchSize ?? DEFAULT_DATASET_PULL_BATCH_SIZE,\n    0,\n    undefined,\n  );\n\n  // Save to output file\n  await writeToFile(opts.outputFile, result, opts.outputFormat);\n\n  if (opts.json) {\n    outputJson({ name, path: opts.outputFile, count: result.length });\n  } else {\n    logger.info(\n      `Successfully created dataset '${name}' `\n      + `and saved ${result.length} datapoints to ${opts.outputFile}`,\n    );\n  }\n};\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, parse, resolve } from \"node:path\";\n\nimport { DEBUG_SESSION_DIR, DEBUG_SESSION_FILE, type DebugSessionFile } from \"@lmnr-ai/types\";\n\n// Coerce an unknown field to a non-empty string, else null — the file is\n// best-effort local state that an agent may hand-edit, so every field is\n// treated defensively rather than trusted. Mirrors the SDK's read.\nconst str = (v: unknown): string | null => (typeof v === \"string\" && v.length > 0 ? v : null);\n\n/**\n * Read `${dir ?? cwd}/.lmnr/debug-session.json`. Best-effort: returns null on a\n * missing / unreadable / malformed file, or one with no usable `session_id`.\n * Mirrors the SDK's reader (`@lmnr-ai/lmnr` `src/debug/debug-session-file.ts`)\n * over the shared `DebugSessionFile` contract from `@lmnr-ai/types`.\n */\nexport const readDebugSessionFile = (dir: string = process.cwd()): DebugSessionFile | null => {\n  try {\n    const raw = readFileSync(join(dir, DEBUG_SESSION_DIR, DEBUG_SESSION_FILE), \"utf-8\");\n    const r = JSON.parse(raw) as Record<string, unknown>;\n    const session_id = str(r.session_id);\n    if (!session_id) return null;\n    return {\n      session_id,\n      trace_id: str(r.trace_id),\n      replay_trace_id: str(r.replay_trace_id),\n      cache_until: str(r.cache_until),\n      debugger_url: str(r.debugger_url),\n      started_at: str(r.started_at) ?? new Date().toISOString(),\n    };\n  } catch {\n    return null;\n  }\n};\n\n/**\n * Find the nearest directory (walking up from `startDir` to the filesystem\n * root) whose `.lmnr/debug-session.json` holds a usable session record, so CLI\n * commands run from a subdirectory of a project act on the project's session.\n * Mirrors the SDK's `findDebugSessionDir`. Returns null when no ancestor\n * (including `startDir`) has one.\n */\nexport const findDebugSessionDir = (startDir: string = process.cwd()): string | null => {\n  let dir = resolve(startDir);\n  const root = parse(dir).root;\n  while (true) {\n    if (readDebugSessionFile(dir) !== null) return dir;\n    const parent = dirname(dir);\n    if (parent === dir || dir === root) return null;\n    dir = parent;\n  }\n};\n\n/**\n * The directory the debug-session file should be read from AND written to: the\n * nearest ancestor (incl. `startDir`) that already has one, else `startDir`\n * itself. Read and write MUST share this anchor — `debug session new` resets\n * the nearest existing file rather than shadowing it with a nested copy.\n */\nexport const resolveDebugSessionDir = (startDir: string = process.cwd()): string =>\n  findDebugSessionDir(startDir) ?? resolve(startDir);\n\n/**\n * Resolve the session id a debug command should act on: the explicit\n * `--session-id` value when given, else the `session_id` of the nearest\n * `.lmnr/debug-session.json` (walking up from `startDir`). Throws an\n * actionable error when neither exists; the command wrapper's error envelope\n * formats it.\n */\nexport const resolveSessionId = (explicit?: string, startDir?: string): string => {\n  if (explicit) return explicit;\n  const file = readDebugSessionFile(resolveDebugSessionDir(startDir));\n  if (file?.session_id) return file.session_id;\n  throw new Error(\n    \"No session id given and no .lmnr/debug-session.json found in this \" +\n    \"directory. Pass --session-id <id> or run `lmnr-cli debug session new`.\",\n  );\n};\n\n/**\n * Write `${dir ?? cwd}/.lmnr/debug-session.json` (mkdir -p first). Best-effort:\n * swallows IO errors. Shares the `DebugSessionFile` contract + filename consts\n * with the SDK (`@lmnr-ai/types`), so the SDK reads this same file at init to\n * join the session `debug session new` minted.\n */\nexport const writeDebugSessionFile = (\n  file: DebugSessionFile,\n  dir: string = process.cwd(),\n): boolean => {\n  try {\n    const directory = join(dir, DEBUG_SESSION_DIR);\n    mkdirSync(directory, { recursive: true });\n    writeFileSync(join(directory, DEBUG_SESSION_FILE), JSON.stringify(file), \"utf-8\");\n    return true;\n  } catch {\n    return false;\n  }\n};\n","import { randomUUID } from \"node:crypto\";\n\nimport { LaminarClient } from \"@lmnr-ai/client\";\nimport { errorMessage, type SessionBlock } from \"@lmnr-ai/types\";\nimport open from \"open\";\n\nimport type { GlobalOpts } from \"../../auth/with-client\";\nimport { DEFAULT_FRONTEND_URL } from \"../../constants\";\nimport {\n  readDebugSessionFile,\n  resolveDebugSessionDir,\n  resolveSessionId,\n  writeDebugSessionFile,\n} from \"../../utils/debug-session-file\";\nimport { readLocalProjectFile } from \"../../utils/local-project-file\";\nimport { initializeLogger } from \"../../utils/logger\";\nimport { outputJson } from \"../../utils/output\";\n\nconst logger = initializeLogger();\n\n/**\n * Options accepted by the session-scoped debug commands (`set-name`, `summary`,\n * `open`), extending the shared globals.\n */\nexport interface DebugSessionScopedOpts extends GlobalOpts {\n  /** Set by `--session-id`; omitted → the debug-session.json `session_id`. */\n  sessionId?: string;\n}\n\n/**\n * Upsert the display name of a debug session. Update-only on the backend: a\n * session id unknown to the project 404s rather than creating a ghost session.\n *\n * The target session is the optional `--session-id` flag; when omitted the\n * session comes from `.lmnr/debug-session.json` (see `resolveSessionId`).\n *\n * Pure handler: the command wrapper (`withProjectClient`) resolves a user-token\n * {@link LaminarClient} (routes to `/v1/cli/*` with the resolved project) and\n * owns the error envelope.\n */\nexport const handleDebugSessionSetName = async (\n  client: LaminarClient,\n  name: string,\n  opts: DebugSessionScopedOpts,\n): Promise<void> => {\n  const sessionId = resolveSessionId(opts.sessionId);\n  await client.rolloutSessions.setName({ sessionId, name });\n\n  if (opts.json) {\n    outputJson({ sessionId, name });\n    return;\n  }\n\n  logger.info(`Set name of session ${sessionId} to \"${name}\".`);\n};\n\n/** Options accepted by `debug session add-note` (extends the shared globals). */\nexport interface DebugSessionAddNoteOpts extends GlobalOpts {\n  /** Set by `--session-id`; omitted → the debug-session.json `session_id`. */\n  sessionId?: string;\n}\n\n/**\n * Attach a free-text note to a debug session as a standalone `text` block.\n *\n * The note is written to the session's block list (`debugger_session_blocks`)\n * keyed by session id — NOT to any trace / evaluation metadata. Each call\n * appends a new block, interleaved by time with the session's trace / evaluation\n * blocks in the debugger UI (and in `debug session summary`). This is the\n * unified note path for both debug runs and evals: `rollout.session_id` links\n * traces / evals to the session; the note only needs the session id.\n *\n * The target session is the optional `--session-id` flag; when omitted the\n * session comes from `.lmnr/debug-session.json` (see `resolveSessionId`) — which\n * every LMNR_DEBUG=1 run (agents and evals alike) keeps pointed at the current\n * session via the SDK's shutdown pointer write.\n *\n * Pure handler: the command wrapper (`withProjectClient`) resolves a user-token\n * {@link LaminarClient} (routes to `/v1/cli/*` with the resolved project) and\n * owns the error envelope.\n */\nexport const handleDebugSessionAddNote = async (\n  client: LaminarClient,\n  note: string,\n  opts: DebugSessionAddNoteOpts,\n): Promise<void> => {\n  const sessionId = resolveSessionId(opts.sessionId);\n  // failOnNotFound: a CLI exit 0 must mean the note actually landed.\n  const blockId = await client.rolloutSessions.addBlock({\n    sessionId,\n    type: \"text\",\n    content: { text: note },\n    failOnNotFound: true,\n  });\n\n  if (opts.json) {\n    outputJson({ sessionId, blockId, note });\n    return;\n  }\n\n  logger.info(`Added note to session ${sessionId}.`);\n};\n\n/** Render one session block into the summary's text form. */\nconst renderBlock = (block: SessionBlock): string | null => {\n  const content = block.content ?? {};\n  switch (block.type) {\n    case \"trace\": {\n      const traceId = typeof content.traceId === \"string\" ? content.traceId : \"\";\n      return traceId ? `<trace id=\"${traceId}\"/>` : null;\n    }\n    case \"evaluation\": {\n      const evaluationId =\n        typeof content.evaluationId === \"string\" ? content.evaluationId : \"\";\n      return evaluationId ? `<evaluation id=\"${evaluationId}\"/>` : null;\n    }\n    case \"text\": {\n      const text = typeof content.text === \"string\" ? content.text : \"\";\n      return text || null;\n    }\n    default:\n      return null;\n  }\n};\n\n/**\n * Print a chronological digest of a debug session: every block (trace /\n * evaluation / text note) on the session, oldest first — the same data the\n * debugger UI renders.\n *\n * The target session is the optional `--session-id` flag; when omitted the\n * session comes from `.lmnr/debug-session.json` (see `resolveSessionId`).\n *\n * Pure handler: the command wrapper (`withProjectClient`) resolves a user-token\n * {@link LaminarClient} (routes to `/v1/cli/*` with the resolved project) and\n * owns the error envelope.\n */\nexport const handleDebugSessionSummary = async (\n  client: LaminarClient,\n  opts: DebugSessionScopedOpts,\n): Promise<void> => {\n  const sessionId = resolveSessionId(opts.sessionId);\n  const blocks = await client.rolloutSessions.listBlocks({ sessionId });\n  // Sort oldest-first defensively — the backend returns creation order, but the\n  // summary's contract is chronological regardless.\n  const ordered = [...blocks].sort((a, b) =>\n    String(a.createdAt).localeCompare(String(b.createdAt)),\n  );\n\n  if (opts.json) {\n    outputJson(ordered);\n    return;\n  }\n\n  if (ordered.length === 0) {\n    console.log(`No blocks found for session ${sessionId}.`);\n    return;\n  }\n\n  const rendered = ordered\n    .map(renderBlock)\n    .filter((b): b is string => b !== null);\n  console.log(rendered.join(\"\\n\\n\"));\n};\n\n/**\n * Build the frontend debugger-session URL. The frontend URL is its own env var\n * (LMNR_FRONTEND_URL) with a cloud default; self-host/local sets it explicitly.\n */\nconst buildDebuggerUrl = (projectId: string, sessionId: string): string => {\n  const frontend =\n    process.env.LMNR_FRONTEND_URL?.trim().replace(/\\/+$/, \"\") || DEFAULT_FRONTEND_URL;\n  return `${frontend}/project/${projectId}/debugger-sessions/${sessionId}`;\n};\n\n/**\n * Open a debug session's debugger page in the browser.\n *\n * The target session is the optional `--session-id` flag; when omitted the\n * session comes from `.lmnr/debug-session.json` (see `resolveSessionId`).\n * The URL is the file's stored `debugger_url` when it belongs to the resolved\n * session, else it is rebuilt from the resolved project (`--project-id` or the\n * linked `.lmnr/project.json`) + LMNR_FRONTEND_URL.\n *\n * Local-only handler (registered via `withLocalOpts`, NOT `withProjectClient`):\n * everything needed lives on disk, so no auth resolution / API call — `open`\n * works offline and before login.\n */\nexport const handleDebugSessionOpen = async (\n  opts: DebugSessionScopedOpts,\n): Promise<void> => {\n  const sessionId = resolveSessionId(opts.sessionId);\n\n  const file = readDebugSessionFile(resolveDebugSessionDir());\n  let debuggerUrl = file?.session_id === sessionId ? file.debugger_url : null;\n  if (!debuggerUrl) {\n    const projectId = opts.projectId || (await readLocalProjectFile())?.projectId;\n    if (!projectId) {\n      throw new Error(\n        \"Cannot build the debugger URL: no project is linked to this \" +\n        \"directory. Pass --project-id or run `lmnr-cli setup`.\",\n      );\n    }\n    debuggerUrl = buildDebuggerUrl(projectId, sessionId);\n  }\n\n  if (opts.json) {\n    outputJson({ sessionId, debuggerUrl });\n  } else {\n    // URL to stdout (agent-capturable); the logger keeps stderr for messages.\n    console.log(debuggerUrl);\n  }\n\n  try {\n    await open(debuggerUrl);\n  } catch (e) {\n    logger.warn(`Could not open a browser (${errorMessage(e)}). URL: ${debuggerUrl}`);\n  }\n};\n\n/** Options accepted by `debug session new` (extends the shared globals). */\nexport interface DebugSessionNewOpts extends GlobalOpts {\n  /** Set by commander's `--no-browser`; false suppresses the browser open. */\n  browser?: boolean;\n}\n\n/**\n * Mint a fresh debug session and reset `.lmnr/debug-session.json` to it.\n *\n * The next `LMNR_DEBUG=1 <run>` in this directory reads that file and rejoins the\n * minted session silently (no browser) — \"new session\" is owned by this command;\n * the SDK only mints when no file exists.\n *\n * Ordering matters: the local file is written FIRST (so the minted session is\n * usable for `LMNR_DEBUG=1` continuation even if the network is down / the\n * backend endpoint isn't deployed yet), THEN the session is best-effort\n * registered with the backend. A registration failure WARNS but does not fail\n * the command (exit 0) — the file is already written.\n *\n * Pure handler: the command wrapper (`withProjectClient`) resolves a user-token\n * {@link LaminarClient} (routes `register()` to `POST /v1/cli/rollouts/{id}` with\n * the resolved project) and owns the error envelope.\n */\nexport const handleDebugSessionNew = async (\n  client: LaminarClient,\n  opts: DebugSessionNewOpts,\n): Promise<void> => {\n  const sessionId = randomUUID();\n\n  // The session file is project-scoped: reset the NEAREST existing\n  // .lmnr/debug-session.json (walking up from cwd) rather than shadowing it\n  // with a nested copy; only when none exists anywhere up the tree is a fresh\n  // one created in cwd. Resolved once — both writes must hit the same file.\n  const sessionDir = resolveDebugSessionDir();\n\n  // 1. Write the file FIRST (nulls for trace/replay/cache, fresh started_at).\n  // The debugger_url is filled in once we learn the project id from register().\n  writeDebugSessionFile({\n    session_id: sessionId,\n    trace_id: null,\n    replay_trace_id: null,\n    cache_until: null,\n    debugger_url: null,\n    started_at: new Date().toISOString(),\n  }, sessionDir);\n\n  // 2. Best-effort register. Routes to POST /v1/cli/rollouts/{id} (userToken\n  // auth). A failure (endpoint missing / offline) warns but never fails — the\n  // file is already usable for continuation.\n  let projectId: string | null = null;\n  try {\n    projectId = await client.rolloutSessions.register({ sessionId });\n  } catch (e) {\n    logger.warn(\n      \"Could not register the debug session with the backend \" +\n      `(the local .lmnr/debug-session.json is still usable): ${errorMessage(e)}`,\n    );\n  }\n\n  // 3. Build the per-session debugger URL once the project id is known and\n  // rewrite the file with it filled in.\n  const debuggerUrl = projectId ? buildDebuggerUrl(projectId, sessionId) : null;\n  if (debuggerUrl) {\n    writeDebugSessionFile({\n      session_id: sessionId,\n      trace_id: null,\n      replay_trace_id: null,\n      cache_until: null,\n      debugger_url: debuggerUrl,\n      started_at: new Date().toISOString(),\n    }, sessionDir);\n  }\n\n  // 4. Output.\n  if (opts.json) {\n    outputJson({ sessionId, projectId, debuggerUrl });\n    return;\n  }\n\n  if (debuggerUrl) {\n    logger.info(`New debug session: ${debuggerUrl}`);\n  } else {\n    logger.info(`New debug session: ${sessionId}`);\n  }\n  // Print the bare session id to stdout so an agent can capture it directly.\n  console.log(sessionId);\n\n  // Default-open the browser (suppressed by --no-browser). Best-effort.\n  if (opts.browser !== false && debuggerUrl) {\n    try {\n      await open(debuggerUrl);\n    } catch {\n      // Best-effort: the URL is already printed for the user to open.\n    }\n  }\n};\n","import open from \"open\";\n\nimport { type Credentials, writeCredentials } from \"../../auth/credentials\";\nimport {\n  CLI_SCOPE,\n  decodeJwtExp,\n  fetchSession,\n  initiateDevice,\n  mintAccessJwt,\n  parseProjectFromMetadata,\n  pollDevice,\n} from \"../../auth/device\";\nimport { DEFAULT_FRONTEND_URL } from \"../../constants\";\nimport { pc } from \"../../utils/colors\";\n\nexport interface LoginOptions {\n  frontendUrl?: string;\n  noBrowser?: boolean;\n}\n\nexport interface LoginResult {\n  /** The signed-in user's id (from the BetterAuth session). */\n  userId: string;\n  /** The signed-in user's email, when present on the session. */\n  userEmail: string | null;\n  /**\n   * The projectId the user selected/created in the browser, delivered back via\n   * the device-token `x-lmnr-metadata` response header (see\n   * `parseProjectFromMetadata`). Null when the browser had nothing to select.\n   */\n  projectId: string | null;\n}\n\nexport async function handleLogin(options: LoginOptions): Promise<LoginResult> {\n  const issuer = pick(options.frontendUrl, process.env.LMNR_FRONTEND_URL, DEFAULT_FRONTEND_URL);\n  // NOTE: login does NOT resolve/store a data-API baseUrl — the device flow,\n  // JWT mint and session fetch all hit `issuer` (frontend). `--base-url` on\n  // login is accepted but inert (candidate for removal); data commands resolve\n  // baseUrl themselves via resolveBaseUrl.\n\n  const da = await initiateDevice(issuer, CLI_SCOPE);\n  const completeUri = da.verification_uri_complete ?? da.verification_uri;\n  process.stderr.write(\n    `\\nOpen this URL in your browser to authorize:\\n  ${pc.cyan(completeUri)}\\n`,\n  );\n  if (da.user_code) {\n    process.stderr.write(`Code: ${pc.bold(pc.cyan(da.user_code))}\\n\\n`);\n  }\n\n  if (!options.noBrowser) {\n    try {\n      await open(completeUri);\n    } catch {\n      // Best-effort. The user can copy/paste the URL.\n    }\n  }\n\n  process.stderr.write(pc.dim(\"Waiting for authorization...\\n\"));\n  const token = await pollDevice(issuer, da.device_code, {\n    intervalSeconds: da.interval,\n    timeoutSeconds: da.expires_in,\n  });\n\n  // The device token's access_token is the durable session token (refresh).\n  const sessionToken = token.access_token;\n  const jwt = await mintAccessJwt(issuer, sessionToken);\n  const session = await fetchSession(issuer, sessionToken);\n\n  const now = new Date().toISOString();\n  const creds: Credentials = {\n    version: 1,\n    issuer,\n    sessionToken,\n    accessToken: jwt,\n    accessTokenExpiresAt: decodeJwtExp(jwt) ?? now,\n    sessionExpiresAt:\n      typeof token.expires_in === \"number\"\n        ? new Date(Date.now() + token.expires_in * 1000).toISOString()\n        : undefined,\n    userEmail: session.email || undefined,\n    userId: session.id,\n    createdAt: now,\n    lastUsedAt: now,\n  };\n  await writeCredentials(creds);\n\n  // NOTE: the user-facing \"logged in / next steps\" summary is intentionally NOT\n  // printed here — handleLogin is shared with `setup`, which prints its own\n  // summary. The `login` command prints the summary itself (see src/index.ts).\n\n  return {\n    userId: session.id,\n    userEmail: session.email || null,\n    projectId: parseProjectFromMetadata(token.metadata),\n  };\n}\n\nfunction pick(...candidates: (string | undefined)[]): string {\n  for (const c of candidates) {\n    if (c && c.length > 0) return c;\n  }\n  return \"\";\n}\n","import {\n  type Credentials,\n  credentialsPath,\n  deleteCredentials,\n  readCredentials,\n} from \"../../auth/credentials\";\n\n/**\n * Best-effort server-side session revoke via POST /api/auth/sign-out with the\n * session token as Bearer. Logout MUST complete locally even if the server is\n * unreachable — the user expects \"log me out\" to remove the file. On any\n * failure we log to stderr and continue.\n */\nexport async function revokeSession(creds: Credentials): Promise<void> {\n  if (!creds.sessionToken || creds.sessionToken.length === 0) {\n    return;\n  }\n  const url = `${trimSlash(creds.issuer)}/api/auth/sign-out`;\n  try {\n    // BetterAuth's sign-out 500s on an empty body (JSON parse fails); send `{}`.\n    const res = await fetch(url, {\n      method: \"POST\",\n      headers: {\n        authorization: `Bearer ${creds.sessionToken}`,\n        \"content-type\": \"application/json\",\n      },\n      body: \"{}\",\n    });\n    if (!res.ok) {\n      process.stderr.write(\n        `warning: session revoke at ${url} returned ${res.status}; ` +\n          \"local credentials still removed.\\n\",\n      );\n    }\n  } catch (e) {\n    const msg = e instanceof Error ? e.message : String(e);\n    process.stderr.write(\n      `warning: session revoke at ${url} failed (${msg}); local credentials still removed.\\n`,\n    );\n  }\n}\n\nexport async function handleLogout(): Promise<void> {\n  const creds = await readCredentials();\n  if (!creds) {\n    process.stderr.write(\"Already logged out.\\n\");\n    return;\n  }\n  const label = creds.userEmail ?? creds.userId;\n  // Delete the local file FIRST, then best-effort revoke the server session.\n  // \"Log me out\" must remove the credentials even if the network revoke hangs\n  // or fails. Accepted residual race: a concurrent near-expiry refresh may\n  // re-write creds just after this delete (durable token + inert JWT; no lock).\n  await deleteCredentials();\n  await revokeSession(creds);\n  process.stderr.write(`Logged out of ${label}. Removed ${credentialsPath()}.\\n`);\n}\n\nfunction trimSlash(url: string): string {\n  return url.replace(/\\/+$/, \"\");\n}\n","import { LaminarClient } from \"@lmnr-ai/client\";\n\nimport type { GlobalOpts } from \"../../auth/with-client\";\nimport { readLocalProjectFile } from \"../../utils/local-project-file\";\nimport { outputJson } from \"../../utils/output\";\nimport { renderTable } from \"../../utils/table\";\n\n/**\n * List the projects the signed-in user can access (discovery — no project\n * scope). Pure handler: the `withUserToken` wrapper resolves the user-token\n * client and owns the error envelope.\n */\nexport const handleProjectsList = async (\n  client: LaminarClient,\n  opts: GlobalOpts,\n): Promise<void> => {\n  const projects = await client.cli.listProjects();\n\n  // Mark the project linked to the current directory (.lmnr/project.json).\n  const linked = (await readLocalProjectFile())?.projectId;\n\n  if (opts.json) {\n    outputJson(projects.map((p) => ({ ...p, linked: p.id === linked })));\n    return;\n  }\n\n  if (projects.length === 0) {\n    console.log(\"No projects found. Create one in the dashboard, then run `lmnr-cli setup`.\");\n    return;\n  }\n\n  const columns = [\"\", \"Workspace\", \"Project\", \"Project ID\"];\n  const rows = projects.map((p) => [p.id === linked ? \"●\" : \"\", p.workspaceName, p.name, p.id]);\n  console.log(renderTable(columns, rows));\n  console.log(\n    linked\n      ? \"\\n● = linked to this directory (lmnr-cli setup). \" +\n      \"Override per-command with --project-id.\\n\"\n      : \"\\nNot linked here. Run `lmnr-cli setup` in your project directory, \" +\n      \"or pass --project-id.\\n\",\n  );\n};\n","import { execFile } from \"node:child_process\";\nimport {\n  access,\n  readFile,\n  rename,\n  stat,\n  writeFile,\n} from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nconst DEFAULT_VAR_NAME = \"LMNR_PROJECT_API_KEY\";\n\n// Env files we inspect, highest precedence first (Next.js-style, minus the\n// NODE_ENV-specific rungs). `.env.local` is the JS/Next secret convention\n// (gitignored); `.env` is the cross-ecosystem default every loader reads —\n// including Python's python-dotenv / pydantic, which don't know `.env.local`.\nconst CANDIDATE_FILES = [\".env.local\", \".env\"] as const;\n\nexport interface WriteEnvResult {\n  /** Absolute path of the .env file. */\n  path: string;\n  /** True when the file did not exist before this call. */\n  created: boolean;\n  /** True when an existing `<varName>=` line was overwritten. */\n  replaced: boolean;\n}\n\n/**\n * Write/replace `<varName>=<value>` in the .env file at `envPath`.\n *\n * Semantics:\n * - If the file does not exist: create it with mode 0o600 and a single line.\n * - If the file exists:\n *   - Replace an existing `^<varName>\\s*=.*` line in place (preserves comments,\n *     ordering, and other keys).\n *   - Otherwise append the line (with a leading newline if the file does not\n *     end in one).\n *   - DO NOT change the file mode on existing files — the user may have set\n *     a deliberate mode and changing it surprises them.\n * - Writes are atomic: write to `<envPath>.tmp`, then rename.\n */\nexport async function writeEnvFile(\n  envPath: string,\n  value: string,\n  varName: string = DEFAULT_VAR_NAME,\n): Promise<WriteEnvResult> {\n  const exists = await fileExists(envPath);\n\n  if (!exists) {\n    const contents = `${varName}=${value}\\n`;\n    await atomicWrite(envPath, contents, 0o600);\n    return { path: envPath, created: true, replaced: false };\n  }\n\n  const original = await readFile(envPath, \"utf-8\");\n  // ^ at line start, m flag so . doesn't match newlines.\n  const regex = new RegExp(`^${escapeRegex(varName)}\\\\s*=.*$`, \"m\");\n  let next: string;\n  let replaced = false;\n  if (regex.test(original)) {\n    next = original.replace(regex, `${varName}=${value}`);\n    replaced = true;\n  } else {\n    const prefix = original.endsWith(\"\\n\") || original.length === 0 ? original : `${original}\\n`;\n    next = `${prefix}${varName}=${value}\\n`;\n  }\n  // Capture existing mode so the tmp inherits dest's perms — POSIX `rename`\n  // adopts the source inode's permissions, so without this an existing 0o600\n  // .env would silently widen to the umask default (0o644) on every rerun.\n  const existingMode = (await stat(envPath)).mode & 0o777;\n  await atomicWrite(envPath, next, existingMode);\n  return { path: envPath, created: false, replaced };\n}\n\n/**\n * Read a single env var's value from a .env file. Returns null when the file\n * is missing, the var is absent, or its value is empty/whitespace.\n */\nexport async function readEnvVar(\n  envPath: string,\n  varName: string = DEFAULT_VAR_NAME,\n): Promise<string | null> {\n  if (!(await fileExists(envPath))) return null;\n  const original = await readFile(envPath, \"utf-8\");\n  const regex = new RegExp(`^${escapeRegex(varName)}\\\\s*=(.*)$`, \"m\");\n  const match = original.match(regex);\n  if (!match) return null;\n  const value = match[1].trim().replace(/^[\"']|[\"']$/g, \"\");\n  return value.length > 0 ? value : null;\n}\n\n/** Where an existing key was found: the process environment, or a specific file. */\nexport type EnvKeySource = { type: \"process-env\" } | { type: \"file\"; path: string };\n\nexport interface EnvKeyLocation {\n  value: string;\n  source: EnvKeySource;\n}\n\n/**\n * Find an already-configured key, checking `process.env` → `.env.local` → `.env`\n * (first match wins, mirroring Next.js precedence). `process.env` comes first\n * because an exported var is what actually runs, regardless of language.\n */\nexport async function findEnvKey(\n  cwd: string,\n  varName: string = DEFAULT_VAR_NAME,\n): Promise<EnvKeyLocation | null> {\n  const fromProcess = process.env[varName]?.trim();\n  if (fromProcess) return { value: fromProcess, source: { type: \"process-env\" } };\n  for (const name of CANDIDATE_FILES) {\n    const path = resolve(cwd, name);\n    const value = await readEnvVar(path, varName);\n    if (value) return { value, source: { type: \"file\", path } };\n  }\n  return null;\n}\n\n/**\n * LMNR_* config keys the CLI hydrates from a project `.env.local` / `.env`.\n * Curated on purpose — we do NOT slurp the whole file, so unrelated app secrets\n * (model API keys, etc.) never enter the CLI process. Notable exclusions:\n *  - `LMNR_GRPC_PORT`: the CLI is REST-only (no gRPC), so it has no use for it.\n *  - `LMNR_LOG_LEVEL`: loggers are built at module-import time (before\n *    `loadLocalEnv` runs), so hydrating it here would silently have no effect.\n *  - `LMNR_PROJECT_ID`: the project comes from `--project-id` or\n *    `.lmnr/project.json` only; `resolveAuth` ignores the env var, so loading\n *    it here would just contradict that.\n */\nexport const AUTOLOADED_ENV_KEYS = [\n  \"LMNR_BASE_URL\",\n  \"LMNR_HTTP_PORT\",\n  \"LMNR_FRONTEND_URL\",\n] as const;\n\n/**\n * Hydrate `process.env` from `.env.local` / `.env` in `cwd` for the curated\n * {@link AUTOLOADED_ENV_KEYS}, WITHOUT overriding values already present in the\n * environment (a real exported var / Claude Code `settings.json` env always\n * wins — `findEnvKey` checks `process.env` first and we skip those).\n *\n * Why this exists: Claude Code and many other runners do NOT inject a project\n * `.env` into a spawned subprocess's environment, so self-hosters who put\n * `LMNR_BASE_URL` / `LMNR_HTTP_PORT` in `.env` previously had to export them or\n * pass flags on every call. cwd-only, no upward directory walk (mirrors\n * dotenv's default) — the CLI must be invoked from the dir holding the `.env`.\n */\nexport async function loadLocalEnv(\n  cwd: string,\n  keys: readonly string[] = AUTOLOADED_ENV_KEYS,\n): Promise<void> {\n  for (const key of keys) {\n    const found = await findEnvKey(cwd, key);\n    // Only hydrate from a file; a process-env hit means it's already set.\n    if (found?.source.type === \"file\") {\n      process.env[key] = found.value;\n    }\n  }\n}\n\n/**\n * Pick the file to write a freshly-minted key into:\n *  - rewrite in place if the key already lives in a file,\n *  - else prefer an existing `.env.local` (its presence proves the project opted\n *    into the gitignored-secret convention) — but never CREATE one, since Python\n *    loaders ignore it,\n *  - else `.env` (the default every ecosystem loads).\n */\nexport async function resolveEnvWriteTarget(\n  cwd: string,\n  existing: EnvKeyLocation | null,\n): Promise<string> {\n  if (existing?.source.type === \"file\") return existing.source.path;\n  const local = resolve(cwd, \".env.local\");\n  if (await fileExists(local)) return local;\n  return resolve(cwd, \".env\");\n}\n\n/**\n * Whether `path` is gitignored. Returns null when it can't be determined (not a\n * git repo / git absent) so callers can stay silent rather than warn wrongly.\n */\nexport async function isPathGitIgnored(path: string): Promise<boolean | null> {\n  try {\n    await execFileAsync(\"git\", [\"check-ignore\", \"-q\", path]);\n    return true; // exit 0 = ignored\n  } catch (err) {\n    // exit 1 = definitely not ignored; 128 (not a repo) / ENOENT (no git) = unknown\n    return (err as { code?: number }).code === 1 ? false : null;\n  }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n  try {\n    await access(path);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nasync function atomicWrite(\n  path: string,\n  contents: string,\n  mode: number | undefined,\n): Promise<void> {\n  const tmp = `${path}.tmp`;\n  await writeFile(tmp, contents, mode === undefined ? undefined : { mode });\n  await rename(tmp, path);\n}\n\nfunction escapeRegex(raw: string): string {\n  return raw.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","// Source coordinates for the Laminar agent skill, fetched from the public\n// lmnr-skills repo at `lmnr-cli setup` time via giget (see\n// ../utils/install-skill.ts).\n\nexport const SKILL_REPO = \"lmnr-ai/lmnr-skills\";\nexport const SKILL_REF = \"main\";\nexport const SKILL_NAME = \"laminar\";\n\n/**\n * giget source for the pinned skill subdir: `github:<owner>/<repo>/<subdir>#<ref>`.\n * giget resolves this against codeload.github.com, gunzips, untars, strips the\n * `repo-<ref>/` prefix, and extracts only the subdir — all the mechanics we'd\n * otherwise hand-roll.\n */\nexport function skillSource(): string {\n  return `github:${SKILL_REPO}/skills/${SKILL_NAME}#${SKILL_REF}`;\n}\n","import { downloadTemplate } from \"giget\";\n\nimport { skillSource } from \"./laminar-skill\";\n\n/**\n * Download the pinned Laminar skill subtree into `dir` using giget.\n *\n * giget owns every quirk we'd otherwise hand-roll: the codeload tarball URL,\n * gunzip, untar, stripping the `repo-<ref>/` leading segment, subdir filtering,\n * and ref pinning. `force` overwrites `dir` so reruns are idempotent.\n *\n * We deliberately do NOT pass `preferOffline`: giget caches the tarball keyed by\n * REF name, and SKILL_REF is a moving branch (`main` / a feature branch), so\n * `preferOffline` would reuse a stale cached tarball forever — reinstalling\n * files that were since deleted upstream. Without it, giget revalidates via the\n * stored etag and re-downloads when the branch moved.\n *\n * Throws on network / resolve / extract errors — callers (skill install is\n * best-effort) catch and skip.\n */\nexport async function downloadSkill(dir: string): Promise<void> {\n  await downloadTemplate(skillSource(), {\n    dir,\n    force: true,\n  });\n}\n","import { access, cp, mkdir, mkdtemp, readdir, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, relative } from \"node:path\";\n\nimport { downloadSkill } from \"../skill/fetch-skill\";\nimport { SKILL_NAME, skillSource } from \"../skill/laminar-skill\";\n\n// Agent dirs we look for in the project root. Order matters only for the\n// \"none present\" default below.\nconst AGENT_DIRS = [\".claude\", \".cursor\", \".codex\", \".agents\"] as const;\n\n// When NO agent dir exists we default to writing the skill into BOTH\n// `.claude/` (Claude Code reads `.claude/skills/`) and `.agents/`, so whichever\n// agent the project later adopts can find it.\nconst DEFAULT_AGENT_DIRS = [\".claude\", \".agents\"];\n\nexport interface InstallSkillResult {\n  /** Absolute paths of every written file (SKILL.md + references/...). */\n  written: string[];\n  /** True when no agent dir existed and we defaulted to `.claude/` + `.agents/`. */\n  defaulted: boolean;\n  /**\n   * True when the skill could not be fetched (network failure) and install was\n   * skipped. `written` is empty and `defaulted` is false.\n   */\n  skipped: boolean;\n}\n\n/**\n * Fetch the pinned Laminar skill (`SKILL_NAME`) from the lmnr-skills repo and\n * write its full tree into every present agent dir under `cwd`\n * (`<dir>/skills/<SKILL_NAME>/SKILL.md`, `.../references/*.md`, ...). If none\n * are present, default to BOTH `.claude/` and `.agents/`. Idempotent —\n * overwrites on rerun.\n *\n * We download ONCE into a temp staging dir (one network hit) and copy it into\n * each agent dir. Skill install is the last, best-effort step of `setup`: a\n * download failure MUST NOT break setup — on error we log a warning and return\n * `{ written: [], defaulted: false, skipped: true }`.\n *\n * For .cursor/.codex the skills layout is not guaranteed to match CC; we write\n * the CC-guaranteed `skills/<SKILL_NAME>/` shape there too rather than\n * inventing a path that silently loads nothing.\n */\nexport async function installSkill(\n  cwd: string = process.cwd(),\n): Promise<InstallSkillResult> {\n  const staging = await mkdtemp(join(tmpdir(), \"lmnr-skill-\"));\n  try {\n    try {\n      await downloadSkill(staging);\n    } catch (err) {\n      process.stderr.write(\n        `Warning: could not fetch the Laminar skill (${skillSource()}): ` +\n        `${describeError(err)}; skipping skill install.\\n`,\n      );\n      return { written: [], defaulted: false, skipped: true };\n    }\n\n    // Files relative to the staging root (e.g. \"SKILL.md\", \"references/x.md\").\n    const relFiles = (await readdir(staging, { recursive: true, withFileTypes: true }))\n      .filter((d) => d.isFile())\n      .map((d) => relative(staging, join(d.parentPath, d.name)));\n\n    const present: string[] = [];\n    for (const dir of AGENT_DIRS) {\n      if (await dirExists(join(cwd, dir))) present.push(dir);\n    }\n\n    const targets = present.length > 0 ? present : DEFAULT_AGENT_DIRS;\n    const written: string[] = [];\n    for (const dir of targets) {\n      const skillRoot = join(cwd, dir, \"skills\", SKILL_NAME);\n      // Replace, don't merge: `cp` alone would leave behind files that were\n      // deleted upstream (e.g. a removed reference doc) from a prior install.\n      await rm(skillRoot, { recursive: true, force: true });\n      await mkdir(skillRoot, { recursive: true });\n      await cp(staging, skillRoot, { recursive: true });\n      for (const rel of relFiles) written.push(join(skillRoot, rel));\n    }\n\n    return { written, defaulted: present.length === 0, skipped: false };\n  } finally {\n    await rm(staging, { recursive: true, force: true });\n  }\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n  try {\n    await access(path);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nfunction describeError(err: unknown): string {\n  return err instanceof Error ? err.message : String(err);\n}\n","import { hostname } from \"node:os\";\nimport { relative } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\n\nimport { type CliProject, LaminarClient, type ProjectKeyProbe } from \"@lmnr-ai/client\";\n\nimport { version } from \"../../../package.json\";\nimport { type Credentials, readCredentials } from \"../../auth/credentials\";\nimport { envHttpPort, refreshIfNeeded } from \"../../auth/resolve\";\nimport { orange, pc, pcOut } from \"../../utils/colors\";\nimport {\n  type EnvKeyLocation,\n  findEnvKey,\n  isPathGitIgnored,\n  resolveEnvWriteTarget,\n  writeEnvFile,\n} from \"../../utils/env-file\";\nimport { installSkill } from \"../../utils/install-skill\";\nimport {\n  type LocalProjectFile,\n  readLocalProjectFile,\n  writeLocalProjectFile,\n} from \"../../utils/local-project-file\";\nimport { handleLogin } from \"../login\";\n\nconst DEFAULT_FRONTEND_URL = \"https://laminar.sh\";\nconst DEFAULT_BASE_URL = \"https://api.lmnr.ai\";\n\n// Exit codes (machine-readable contract — each distinct so automation can\n// branch on the failure mode):\n//   4  no_access            — user lacks access to the linked project\n//   6  login_failed         — device-flow login failed / no creds after login\n//   7  no_project           — no project to select (and none could be created)\n//   8  env_write_failed     — minted a key but couldn't write ./.env\n//   9  setup_key_failed     — POST /api/cli/api-key failed\n//   10 list_projects_failed — GET /v1/cli/projects (discovery) failed\n//   11 key_probe_failed     — couldn't verify the existing key (network/server error)\n//   12 key_mismatch         — existing key belongs to a different project\nconst EXIT_NO_ACCESS = 4;\nconst EXIT_LOGIN_FAILED = 6;\nconst EXIT_NO_PROJECT = 7;\nconst EXIT_ENV_WRITE_FAILED = 8;\nconst EXIT_SETUP_KEY_FAILED = 9;\nconst EXIT_LIST_PROJECTS_FAILED = 10;\nconst EXIT_KEY_PROBE_FAILED = 11;\nconst EXIT_KEY_MISMATCH = 12;\n\nexport interface SetupOptions {\n  writeEnv?: boolean;\n  json?: boolean;\n  noBrowser?: boolean;\n  frontendUrl?: string;\n  baseUrl?: string;\n  /**\n   * Explicit project id. Disambiguates when the user can access >1 project\n   * (otherwise --json setup errors `project_ambiguous`). Validated against the\n   * user's accessible projects before linking.\n   */\n  projectId?: string;\n}\n\ninterface SetupKeyResponse {\n  apiKey: string;\n  apiKeyId: string;\n  projectId: string;\n  projectName: string;\n  workspaceId: string;\n  workspaceName: string;\n}\n\nexport interface SetupResult {\n  projectId: string;\n  projectName: string | null;\n  workspaceId: string | null;\n  workspaceName: string | null;\n  /** The key written to .env, or null when an existing matching key was reused. */\n  apiKey: string | null;\n  envFileUpdated: string | null;\n  /** SKILL.md paths written by the skill installer. */\n  skillsInstalled: string[];\n  frontendUrl: string;\n  userEmail: string | null;\n}\n\n/**\n * Directory-scoped onboarding (SPEC decision tree):\n *  - log in if needed (browser picks/creates the project; its id rides back on\n *    the device-token metadata, see parseProjectFromMetadata),\n *  - resolve a project for this directory (`.lmnr/project.json`), enforcing\n *    access,\n *  - mint a project API key only when one isn't already configured for this\n *    project (checked across process.env → .env.local → .env), then write it to\n *    an existing .env.local or else .env,\n *  - install the Laminar skill into present agent dirs,\n *  - print a summary.\n *\n * The minted key goes ONLY into the project's env file, never into\n * credentials.json (which stores user-scoped BetterAuth tokens).\n */\nexport async function handleSetup(options: SetupOptions): Promise<void> {\n  const writeEnv = options.writeEnv !== false;\n  const frontendUrl = pick(\n    options.frontendUrl,\n    process.env.LMNR_FRONTEND_URL,\n    DEFAULT_FRONTEND_URL,\n  );\n  const baseUrl = pick(options.baseUrl, process.env.LMNR_BASE_URL, DEFAULT_BASE_URL);\n  const isJson = options.json === true;\n\n  if (!isJson) {\n    process.stderr.write(`\\n${orange(\"Laminar CLI\")} ${pc.dim(`v${version}`)}\\n\\n`);\n  }\n\n  const cwd = process.cwd();\n  // Detect an already-configured key across process.env → .env.local → .env.\n  const existingKey = await findEnvKey(cwd);\n\n  let creds: Credentials | null = await safeReadCredentials();\n  let link = await readLocalProjectFile();\n\n  // --- 1. Login + project resolution ---------------------------------------\n\n  if (!creds) {\n    // Not logged in: run the device flow. The browser is where the project is\n    // chosen/created (when there's no link), and the chosen id rides back on\n    // the device-token metadata (parseProjectFromMetadata).\n    let login;\n    try {\n      login = await handleLogin({ frontendUrl, noBrowser: options.noBrowser });\n    } catch (err) {\n      emitError(isJson, \"login_failed\", describeError(err));\n      process.exit(EXIT_LOGIN_FAILED);\n    }\n    creds = await safeReadCredentials();\n    if (!creds) {\n      emitError(isJson, \"login_failed\", \"credentials missing after login\");\n      process.exit(EXIT_LOGIN_FAILED);\n    }\n\n    const issuer = creds.issuer || frontendUrl;\n    const userBaseUrl = baseUrl;\n\n    if (link) {\n      // Directory already declares the project — ignore the metadata-borne id\n      // and assert the freshly-authenticated user can access the linked project.\n      await assertAccess(creds, userBaseUrl, link, existingKey, isJson);\n    } else if (login.projectId) {\n      // Browser-selected (or just-created) project. Trust it and write the link.\n      link = await writeLink(issuer, userBaseUrl, login.projectId, isJson);\n    } else {\n      // Defensive: fall back to the CLI picker if the browser didn't attach a\n      // project via metadata.\n      link = await resolveProjectViaCli(creds, userBaseUrl, issuer, isJson, options);\n    }\n  } else {\n    // Already logged in.\n    const userBaseUrl = baseUrl;\n    const issuer = creds.issuer || frontendUrl;\n    if (link) {\n      await assertAccess(creds, userBaseUrl, link, existingKey, isJson);\n    } else {\n      link = await resolveProjectViaCli(creds, userBaseUrl, issuer, isJson, options);\n    }\n  }\n\n  if (!isJson) {\n    process.stderr.write(`${pc.green(\"✓\")} Logged in as ${creds.userEmail ?? \"<unknown>\"}\\n`);\n    process.stderr.write(\n      `${pc.green(\"✓\")} Project: ${link.projectName ?? link.projectId}` +\n      (link.workspaceName ? pc.dim(` (${link.workspaceName})`) : \"\") +\n      \"\\n\",\n    );\n  }\n\n  // --- 2. Assert invariants -------------------------------------------------\n\n  if (!creds || !link.projectId) {\n    emitError(isJson, \"setup_invariant\", \"missing credentials or project after resolution\");\n    process.exit(EXIT_NO_PROJECT);\n  }\n\n  const issuer = creds.issuer || frontendUrl;\n  const userBaseUrl = baseUrl;\n\n  // --- 3. Key handling (SPEC 36-42) -----------------------------------------\n\n  let apiKey: string | null = null;\n  let envPath: string | null = null;\n  let keyMeta: SetupKeyResponse | null = null;\n\n  let needMint = true;\n  if (existingKey) {\n    const probe = await probeProjectKey(creds, existingKey.value, userBaseUrl);\n    const where =\n      existingKey.source.type === \"process-env\"\n        ? \"your environment\"\n        : relative(cwd, existingKey.source.path);\n\n    if (probe.status === \"unverifiable\") {\n      // Couldn't verify the key (network/server error). Do NOT mint — that would\n      // clobber a possibly-valid key on a transient blip. Abort so the user retries.\n      emitError(\n        isJson,\n        \"key_probe_failed\",\n        `Couldn't verify the existing Project API Key in ${where} (network or server error). ` +\n        \"Check your connection and re-run.\",\n      );\n      process.exit(EXIT_KEY_PROBE_FAILED);\n    } else if (probe.status === \"ok\" && probe.projectId === link.projectId) {\n      // Already configured for this project. Respect the user's setup: no mint,\n      // no write (option a) — including when the key only lives in process.env.\n      needMint = false;\n      if (!isJson) {\n        process.stderr.write(`${pc.green(\"✓\")} Project API Key already set in ${where}\\n`);\n      }\n    } else if (probe.status === \"ok\") {\n      // Valid key, but for a DIFFERENT project. Refuse to clobber it — abort so the\n      // user resolves the conflict deliberately rather than silently overwriting.\n      emitError(\n        isJson,\n        \"key_mismatch\",\n        `The Project API Key in ${where} belongs to a different project (${probe.projectId}), ` +\n        `not the one linked here (${link.projectId}). Remove or update it, then re-run.`,\n      );\n      process.exit(EXIT_KEY_MISMATCH);\n    } else if (!isJson) {\n      // invalid / revoked (401) — minting a fresh key is the correct recovery.\n      process.stderr.write(\n        `${pc.yellow(\"⚠\")} Existing Project API Key in ${where} is invalid or revoked, ` +\n        `minting a new one\\n`,\n      );\n    }\n  }\n\n  if (needMint) {\n    try {\n      keyMeta = await mintSetupKey(issuer, creds.sessionToken, link.projectId);\n    } catch (err) {\n      emitError(isJson, \"setup_key_failed\", describeError(err));\n      process.exit(EXIT_SETUP_KEY_FAILED);\n    }\n    apiKey = keyMeta.apiKey;\n\n    // Backfill display details onto the link if we learned them while minting.\n    if (!link.projectName && keyMeta.projectName) link.projectName = keyMeta.projectName;\n    if (!link.workspaceName && keyMeta.workspaceName) link.workspaceName = keyMeta.workspaceName;\n    if (!link.workspaceId && keyMeta.workspaceId) link.workspaceId = keyMeta.workspaceId;\n\n    if (writeEnv) {\n      const target = await resolveEnvWriteTarget(cwd, existingKey);\n      try {\n        const result = await writeEnvFile(target, apiKey);\n        envPath = result.path;\n        if (!isJson) {\n          const rel = relative(cwd, result.path);\n          const verb = result.created\n            ? \"Created\"\n            : result.replaced\n              ? \"Updated LMNR_PROJECT_API_KEY in\"\n              : \"Added LMNR_PROJECT_API_KEY to\";\n          process.stderr.write(`${pc.green(\"✓\")} ${verb} ${rel}\\n`);\n          // The key is a secret; nudge if it landed in a tracked file.\n          if ((await isPathGitIgnored(result.path)) === false) {\n            process.stderr.write(\n              `${pc.yellow(\"⚠\")} ${rel} isn't gitignored; add it so the key isn't committed\\n`,\n            );\n          }\n        }\n      } catch (err) {\n        process.stderr.write(\n          `\\n${pc.red(\"ERROR\")}: failed to write ${target}: ${describeError(err)}\\n` +\n          pc.dim(\"Your API key (set it manually):\") +\n          `\\n  LMNR_PROJECT_API_KEY=${apiKey}\\n\\n`,\n        );\n        if (isJson) {\n          process.stdout.write(\n            JSON.stringify({\n              error: \"env_write_failed\",\n              apiKey,\n              projectId: link.projectId,\n              message: describeError(err),\n            }) + \"\\n\",\n          );\n        }\n        process.exit(EXIT_ENV_WRITE_FAILED);\n      }\n    }\n  }\n\n  // --- 4. Skill install -----------------------------------------------------\n\n  let skillsInstalled: string[] = [];\n  try {\n    // installSkill fetches the skill from the lmnr-skills repo and is\n    // best-effort: it logs + returns `skipped: true` on network/codeload\n    // failure rather than throwing, so setup never breaks here.\n    const skillResult = await installSkill(process.cwd());\n    skillsInstalled = skillResult.written;\n    if (!isJson) {\n      if (skillResult.skipped) {\n        process.stderr.write(pc.dim(\"  Laminar skill install skipped\\n\"));\n      } else if (skillResult.written.length > 0) {\n        // One mark for the whole skill, not one per file (SKILL.md + references).\n        const note = skillResult.defaulted\n          ? pc.dim(\" (no agent dir found; defaulted to .claude and .agents)\")\n          : \"\";\n        process.stderr.write(`${pc.green(\"✓\")} Installed Laminar skill${note}\\n`);\n      }\n    }\n  } catch (err) {\n    if (!isJson) {\n      process.stderr.write(\n        `${pc.yellow(\"Warning\")}: could not install Laminar skill (${describeError(err)}).\\n`,\n      );\n    }\n  }\n\n  // --- 5. Summary -----------------------------------------------------------\n\n  const frontendLink = `${trimSlash(issuer)}/project/${link.projectId}/traces`;\n\n  const result: SetupResult = {\n    projectId: link.projectId,\n    projectName: link.projectName ?? null,\n    workspaceId: link.workspaceId ?? null,\n    workspaceName: link.workspaceName ?? null,\n    apiKey,\n    envFileUpdated: envPath,\n    skillsInstalled,\n    frontendUrl: frontendLink,\n    userEmail: creds.userEmail ?? null,\n  };\n\n  if (isJson) {\n    process.stdout.write(JSON.stringify(result) + \"\\n\");\n  } else {\n    const docsUrl = \"https://laminar.sh/docs/tracing/integrations/overview\";\n    const verifyCmd =\n      'lmnr-cli sql query \"SELECT * FROM traces ORDER BY start_time DESC LIMIT 1\" --json';\n    process.stdout.write(\n      \"\\nNext steps:\\n\" +\n      \"  1. Instrument your project with Laminar using the installed skill or the docs:\\n\" +\n      `     ${pcOut.cyan(docsUrl)}\\n` +\n      \"  2. Run your project.\\n\" +\n      \"  3. Verify instrumentation:\\n\" +\n      `     ${pcOut.green(verifyCmd)}\\n` +\n      \"  4. View your traces in the browser:\\n\" +\n      `     ${pcOut.cyan(frontendLink)}\\n`,\n    );\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Project resolution helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a project via the CLI (logged-in, no link). 0 projects routes to the\n * browser create flow (gap A): we re-run the device flow, which lands on the\n * /device picker → first-project create UI, and the new project's id rides back\n * on the device-token metadata. >1 prompts a CLI choice; ==1 auto-selects.\n */\nasync function resolveProjectViaCli(\n  creds: Credentials,\n  userBaseUrl: string,\n  issuer: string,\n  isJson: boolean,\n  options: SetupOptions,\n): Promise<LocalProjectFile> {\n  let projects: CliProject[];\n  try {\n    projects = await listProjects(creds, userBaseUrl);\n  } catch (err) {\n    emitError(isJson, \"list_projects_failed\", describeError(err));\n    process.exit(EXIT_LIST_PROJECTS_FAILED);\n  }\n\n  if (projects.length === 0) {\n    // Gap A: no project to select and the CLI can't create one. Drive the\n    // browser create flow — same path the not-logged-in 0-project user takes —\n    // so project creation lives in ONE place (the /device picker).\n    if (isJson) {\n      emitError(\n        isJson,\n        \"no_projects\",\n        `No projects found. Run \\`lmnr-cli setup\\` interactively (it opens the browser ` +\n        `to create your first project) or create one at ${trimSlash(issuer)}/onboarding.`,\n      );\n      process.exit(EXIT_NO_PROJECT);\n    }\n    process.stderr.write(\n      \"\\nYou have no projects yet. Opening the browser to create your first one...\\n\",\n    );\n    let login;\n    try {\n      login = await handleLogin({\n        frontendUrl: issuer,\n        noBrowser: options.noBrowser,\n      });\n    } catch (err) {\n      emitError(isJson, \"login_failed\", describeError(err));\n      process.exit(EXIT_LOGIN_FAILED);\n    }\n    if (!login.projectId) {\n      emitError(\n        isJson,\n        \"no_projects\",\n        `No project was created. Create one at ${trimSlash(issuer)}/onboarding then re-run setup.`,\n      );\n      process.exit(EXIT_NO_PROJECT);\n    }\n    return writeLink(issuer, userBaseUrl, login.projectId, isJson);\n  }\n\n  let chosen: CliProject;\n  if (options.projectId) {\n    // Explicit --project-id disambiguates. Validate against the accessible set.\n    const match = projects.find((p) => p.id === options.projectId);\n    if (!match) {\n      emitError(\n        isJson,\n        \"no_access\",\n        `You don't have access to project ${options.projectId}. Accessible: ` +\n        projects.map((p) => `${p.id} (${p.workspaceName}/${p.name})`).join(\", \"),\n      );\n      process.exit(EXIT_NO_ACCESS);\n    }\n    chosen = match;\n  } else if (projects.length === 1) {\n    chosen = projects[0];\n  } else {\n    if (isJson) {\n      emitError(\n        isJson,\n        \"project_ambiguous\",\n        `Multiple projects: pass --project-id <id>, or run setup interactively. ` +\n        projects.map((p) => `${p.id} (${p.workspaceName}/${p.name})`).join(\", \"),\n      );\n      process.exit(EXIT_NO_PROJECT);\n    }\n    chosen = await promptProjectChoice(projects);\n  }\n\n  const linkPath = await writeLocalProjectFile({\n    projectId: chosen.id,\n    projectName: chosen.name,\n    workspaceId: chosen.workspaceId,\n    workspaceName: chosen.workspaceName,\n  });\n  if (!isJson) process.stderr.write(`${pc.green(\"✓\")} Linked ${linkPath}\\n`);\n  return {\n    projectId: chosen.id,\n    projectName: chosen.name,\n    workspaceId: chosen.workspaceId,\n    workspaceName: chosen.workspaceName,\n  };\n}\n\n/** Write `.lmnr/project.json`, enriching display details from listProjects when possible. */\nasync function writeLink(\n  issuer: string,\n  userBaseUrl: string,\n  projectId: string,\n  isJson: boolean,\n): Promise<LocalProjectFile> {\n  let link: LocalProjectFile = { projectId };\n  try {\n    const creds = await safeReadCredentials();\n    if (creds) {\n      const projects = await listProjects(creds, userBaseUrl);\n      const match = projects.find((p) => p.id === projectId);\n      if (match) {\n        link = {\n          projectId,\n          projectName: match.name,\n          workspaceId: match.workspaceId,\n          workspaceName: match.workspaceName,\n        };\n      }\n    }\n  } catch {\n    // Best-effort enrichment — the id is enough to proceed.\n  }\n  try {\n    const linkPath = await writeLocalProjectFile(link);\n    if (!isJson) process.stderr.write(`${pc.green(\"✓\")} Linked ${linkPath}\\n`);\n  } catch (err) {\n    if (!isJson) {\n      process.stderr.write(\n        `${pc.yellow(\"Warning\")}: could not write .lmnr/project.json (${describeError(err)}). ` +\n        `CLI commands will need --project-id ${projectId}.\\n`,\n      );\n    }\n  }\n  return link;\n}\n\n/**\n * Access check: the logged-in user must be a member of the directory-linked\n * project (`link.projectId`). Calls GET /v1/cli/projects (user JWT) and asserts\n * the id is present; aborts otherwise (SPEC: \"You don't have access to the\n * project in this directory\"). On failure, names the actual mismatch (linked\n * project vs. logged-in account) and the two things that pin a stale project —\n * `.lmnr/project.json` and any `LMNR_PROJECT_API_KEY` in the environment.\n */\nasync function assertAccess(\n  creds: Credentials,\n  userBaseUrl: string,\n  link: LocalProjectFile,\n  existingKey: EnvKeyLocation | null,\n  isJson: boolean,\n): Promise<void> {\n  let projects: CliProject[];\n  try {\n    projects = await listProjects(creds, userBaseUrl);\n  } catch (err) {\n    // Discovery FAILED (network/5xx) — we couldn't determine access. Report it\n    // as a transient list failure (exit 10), NOT no_access (exit 4): automation\n    // must be able to retry instead of concluding the user lacks access.\n    emitError(isJson, \"list_projects_failed\", describeError(err));\n    process.exit(EXIT_LIST_PROJECTS_FAILED);\n  }\n  if (!projects.some((p) => p.id === link.projectId)) {\n    emitError(isJson, \"no_access\", buildNoAccessDetail(link, creds, existingKey, projects));\n    process.exit(EXIT_NO_ACCESS);\n  }\n}\n\n/**\n * Build the `no_access` detail: lead with the SPEC sentence (so substring\n * matchers keep working), then explain the linked-project-vs-account mismatch\n * and the concrete remediation steps.\n */\nfunction buildNoAccessDetail(\n  link: LocalProjectFile,\n  creds: Credentials,\n  existingKey: EnvKeyLocation | null,\n  accessible: CliProject[],\n): string {\n  const project = link.projectName ? `\"${link.projectName}\" (${link.projectId})` : link.projectId;\n  const account = creds.userEmail ?? \"the current account\";\n  const workspace = link.workspaceName ? ` in workspace \"${link.workspaceName}\"` : \"\";\n  const keyWhere =\n    existingKey === null\n      ? null\n      : existingKey.source.type === \"process-env\"\n        ? { loc: \"your environment\", verb: \"unset it\" }\n        : { loc: relative(process.cwd(), existingKey.source.path), verb: \"remove that line\" };\n  const envHint = keyWhere\n    ? `\\n  • A stale LMNR_PROJECT_API_KEY in ${keyWhere.loc} can pin a different project — ` +\n      `${keyWhere.verb}, then re-run setup.`\n    : \"\";\n  const accessLine =\n    accessible.length > 0\n      ? `You're logged in as ${account}, which has access to ${accessible.length} ` +\n        `project(s), but not this one.`\n      : `You're logged in as ${account}, which has access to no projects.`;\n\n  return (\n    `You don't have access to the project in this directory. ` +\n    `It's linked (.lmnr/project.json) to project ${project}${workspace}. ${accessLine}\\n\\n` +\n    `To fix, pick one:\\n` +\n    `  • Wrong account? Run \\`lmnr-cli login\\` as someone with access, then re-run setup.\\n` +\n    `  • Want a different project here? Remove the link and re-run setup: ` +\n    `\\`rm .lmnr/project.json && lmnr-cli setup\\`.${envHint}`\n  );\n}\n\n/** List the projects the user can access (user-JWT-authed discovery). */\nasync function listProjects(creds: Credentials, baseUrl: string): Promise<CliProject[]> {\n  const updated = await refreshIfNeeded(creds);\n  // Discovery client: CliResource hits /v1/cli/projects with the bare bearer,\n  // no project id needed (it overrides BaseResource's headers/prefix).\n  const client = new LaminarClient({\n    baseUrl,\n    // setup has no --port flag, so honor LMNR_HTTP_PORT for local self-host\n    // (baseUrl carries no port by convention). Cloud falls back to 443.\n    port: envHttpPort(),\n    auth: { type: \"userToken\", token: updated.accessToken, projectId: \"\" },\n  });\n  return client.cli.listProjects();\n}\n\n/**\n * Resolve which project an existing project API key belongs to, via the\n * user-token CLI endpoint (`POST /v1/cli/project`, key in body). By setup time\n * the CLI is already logged in, so we authenticate as the user (JWT bearer)\n * rather than re-deriving auth from the project key itself. The server also\n * confirms the user is a member of the resolved project.\n */\nasync function probeProjectKey(\n  creds: Credentials,\n  apiKey: string,\n  baseUrl: string,\n): Promise<ProjectKeyProbe> {\n  const updated = await refreshIfNeeded(creds);\n  const client = new LaminarClient({\n    baseUrl,\n    port: envHttpPort(),\n    auth: { type: \"userToken\", token: updated.accessToken, projectId: \"\" },\n  });\n  return client.cli.resolveProjectByApiKey(apiKey);\n}\n\nasync function safeReadCredentials(): Promise<Credentials | null> {\n  try {\n    return await readCredentials();\n  } catch {\n    return null;\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Key minting\n// ---------------------------------------------------------------------------\n\n/** POST /api/cli/api-key with the session bearer for an explicit project. */\nasync function mintSetupKey(\n  issuer: string,\n  sessionToken: string,\n  projectId: string,\n): Promise<SetupKeyResponse> {\n  const url = `${trimSlash(issuer)}/api/cli/api-key`;\n  const res = await fetch(url, {\n    method: \"POST\",\n    headers: { authorization: `Bearer ${sessionToken}`, \"content-type\": \"application/json\" },\n    body: JSON.stringify({ deviceName: hostname(), projectId }),\n  });\n  if (res.ok) {\n    return (await res.json()) as SetupKeyResponse;\n  }\n  const body = (await res.json().catch(() => ({}))) as { error?: string };\n  throw new Error(body.error ?? `api-key request failed (${res.status})`);\n}\n\nasync function promptProjectChoice(projects: CliProject[]): Promise<CliProject> {\n  process.stderr.write(\"\\nMultiple projects available. Choose one:\\n\");\n  projects.forEach((p, i) => {\n    process.stderr.write(`  ${i + 1}) ${p.workspaceName} / ${p.name}\\n`);\n  });\n  const rl = createInterface({ input: process.stdin, output: process.stderr });\n  try {\n    while (true) {\n      const answer = (await rl.question(`Select [1-${projects.length}]: `)).trim();\n      const idx = Number.parseInt(answer, 10);\n      if (Number.isInteger(idx) && idx >= 1 && idx <= projects.length) {\n        return projects[idx - 1];\n      }\n      process.stderr.write(`${pc.red(\"Invalid selection.\")}\\n`);\n    }\n  } finally {\n    rl.close();\n  }\n}\n\nfunction pick(...candidates: (string | undefined)[]): string {\n  for (const c of candidates) {\n    if (c && c.length > 0) return c;\n  }\n  return \"\";\n}\n\nfunction trimSlash(url: string): string {\n  return url.replace(/\\/+$/, \"\");\n}\n\nfunction describeError(err: unknown): string {\n  if (err instanceof Error) return err.message;\n  return String(err);\n}\n\nfunction emitError(json: boolean, code: string, detail: string): void {\n  if (json) {\n    process.stdout.write(JSON.stringify({ error: code, detail }) + \"\\n\");\n  } else {\n    process.stderr.write(`\\n${pc.red(`ERROR (${code})`)}: ${detail}\\n`);\n  }\n}\n","import { LaminarClient } from \"@lmnr-ai/client\";\n\nimport type { GlobalOpts } from \"../../auth/with-client\";\nimport { outputJson } from \"../../utils/output\";\nimport { renderTable } from \"../../utils/table\";\n\n/**\n * Run a SQL query against the project's data and print the rows. Pure handler:\n * the command wrapper (`withProjectClient`) resolves the client and owns the\n * error envelope (`--json` → structured error + exit, otherwise log + exit).\n */\nexport const handleSqlQuery = async (\n  client: LaminarClient,\n  query: string,\n  opts: GlobalOpts,\n): Promise<void> => {\n  const rows = await client.sql.query(query);\n\n  if (opts.json) {\n    outputJson(rows);\n    return;\n  }\n\n  if (rows.length === 0) {\n    console.log(\"No rows returned.\");\n    return;\n  }\n\n  const columns = Object.keys(rows[0]);\n  const tableRows = rows.map((row) =>\n    columns.map((col) => String(row[col] ?? \"\")),\n  );\n\n  console.log(renderTable(columns, tableRows));\n  console.log(`\\n${rows.length} row(s)\\n`);\n};\n","export const SQL_SCHEMA_HELP = `\nAvailable tables:\n  spans\n    span_id (UUID), name (String), span_type (String: DEFAULT|LLM|TOOL),\n    start_time (DateTime64), end_time (DateTime64), duration (Float64),\n    input_cost (Float64), output_cost (Float64), total_cost (Float64),\n    input_tokens (Int64), output_tokens (Int64), total_tokens (Int64),\n    request_model (String), response_model (String), model (String),\n    trace_id (UUID), provider (String), path (String),\n    input (String), output (String), status (String),\n    parent_span_id (UUID), attributes (String), tags (Array(String))\n\n  traces\n    id (UUID), start_time (DateTime64), end_time (DateTime64),\n    input_tokens (Int64), output_tokens (Int64), total_tokens (Int64),\n    input_cost (Float64), output_cost (Float64), total_cost (Float64),\n    duration (Float64), metadata (String), session_id (String),\n    user_id (String), status (String), top_span_id (UUID),\n    top_span_name (String), top_span_type (String), trace_type (String),\n    tags (Array(String)), has_browser_session (Bool)\n\n  events\n    id (UUID), type (String), name (String), span_id (UUID),\n    timestamp (DateTime64), attributes (String)\n\n  signal_events\n    id (UUID), signal_id (UUID), trace_id (UUID), run_id (UUID),\n    name (String), payload (String), timestamp (DateTime64),\n    severity (UInt8: 0=INFO|1=WARNING|2=CRITICAL), summary (String),\n    clusters (Array(UUID))\n\n  clusters\n    id (UUID), signal_id (UUID), name (String),\n    level (UInt8), parent_id (UUID), num_signal_events (UInt32),\n    num_children_clusters (UInt16),\n    created_at (DateTime64), updated_at (DateTime64)\n\n  signal_runs\n    signal_id (UUID), job_id (UUID), trigger_id (UUID), run_id (UUID),\n    trace_id (UUID), status (String), event_id (UUID), updated_at (DateTime64)\n\n  evaluation_datapoints\n    id (UUID), evaluation_id (UUID), data (String), target (String),\n    metadata (String), executor_output (String), index (UInt64),\n    trace_id (UUID), group_id (String), scores (String),\n    created_at (DateTime64), dataset_id (UUID),\n    dataset_datapoint_id (UUID), dataset_datapoint_created_at (DateTime64)\n\n  dataset_datapoints\n    id (UUID), created_at (DateTime64), dataset_id (UUID),\n    data (String), target (String), metadata (String)\n`;\n","#!/usr/bin/env node\n\nimport { errorMessage } from \"@lmnr-ai/types\";\nimport { Command } from \"commander\";\n\nimport { version } from \"../package.json\";\nimport { withLocalOpts, withProjectClient, withUserToken } from \"./auth/with-client\";\nimport { handleAsk } from \"./commands/ask\";\nimport {\n  handleDatasetsCreate,\n  handleDatasetsList,\n  handleDatasetsPull,\n  handleDatasetsPush,\n} from \"./commands/dataset\";\nimport {\n  handleDebugSessionAddNote,\n  handleDebugSessionNew,\n  handleDebugSessionOpen,\n  handleDebugSessionSetName,\n  handleDebugSessionSummary,\n} from \"./commands/debug\";\nimport { handleLogin } from \"./commands/login\";\nimport { handleLogout } from \"./commands/logout\";\nimport { handleProjectsList } from \"./commands/project\";\nimport { handleSetup } from \"./commands/setup\";\nimport { handleSqlQuery } from \"./commands/sql\";\nimport { SQL_SCHEMA_HELP } from \"./commands/sql/schema\";\nimport { pc } from \"./utils/colors\";\nimport { loadLocalEnv } from \"./utils/env-file\";\n\nasync function main() {\n  // Hydrate LMNR_* config from a project .env(.local) before anything reads it\n  // (login/setup/resolve read process.env at command-execution time, which is\n  // after this). Runners like Claude Code don't inject .env into the subprocess\n  // env, so this is how a local self-host config gets picked up.\n  await loadLocalEnv(process.cwd());\n\n  const program = new Command();\n\n  program\n    .name(\"lmnr-cli\")\n    .description(\"CLI for the Laminar agent observability platform\")\n    .version(version, \"-v, --version\", \"display version number\");\n\n  const datasetsCmd = program\n    .command(\"dataset\")\n    .description(\"Manage datasets\")\n    .option(\n      \"--project-id <id>\",\n      \"Target project id. Defaults to the linked .lmnr/project.json. \" +\n      \"Run `lmnr-cli login` first.\",\n    )\n    .option(\n      \"--base-url <url>\",\n      \"Base URL for the Laminar API. Defaults to https://api.lmnr.ai or LMNR_BASE_URL env variable\",\n    )\n    .option(\n      \"--port <port>\",\n      \"Port for the Laminar API. Defaults to 443\",\n      (val) => parseInt(val, 10),\n    )\n    .option(\"--json\", \"Output structured JSON to stdout\");\n\n  // Datasets list command\n  datasetsCmd\n    .command(\"list\")\n    .description(\"List all datasets\")\n    .action(withProjectClient(handleDatasetsList));\n\n  // Datasets push command\n  datasetsCmd\n    .command(\"push\")\n    .description(\"Push datapoints to an existing dataset\")\n    .argument(\n      \"<paths...>\",\n      \"Paths to files or directories containing data to push\",\n    )\n    .option(\n      \"-n, --name <name>\",\n      \"Name of the dataset (either name or id must be provided)\",\n    )\n    .option(\n      \"--id <id>\",\n      \"ID of the dataset (either name or id must be provided)\",\n    )\n    .option(\"-r, --recursive\", \"Recursively read files in directories\", false)\n    .option(\n      \"--batch-size <size>\",\n      \"Batch size for pushing data\",\n      (val) => parseInt(val, 10),\n      100,\n    )\n    .action(withProjectClient(handleDatasetsPush));\n\n  // Datasets pull command\n  datasetsCmd\n    .command(\"pull\")\n    .description(\"Pull data from a dataset\")\n    .argument(\n      \"[output-path]\",\n      \"Path to save the data. If not provided, prints to console\",\n    )\n    .option(\n      \"-n, --name <name>\",\n      \"Name of the dataset (either name or id must be provided)\",\n    )\n    .option(\n      \"--id <id>\",\n      \"ID of the dataset (either name or id must be provided)\",\n    )\n    .option(\n      \"--output-format <format>\",\n      \"Output format (json, csv, jsonl). Inferred from file extension if not provided\",\n    )\n    .option(\n      \"--batch-size <size>\",\n      \"Batch size for pulling data\",\n      (val) => parseInt(val, 10),\n      100,\n    )\n    .option(\"--limit <limit>\", \"Limit number of datapoints to pull\", (val) =>\n      parseInt(val, 10),\n    )\n    .option(\n      \"--offset <offset>\",\n      \"Offset for pagination\",\n      (val) => parseInt(val, 10),\n      0,\n    )\n    .action(withProjectClient(handleDatasetsPull));\n\n  // Datasets create command\n  datasetsCmd\n    .command(\"create\")\n    .description(\"Create a dataset from input files\")\n    .argument(\"<name>\", \"Name of the dataset to create\")\n    .argument(\n      \"<paths...>\",\n      \"Paths to files or directories containing data to push\",\n    )\n    .requiredOption(\"-o, --output-file <file>\", \"Path to save the pulled data\")\n    .option(\n      \"--output-format <format>\",\n      \"Output format (json, csv, jsonl). Inferred from file extension if not provided\",\n    )\n    .option(\"-r, --recursive\", \"Recursively read files in directories\", false)\n    .option(\n      \"--batch-size <size>\",\n      \"Batch size for pushing/pulling data\",\n      (val) => parseInt(val, 10),\n      100,\n    )\n    .action(withProjectClient(handleDatasetsCreate));\n\n  const sqlCmd = program\n    .command(\"sql\")\n    .description(\"Run SQL queries against your Laminar project data\")\n    .option(\n      \"--project-id <id>\",\n      \"Target project id. Defaults to the linked .lmnr/project.json. \" +\n      \"Run `lmnr-cli login` first.\",\n    )\n    .option(\n      \"--base-url <url>\",\n      \"Base URL for the Laminar API. Defaults to https://api.lmnr.ai or LMNR_BASE_URL env variable\",\n    )\n    .option(\n      \"--port <port>\",\n      \"Port for the Laminar API. Defaults to 443\",\n      (val) => parseInt(val, 10),\n    )\n    .option(\"--json\", \"Output structured JSON to stdout\");\n\n  sqlCmd\n    .command(\"query\")\n    .description(\"Execute a SQL query\")\n    .argument(\"<query>\", \"SQL query string\")\n    .action(withProjectClient(handleSqlQuery))\n    .addHelpText(\n      \"after\",\n      SQL_SCHEMA_HELP +\n      `\nExamples:\n  $ lmnr-cli sql query \"SELECT * FROM spans LIMIT 10\"\n  $ lmnr-cli sql query \"SELECT id, total_cost, status FROM traces LIMIT 20\"\n  $ lmnr-cli sql query \"SELECT * FROM spans LIMIT 10\" --json\n`,\n    );\n\n  sqlCmd\n    .command(\"schema\")\n    .description(\"Show available tables and their columns\")\n    .action(() => {\n      process.stdout.write(SQL_SCHEMA_HELP);\n    });\n\n  program\n    .command(\"ask\")\n    .description(\"Ask the Laminar agent a natural-language question about your project\")\n    .argument(\"<query>\", \"Natural-language question\")\n    .option(\n      \"--project-id <id>\",\n      \"Target project id. Defaults to the linked .lmnr/project.json. \" +\n      \"Run `lmnr-cli login` first.\",\n    )\n    .option(\n      \"--base-url <url>\",\n      \"Base URL for the Laminar API. Defaults to https://api.lmnr.ai or LMNR_BASE_URL env variable\",\n    )\n    .option(\n      \"--port <port>\",\n      \"Port for the Laminar API. Defaults to 443\",\n      (val) => parseInt(val, 10),\n    )\n    .option(\n      \"--conversation <id>\",\n      \"Continue a previous conversation by its id (printed after each answer in human mode, \" +\n      \"or in the `--json` output as `conversationId`)\",\n    )\n    .option(\"--json\", \"Output structured JSON ({ answer, conversationId, tools }) to stdout\")\n    .action(withLocalOpts(handleAsk))\n    .addHelpText(\n      \"after\",\n      `\nRuns on your logged-in user session (\\`lmnr-cli login\\`) and targets a project via\n--project-id or the linked .lmnr/project.json. The agent answers from your\nproject's traces/spans/evals via read-only SQL and trace inspection.\n\nExamples:\n  $ lmnr-cli ask \"why did my latest trace fail?\"\n  $ lmnr-cli ask \"how many traces errored in the last day?\"\n  $ lmnr-cli ask \"summarize the most expensive trace today\" --json\n  $ lmnr-cli ask \"and which model did it use?\" --conversation <id>\n`,\n    );\n\n  const projectCmd = program.command(\"project\").description(\"Work with Laminar projects\");\n\n  projectCmd\n    .command(\"list\")\n    .description(\"List the projects you can access (● = linked to this directory)\")\n    .option(\n      \"--base-url <url>\",\n      \"Base URL for the Laminar API. Defaults to the logged-in session or LMNR_BASE_URL\",\n    )\n    .option(\n      \"--port <port>\",\n      \"Port for the Laminar API. Defaults to 443\",\n      (val) => parseInt(val, 10),\n    )\n    .option(\"--json\", \"Output structured JSON to stdout\")\n    .action(withUserToken(handleProjectsList));\n\n  program\n    .command(\"login\")\n    .description(\"Authenticate the CLI via OAuth Device Flow\")\n    .option(\n      \"--frontend-url <url>\",\n      \"Frontend URL (issuer). Defaults to https://laminar.sh or LMNR_FRONTEND_URL env variable\",\n    )\n    .option(\"--no-browser\", \"Do not open the verification URL in a browser\")\n    .action(async (options) => {\n      const result = await handleLogin(options);\n      process.stderr.write(`${pc.green(\"✓\")} Logged in as ${result.userEmail ?? \"<unknown>\"}.\\n`);\n      process.stderr.write(\n        pc.dim(\"Client: lmnr-cli. Tokens stored at ~/.config/lmnr/credentials.json (mode 0600).\\n\"),\n      );\n      process.stderr.write(\n        pc.dim(\"Run `lmnr-cli setup` in a project directory to link it and write its API key.\\n\"),\n      );\n    });\n\n  program\n    .command(\"logout\")\n    .description(\"Log out and remove the stored credentials\")\n    .action(async () => {\n      await handleLogout();\n    });\n\n  program\n    .command(\"setup\")\n    .description(\n      \"One-shot onboarding: login, select a project, write its key to .env, \" +\n      \"link .lmnr, and install the Laminar agent skill\",\n    )\n    .option(\"--write-env\", \"Write LMNR_PROJECT_API_KEY to ./.env (default)\", true)\n    .option(\"--no-write-env\", \"Do not write to ./.env\")\n    .option(\n      \"--project-id <id>\",\n      \"Project to link when you can access more than one (disambiguates the \" +\n      \"project_ambiguous case in --json mode)\",\n    )\n    .option(\"--json\", \"Emit a machine-readable JSON line on stdout\")\n    .option(\"--no-browser\", \"Do not auto-open the device-flow URL\")\n    .option(\n      \"--frontend-url <url>\",\n      \"Frontend URL (issuer). Defaults to LMNR_FRONTEND_URL or https://laminar.sh\",\n    )\n    .option(\n      \"--base-url <url>\",\n      \"Base URL for the Laminar API. Defaults to LMNR_BASE_URL or https://api.lmnr.ai\",\n    )\n    .action(async (options) => {\n      await handleSetup(options);\n    });\n\n  const debugCmd = program\n    .command(\"debug\")\n    .description(\"Operate on debug sessions\")\n    .option(\n      \"--project-id <id>\",\n      \"Target project id. Defaults to the linked .lmnr/project.json. \" +\n      \"Run `lmnr-cli login` first.\",\n    )\n    .option(\n      \"--base-url <url>\",\n      \"Base URL for the Laminar API. Defaults to https://api.lmnr.ai or LMNR_BASE_URL env variable\",\n    )\n    .option(\n      \"--port <port>\",\n      \"Port for the Laminar API. Defaults to 443\",\n      (val) => parseInt(val, 10),\n    )\n    .option(\"--json\", \"Output structured JSON to stdout\")\n    .addHelpText(\n      \"after\",\n      `\nLearn more about debugging features at https://laminar.sh/docs/platform/debugger\n`,\n    );\n\n  const debugSessionCmd = debugCmd\n    .command(\"session\")\n    .description(\"Manage debug sessions\")\n    .addHelpText(\n      \"after\",\n      `\nLearn more about debugging features at https://laminar.sh/docs/platform/debugger\n`,\n    );\n\n  debugSessionCmd\n    .command(\"set-name\")\n    .description(\"Set the display name of a debug session\")\n    .argument(\"<name>\", \"Session display name\")\n    .option(\n      \"--session-id <id>\",\n      \"Debug session ID. Defaults to the session in .lmnr/debug-session.json\",\n    )\n    .action(withProjectClient(handleDebugSessionSetName))\n    .addHelpText(\n      \"after\",\n      `\nWithout --session-id, the name applies to the session recorded in\n.lmnr/debug-session.json (written by \\`debug session new\\` / LMNR_DEBUG=1 runs).\n\nExamples:\n  $ lmnr-cli debug session set-name \"Fix report length + search tool\"\n  $ lmnr-cli debug session set-name \"Fix report length\" --session-id <session-id>\n`,\n    );\n\n  debugSessionCmd\n    .command(\"add-note\")\n    .description(\"Attach a free-text note to a debug session (a standalone text block)\")\n    .argument(\"<note>\", \"Note text (may contain markdown)\")\n    .option(\n      \"--session-id <id>\",\n      \"Debug session ID. Defaults to the session in .lmnr/debug-session.json\",\n    )\n    .action(withProjectClient(handleDebugSessionAddNote))\n    .addHelpText(\n      \"after\",\n      `\nThe note is stored as a standalone text block on the session (not on any trace\nor evaluation), keyed by session id. Each call appends a new block, interleaved\nby time with the session's traces / evals. Works for any LMNR_DEBUG=1 run,\nincluding evaluations — all of them keep .lmnr/debug-session.json pointed at the\ncurrent session.\n\nWithout --session-id, the note goes to the session recorded in\n.lmnr/debug-session.json (written by \\`debug session new\\` or any LMNR_DEBUG=1\nrun, including evals).\n\nExamples:\n  $ lmnr-cli debug session add-note \"Reproduced the timeout on the search tool.\"\n  $ lmnr-cli debug session add-note \"Fixed after bumping the timeout.\" --session-id <session-id>\n`,\n    );\n\n  debugSessionCmd\n    .command(\"summary\")\n    .description(\"Print every block in a debug session (traces, evals, notes), oldest first\")\n    .option(\n      \"--session-id <id>\",\n      \"Debug session ID. Defaults to the session in .lmnr/debug-session.json\",\n    )\n    .action(withProjectClient(handleDebugSessionSummary))\n    .addHelpText(\n      \"after\",\n      `\nWithout --session-id, summarizes the session recorded in\n.lmnr/debug-session.json (written by \\`debug session new\\` or any LMNR_DEBUG=1\nrun, including evals).\n\nOutput is one entry per block (oldest first): traces and evaluations as\nself-closing tags, text notes as their raw markdown:\n\n  <trace id=\"{trace-id}\"/>\n  {note}\n  <evaluation id=\"{evaluation-id}\"/>\n\nWith --json, prints an array of {\"id\", \"createdAt\", \"type\", \"content\"} blocks.\n\nExamples:\n  $ lmnr-cli debug session summary\n  $ lmnr-cli debug session summary --session-id <session-id> --json\n`,\n    );\n\n  debugSessionCmd\n    .command(\"open\")\n    .description(\"Open a debug session's debugger page in the browser\")\n    .option(\n      \"--session-id <id>\",\n      \"Debug session ID. Defaults to the session in .lmnr/debug-session.json\",\n    )\n    .action(withLocalOpts(handleDebugSessionOpen))\n    .addHelpText(\n      \"after\",\n      `\nWithout --session-id, opens the session recorded in .lmnr/debug-session.json\n(written by \\`debug session new\\` / LMNR_DEBUG=1 runs). The URL is also printed\nto stdout; in --json mode a {\"sessionId\",\"debuggerUrl\"} object is printed\ninstead. Local-only: no login or network needed.\n\nExamples:\n  $ lmnr-cli debug session open\n  $ lmnr-cli debug session open --session-id <session-id>\n`,\n    );\n\n  debugSessionCmd\n    .command(\"new\")\n    .description(\"Create a fresh debug session and reset .lmnr/debug-session.json\")\n    .option(\"--no-browser\", \"Do not open the debugger session URL in a browser\")\n    .action(withProjectClient(handleDebugSessionNew))\n    .addHelpText(\n      \"after\",\n      `\nMints a new session id, writes it to .lmnr/debug-session.json (resetting any\nprior session), and registers it with the backend. The next \\`LMNR_DEBUG=1 <run>\\`\nin this directory rejoins this session silently (no browser).\n\nThe bare session id is printed to stdout; in --json mode a\n{\"sessionId\",\"projectId\",\"debuggerUrl\"} object is printed instead.\n\nExamples:\n  $ lmnr-cli debug session new\n  $ lmnr-cli debug session new --json\n  $ lmnr-cli debug session new --no-browser\n`,\n    );\n\n  program.addHelpText(\n    \"after\",\n    `\nAuthentication:\n  Run \\`lmnr-cli setup\\` to login, link this directory, write a project API key to\n  ./.env, and install the Laminar skill \n  \\`lmnr-cli login\\` authenticates as a user. Every project command\n  (sql / dataset / project / debug) runs on that user session and\n  targets a project via --project-id or the linked .lmnr/project.json.\n\nExamples:\n  lmnr-cli setup                                           # Logs in and prepares directory\n  lmnr-cli login                                           # Authenticate (user)\n  lmnr-cli project list                                    # Projects you can access\n  lmnr-cli logout                                          # Log out\n  lmnr-cli dataset list --json                             # List all datasets\n  lmnr-cli dataset push data.jsonl -n my-dataset --json    # Push data to a dataset\n  lmnr-cli dataset pull output.jsonl -n my-dataset --json  # Pull data from a dataset\n  lmnr-cli sql query \"SELECT * FROM spans LIMIT 10\" --json # Query spans\n  lmnr-cli sql schema                                      # Show available tables\n  lmnr-cli debug session new                               # Mint a fresh debug session\n  lmnr-cli debug session open                              # Open the session in the browser\n  lmnr-cli debug session set-name \"title\"                  # Rename the current debug session\n  lmnr-cli debug session add-note \"note text\"              # Add a note to the current session\n  lmnr-cli debug session summary                           # All blocks in the session, oldest first\n\nFor more information about the Laminar platfrom:\n  Documentation: https://laminar.sh/docs\n`,\n  );\n\n  await program.parseAsync();\n}\n\nmain().catch((err) => {\n  console.error(errorMessage(err));\n  process.exit(1);\n});\n"],"x_google_ignoreList":[2,3,4,5],"mappings":"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"}