{"_id":"@cognelis/langfuse-cli","_rev":"3-72ebff033a15130a70737088cecb0e45","name":"@cognelis/langfuse-cli","dist-tags":{"latest":"2.1.0"},"versions":{"2.0.0":{"name":"@cognelis/langfuse-cli","version":"2.0.0","keywords":["langfuse","cli","llm","observability","tracing","prompts"],"author":{"name":"Langfuse"},"license":"MIT","_id":"@cognelis/langfuse-cli@2.0.0","maintainers":[{"name":"wanzhou","email":"dnvyrn@gmail.com"}],"homepage":"https://github.com/cognelis/langfuse-cli#readme","bugs":{"url":"https://github.com/cognelis/langfuse-cli/issues"},"bin":{"langfuse-cli":"bin/langfuse-cli.mjs"},"dist":{"shasum":"a2c3afeac9b1c4bf202866fe93268692107fcb8c","tarball":"https://registry.npmjs.org/@cognelis/langfuse-cli/-/langfuse-cli-2.0.0.tgz","fileCount":28,"integrity":"sha512-+UBK8MYeAMsJZQ/w1JDtgXGRp1RiZr0kTFT9XfUoKZvyjr/Sh0f2NkQbI/NaNpNTCtIFVuhWObYw7SXMa/arbA==","signatures":[{"sig":"MEUCID3X/Rk7MXzTAfdu/ufnfSEB8fa3ZGAqrYZFSN9vgQJ3AiEA/79lP5hIKZt2zHzYqGiS2cdz1vzlHdoV81VHm4iBf+I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":921915},"type":"module","engines":{"node":">=20"},"gitHead":"13b24c4267c1c767907dfe0263d17d849f8ee5d4","scripts":{"test":"bun test","build":"bun scripts/build.ts","compile":"bun run build && bun scripts/compile.ts","typecheck":"tsc --noEmit","release:check":"bun scripts/release-check.ts","goldens:update":"bun scripts/goldens.ts","prepublishOnly":"bun run release:check && bun run build","conformance:all":"bun conformance/src/all.ts","conformance:run":"bun conformance/src/cli.ts run","conformance:sync":"bun conformance/src/cli.ts sync","conformance:add-version":"bun conformance/src/add-version.ts"},"_npmUser":{"name":"wanzhou","email":"dnvyrn@gmail.com"},"overrides":{"ajv":"8.17.1"},"repository":{"url":"git+https://github.com/cognelis/langfuse-cli.git","type":"git"},"_npmVersion":"10.9.7","description":"Interact with the Langfuse API from the command line, with keyring-backed profiles","directories":{},"_nodeVersion":"22.22.2","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"8.17.1","yaml":"^2.9.0","semver":"^7.8.5","@types/bun":"^1.3.14","typescript":"^7.0.2","ajv-formats":"^3.0.1","@types/semver":"^7.8.0","@apidevtools/swagger-parser":"^12.1.0"},"_npmOperationalInternal":{"tmp":"tmp/langfuse-cli_2.0.0_1788635525768_0.2789079992648771","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@cognelis/langfuse-cli","version":"2.0.1","keywords":["langfuse","cli","llm","observability","tracing","prompts"],"author":{"name":"Langfuse"},"license":"MIT","_id":"@cognelis/langfuse-cli@2.0.1","maintainers":[{"name":"wanzhou","email":"dnvyrn@gmail.com"}],"homepage":"https://github.com/cognelis/langfuse-cli#readme","bugs":{"url":"https://github.com/cognelis/langfuse-cli/issues"},"bin":{"langfuse-cli":"bin/langfuse-cli.mjs"},"dist":{"shasum":"e3afe59ad8ca873fa464b695ad55f46d466ba758","tarball":"https://registry.npmjs.org/@cognelis/langfuse-cli/-/langfuse-cli-2.0.1.tgz","fileCount":28,"integrity":"sha512-unuMPM2IADdCyycvzAyAwBfNKeF2xkitl+rW55nHgYFYP1VKcINygxrJd6GRYaHGwUiNJ0dsfrIhykXqSStFVw==","signatures":[{"sig":"MEUCIQCsvR9cUZdk7di4s5d9pjA/ywXbPfWLGwcxEzmqbIKG1QIgC40pkkvOIGYUUA3FhASWfqPjyDCSbVRz7VHLfhR7J7g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDfAw3YvxUloMivWSgtYqpMXBG4SRJ0zwzlXnIR8nNtqAIgIrwSSkIeeo9epVz/fK/fopREdgTkfrNYijnaJK4l4bE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cognelis%2flangfuse-cli@2.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":922279},"type":"module","engines":{"node":">=20"},"gitHead":"c9a58ca0fe904faf8e852133423b8b769cefdb6b","scripts":{"test":"bun test","build":"bun scripts/build.ts","compile":"bun run build && bun scripts/compile.ts","typecheck":"tsc --noEmit","release:check":"bun scripts/release-check.ts","goldens:update":"bun scripts/goldens.ts","prepublishOnly":"bun run release:check && bun run build","conformance:all":"bun conformance/src/all.ts","conformance:run":"bun conformance/src/cli.ts run","conformance:sync":"bun conformance/src/cli.ts sync","conformance:add-version":"bun conformance/src/add-version.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1b4f1297-7007-4602-a2ba-2bc173eff7a9"}},"overrides":{"ajv":"8.17.1"},"repository":{"url":"git+https://github.com/cognelis/langfuse-cli.git","type":"git"},"_npmVersion":"12.0.2","description":"Interact with the Langfuse API from the command line, with keyring-backed profiles","directories":{},"_nodeVersion":"24.20.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"8.17.1","yaml":"^2.9.0","semver":"^7.8.5","@types/bun":"^1.3.14","typescript":"^7.0.2","ajv-formats":"^3.0.1","@types/semver":"^7.8.0","@apidevtools/swagger-parser":"^12.1.0"},"_npmOperationalInternal":{"tmp":"tmp/langfuse-cli_2.0.1_1788637084997_0.38251986284784345","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"_id":"@cognelis/langfuse-cli@2.1.0","bin":{"langfuse-cli":"bin/langfuse-cli.mjs"},"bugs":{"url":"https://github.com/cognelis/langfuse-cli/issues"},"dist":{"shasum":"c121e29341674f3395f0c45e545d6f872db3b470","tarball":"https://registry.npmjs.org/@cognelis/langfuse-cli/-/langfuse-cli-2.1.0.tgz","fileCount":28,"integrity":"sha512-ig+/JQntnS2V9qbGvTMLkv+fOR3nV1D07TtsC3q170r40ftQYqg3Z/PLJxnp3Sg4wnLjyC5VQuK0W23WHsRLAw==","signatures":[{"sig":"MEYCIQDZyqK7ryc53ytK8clSNz5fpEDcuzqa7diELUZYyB9Q5gIhANkBxNS+UaHcZDa8K6Zl8+fsjAFj1Xg9e6UkBPNTYG9c","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID6VdX/0Fg8aUs3E9nxcFmQI3JppCefcKRcKBNr/sqOdAiEA3zCajyf5EMBI5mvL6VjAhtwKuJOMByHbquD1eOWoTuE="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cognelis%2flangfuse-cli@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":924390},"name":"@cognelis/langfuse-cli","type":"module","author":{"name":"Langfuse"},"engines":{"node":">=20"},"gitHead":"0b7a75dac2a23f053453f8ab0f80f0bad250dda2","license":"MIT","scripts":{"test":"bun test","build":"bun scripts/build.ts","compile":"bun run build && bun scripts/compile.ts","typecheck":"tsc --noEmit","release:check":"bun scripts/release-check.ts","goldens:update":"bun scripts/goldens.ts","prepublishOnly":"bun run release:check && bun run build","conformance:all":"bun conformance/src/all.ts","conformance:run":"bun conformance/src/cli.ts run","conformance:sync":"bun conformance/src/cli.ts sync","conformance:add-version":"bun conformance/src/add-version.ts"},"version":"2.1.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1b4f1297-7007-4602-a2ba-2bc173eff7a9"}},"homepage":"https://github.com/cognelis/langfuse-cli#readme","keywords":["langfuse","cli","llm","observability","tracing","prompts"],"overrides":{"ajv":"8.17.1"},"repository":{"url":"git+https://github.com/cognelis/langfuse-cli.git","type":"git"},"_npmVersion":"12.0.2","description":"Interact with the Langfuse API from the command line, with keyring-backed profiles","directories":{},"maintainers":[{"name":"wanzhou","email":"dnvyrn@gmail.com"}],"_nodeVersion":"24.20.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"8.17.1","yaml":"^2.9.0","semver":"^7.8.5","@types/bun":"^1.3.14","typescript":"^7.0.2","ajv-formats":"^3.0.1","@types/semver":"^7.8.0","@apidevtools/swagger-parser":"^12.1.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/langfuse-cli_2.1.0_1788677792137_0.15615053321462113"}}},"time":{"created":"2026-09-05T19:12:05.548Z","modified":"2026-09-06T06:56:32.567Z","2.0.0":"2026-09-05T19:12:05.919Z","2.0.1":"2026-09-05T19:38:05.167Z","2.1.0":"2026-09-06T06:56:32.224Z"},"bugs":{"url":"https://github.com/cognelis/langfuse-cli/issues"},"author":{"name":"Langfuse"},"license":"MIT","homepage":"https://github.com/cognelis/langfuse-cli#readme","keywords":["langfuse","cli","llm","observability","tracing","prompts"],"repository":{"url":"git+https://github.com/cognelis/langfuse-cli.git","type":"git"},"description":"Interact with the Langfuse API from the command line, with keyring-backed profiles","maintainers":[{"name":"wanzhou","email":"dnvyrn@gmail.com"}],"readme":"# langfuse-cli\n\n`langfuse-cli` is a command-line client for repeatable [Langfuse](https://langfuse.com) work in terminals, CI jobs, and JSON pipelines. It keeps the secret key in the operating-system credential store, so a working setup never leaves a key in a dotfile, in an environment variable on disk, or in your shell history.\n\nThe repository also ships one Agent Skill and plugin manifests, so Codex and Claude Code can use the CLI without inventing commands or handling credentials.\n\n## Install\n\nNode.js 20+ or Bun. The CLI has zero runtime dependencies.\n\n```sh\nnpm i -g @cognelis/langfuse-cli\nlangfuse-cli --version\n```\n\nOr from a checkout:\n\n```sh\nbun install\nbun run build\nnpm i -g .\n```\n\nThe binary is named `langfuse-cli`. The package is scoped because the bare\n`langfuse-cli` name belongs to [upstream](https://github.com/langfuse/langfuse-cli).\n\n### Single-file executable\n\nAn `npm i -g` install ties the CLI to the Node version it was installed under.\nEvery [release](https://github.com/cognelis/langfuse-cli/releases) also carries\na standalone executable with no Node dependency and all six API contracts\nembedded, for macOS, Linux and Windows on both x86-64 and arm64:\n\n```sh\n# pick the asset for your platform: langfuse-cli-{darwin,linux}-{arm64,amd64}\n# or langfuse-cli-windows-{arm64,amd64}.exe\ncurl -fsSL -o langfuse-cli \\\n  https://github.com/cognelis/langfuse-cli/releases/latest/download/langfuse-cli-darwin-arm64\nchmod +x langfuse-cli && ./langfuse-cli --version\n```\n\nEach asset is built and started on a runner of its own platform before the\nrelease is published, and `checksums.txt` in the same release verifies a\ndownload:\n\n```sh\nshasum -a 256 --ignore-missing -c checksums.txt\n```\n\nOr build it from a checkout:\n\n```sh\nbun run compile              # writes dist/langfuse-cli\nbun run compile ~/bin/langfuse-cli\nbun run compile ./langfuse-cli --target bun-linux-arm64   # cross-compile\n```\n\nThe contracts have to be embedded rather than read from disk: a compiled binary\nhas no `dist/contracts/` beside it, and Bun's bundler cannot see a runtime\n`readFile(new URL(...))`. They are carried as unparsed strings and parsed on\ndemand, so startup does not pay for six snapshots. The result is ~60 MB (Bun\nbundles its runtime) and starts in about 10 ms once the page cache is warm.\n\n## Authenticate\n\nFor a workstation, start the guided setup. It creates or repairs a profile, masks the secret key while typing, verifies the connection before saving, stores the key in the operating-system credential store, activates the profile, and offers to install the bundled Skill.\n\n```sh\nlangfuse-cli init\n```\n\nThe setup is deliberately terminal-only and never starts implicitly. If input or output is redirected it exits without changing anything and prints the equivalent non-interactive commands.\n\nFor CI and short-lived shells, use environment variables. Keep the secret in the CI provider's secret store and disable shell tracing.\n\n```sh\nset +x\nexport LANGFUSE_HOST=\"https://cloud.langfuse.com\"\nexport LANGFUSE_PUBLIC_KEY=\"pk-lf-...\"\nexport LANGFUSE_SECRET_KEY=\"...from a secret store...\"\nlangfuse-cli doctor --json\n```\n\nFor scripts that intentionally persist a profile, profiles store only the host and the public key. The secret key is verified before it is stored in the keyring.\n\n```sh\nlangfuse-cli profile add production --host https://langfuse.example.com --public-key pk-lf-...\nlangfuse-cli profile use production\nprintf '%s' \"$LANGFUSE_SECRET_KEY\" | langfuse-cli auth login --secret-key-stdin\nlangfuse-cli doctor --json\n```\n\nRunning `langfuse-cli auth login` without `--secret-key-stdin` opens a masked prompt. Use `--no-verify` only for an intentional offline setup; the result records a warning. **There is intentionally no `--secret-key` flag**, so the secret never enters shell history or process listings. `config show` and `profile show` report only whether a key exists, never its value.\n\nKeep test and production instances in separate profiles. Select one for a single command with `--profile`, or change the default with `profile use`:\n\n```sh\nlangfuse-cli --profile test init\nlangfuse-cli --profile prod init\nlangfuse-cli profile use test\nlangfuse-cli --profile prod profile show\nlangfuse-cli --profile prod api projects list\n```\n\nConnections resolve in this order: `--host`, then `--profile`, then `LANGFUSE_HOST` (or `LANGFUSE_BASE_URL`), then the default profile. `LANGFUSE_SECRET_KEY` overrides the selected profile's stored key; unset it to use that profile's credential. Because `--host` and `LANGFUSE_HOST` name an address directly, they take their credentials from the environment — a stray profile can never silently supply a key for an address you typed by hand.\n\nChanging an instance address with `profile update <name> --host <url>` clears the saved secret key before saving the new address, and tells you to authenticate again. An equivalent normalized URL preserves the key. If the credential store cannot clear the old key, the address is left unchanged.\n\n### Where the secret actually goes\n\n| Platform | Backend | Command used |\n|---|---|---|\n| macOS | login keychain | `security` |\n| Linux | Freedesktop secret service | `secret-tool` |\n| Windows | DPAPI, per-user encryption | `powershell` |\n| fallback | `credentials.json`, mode 0600 | — |\n\nEvery backend receives the secret on **stdin**; it is never passed as an argument, so it stays out of the process list. The fallback is only chosen when no system store is reachable, and every command that relies on it prints a warning. Force it with `LANGFUSE_CREDENTIAL_STORE=file`.\n\n## Diagnose a connection\n\nRun the read-only diagnostic before remote automation or when a connection fails:\n\n```sh\nlangfuse-cli doctor --json\n```\n\nIt checks the CLI version, connection configuration, credential availability, API connectivity, and authentication **in that order** — nothing downstream is meaningful until the step before it passes. A completed run always writes its ordered `pass`/`fail`/`skipped` report to stdout, then exits with the code matching the first failure, so scripts should capture stdout before testing the status.\n\n## Query Langfuse\n\n```sh\n# Discover resources\nlangfuse-cli api help\nlangfuse-cli api prompts help\nlangfuse-cli api prompts create help\nlangfuse-cli api schema --json        # machine-readable discovery\n\n# Prompts\nlangfuse-cli api prompts list\nlangfuse-cli api prompts get my-prompt\nlangfuse-cli api prompts create --type text --name my-prompt --prompt 'Hello {{name}}'\nlangfuse-cli api prompts create --type chat --name support \\\n  --prompt '{\"role\":\"system\",\"content\":\"be nice\"}' \\\n  --prompt '{\"role\":\"user\",\"content\":\"{{question}}\"}'\n\n# Observations, traces, datasets, scores\nlangfuse-cli api observations list --limit 10\nlangfuse-cli api observations list --trace-id <trace-id>\nlangfuse-cli api datasets list\nlangfuse-cli api dataset-items list --dataset-name my-dataset\nlangfuse-cli api scores list --limit 20\n\n# Fetch every page of a paginated list (page- and cursor-based), max 1000 items\nlangfuse-cli api observations list --all\nlangfuse-cli api observations list --limit 100 --all --max-items 5000\n\n# Preview the request without sending it\nlangfuse-cli api observations list --limit 5 --curl\n\n# Pin an API snapshot for an older self-hosted deployment\nlangfuse-cli --api-version 3 api traces list\nlangfuse-cli --api-version 3.150.0 api traces list\nlangfuse-cli --api-version auto api prompts list   # detect via /api/public/health\n```\n\nOpenAPI tags and explicit route versions remain accepted aliases, for example `scores-v3 list` for the canonical `scores list`. Verbose OpenAPI `operationId` values remain available in `api schema --json` but are never required as CLI commands.\n\n`--body-json` and `--body-file` provide a lossless input path for nested objects, arrays, unions, and free-form JSON. Simple request-body fields also get generated kebab-case flags (for example `--object-id` for the `objectId` field), consistent with query-parameter flags; wire names are never affected.\n\nUnion bodies with a discriminator (for example prompt create's chat vs. text variants) support field flags directly: the discriminator flag selects the variant and the CLI validates against that variant's schema — `langfuse-cli api help <resource> <action>` shows the per-variant fields. Unions without a clean discriminator stay `--body-json`-only rather than guessing.\n\n## Command groups\n\n```text\ninit\ndoctor\napi <resource> <action>\nauth login|check|logout\nprofile add|update|list|show|use|remove\nconfig path|show\nskills install [--target all|codex|claude]\ncompletion zsh|bash|fish\n```\n\n## Output contract\n\nSuccessful JSON output has a stable versioned envelope:\n\n```json\n{\n  \"schemaVersion\": \"1\",\n  \"command\": \"api.projects.list\",\n  \"data\": {},\n  \"meta\": {\n    \"status\": 200,\n    \"profile\": \"prod\",\n    \"host\": \"https://langfuse.example.com\",\n    \"elapsedMs\": 72\n  }\n}\n```\n\nFormat selection follows `--output`:\n\n| value | behaviour |\n|---|---|\n| `auto` (default) | a table on a terminal, the JSON envelope everywhere else |\n| `table` | human-readable columns |\n| `json` | the versioned envelope (same as `--json`) |\n| `raw` | the payload only, no envelope (same as `--raw`) |\n\nA human sees columns and a pipeline receives parseable output, neither having to\npass a flag:\n\n```console\n$ langfuse-cli profile list\ncurrent  name  host                                key\n-------  ----  ----------------------------------  ------\n         prod  https://langfuse.example.com        stored\n*        test  https://langfuse-test.example.com   stored\nProfile: test\n\n$ langfuse-cli profile list | jq -r '.data[].name'\nprod\ntest\n```\n\nTable output matches signoz-cli: a header over a dashed rule, columns sized to\ntheir widest cell, `key: value` blocks with aligned colons, and the trailing\n`Profile:` line on stderr so stdout stays clean even when a table is piped.\n\nDiagnostics and warnings go to stderr; stdout stays clean for pipelines. The single exception is `doctor`, whose report *is* the result and so is written to stdout even when it exits nonzero. `--out-file <path>` writes the response body to a file instead of stdout.\n\n## Exit codes\n\n| Code | Meaning |\n| ---: | --- |\n| 0 | Successful API response or local command |\n| 1 | Unexpected internal failure |\n| 2 | Invalid command or input (usage); no request sent |\n| 3 | Missing or invalid configuration/credentials; no request sent |\n| 4 | Network, DNS, TLS, or timeout failure reaching the host |\n| 5 | The API responded with a non-success HTTP status (response is still printed) |\n| 6 | Local file or bundled-contract failure |\n\n## Install the agent skill\n\n```sh\n# Install for both Codex and Claude Code (default)\nlangfuse-cli skills install\n# Only one agent\nlangfuse-cli skills install --target codex\nlangfuse-cli skills install --target claude\n```\n\nThe skill ships **inside the package**, so installation needs no network access, no host, and no credentials. It installs `SKILL.md` together with every `references/*.md` the skill links to — printing only the top-level file, as the removed `get-skill` command did, left those links dangling. The operation is idempotent: rerunning updates managed files, reports `unchanged` when nothing differs, and preserves unrelated files in the target directory.\n\nTargets are `~/.agents/skills/langfuse` for Codex and `$CLAUDE_CONFIG_DIR/skills/langfuse` (default `~/.claude/skills/langfuse`) for Claude Code.\n\n### Advanced: plugin lifecycle alternatives\n\nThe same skill directory is packaged for both agents at `plugins/langfuse-cli/skills/langfuse`. Use the plugin lifecycle instead when you want the repository marketplace installation.\n\nFor Claude Code:\n\n```text\n/plugin marketplace add /absolute/path/to/langfuse-cli\n/plugin install langfuse-cli@langfuse-cli\n```\n\nFor Codex:\n\n```sh\ncodex plugin marketplace add /absolute/path/to/langfuse-cli\n```\n\nThe Claude Code manifest is `plugins/langfuse-cli/.claude-plugin/plugin.json`; the Codex manifest is `plugins/langfuse-cli/.codex-plugin/plugin.json`.\n\n## Shell completion\n\n```sh\n# zsh — any directory on $fpath\nlangfuse-cli completion zsh > ~/.zsh/completions/_langfuse-cli\nexec zsh\n\n# If that directory is new, put it on $fpath before compinit runs:\n#   fpath=(~/.zsh/completions $fpath)\n# oh-my-zsh users can instead use ~/.oh-my-zsh/completions, which is\n# already on $fpath.\n\n# bash\nlangfuse-cli completion bash > /usr/local/etc/bash_completion.d/langfuse-cli\n\n# fish\nlangfuse-cli completion fish > ~/.config/fish/completions/langfuse-cli.fish\n```\n\nCompletion covers commands, subcommands, global options, profile names, API\nresources, their actions, and each action's own parameters:\n\n```text\nlangfuse-cli <TAB>                     init doctor api auth profile config skills completion\nlangfuse-cli --profile <TAB>           test  prod                    (from your config)\nlangfuse-cli api <TAB>                 prompts traces observations datasets scores ...\nlangfuse-cli api prompts <TAB>         create delete get list update-version\nlangfuse-cli api prompts list --<TAB>  --name --label --tag --page --limit --all ...\n```\n\nCandidates are grouped, so subcommands are listed as their own block instead of\nsorting alphabetically among the options — `--json` no longer lands between\n`init` and `profile`. The wire format is `value<TAB>description<TAB>group`, and\nthe zsh script offers each group through a separate `_describe` call.\n\nThe generated script contains no command table. It calls back into a hidden\n`__complete` command on every keypress, which is what keeps it correct when the\nCLI is upgraded, when profiles change, and — the reason a static script would\nbe wrong here — when `--api-version` changes the command surface: 3.50 exposes\n22 resources, 4.16 exposes 37. Completion never performs network I/O, so\n`--api-version auto` falls back to the newest bundled contract rather than\nprobing the server.\n\nThe callback reads the config for profile names but never opens the credential\nstore, and any failure yields no candidates instead of an error, so a broken\nconfig cannot corrupt the shell's display.\n\n## Relationship to upstream\n\nThis is a fork of [`langfuse/langfuse-cli`](https://github.com/langfuse/langfuse-cli), maintained as a companion to `signoz-cli` with the same operational contract: keyring-backed credentials, named profiles, an ordered `doctor`, a versioned JSON envelope, stable exit codes, and a bundled agent skill. It diverges from upstream deliberately:\n\n- `--secret-key` was removed; use `auth login` or `LANGFUSE_SECRET_KEY`.\n- `--output <path>` became `--out-file <path>`; `--output` no longer selects a format.\n- `--json` now emits the versioned envelope rather than `{status, headers, body}`.\n- `get-skill` became `skills install`.\n- `completion zsh|bash|fish` was added, backed by a `__complete` callback.\n- `bun run compile` produces a standalone executable with the contracts embedded.\n- `--output` selects the format (`auto|table|json|raw`) instead of naming a file,\n  and human-readable output is rendered as tables aligned with signoz-cli.\n\nThe multi-version OpenAPI contract system and the conformance suite are inherited from upstream unchanged.\n\n## API Reference\n\nSee the full [Langfuse API Reference](https://api.reference.langfuse.com/).\n\n## Contributing\n\nThe CLI is implemented in TypeScript and runs on Node.js 20+ or Bun. It has zero external runtime dependencies and never parses OpenAPI during invocation.\n\nSee [MAINTENANCE.md](MAINTENANCE.md) for build, API snapshot, testing, and release workflows. The version-pinned black-box suite is documented separately in [`conformance/README.md`](conformance/README.md).\n","readmeFilename":"README.md"}