diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 611a58fc..ae24f2fa 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -16,90 +16,17 @@ name: Build on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] permissions: contents: read jobs: - build-no-console: - name: Build (no console, no CGO) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 - with: - go-version-file: go.mod - - - name: Build without console tag - env: - CGO_ENABLED: "0" - run: go build -o bin/lk ./cmd/lk - - - name: Verify binary - run: bin/lk --help > /dev/null - - lint-and-test: + cross-build: + name: Cross-build (goreleaser snapshot) runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - submodules: true - - - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 - with: - go-version-file: go.mod - - - name: Static Check - uses: dominikh/staticcheck-action@288b4e28bae83c59f35f73651aeb5cab746a06fc # v1.4.0 - with: - version: "latest" - install-go: false - - - name: Test - run: go test -v ./... - - build: - strategy: - fail-fast: false - matrix: - include: - - os: macos-latest - suffix: darwin_arm64 - - os: ubuntu-latest - suffix: linux_amd64 - zig_target: x86_64-linux-gnu.2.28 - alsa_arch: amd64 - alsa_triple: x86_64-linux-gnu - - os: ubuntu-latest - suffix: linux_arm64 - zig_target: aarch64-linux-gnu.2.28 - alsa_arch: arm64 - alsa_triple: aarch64-linux-gnu - goarch: arm64 - - os: ubuntu-latest - suffix: linux_arm - zig_target: arm-linux-gnueabihf.2.28 - alsa_arch: armhf - alsa_triple: arm-linux-gnueabihf - goarch: arm - goarm: "7" - - os: ubuntu-latest - suffix: windows_amd64 - zig_target: x86_64-windows-gnu - goos: windows - goarch: amd64 - - os: ubuntu-latest - suffix: windows_arm64 - zig_target: aarch64-windows-gnu - goos: windows - goarch: arm64 - runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -111,72 +38,27 @@ jobs: go-version-file: go.mod - name: Install Zig - if: matrix.zig_target uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 with: version: 0.14.1 - - name: Install ALSA headers - if: matrix.alsa_arch - run: | - sudo dpkg --add-architecture ${{ matrix.alsa_arch }} - if [ "${{ matrix.alsa_arch }}" != "amd64" ]; then - CODENAME=$(lsb_release -cs) - # Restrict existing sources to amd64 to avoid 404s for foreign arch - for f in /etc/apt/sources.list.d/*.sources; do - grep -q '^Architectures:' "$f" || sudo sed -i '/^Types:/a Architectures: amd64 i386' "$f" - done - # Add ports.ubuntu.com for the foreign architecture - printf 'Types: deb\nURIs: http://ports.ubuntu.com/ubuntu-ports\nSuites: %s %s-updates\nComponents: main universe\nArchitectures: %s\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\n' \ - "$CODENAME" "$CODENAME" "${{ matrix.alsa_arch }}" | sudo tee /etc/apt/sources.list.d/ports.sources - fi - sudo apt-get update - sudo apt-get install -y libasound2-dev:${{ matrix.alsa_arch }} + - name: Cache cross-compile inputs + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: .cross + key: cross-${{ runner.os }}-zig0.14.1-alsa1.2.12-${{ hashFiles('scripts/setup-cross.sh') }} - - name: Generate Windows import libraries - if: matrix.goos == 'windows' && matrix.zig_target - run: | - ZIG_LIB=$(zig env | jq -r '.lib_dir') - echo "ZIG_LIB=${ZIG_LIB}" >> "$GITHUB_ENV" - LIB_DIR="${ZIG_LIB}/libc/mingw/lib-common" - # Zig bundles MinGW .def files but lld needs .a import libraries. - # Go's compiled objects embed COFF /DEFAULTLIB directives (e.g. dbghelp, - # bcrypt) that lld resolves directly, bypassing Zig's lazy .def→.a - # generation. Pre-generate all import libraries so lld can find them. - MACHINE=${{ matrix.goarch == 'amd64' && 'i386:x86-64' || 'arm64' }} - for def in "${LIB_DIR}"/*.def; do - lib=$(basename "$def" .def) - [ -f "${LIB_DIR}/lib${lib}.a" ] && continue - zig dlltool -d "$def" -l "${LIB_DIR}/lib${lib}.a" -m "$MACHINE" 2>/dev/null || true - done + - name: GoReleaser snapshot build + uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7 + with: + distribution: goreleaser + version: latest + args: build --snapshot --clean - - name: Build - env: - CGO_ENABLED: ${{ (matrix.goos && !matrix.zig_target) && '0' || '1' }} - CC: ${{ matrix.zig_target && format('zig cc -target {0}', matrix.zig_target) || '' }} - CXX: ${{ matrix.zig_target && format('zig c++ -target {0}', matrix.zig_target) || '' }} - # Zig uses its own sysroot; point it at the system ALSA headers and libraries - CGO_CFLAGS: ${{ matrix.alsa_triple && format('-isystem /usr/include -isystem /usr/include/{0}', matrix.alsa_triple) || '' }} - CGO_LDFLAGS: ${{ matrix.alsa_triple && format('-L/usr/lib/{0}', matrix.alsa_triple) || '' }} - # -fms-extensions: enable __try/__except (SEH) used by WebRTC - # -DNTDDI_VERSION: target Windows 10 base to skip WinRT includes absent from MinGW - CGO_CXXFLAGS: ${{ matrix.goos == 'windows' && '-fms-extensions -DNTDDI_VERSION=0x0A000000' || '' }} - GOOS: ${{ matrix.goos || '' }} - GOARCH: ${{ matrix.goarch || '' }} - GOARM: ${{ matrix.goarm || '' }} - shell: bash + - name: Verify native binary runs run: | - EXT=""; if [ "${GOOS:-}" = "windows" ]; then EXT=".exe"; fi - TAGS="" - if [ "$CGO_ENABLED" = "1" ]; then TAGS="-tags console"; fi - # Force external linking for Windows so Go uses zig cc (CC) as the linker, - # and add Zig's MinGW lib path so lld can find the generated import libraries. - EXTLD="" - if [ "${GOOS:-}" = "windows" ] && [ "$CGO_ENABLED" = "1" ]; then - EXTLD="-linkmode=external -extldflags '-L${ZIG_LIB}/libc/mingw/lib-common'" - fi - go build $TAGS -ldflags "-w -s $EXTLD" -o "bin/lk${EXT}" ./cmd/lk - - - name: Verify binary - if: "!matrix.goos && !matrix.goarch" - run: bin/lk --help > /dev/null + # Pick the linux-amd64 binary out of dist/ and run --help. + binary=$(find dist -type f -name lk -path '*linux*amd64*' | head -n1) + test -n "$binary" || { echo "no linux/amd64 binary in dist/"; exit 1; } + # Static-libgcc/libstdc++ binary should run on glibc 2.28+ Ubuntu runners. + "$binary" --help > /dev/null diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml deleted file mode 100644 index 45e2302a..00000000 --- a/.github/workflows/docker.yaml +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2023 LiveKit, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: Release to Docker - -# on events -on: - push: - tags: - - v* - -# workflow tasks -jobs: - docker: - name: Generate builds for Docker - runs-on: ubuntu-latest - steps: - - name: Checkout Git LFS - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - lfs: 'true' - - - run: git lfs pull - - - name: Docker meta - id: meta - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 - with: - # list of Docker images to use as base name for tags - images: | - livekit/livekit-cli - # generate Docker tags based on the following events/attributes - tags: | - type=semver,pattern=v{{version}} - type=semver,pattern=v{{major}}.{{minor}} - - - name: Set up QEMU - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - - - name: Login to DockerHub - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - id: docker_build - uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64 - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6c2cca51..4b4e03d8 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -22,6 +22,7 @@ on: permissions: contents: write + packages: write # workflow tasks jobs: @@ -83,6 +84,29 @@ jobs: with: go-version-file: go.mod + - name: Install Zig + uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 + with: + version: 0.14.1 + + - name: Cache cross-compile inputs + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: .cross + key: cross-${{ runner.os }}-zig0.14.1-alsa1.2.12-${{ hashFiles('scripts/setup-cross.sh') }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + + - name: Login to DockerHub + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Run GoReleaser uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 42d671d0..eb1ba066 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -21,6 +21,10 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Install ALSA headers (Linux) + if: matrix.os == 'ubuntu-latest' + run: sudo apt-get update && sudo apt-get install -y libasound2-dev + - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: @@ -41,6 +45,18 @@ jobs: set -euo pipefail go test -race -json -v ./... 2>&1 | tee test.log + - name: Verify fish_autocomplete is up to date + if: matrix.os == 'ubuntu-latest' + shell: bash + run: | + go build -o /tmp/lk ./cmd/lk + /tmp/lk generate-fish-completion -o /tmp/fish_autocomplete.fresh + if ! diff -u autocomplete/fish_autocomplete /tmp/fish_autocomplete.fresh; then + echo "::error::autocomplete/fish_autocomplete is stale; regenerate with:" + echo " go build -o /tmp/lk ./cmd/lk && /tmp/lk generate-fish-completion -o autocomplete/fish_autocomplete" + exit 1 + fi + - name: Upload test log uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 if: always() diff --git a/.gitignore b/.gitignore index fa396b82..23f3a401 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ bin/ .idea/ dist/ +.cross/ # Local artifacts .task/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 19aebb7d..df8ba808 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -12,32 +12,104 @@ # See the License for the specific language governing permissions and # limitations under the License. +# All builds set CGO_ENABLED=1 — audio (portaudio/webrtc APM) is in every +# binary. Linux/Windows cross-compiles use zig cc as the C/C++ toolchain; +# scripts/setup-cross.sh builds static libasound.a (linux) and pre-generates +# MinGW import libs (windows) under .cross// before each build. + version: 2 before: hooks: - go mod tidy + builds: - - id: lk + - id: lk-darwin-arm64 + main: ./cmd/lk + binary: lk env: - - CGO_ENABLED=0 + - CGO_ENABLED=1 + goos: [darwin] + goarch: [arm64] + ldflags: + - -s -w + + - id: lk-linux-amd64 main: ./cmd/lk binary: lk - goarm: - - "7" - goarch: - - amd64 - - arm64 - - arm - goos: - - linux - - windows - - darwin - ignore: - - goos: windows - goarch: arm + hooks: + pre: + - cmd: scripts/setup-cross.sh linux/amd64 + env: + - CGO_ENABLED=1 + - CC=zig cc -target x86_64-linux-gnu.2.28 + - CXX=zig c++ -target x86_64-linux-gnu.2.28 + - CGO_CFLAGS=-I{{ .Env.PWD }}/.cross/linux_amd64/include + # -L points at scripts/setup-cross.sh's static libasound.a. zig's sysroot + # excludes /usr/lib so the `-lasound` from #cgo LDFLAGS resolves here. + - CGO_LDFLAGS=-L{{ .Env.PWD }}/.cross/linux_amd64/lib + goos: [linux] + goarch: [amd64] + ldflags: + - -s -w + - -linkmode=external + + - id: lk-linux-arm64 + main: ./cmd/lk + binary: lk + hooks: + pre: + - cmd: scripts/setup-cross.sh linux/arm64 + env: + - CGO_ENABLED=1 + - CC=zig cc -target aarch64-linux-gnu.2.28 + - CXX=zig c++ -target aarch64-linux-gnu.2.28 + - CGO_CFLAGS=-I{{ .Env.PWD }}/.cross/linux_arm64/include + - CGO_LDFLAGS=-L{{ .Env.PWD }}/.cross/linux_arm64/lib + goos: [linux] + goarch: [arm64] + ldflags: + - -s -w + - -linkmode=external + + - id: lk-windows-amd64 + main: ./cmd/lk + binary: lk + hooks: + pre: + - cmd: scripts/setup-cross.sh windows/amd64 + env: + - CGO_ENABLED=1 + - CC=zig cc -target x86_64-windows-gnu + - CXX=zig c++ -target x86_64-windows-gnu + # -fms-extensions: enable __try/__except (SEH) used by WebRTC + # -DNTDDI_VERSION: target Windows 10 base to skip WinRT includes absent from MinGW + - CGO_CXXFLAGS=-fms-extensions -DNTDDI_VERSION=0x0A000000 -fno-sanitize=all + goos: [windows] + goarch: [amd64] + ldflags: + - -s -w + - -linkmode=external + - -extldflags=-L{{ .Env.PWD }}/.cross/windows_amd64/mingw_lib + + - id: lk-windows-arm64 + main: ./cmd/lk + binary: lk + hooks: + pre: + - cmd: scripts/setup-cross.sh windows/arm64 + env: + - CGO_ENABLED=1 + - CC=zig cc -target aarch64-windows-gnu + - CXX=zig c++ -target aarch64-windows-gnu + - CGO_CXXFLAGS=-fms-extensions -DNTDDI_VERSION=0x0A000000 -fno-sanitize=all + goos: [windows] + goarch: [arm64] ldflags: - -s -w + - -linkmode=external + - -extldflags=-L{{ .Env.PWD }}/.cross/windows_arm64/mingw_lib + archives: - name_template: "lk_{{ .Version }}_{{ .Os }}_{{ .Arch }}" format_overrides: @@ -46,21 +118,67 @@ archives: files: - LICENSE - 'autocomplete/*' + +dockers: + - image_templates: + - "livekit/livekit-cli:{{ .Tag }}-amd64" + - "livekit/livekit-cli:v{{ .Major }}.{{ .Minor }}-amd64" + ids: [lk-linux-amd64] + goos: linux + goarch: amd64 + dockerfile: Dockerfile + use: buildx + build_flag_templates: + - "--platform=linux/amd64" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.version={{ .Version }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .GitURL }}" + + - image_templates: + - "livekit/livekit-cli:{{ .Tag }}-arm64" + - "livekit/livekit-cli:v{{ .Major }}.{{ .Minor }}-arm64" + ids: [lk-linux-arm64] + goos: linux + goarch: arm64 + dockerfile: Dockerfile + use: buildx + build_flag_templates: + - "--platform=linux/arm64" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.version={{ .Version }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .GitURL }}" + +docker_manifests: + - name_template: "livekit/livekit-cli:{{ .Tag }}" + image_templates: + - "livekit/livekit-cli:{{ .Tag }}-amd64" + - "livekit/livekit-cli:{{ .Tag }}-arm64" + - name_template: "livekit/livekit-cli:v{{ .Major }}.{{ .Minor }}" + image_templates: + - "livekit/livekit-cli:v{{ .Major }}.{{ .Minor }}-amd64" + - "livekit/livekit-cli:v{{ .Major }}.{{ .Minor }}-arm64" + release: github: owner: livekit name: livekit-cli draft: true prerelease: auto + changelog: sort: asc filters: exclude: - '^docs:' - '^test:' + gomod: proxy: false + checksum: name_template: 'checksums.txt' + snapshot: version_template: "{{ incpatch .Version }}-next" diff --git a/Dockerfile b/Dockerfile index cb970e6b..16c223c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,31 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.26-alpine AS builder +# Consumed by goreleaser, which drops the pre-built `lk` binary into the build +# context. Distroless gives us glibc (the binary targets glibc 2.28+) plus CA +# certs for TLS, without a shell or package manager. +FROM gcr.io/distroless/base-debian12 -ARG TARGETPLATFORM -ARG TARGETARCH -RUN echo building for "$TARGETPLATFORM" +COPY lk /lk -WORKDIR /workspace - -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -# cache deps before building and copying source so that we don't need to re-download as much -# and so that source changes don't invalidate our downloaded layer -RUN go mod download - -# Copy the go source -COPY cmd/ cmd/ -COPY pkg/ pkg/ -COPY version.go version.go - -RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -a -o lk ./cmd/lk - -FROM alpine:3.21 - -COPY --from=builder /workspace/lk /lk - -# Run the binary. ENTRYPOINT ["/lk"] diff --git a/Makefile b/Makefile deleted file mode 100644 index fff21213..00000000 --- a/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -ifeq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif - -ifeq ($(OS),Windows_NT) - DETECTED_OS := Windows -else - DETECTED_OS := $(shell uname -s) -endif - -cli: check_lfs - GOOS=darwin GOARCH=arm64 go build -ldflags "-w -s" -o bin/lk ./cmd/lk - GOOS=linux GOARCH=amd64 go build -ldflags "-w -s" -o bin/lk-linux ./cmd/lk - GOOS=windows GOARCH=amd64 go build -ldflags "-w -s" -o bin/lk.exe ./cmd/lk - - -console: - CGO_ENABLED=1 go build -tags console -ldflags "-w -s" -o bin/lk ./cmd/lk - -install: cli -ifeq ($(DETECTED_OS),Windows) - cp bin/lk.exe $(GOBIN)/lk.exe - ln -sf $(GOBIN)/lk.exe $(GOBIN)/livekit-cli.exe -else ifeq ($(DETECTED_OS),Darwin) - cp bin/lk $(GOBIN)/lk - ln -sf $(GOBIN)/lk $(GOBIN)/livekit-cli -else - cp bin/lk-linux $(GOBIN)/lk - ln -sf $(GOBIN)/lk $(GOBIN)/livekit-cli -endif - -check_lfs: - @{ \ - if [ ! -n $(find pkg/provider/resources -name neon_720_2000.ivf -size +100) ]; then \ - echo "Video resources not found. Ensure Git LFS is installed"; \ - exit 1; \ - fi \ - } - -lint: - golangci-lint run ./... - -fish_autocomplete: cli - ./bin/lk generate-fish-completion -o autocomplete/fish_autocomplete diff --git a/README.md b/README.md index e2ebb1f4..c011bec6 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,23 @@ Or download a precompiled binary for the [latest release](https://github.com/liv This repo uses [Git LFS](https://git-lfs.github.com/) for embedded video resources. Please ensure git-lfs is installed on your machine. +Every build of `lk` includes the audio/console subsystem (CGO + PortAudio + WebRTC APM). You will need platform headers/libraries for the C compile: + +- **macOS**: nothing to install — CoreAudio frameworks ship with Xcode CLT. +- **Linux**: `sudo apt-get install libasound2-dev` (or your distro's ALSA dev package). +- **Windows**: MinGW from the standard Go distribution. + +Then: + ```shell git clone https://github.com/livekit/livekit-cli && cd livekit-cli -make install +go build ./cmd/lk +``` + +To cross-compile for another platform, install [Zig](https://ziglang.org/download/) 0.14.1 and run a [GoReleaser](https://goreleaser.com/) snapshot build: + +```shell +goreleaser build --single-target --snapshot --clean ``` diff --git a/autocomplete/fish_autocomplete b/autocomplete/fish_autocomplete index 61b7c0d8..ceb5b9ca 100644 --- a/autocomplete/fish_autocomplete +++ b/autocomplete/fish_autocomplete @@ -2,7 +2,7 @@ function __fish_lk_no_subcommand --description 'Test if there has been any subcommand yet' for i in (commandline -opc) - if contains -- $i generate-fish-completion app agent a cloud project room create-room list-rooms list-room update-room-metadata list-participants get-participant remove-participant update-participant mute-track update-subscriptions send-data token create-token join-room dispatch egress start-room-composite-egress start-web-egress start-participant-egress start-track-composite-egress start-track-egress list-egress update-layout update-stream stop-egress test-egress-template ingress create-ingress update-ingress list-ingress delete-ingress sip list-sip-trunk delete-sip-trunk create-sip-dispatch-rule list-sip-dispatch-rule delete-sip-dispatch-rule create-sip-participant replay perf load-test completion + if contains -- $i generate-fish-completion app agent a cloud docs project room create-room list-rooms list-room update-room-metadata list-participants get-participant remove-participant update-participant mute-track update-subscriptions send-data token create-token join-room dispatch egress start-room-composite-egress start-web-egress start-participant-egress start-track-composite-egress start-track-egress list-egress update-layout update-stream stop-egress test-egress-template ingress create-ingress update-ingress list-ingress delete-ingress sip list-sip-trunk delete-sip-trunk create-sip-dispatch-rule list-sip-dispatch-rule delete-sip-dispatch-rule create-sip-participant number replay perf load-test completion return 1 end end @@ -18,6 +18,8 @@ complete -c lk -n '__fish_lk_no_subcommand' -f -l subdomain -r -d '`SUBDOMAIN` o complete -c lk -n '__fish_lk_no_subcommand' -f -l config -r -d 'Config `TOML` to use in the working directory' complete -c lk -n '__fish_lk_no_subcommand' -f -l curl -d 'Print curl commands for API actions' complete -c lk -n '__fish_lk_no_subcommand' -f -l verbose +complete -c lk -n '__fish_lk_no_subcommand' -f -l yes -s y -d 'Assume yes for confirmations; fail or use default for other prompts (use in CI/non-interactive)' +complete -c lk -n '__fish_lk_no_subcommand' -f -l quiet -s q -d 'Suppress informational output to stderr (warnings and errors still print)' complete -c lk -n '__fish_lk_no_subcommand' -f -l help -s h -d 'show help' complete -c lk -n '__fish_lk_no_subcommand' -f -l version -s v -d 'print the version' complete -c lk -n '__fish_seen_subcommand_from generate-fish-completion' -f -l out -s o -r @@ -26,206 +28,343 @@ complete -x -c lk -n '__fish_seen_subcommand_from generate-fish-completion; and complete -x -c lk -n '__fish_lk_no_subcommand' -a 'app' -d 'Initialize and manage applications' complete -c lk -n '__fish_seen_subcommand_from app' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from app; and not __fish_seen_subcommand_from create list-templates install run env help h' -a 'create' -d 'Bootstrap a new application from a template or through guided creation' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l template -r -d '`TEMPLATE` to instantiate, see https://github.com/livekit-examples' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l template-url -r -d '`URL` to instantiate, must contain a taskfile.yaml' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l sandbox -r -d '`NAME` of the sandbox, see your cloud dashboard' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from create' -f -l template -r -d '`TEMPLATE` to instantiate, see https://github.com/livekit-examples' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from create' -f -l template-url -r -d '`URL` to instantiate, must contain a taskfile.yaml' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from create' -f -l install -d 'Run installation after creating the application' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from app; and not __fish_seen_subcommand_from create list-templates install run env help h' -a 'list-templates' -d 'List available templates to bootstrap a new application' -complete -c lk -n '__fish_seen_subcommand_from list-templates' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list-templates' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list-templates; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from install' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from install; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from run' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from run; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from list-templates' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from list-templates' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from list-templates; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from install' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from run' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from run; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from app; and not __fish_seen_subcommand_from create list-templates install run env help h' -a 'env' -d 'Fill environment variables based on .env.example (optional) and project credentials' -complete -c lk -n '__fish_seen_subcommand_from env' -f -l write -s w -d 'Write environment variables to file' -complete -c lk -n '__fish_seen_subcommand_from env' -l destination -s d -r -d 'Destination file path, when used with --write' -complete -c lk -n '__fish_seen_subcommand_from env' -l example -s e -r -d 'Example file path' -complete -c lk -n '__fish_seen_subcommand_from env' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from env; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from env' -f -l write -s w -d 'Write environment variables to file' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from env' -f -l overwrite -s o -d 'Replace destination file instead of merging into existing contents' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from env' -l destination -s d -r -d 'Destination file path, when used with --write' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from env' -l example -s e -r -d 'Example file path' +complete -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from env' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from app; and __fish_seen_subcommand_from env; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from app; and not __fish_seen_subcommand_from create list-templates install run env help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_lk_no_subcommand' -a 'agent' -d 'Manage LiveKit Cloud Agents' complete -c lk -n '__fish_seen_subcommand_from agent a' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'create' -d 'Create a new LiveKit Cloud Agent' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' -complete -c lk -n '__fish_seen_subcommand_from create' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l silent -d 'If set, will not prompt for confirmation' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'config' -d 'Creates a livekit.toml in the working directory for an existing agent.' -complete -c lk -n '__fish_seen_subcommand_from config' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from config' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'deploy' -d 'Deploy a new version of the agent' -complete -c lk -n '__fish_seen_subcommand_from deploy' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' -complete -c lk -n '__fish_seen_subcommand_from deploy' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' -complete -c lk -n '__fish_seen_subcommand_from deploy' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from deploy; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'status' -d 'Get the status of an agent' -complete -c lk -n '__fish_seen_subcommand_from status' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from status' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from status; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'update' -d 'Update an agent metadata and secrets. This will restart the agent.' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' -complete -c lk -n '__fish_seen_subcommand_from update' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'rollback' -d 'Rollback an agent to a previous version' -complete -c lk -n '__fish_seen_subcommand_from rollback' -f -l version -r -d 'Version to rollback to, defaults to most recent previous to current.' -complete -c lk -n '__fish_seen_subcommand_from rollback' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from rollback' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from rollback; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'logs' -d 'Tail logs from agent' -complete -c lk -n '__fish_seen_subcommand_from logs tail' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from logs tail' -f -l log-type -r -d 'Type of logs to retrieve. Valid values are \'deploy\' and \'build\'' -complete -c lk -n '__fish_seen_subcommand_from logs tail' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from logs tail; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'delete' -d 'Delete an agent' -complete -c lk -n '__fish_seen_subcommand_from delete destroy' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from delete destroy' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete destroy; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'versions' -d 'List versions of an agent' -complete -c lk -n '__fish_seen_subcommand_from versions' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from versions' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from versions; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'list' -d 'List all LiveKit Cloud Agents' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l id -r -d '`IDs` of agent(s)' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'secrets' -d 'List secrets for an agent' -complete -c lk -n '__fish_seen_subcommand_from secrets' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from secrets' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from secrets; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'update-secrets' -d 'Update secrets for an agent, will cause a re-start of the agent.' -complete -c lk -n '__fish_seen_subcommand_from update-secrets' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' -complete -c lk -n '__fish_seen_subcommand_from update-secrets' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' -complete -c lk -n '__fish_seen_subcommand_from update-secrets' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' -complete -c lk -n '__fish_seen_subcommand_from update-secrets' -f -l overwrite -d 'If set, will overwrite existing secrets' -complete -c lk -n '__fish_seen_subcommand_from update-secrets' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update-secrets; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from create config deploy status update rollback logs tail delete destroy versions list secrets update-secrets help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'init' -d 'Initialize a new LiveKit Cloud agent project' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from init' -f -l region -r -d 'Region to deploy the agent to. If unset, will deploy to the nearest region.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from init' -f -l install -d 'Run installation after creating the application' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from init' -f -l help -s h -d 'show help' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from init' -f -l deploy -d 'If set, automatically deploys the agent to LiveKit Cloud after initialization.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from init' -f -l template -r -d '`TEMPLATE` to instantiate, see https://github.com/livekit-examples' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from init' -f -l template-url -r -d '`URL` to instantiate, must contain a taskfile.yaml' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'create' -d 'Create a new LiveKit Cloud Agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l secret-mount -r -d 'Local path to a secret file to be mounted on agent environment' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l ignore-empty-secrets -d 'If set, will skip environment variables with empty values from secrets files instead of failing' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l silent -d 'If set, will not prompt for confirmation' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l region -r -d 'Region to deploy the agent to. If unset, will deploy to the nearest region.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l image -r -d 'Pre-built image from the local Docker daemon (e.g. myimage:latest). Requires Docker.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l image-tar -r -d 'Pre-built image from an OCI tar file (e.g. ./image.tar). No Docker daemon required.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'dockerfile' -d 'Generate Dockerfile and .dockerignore for your project' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dockerfile' -f -l silent -d 'If set, will not prompt for confirmation' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dockerfile' -f -l overwrite -d 'Overwrite existing Dockerfile and/or .dockerignore if they exist' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dockerfile' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dockerfile; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'config' -d 'Creates a livekit.toml in the working directory for an existing agent.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from config' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from config' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'deploy' -d 'Deploy a new version of the agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l secret-mount -r -d 'Local path to a secret file to be mounted on agent environment' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l silent -d 'If set, will not prompt for confirmation' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l region -r -d 'Region to deploy the agent to. If unset, will deploy to the nearest region.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l ignore-empty-secrets -d 'If set, will skip environment variables with empty values from secrets files instead of failing' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l image -r -d 'Pre-built image from the local Docker daemon (e.g. myimage:latest). Requires Docker.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l image-tar -r -d 'Pre-built image from an OCI tar file (e.g. ./image.tar). No Docker daemon required.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from deploy; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'status' -d 'Get the status of an agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from status' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from status' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from status; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'update' -d 'Update an agent metadata and secrets. This will restart the agent.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update' -f -l secret-mount -r -d 'Local path to a secret file to be mounted on agent environment' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update' -f -l ignore-empty-secrets -d 'If set, will skip environment variables with empty values from secrets files instead of failing' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'restart' -d 'Restart an agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from restart' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from restart' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from restart; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'rollback' -d 'Rollback an agent to a previous version' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from rollback' -f -l version -r -d 'Version to rollback to, defaults to most recent previous to current.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from rollback' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from rollback' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from rollback; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'logs' -d 'Tail logs from agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from logs tail' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from logs tail' -f -l log-type -r -d 'Type of logs to retrieve. Valid values are \'deploy\' and \'build\'' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from logs tail' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from logs tail; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'delete' -d 'Delete an agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from delete destroy' -f -l silent -d 'If set, will not prompt for confirmation' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from delete destroy' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from delete destroy' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from delete destroy; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'versions' -d 'List versions of an agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from versions' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from versions' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from versions; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'list' -d 'List all LiveKit Cloud Agents' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from list' -f -l id -r -d '`IDs` of agent(s)' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'secrets' -d 'List secrets for an agent' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from secrets' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from secrets' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from secrets; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'update-secrets' -d 'Update secrets for an agent, will cause a re-start of the agent.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets' -f -l secrets -r -d 'KEY=VALUE comma separated secrets. These will be injected as environment variables into the agent. These take precedence over secrets-file.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets' -l secrets-file -r -d '`FILE` containing secret KEY=VALUE pairs, one per line. These will be injected as environment variables into the agent.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets' -f -l secret-mount -r -d 'Local path to a secret file to be mounted on agent environment' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets' -f -l ignore-empty-secrets -d 'If set, will skip environment variables with empty values from secrets files instead of failing' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets' -f -l id -r -d '`ID` of the agent. If unset, and the livekit.toml file is present, will use the id found there.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets' -f -l overwrite -d 'If set, will overwrite existing secrets' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from update-secrets; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'private-link' -d 'Manage private links for agents' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and not __fish_seen_subcommand_from create list delete health-status help h' -a 'create' -d 'Create a private link' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create' -f -l name -r -d 'Private link name' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create' -f -l region -r -d 'LiveKit region. If unset in interactive mode, a picker of available regions is shown.' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create' -f -l port -r -d 'Destination port' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create' -f -l endpoint -r -d 'Customer-provided endpoint identifier' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create' -f -l cloud-region -r -d 'Cloud provider region (e.g. eastus, us-east-2). Required when --endpoint is an Azure Resource ID' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and not __fish_seen_subcommand_from create list delete health-status help h' -a 'list' -d 'List private links with health' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and not __fish_seen_subcommand_from create list delete health-status help h' -a 'delete' -d 'Delete a private link' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from delete' -f -l id -r -d 'Private link ID' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from delete' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and not __fish_seen_subcommand_from create list delete health-status help h' -a 'health-status' -d 'Get private link health status' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from health-status' -f -l id -r -d 'Private link ID' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from health-status' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from health-status' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and __fish_seen_subcommand_from health-status; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from private-link; and not __fish_seen_subcommand_from create list delete health-status help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'start' -d 'Run an agent in production mode' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from start' -f -l log-level -r -d 'Log level (TRACE, DEBUG, INFO, WARN, ERROR)' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from start' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from start; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'dev' -d 'Run an agent in development mode with auto-reload' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dev' -f -l log-level -r -d 'Log level (TRACE, DEBUG, INFO, WARN, ERROR)' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dev' -f -l no-reload -d 'Disable auto-reload on file changes' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dev' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from dev; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'console' -d 'Voice chat with an agent via mic/speakers' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l port -s p -r -d 'TCP port for agent communication' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l input-device -r -d 'Input device index or name substring' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l output-device -r -d 'Output device index or name substring' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l list-devices -d 'List available audio devices and exit' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l no-aec -d 'Disable acoustic echo cancellation' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l text -s t -d 'Start in text mode instead of audio mode' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l record -d 'Record audio and session report to console-recordings/' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'simulate' -d 'Run agent simulations against LiveKit Cloud' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l num-simulations -s n -r -d 'Number of scenarios to generate' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l description -r -d 'Agent description for scenario generation' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l scenario-group-id -r -d 'Use a pre-configured scenario group' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l config -r -d 'Path to simulation config `FILE`' +complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console simulate help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_lk_no_subcommand' -a 'cloud' -d 'Interact with LiveKit Cloud services' complete -c lk -n '__fish_seen_subcommand_from cloud' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from cloud; and not __fish_seen_subcommand_from auth help h' -a 'auth' -d 'Authenticate LiveKit Cloud account to link your projects' -complete -c lk -n '__fish_seen_subcommand_from auth' -f -l revoke -s R -complete -c lk -n '__fish_seen_subcommand_from auth' -f -l timeout -s t -r -d 'Number of `SECONDS` to attempt authentication before giving up' -complete -c lk -n '__fish_seen_subcommand_from auth' -f -l poll-interval -s i -r -d 'Number of `SECONDS` between poll requests to verify authentication' -complete -c lk -n '__fish_seen_subcommand_from auth' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from auth; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from cloud; and __fish_seen_subcommand_from auth' -f -l revoke -s R +complete -c lk -n '__fish_seen_subcommand_from cloud; and __fish_seen_subcommand_from auth' -f -l timeout -s t -r -d 'Number of `SECONDS` to attempt authentication before giving up' +complete -c lk -n '__fish_seen_subcommand_from cloud; and __fish_seen_subcommand_from auth' -f -l poll-interval -s i -r -d 'Number of `SECONDS` between poll requests to verify authentication' +complete -c lk -n '__fish_seen_subcommand_from cloud; and __fish_seen_subcommand_from auth' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from cloud; and __fish_seen_subcommand_from auth; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from cloud; and not __fish_seen_subcommand_from auth help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_lk_no_subcommand' -a 'docs' -d 'Search and browse LiveKit documentation' +complete -c lk -n '__fish_seen_subcommand_from docs' -f -l json -s j -d 'Output as JSON instead of markdown' +complete -c lk -n '__fish_seen_subcommand_from docs' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'overview' -d 'Get a complete overview of the documentation site and table of contents' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from overview' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from overview; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'search' -d 'Search the LiveKit documentation' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from search' -f -l query -s q -r -d 'Search `QUERY` text' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from search' -f -l page -s p -r -d 'Page number (starts at 0)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from search' -f -l hits-per-page -r -d 'Results per page (1-50, default 20)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from search' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from search; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'get-page' -d 'Fetch one or more documentation pages as markdown' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from get-page get-pages' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from get-page get-pages; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'code-search' -d 'Search code across LiveKit GitHub repositories' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search' -f -l query -s q -r -d 'Search term (use code identifiers, not natural language)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search' -f -l repo -s r -r -d 'Target `REPO` (e.g. livekit/agents) or ALL' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search' -f -l language -s l -r -d 'Language filter (e.g. Python, TypeScript)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search' -f -l scope -r -d 'Search scope: content, filename, or both' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search' -f -l limit -r -d 'Max results to return (1-50)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search' -f -l full-file -d 'Return full file content instead of snippets' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from code-search; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'changelog' -d 'Get recent releases and changelog for a LiveKit SDK or package' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from changelog' -f -l releases -r -d 'Number of releases to fetch (1-20)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from changelog' -f -l skip -r -d 'Number of releases to skip for pagination' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from changelog' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from changelog; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'list-sdks' -d 'List all LiveKit SDK repositories and package names' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from list-sdks' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from list-sdks; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'pricing-info' -d 'Get LiveKit Cloud pricing information' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from pricing-info' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from pricing-info; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'submit-feedback' -d 'Submit feedback on the LiveKit documentation' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from submit-feedback' -f -l page -r -d 'The docs `PAGE` the feedback is about (e.g. /agents/build/tools)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from submit-feedback' -f -l feedback -s f -r -d 'Feedback text (max 1024 characters)' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from submit-feedback' -f -l agent -r -d 'Identity of the agent submitting feedback (e.g. "Cursor", "Claude Code")' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from submit-feedback' -f -l model -r -d 'Model `ID` used by the agent (e.g. "gpt-5", "claude-4.5-sonnet")' +complete -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from submit-feedback' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and __fish_seen_subcommand_from submit-feedback; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from overview search get-page get-pages code-search changelog list-sdks pricing-info submit-feedback help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_lk_no_subcommand' -a 'project' -d 'Add or remove projects and view existing project properties' complete -c lk -n '__fish_seen_subcommand_from project' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from project; and not __fish_seen_subcommand_from add list remove set-default help h' -a 'add' -d 'Add a new project (for LiveKit Cloud projects, also see `lk cloud auth`)' -complete -c lk -n '__fish_seen_subcommand_from add' -f -l url -r -d '`URL` of the LiveKit server' -complete -c lk -n '__fish_seen_subcommand_from add' -f -l api-key -r -d 'Project `KEY`' -complete -c lk -n '__fish_seen_subcommand_from add' -f -l api-secret -r -d 'Project `SECRET`' -complete -c lk -n '__fish_seen_subcommand_from add' -f -l default -d 'Set this project as the default' -complete -c lk -n '__fish_seen_subcommand_from add' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from add' -f -l url -r -d '`URL` of the LiveKit server' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from add' -f -l api-key -r -d 'Project `KEY`' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from add' -f -l api-secret -r -d 'Project `SECRET`' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from add' -f -l default -d 'Set this project as the default' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from add' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from project; and not __fish_seen_subcommand_from add list remove set-default help h' -a 'list' -d 'List all configured projects' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from project; and not __fish_seen_subcommand_from add list remove set-default help h' -a 'remove' -d 'Remove an existing project from config' -complete -c lk -n '__fish_seen_subcommand_from remove' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from remove; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from remove' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from remove; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from project; and not __fish_seen_subcommand_from add list remove set-default help h' -a 'set-default' -d 'Set a project as default to use with other commands' -complete -c lk -n '__fish_seen_subcommand_from set-default' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from set-default; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from set-default' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from project; and __fish_seen_subcommand_from set-default; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from project; and not __fish_seen_subcommand_from add list remove set-default help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_lk_no_subcommand' -a 'room' -d 'Create or delete rooms and manage existing room properties' complete -c lk -n '__fish_seen_subcommand_from room' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'create' -d 'Create a room' -complete -c lk -n '__fish_seen_subcommand_from create' -l room-egress-file -r -d 'RoomCompositeRequest `JSON` file (see examples/room-composite-file.json)' -complete -c lk -n '__fish_seen_subcommand_from create' -l participant-egress-file -r -d 'ParticipantEgress `JSON` file (see examples/auto-participant-egress.json)' -complete -c lk -n '__fish_seen_subcommand_from create' -l track-egress-file -r -d 'AutoTrackEgress `JSON` file (see examples/auto-track-egress.json)' -complete -c lk -n '__fish_seen_subcommand_from create' -l agents-file -r -d 'Agents configuration `JSON` file' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l room-preset -r -d '`NAME` of the room configuration preset to associate with the created room' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l min-playout-delay -r -d 'Minimum playout delay for video (in `MS`)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l max-playout-delay -r -d 'Maximum playout delay for video (in `MS`)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l sync-streams -d 'Improve A/V sync by placing them in the same stream. when enabled, transceivers will not be reused' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l empty-timeout -r -d 'Number of `SECS` to keep the room open before any participant joins' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l departure-timeout -r -d 'Number of `SECS` to keep the room open after the last participant leaves' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -l room-egress-file -r -d 'RoomCompositeRequest `JSON` file (see examples/room-composite-file.json)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -l participant-egress-file -r -d 'ParticipantEgress `JSON` file (see examples/auto-participant-egress.json)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -l track-egress-file -r -d 'AutoTrackEgress `JSON` file (see examples/auto-track-egress.json)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -l agents-file -r -d 'Agents configuration `JSON` file' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -f -l room-preset -r -d '`NAME` of the room configuration preset to associate with the created room' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -f -l min-playout-delay -r -d 'Minimum playout delay for video (in `MS`)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -f -l max-playout-delay -r -d 'Maximum playout delay for video (in `MS`)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -f -l sync-streams -d 'Improve A/V sync by placing them in the same stream. when enabled, transceivers will not be reused' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -f -l empty-timeout -r -d 'Number of `SECS` to keep the room open before any participant joins' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -f -l departure-timeout -r -d 'Number of `SECS` to keep the room open after the last participant leaves' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'list' -d 'List or search for active rooms by name' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'update' -d 'Modify properties of an active room' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l metadata -r -complete -c lk -n '__fish_seen_subcommand_from update' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update' -f -l metadata -r +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'delete' -d 'Delete a room' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'join' -d 'Joins a room as a participant' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l identity -r -d '`ID` of participant' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l publish-demo -d 'Publish demo video as a loop' -complete -c lk -n '__fish_seen_subcommand_from join' -l publish -r -d '`FILES` to publish as tracks to room (supports .h264, .ivf, .ogg). Can be used multiple times to publish multiple files. Can publish from Unix or TCP socket using the format \'://\' or \'://\' respectively. Valid codecs are "h264", "vp8", "opus"' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l publish-data -r -d 'Publish user data to the room.' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l publish-dtmf -r -d 'Publish DTMF digits to the room. Character \'w\' adds 0.5 sec delay.' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l fps -r -d 'If video files are published, indicates `FPS` of video' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l exit-after-publish -d 'When publishing, exit after file or stream is complete' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l attribute -r -d 'set attributes in key=value format, can be used multiple times' -complete -c lk -n '__fish_seen_subcommand_from join' -l attribute-file -r -d 'read attributes from a `JSON` file' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l auto-subscribe -d 'Automatically subscribe to published tracks.' -complete -c lk -n '__fish_seen_subcommand_from join' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from join; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l open -r -d 'Open relevant `APP` in browser, supported options: [meet console]' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l publish-demo -d 'Publish demo video as a loop' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -l publish -r -d '`FILES` to publish as tracks to room (supports .h264, .ivf, .ogg). Can be used multiple times to publish multiple files. Can publish from Unix or TCP socket using the format \':///\' or \'://\' respectively. Valid codecs are "h264", "h265", "vp8", "opus". For simulcast: use 2-3 h264:// or h265:// URLs with format \':///x\' or \':///path/to//x\' (all layers must use the same codec; quality determined by width order)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l publish-data -r -d 'Publish user data to the room.' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l publish-dtmf -r -d 'Publish DTMF digits to the room. Character \'w\' adds 0.5 sec delay.' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l fps -r -d 'If video files are published, indicates `FPS` of video' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l h26x-streaming-format -r -d 'Format to use when reading H.264 from file or socket, "annex-b" OR "length-prefixed"' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l attach-frame-metadata -d 'Parse H264/H265 SEI for LKTS frame metadata (user timestamp and frame ID) and append packet trailer to each encoded frame' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l exit-after-publish -d 'When publishing, exit after file or stream is complete' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l attribute -r -d 'set attributes in key=value format, can be used multiple times' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -l attribute-file -r -d 'read attributes from a `JSON` file' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l auto-subscribe -d 'Automatically subscribe to published tracks.' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l metadata -r -d '`JSON` metadata which will be passed to participant' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from join; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'participants' -d 'Manage room participants' -complete -c lk -n '__fish_seen_subcommand_from participants' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'list' -d 'List or search for active rooms by name' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'get' -d 'Fetch metadata of a room participant' -complete -c lk -n '__fish_seen_subcommand_from get' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from get' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from get; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'remove' -d 'Remove a participant from a room' -complete -c lk -n '__fish_seen_subcommand_from remove' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from remove' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from remove; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'forward' -d 'Forward a participant to a different room' -complete -c lk -n '__fish_seen_subcommand_from forward' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from forward' -f -l identity -r -d '`ID` of participant' -complete -c lk -n '__fish_seen_subcommand_from forward' -f -l destination-room -r -d '`NAME` of the destination room' -complete -c lk -n '__fish_seen_subcommand_from forward' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from forward; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'move' -d 'Move a participant to a different room' -complete -c lk -n '__fish_seen_subcommand_from move' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from move' -f -l identity -r -d '`ID` of participant' -complete -c lk -n '__fish_seen_subcommand_from move' -f -l destination-room -r -d '`NAME` of the destination room' -complete -c lk -n '__fish_seen_subcommand_from move' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from move; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'update' -d 'Change the metadata and permissions for a room participant' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l metadata -r -d 'JSON describing participant metadata (existing values for unset fields)' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l permissions -r -d 'JSON describing participant permissions (existing values for unset fields)' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'list' -d 'List or search for active rooms by name' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'get' -d 'Fetch metadata of a room participant' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from get' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from get' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from get' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'remove' -d 'Remove a participant from a room' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from remove' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from remove' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from remove' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from remove; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'forward' -d 'Forward a participant to a different room' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from forward' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from forward' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from forward' -f -l destination-room -r -d '`NAME` of the destination room' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from forward' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from forward; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'move' -d 'Move a participant to a different room' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from move' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from move' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from move' -f -l destination-room -r -d '`NAME` of the destination room' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from move' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from move; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'update' -d 'Change the metadata and permissions for a room participant' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from update' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from update' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from update' -f -l metadata -r -d 'JSON describing participant metadata (existing values for unset fields)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from update' -f -l permissions -r -d 'JSON describing participant permissions (existing values for unset fields)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from participants; and not __fish_seen_subcommand_from list get remove forward move update help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'mute-track' -d 'Mute or unmute a track' -complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l identity -r -d '`ID` of participant' -complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l help -s h -d 'show help' -complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l mute -s m -d 'Mute the track' -complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l unmute -s u -d 'Unmute the track' -complete -x -c lk -n '__fish_seen_subcommand_from mute-track; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from mute-track' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from mute-track' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from mute-track' -f -l help -s h -d 'show help' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from mute-track' -f -l mute -s m -d 'Mute the track' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from mute-track' -f -l unmute -s u -d 'Unmute the track' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from mute-track; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'update-subscriptions' -d 'Subscribe or unsubscribe from a track' -complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l identity -r -d '`ID` of participant' -complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l help -s h -d 'show help' -complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l subscribe -s s -d 'Subscribe to the track' -complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l unsubscribe -s S -d 'Unsubscribe to the track' -complete -x -c lk -n '__fish_seen_subcommand_from update-subscriptions; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update-subscriptions' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update-subscriptions' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update-subscriptions' -f -l help -s h -d 'show help' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update-subscriptions' -f -l subscribe -s s -d 'Subscribe to the track' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update-subscriptions' -f -l unsubscribe -s S -d 'Unsubscribe to the track' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from update-subscriptions; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'send-data' -d 'Send arbitrary JSON data to client' -complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l topic -r -d '`TOPIC` of the message' -complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l identity -r -d 'One or more participant identities to send the message to. When empty, broadcasts to the entire room' -complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from send-data; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from send-data' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from send-data' -f -l topic -r -d '`TOPIC` of the message' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from send-data' -f -l identity -r -d 'One or more participant identities to send the message to. When empty, broadcasts to the entire room' +complete -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from send-data' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from room; and __fish_seen_subcommand_from send-data; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from room; and not __fish_seen_subcommand_from create list update delete join participants mute-track update-subscriptions send-data help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from create-room' -f -l name -r -d 'name of the room' complete -c lk -n '__fish_seen_subcommand_from create-room' -f -l room-egress-file -r -d 'RoomCompositeRequest json file (see examples/room-composite-file.json)' @@ -242,69 +381,74 @@ complete -c lk -n '__fish_seen_subcommand_from create-room' -f -l help -s h -d ' complete -x -c lk -n '__fish_seen_subcommand_from create-room; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from list-rooms' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from list-rooms; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from list-room' -f -l room -r -d '`NAME` of the room' +complete -c lk -n '__fish_seen_subcommand_from list-room' -f -l room -s r -r -d '`NAME` of the room (supports templates)' complete -c lk -n '__fish_seen_subcommand_from list-room' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from list-room; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from update-room-metadata' -f -l room -r -d '`NAME` of the room' +complete -c lk -n '__fish_seen_subcommand_from update-room-metadata' -f -l room -s r -r -d '`NAME` of the room (supports templates)' complete -c lk -n '__fish_seen_subcommand_from update-room-metadata' -f -l metadata -r complete -c lk -n '__fish_seen_subcommand_from update-room-metadata' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from update-room-metadata; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from list-participants' -f -l room -r -d '`NAME` of the room' +complete -c lk -n '__fish_seen_subcommand_from list-participants' -f -l room -s r -r -d '`NAME` of the room (supports templates)' complete -c lk -n '__fish_seen_subcommand_from list-participants' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from list-participants; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from get-participant' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from get-participant' -f -l identity -r -d '`ID` of participant' +complete -c lk -n '__fish_seen_subcommand_from get-participant' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from get-participant' -f -l identity -s i -r -d '`ID` of participant (supports templates)' complete -c lk -n '__fish_seen_subcommand_from get-participant' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from get-participant; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from remove-participant' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from remove-participant' -f -l identity -r -d '`ID` of participant' +complete -c lk -n '__fish_seen_subcommand_from remove-participant' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from remove-participant' -f -l identity -s i -r -d '`ID` of participant (supports templates)' complete -c lk -n '__fish_seen_subcommand_from remove-participant' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from remove-participant; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from update-participant' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from update-participant' -f -l identity -r -d '`ID` of participant' +complete -c lk -n '__fish_seen_subcommand_from update-participant' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from update-participant' -f -l identity -s i -r -d '`ID` of participant (supports templates)' complete -c lk -n '__fish_seen_subcommand_from update-participant' -f -l metadata -r -d '`JSON` describing participant metadata' complete -c lk -n '__fish_seen_subcommand_from update-participant' -f -l permissions -r -d '`JSON` describing participant permissions (existing values for unset fields)' complete -c lk -n '__fish_seen_subcommand_from update-participant' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from update-participant; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l identity -r -d '`ID` of participant' +complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l identity -s i -r -d '`ID` of participant (supports templates)' complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l help -s h -d 'show help' complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l m -s mute -s muted -d 'Mute the track' complete -c lk -n '__fish_seen_subcommand_from mute-track' -f -l u -s unmute -d 'Unmute the track' complete -x -c lk -n '__fish_seen_subcommand_from mute-track; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l identity -r -d '`ID` of participant' +complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l identity -s i -r -d '`ID` of participant (supports templates)' complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l subscribe -d 'Set to true to subscribe, otherwise it\'ll unsubscribe' complete -c lk -n '__fish_seen_subcommand_from update-subscriptions' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from update-subscriptions; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l room -r -d '`NAME` of the room' +complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l room -s r -r -d '`NAME` of the room (supports templates)' complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l topic -r -d '`TOPIC` of the message' complete -c lk -n '__fish_seen_subcommand_from send-data' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from send-data; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_lk_no_subcommand' -a 'token' -d 'Create access tokens with granular capabilities' complete -c lk -n '__fish_seen_subcommand_from token' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from token; and not __fish_seen_subcommand_from create help h' -a 'create' -d 'Creates an access token' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l create -d 'Ability to create or delete rooms' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l list -d 'Ability to list rooms' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l join -d 'Ability to join a room (requires --room and --identity)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l admin -d 'Ability to moderate a room (requires --room)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l egress -d 'Ability to interact with Egress services' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l ingress -d 'Ability to interact with Ingress services' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l allow-update-metadata -d 'Ability to update their own name and metadata' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l allow-source -r -d 'Restrict publishing to only `SOURCE` types (e.g. --allow-source camera,microphone), defaults to all' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l identity -s i -r -d 'Unique `ID` of the participant, used with --join' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l name -s n -r -d '`NAME` of the participant, used with --join. defaults to identity' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l room -s r -r -d '`NAME` of the room to join' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l token-only -d 'Output only the access token' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l metadata -r -d '`JSON` metadata to encode in the token, will be passed to participant' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l attribute -r -d 'set attributes in key=value format, can be used multiple times' -complete -c lk -n '__fish_seen_subcommand_from create' -l attribute-file -r -d 'read attributes from a `JSON` file' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l valid-for -r -d '`TIME` that the token is valid for, e.g. "5m", "1h10m" (s: seconds, m: minutes, h: hours)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l grant -r -d 'Additional `VIDEO_GRANT` fields. It\'ll be merged with other arguments (JSON formatted)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l open -r -d 'Open relevant `APP` in browser, supported options: [meet console]' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l create -d 'Ability to create or delete rooms' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l list -d 'Ability to list rooms' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l join -d 'Ability to join a room (requires --room and --identity)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l admin -d 'Ability to moderate a room (requires --room)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l egress -d 'Ability to interact with Egress services' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l ingress -d 'Ability to interact with Ingress services' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l inference -d 'Ability to perform inference (AI endpoints)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l allow-update-metadata -d 'Ability to update their own name and metadata' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l allow-source -r -d 'Restrict publishing to only `SOURCE` types (e.g. --allow-source camera,microphone), defaults to all' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l name -s n -r -d '`NAME` of the participant, used with --join (defaults to identity) (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l metadata -r -d '`JSON` metadata to encode in the token, will be passed to participant' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l attribute -r -d 'set attributes in key=value format, can be used multiple times' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -l attribute-file -r -d 'read attributes from a `JSON` file' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l valid-for -r -d '`TIME` that the token is valid for, e.g. "5m", "1h10m" (s: seconds, m: minutes, h: hours)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l grant -r -d 'Additional `VIDEO_GRANT` fields. It\'ll be merged with other arguments (JSON formatted)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l agent -r -d 'Agent to dispatch to the room (identified by agent_name)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l job-metadata -r -d 'Metadata attached to job dispatched to the agent (ctx.job.metadata)' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create' -f -l token-only -d 'Output only the access token' +complete -x -c lk -n '__fish_seen_subcommand_from token; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from token; and not __fish_seen_subcommand_from create help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l room -s r -r -d '`NAME` of the room (supports templates)' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l create -d 'Ability to create or delete rooms' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l list -d 'Ability to list rooms' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l join -d 'Ability to join a room (requires --room and --identity)' @@ -316,9 +460,6 @@ complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l allow-update- complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l allow-source -r -d 'Allow one or more `SOURCE`s to be published (i.e. --allow-source camera,microphone). if left blank, all sources are allowed' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l identity -s i -r -d 'Unique `ID` of the participant, used with --join' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l name -s n -r -d '`NAME` of the participant, used with --join. defaults to identity' -complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l room -s r -r -d '`NAME` of the room to join' -complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l token-only -d 'Output only the access token' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l room-configuration -r -d 'name of the room configuration to use when creating a room' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l metadata -r -d '`JSON` metadata to encode in the token, will be passed to participant' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l attribute -r -d 'set attributes in key=value format, can be used multiple times' @@ -326,11 +467,13 @@ complete -c lk -n '__fish_seen_subcommand_from create-token' -l attribute-file - complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l valid-for -r -d 'Amount of `TIME` that the token is valid for. i.e. "5m", "1h10m" (s: seconds, m: minutes, h: hours)' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l grant -r -d 'Additional `VIDEO_GRANT` fields. It\'ll be merged with other arguments (JSON formatted)' complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l help -s h -d 'show help' +complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from create-token' -f -l token-only -d 'Output only the access token' complete -x -c lk -n '__fish_seen_subcommand_from create-token; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l identity -r -d '`ID` of participant' +complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l identity -s i -r -d '`ID` of participant (supports templates)' complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l publish-demo -d 'publish demo video as a loop' -complete -c lk -n '__fish_seen_subcommand_from join-room' -l publish -r -d '`FILES` to publish as tracks to room (supports .h264, .ivf, .ogg). can be used multiple times to publish multiple files. can publish from Unix or TCP socket using the format \'://\' or \'://\' respectively. Valid codecs are "h264", "vp8", "opus"' +complete -c lk -n '__fish_seen_subcommand_from join-room' -l publish -r -d '`FILES` to publish as tracks to room (supports .h264, .h265, .ivf, .ogg). can be used multiple times to publish multiple files. can publish from Unix or TCP socket using the format \'://\' or \'://\' respectively. Valid codecs are "h264", "h265", "vp8", "opus"' complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l fps -r -d 'if video files are published, indicates FPS of video' complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l exit-after-publish -d 'when publishing, exit after file or stream is complete' complete -c lk -n '__fish_seen_subcommand_from join-room' -f -l help -s h -d 'show help' @@ -338,58 +481,58 @@ complete -x -c lk -n '__fish_seen_subcommand_from join-room; and not __fish_seen complete -x -c lk -n '__fish_lk_no_subcommand' -a 'dispatch' -d 'Create, list, and delete agent dispatches' complete -c lk -n '__fish_seen_subcommand_from dispatch' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and not __fish_seen_subcommand_from list get create delete help h' -a 'list' -d 'List all agent dispatches in a room' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and not __fish_seen_subcommand_from list get create delete help h' -a 'get' -d 'Get an agent dispatch by room and ID' -complete -c lk -n '__fish_seen_subcommand_from get' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from get; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from get' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and not __fish_seen_subcommand_from list get create delete help h' -a 'create' -d 'Create an agent dispatch' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l room -r -d 'room name' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l new-room -d 'when set, will generate a unique room name' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l agent-name -r -d 'agent to dispatch' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l metadata -r -d 'metadata to send to agent' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from create' -f -l room -r -d 'room name' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from create' -f -l new-room -d 'when set, will generate a unique room name' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from create' -f -l agent-name -r -d 'agent to dispatch' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from create' -f -l metadata -r -d 'metadata to send to agent' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and not __fish_seen_subcommand_from list get create delete help h' -a 'delete' -d 'Delete an agent dispatch' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from dispatch; and not __fish_seen_subcommand_from list get create delete help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_lk_no_subcommand' -a 'egress' -d 'Record or stream media from LiveKit to elsewhere' complete -c lk -n '__fish_seen_subcommand_from egress' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from egress; and not __fish_seen_subcommand_from start list stop test-template update-layout update-stream' -a 'start' -d 'Start egresses of various types' -complete -c lk -n '__fish_seen_subcommand_from start' -f -l type -r -d 'Specify `TYPE` of egress (see above)' -complete -c lk -n '__fish_seen_subcommand_from start' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from start; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from start' -f -l type -r -d 'Specify `TYPE` of egress (see above)' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from start' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from start; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from egress; and not __fish_seen_subcommand_from start list stop test-template update-layout update-stream' -a 'list' -d 'List and search active egresses' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l id -r -d 'List a specific egress `ID`, can be used multiple times' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l room -r -d 'Limits list to a certain room `NAME`' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l active -s a -d 'Lists only active egresses' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from list' -f -l id -r -d 'List a specific egress `ID`, can be used multiple times' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from list' -f -l room -r -d 'Limits list to a certain room `NAME`' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from list' -f -l active -s a -d 'Lists only active egresses' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from egress; and not __fish_seen_subcommand_from start list stop test-template update-layout update-stream' -a 'stop' -d 'Stop an active egress' -complete -c lk -n '__fish_seen_subcommand_from stop' -f -l id -r -d 'Egress ID to stop, can be specified multiple times' -complete -c lk -n '__fish_seen_subcommand_from stop' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from stop; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from stop' -f -l id -r -d 'Egress ID to stop, can be specified multiple times' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from stop' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from stop; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from egress; and not __fish_seen_subcommand_from start list stop test-template update-layout update-stream' -a 'test-template' -d 'See what your egress template will look like in a recording' -complete -c lk -n '__fish_seen_subcommand_from test-template' -f -l base-url -r -d 'Base template `URL`' -complete -c lk -n '__fish_seen_subcommand_from test-template' -f -l layout -r -d 'Layout `TYPE`' -complete -c lk -n '__fish_seen_subcommand_from test-template' -f -l publishers -r -d '`NUMBER` of publishers' -complete -c lk -n '__fish_seen_subcommand_from test-template' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from test-template' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from test-template; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from test-template' -f -l base-url -r -d 'Base template `URL`' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from test-template' -f -l layout -r -d 'Layout `TYPE`' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from test-template' -f -l publishers -r -d '`NUMBER` of publishers' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from test-template' -f -l room -r -d '`NAME` of the room' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from test-template' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from test-template; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from egress; and not __fish_seen_subcommand_from start list stop test-template update-layout update-stream' -a 'update-layout' -d 'Updates layout for a live room composite egress' -complete -c lk -n '__fish_seen_subcommand_from update-layout' -f -l id -r -d 'Egress ID' -complete -c lk -n '__fish_seen_subcommand_from update-layout' -f -l layout -r -d 'new web layout' -complete -c lk -n '__fish_seen_subcommand_from update-layout' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update-layout; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-layout' -f -l id -r -d 'Egress ID' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-layout' -f -l layout -r -d 'new web layout' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-layout' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-layout; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from egress; and not __fish_seen_subcommand_from start list stop test-template update-layout update-stream' -a 'update-stream' -d 'Adds or removes RTMP output urls from a live stream' -complete -c lk -n '__fish_seen_subcommand_from update-stream' -f -l id -r -d 'Egress ID' -complete -c lk -n '__fish_seen_subcommand_from update-stream' -f -l add-urls -r -d 'urls to add' -complete -c lk -n '__fish_seen_subcommand_from update-stream' -f -l remove-urls -r -d 'urls to remove' -complete -c lk -n '__fish_seen_subcommand_from update-stream' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update-stream; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from start-room-composite-egress' -f -l request -r -d 'RoomCompositeEgressRequest as JSON file' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-stream' -f -l id -r -d 'Egress ID' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-stream' -f -l add-urls -r -d 'urls to add' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-stream' -f -l remove-urls -r -d 'urls to remove' +complete -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-stream' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from egress; and __fish_seen_subcommand_from update-stream; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from start-room-composite-egress' -f -l request -r -d 'RoomCompositeEgressRequest as JSON file (or - for stdin)' complete -c lk -n '__fish_seen_subcommand_from start-room-composite-egress' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from start-room-composite-egress; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from start-web-egress' -f -l request -r -d 'WebEgressRequest as json file (see cmd/livekit-cli/examples)' @@ -430,20 +573,20 @@ complete -x -c lk -n '__fish_seen_subcommand_from test-egress-template; and not complete -x -c lk -n '__fish_lk_no_subcommand' -a 'ingress' -d 'Import outside media sources into a LiveKit room' complete -c lk -n '__fish_seen_subcommand_from ingress' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from ingress; and not __fish_seen_subcommand_from create update list delete help h' -a 'create' -d 'Create an ingress' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from ingress; and not __fish_seen_subcommand_from create update list delete help h' -a 'update' -d 'Update an ingress' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from ingress; and not __fish_seen_subcommand_from create update list delete help h' -a 'list' -d 'List all active ingress' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l room -r -d 'Limits list to a certain room `NAME`' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l id -r -d 'List a specific ingress `ID`' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from list' -f -l room -r -d 'Limits list to a certain room `NAME`' +complete -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from list' -f -l id -r -d 'List a specific ingress `ID`' +complete -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from ingress; and not __fish_seen_subcommand_from create update list delete help h' -a 'delete' -d 'Delete an ingress' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from ingress; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from ingress; and not __fish_seen_subcommand_from create update list delete help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from create-ingress' -f -l request -r -d 'CreateIngressRequest as json file (see cmd/lk/examples)' complete -c lk -n '__fish_seen_subcommand_from create-ingress' -f -l help -s h -d 'show help' @@ -461,117 +604,123 @@ complete -x -c lk -n '__fish_seen_subcommand_from delete-ingress; and not __fish complete -x -c lk -n '__fish_lk_no_subcommand' -a 'sip' -d 'Manage SIP Trunks, Dispatch Rules, and Participants' complete -c lk -n '__fish_seen_subcommand_from sip' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from sip; and not __fish_seen_subcommand_from inbound in inbound-trunk outbound out outbound-trunk dispatch dispatch-rule participant help h' -a 'inbound' -d 'Inbound SIP Trunk management' -complete -c lk -n '__fish_seen_subcommand_from inbound in inbound-trunk' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'list' -d 'List all inbound SIP Trunks' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'create' -d 'Create an inbound SIP Trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l name -r -d 'Sets a new name for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l numbers -r -d 'Sets a list of numbers for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l media-enc -r -d 'Sets media encryption for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l auth-user -r -d 'Set username for authentication' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l auth-pass -r -d 'Set password for authentication' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'update' -d 'Update an inbound SIP Trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l id -r -d 'ID for the trunk to update' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l name -r -d 'Sets a new name for the trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l numbers -r -d 'Sets a new list of numbers for the trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l auth-user -r -d 'Set username for authentication' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l auth-pass -r -d 'Set password for authentication' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'delete' -d 'Delete a SIP Trunk' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'list' -d 'List all inbound SIP Trunks' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'create' -d 'Create an inbound SIP Trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from create' -f -l name -r -d 'Sets a new name for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from create' -f -l numbers -r -d 'Sets a list of numbers for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from create' -f -l media-enc -r -d 'Sets media encryption for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from create' -f -l auth-user -r -d 'Set username for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from create' -f -l auth-pass -r -d 'Set password for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'update' -d 'Update an inbound SIP Trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from update' -f -l id -r -d 'ID for the trunk to update' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from update' -f -l name -r -d 'Sets a new name for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from update' -f -l numbers -r -d 'Sets a new list of numbers for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from update' -f -l auth-user -r -d 'Set username for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from update' -f -l auth-pass -r -d 'Set password for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'delete' -d 'Delete a SIP Trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from inbound in inbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from sip; and not __fish_seen_subcommand_from inbound in inbound-trunk outbound out outbound-trunk dispatch dispatch-rule participant help h' -a 'outbound' -d 'Outbound SIP Trunk management' -complete -c lk -n '__fish_seen_subcommand_from outbound out outbound-trunk' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'list' -d 'List all outbound SIP Trunk' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'create' -d 'Create an outbound SIP Trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l name -r -d 'Sets a new name for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l address -r -d 'Sets a destination address for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l transport -r -d 'Sets a transport for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l destination-country -r -d 'Sets a destination country for the trunk as ISO 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l media-enc -r -d 'Sets media encryption for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l numbers -r -d 'Sets a list of numbers for the trunk' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l auth-user -r -d 'Set username for authentication' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l auth-pass -r -d 'Set password for authentication' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'update' -d 'Update an outbound SIP Trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l id -r -d 'ID for the trunk to update' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l name -r -d 'Sets a new name for the trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l address -r -d 'Sets a new destination address for the trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l transport -r -d 'Sets a new transport for the trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l destination-country -r -d 'Sets a destination country for the trunk as ISO 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l numbers -r -d 'Sets a new list of numbers for the trunk' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l auth-user -r -d 'Set username for authentication' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l auth-pass -r -d 'Set password for authentication' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'delete' -d 'Delete SIP Trunk' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'list' -d 'List all outbound SIP Trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'create' -d 'Create an outbound SIP Trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l name -r -d 'Sets a new name for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l address -r -d 'Sets a destination address for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l transport -r -d 'Sets a transport for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l destination-country -r -d 'Sets a destination country for the trunk as ISO 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l media-enc -r -d 'Sets media encryption for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l numbers -r -d 'Sets a list of numbers for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l auth-user -r -d 'Set username for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l auth-pass -r -d 'Set password for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'update' -d 'Update an outbound SIP Trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l id -r -d 'ID for the trunk to update' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l name -r -d 'Sets a new name for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l address -r -d 'Sets a new destination address for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l transport -r -d 'Sets a new transport for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l destination-country -r -d 'Sets a destination country for the trunk as ISO 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l numbers -r -d 'Sets a new list of numbers for the trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l auth-user -r -d 'Set username for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l auth-pass -r -d 'Set password for authentication' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'delete' -d 'Delete SIP Trunk' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from outbound out outbound-trunk; and not __fish_seen_subcommand_from list create update delete help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from sip; and not __fish_seen_subcommand_from inbound in inbound-trunk outbound out outbound-trunk dispatch dispatch-rule participant help h' -a 'dispatch' -d 'SIP Dispatch Rule management' -complete -c lk -n '__fish_seen_subcommand_from dispatch dispatch-rule' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'list' -d 'List all SIP Dispatch Rule' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'create' -d 'Create a SIP Dispatch Rule' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l name -r -d 'Sets a new name for the dispatch rule' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l trunks -r -d 'Sets a list of trunks for the dispatch rule' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l direct -r -d 'Sets a direct dispatch to a specified room' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l caller -s individual -r -d 'Sets a individual caller dispatch to a new room with a specific prefix' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l callee -r -d 'Sets a callee number dispatch to a new room with a specific prefix' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l pin -d 'PIN for a dispatch rule' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l randomize -d 'Randomize room name, only applies to callee dispatch' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'update' -d 'Update a SIP Dispatch Rule' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l id -r -d 'ID for the rule to update' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l name -r -d 'Sets a new name for the rule' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l trunks -r -d 'Sets a new list of trunk IDs' -complete -c lk -n '__fish_seen_subcommand_from update' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'delete' -d 'Delete SIP Dispatch Rule' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'list' -d 'List all SIP Dispatch Rule' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'create' -d 'Create a SIP Dispatch Rule' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create' -f -l name -r -d 'Sets a new name for the dispatch rule' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create' -f -l trunks -r -d 'Sets a list of trunks for the dispatch rule' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create' -f -l direct -r -d 'Sets a direct dispatch to a specified room' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create' -f -l caller -s individual -r -d 'Sets a individual caller dispatch to a new room with a specific prefix' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create' -f -l callee -r -d 'Sets a callee number dispatch to a new room with a specific prefix' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create' -f -l randomize -d 'Randomize room name' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'update' -d 'Update a SIP Dispatch Rule' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l id -r -d 'ID for the rule to update' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l name -r -d 'Sets a new name for the rule' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l trunks -r -d 'Sets a new list of trunk IDs' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l direct -r -d 'Sets a direct dispatch to a specified room' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l caller -s individual -r -d 'Sets a individual caller dispatch to a new room with a specific prefix' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l callee -r -d 'Sets a callee number dispatch to a new room with a specific prefix' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update' -f -l randomize -d 'Randomize room name' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'delete' -d 'Delete SIP Dispatch Rule' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from dispatch dispatch-rule; and not __fish_seen_subcommand_from list create update delete help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from sip; and not __fish_seen_subcommand_from inbound in inbound-trunk outbound out outbound-trunk dispatch dispatch-rule participant help h' -a 'participant' -d 'SIP Participant management' -complete -c lk -n '__fish_seen_subcommand_from participant' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from participant; and not __fish_seen_subcommand_from create transfer help h' -a 'create' -d 'Create a SIP Participant' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l trunk -r -d '`SIP_TRUNK_ID` to use for the call (overrides json config)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l number -r -d '`SIP_NUMBER` to use for the call (overrides json config)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l call -r -d '`SIP_CALL_TO` number to use (overrides json config)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l room -r -d '`ROOM_NAME` to place the call to (overrides json config)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l identity -r -d '`PARTICIPANT_IDENTITY` to use (overrides json config)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l name -r -d '`PARTICIPANT_NAME` to use (overrides json config)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l wait -d 'wait for the call to dial (overrides json config)' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l timeout -r -d 'timeout for the call to dial' -complete -c lk -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participant; and not __fish_seen_subcommand_from create transfer help h' -a 'transfer' -d 'Transfer a SIP Participant' -complete -c lk -n '__fish_seen_subcommand_from transfer' -f -l room -r -d '`NAME` of the room' -complete -c lk -n '__fish_seen_subcommand_from transfer' -f -l identity -r -d '`ID` of participant' -complete -c lk -n '__fish_seen_subcommand_from transfer' -f -l to -r -d '`SIP URL` to transfer the call to. Use \'tel:\' to transfer to a phone' -complete -c lk -n '__fish_seen_subcommand_from transfer' -f -l play-dialtone -d 'if set, a dial tone will be played to the SIP participant while the transfer is being attempted' -complete -c lk -n '__fish_seen_subcommand_from transfer' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from transfer; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from participant; and not __fish_seen_subcommand_from create transfer help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and not __fish_seen_subcommand_from create transfer help h' -a 'create' -d 'Create a SIP Participant' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l trunk -r -d '`SIP_TRUNK_ID` to use for the call (overrides json config)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l number -r -d '`SIP_NUMBER` to use for the call (overrides json config)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l call -r -d '`SIP_CALL_TO` number to use (overrides json config)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l name -r -d '`PARTICIPANT_NAME` to use (overrides json config)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l display-name -r -d '`DISPLAY_NAME` for the \'From\' SIP header (overrides json config)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l no-display-name -d 'Avoid defaulting the display name, and do a CNAM lookup instead (overrides display-name setting)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l wait -d 'wait for the call to dial (overrides json config)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l timeout -r -d 'timeout for the call to dial' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l header -r -d 'Custom SIP header in format \'Key:Value\' (can be specified multiple times)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from create; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and not __fish_seen_subcommand_from create transfer help h' -a 'transfer' -d 'Transfer a SIP Participant' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from transfer' -f -l room -s r -r -d '`NAME` of the room (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from transfer' -f -l identity -s i -r -d '`ID` of participant (supports templates)' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from transfer' -f -l to -r -d '`SIP URL` to transfer the call to. Use \'tel:\' to transfer to a phone' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from transfer' -f -l play-dialtone -d 'if set, a dial tone will be played to the SIP participant while the transfer is being attempted' +complete -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from transfer' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and __fish_seen_subcommand_from transfer; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from sip; and __fish_seen_subcommand_from participant; and not __fish_seen_subcommand_from create transfer help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from sip; and not __fish_seen_subcommand_from inbound in inbound-trunk outbound out outbound-trunk dispatch dispatch-rule participant help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from list-sip-trunk' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from list-sip-trunk; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from delete-sip-trunk' -f -l id -r -d 'SIPTrunk ID' complete -c lk -n '__fish_seen_subcommand_from delete-sip-trunk' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from delete-sip-trunk; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from create-sip-dispatch-rule' -f -l request -r -d 'CreateSIPDispatchRuleRequest as JSON file' +complete -c lk -n '__fish_seen_subcommand_from create-sip-dispatch-rule' -f -l request -r -d 'CreateSIPDispatchRuleRequest as JSON file (or - for stdin)' complete -c lk -n '__fish_seen_subcommand_from create-sip-dispatch-rule' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from create-sip-dispatch-rule; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from list-sip-dispatch-rule' -f -l help -s h -d 'show help' @@ -579,57 +728,103 @@ complete -x -c lk -n '__fish_seen_subcommand_from list-sip-dispatch-rule; and no complete -c lk -n '__fish_seen_subcommand_from delete-sip-dispatch-rule' -f -l id -r -d 'SIPDispatchRule ID' complete -c lk -n '__fish_seen_subcommand_from delete-sip-dispatch-rule' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from delete-sip-dispatch-rule; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -c lk -n '__fish_seen_subcommand_from create-sip-participant' -f -l request -r -d 'CreateSIPParticipantRequest as JSON file' +complete -c lk -n '__fish_seen_subcommand_from create-sip-participant' -f -l request -r -d 'CreateSIPParticipantRequest as JSON file (or - for stdin)' complete -c lk -n '__fish_seen_subcommand_from create-sip-participant' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from create-sip-participant; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_lk_no_subcommand' -a 'number' -d 'Manage phone numbers' +complete -c lk -n '__fish_seen_subcommand_from number' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from number; and not __fish_seen_subcommand_from search purchase list get update release help h' -a 'search' -d 'Search available phone numbers in inventory' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from search' -f -l country-code -r -d 'Filter by country code (e.g., "US", "CA")' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from search' -f -l area-code -r -d 'Filter by area code (e.g., "415")' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from search' -f -l limit -r -d 'Maximum number of results (default: 50)' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from search' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from search' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from search; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from number; and not __fish_seen_subcommand_from search purchase list get update release help h' -a 'purchase' -d 'Purchase phone numbers from inventory' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from purchase' -f -l numbers -r -d 'Phone numbers to purchase (e.g., "+1234567890", "+1234567891")' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from purchase' -f -l sip-dispatch-rule-id -r -d 'SIP dispatch rule ID to apply to all purchased numbers' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from purchase' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from purchase; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from number; and not __fish_seen_subcommand_from search purchase list get update release help h' -a 'list' -d 'List phone numbers for a project' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from list' -f -l limit -r -d 'Maximum number of results per page (default: 50)' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from list' -f -l offset -r -d 'Offset for pagination (default: 0)' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from list' -f -l status -r -d 'Filter by status(es) (active, pending, released, offline). Multiple values can be specified.' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from list' -f -l sip-dispatch-rule-id -r -d 'Filter by SIP dispatch rule ID' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from number; and not __fish_seen_subcommand_from search purchase list get update release help h' -a 'get' -d 'Get a phone number from a project' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from get' -f -l id -r -d 'Use phone number ID for direct lookup' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from get' -f -l number -r -d 'Use phone number string for lookup' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from get' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from number; and not __fish_seen_subcommand_from search purchase list get update release help h' -a 'update' -d 'Update a phone number in a project' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from update' -f -l id -r -d 'Use phone number ID for direct lookup' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from update' -f -l number -r -d 'Use phone number string for lookup' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from update' -f -l sip-dispatch-rule-id -r -d 'SIP dispatch rule ID to assign to the phone number' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from update' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from number; and not __fish_seen_subcommand_from search purchase list get update release help h' -a 'release' -d 'Release phone numbers' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from release' -f -l ids -r -d 'Use phone number IDs for direct lookup' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from release' -f -l numbers -r -d 'Use phone number strings for lookup' +complete -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from release' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from number; and __fish_seen_subcommand_from release; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from number; and not __fish_seen_subcommand_from search purchase list get update release help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from replay' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list load seek close delete' -a 'list' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' -complete -c lk -n '__fish_seen_subcommand_from list' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list load seek close delete' -a 'load' -complete -c lk -n '__fish_seen_subcommand_from load' -f -l id -r -d 'Replay `ID`' -complete -c lk -n '__fish_seen_subcommand_from load' -f -l room -r -d 'Playback room name' -complete -c lk -n '__fish_seen_subcommand_from load' -f -l pts -r -d 'Playback start time' -complete -c lk -n '__fish_seen_subcommand_from load' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from load; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list load seek close delete' -a 'seek' -complete -c lk -n '__fish_seen_subcommand_from seek' -f -l id -r -d 'Playback `ID`' -complete -c lk -n '__fish_seen_subcommand_from seek' -f -l pts -r -d 'Playback start time' -complete -c lk -n '__fish_seen_subcommand_from seek' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from seek; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list load seek close delete' -a 'close' -complete -c lk -n '__fish_seen_subcommand_from close' -f -l id -r -d 'Playback `ID`' -complete -c lk -n '__fish_seen_subcommand_from close' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from close; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' -complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list load seek close delete' -a 'delete' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l id -r -d 'Replay `ID`' -complete -c lk -n '__fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list playback seek close export delete' -a 'list' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from list' -f -l json -s j -d 'Output as JSON' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from list' -f -l room -r -d 'Playback room name' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from list' -f -l token -r -d 'Pagination token' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from list' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list playback seek close export delete' -a 'playback' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from playback' -f -l id -r -d 'Replay `ID`' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from playback' -f -l room -r -d 'Playback room name' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from playback' -f -l offset -r -d 'Playback start time (ex: 30s, 1m)' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from playback' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from playback; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list playback seek close export delete' -a 'seek' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from seek' -f -l id -r -d 'Playback `ID`' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from seek' -f -l offset -r -d 'Playback start time (ex: 30s, 1m)' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from seek' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from seek; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list playback seek close export delete' -a 'close' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from close' -f -l id -r -d 'Playback `ID`' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from close' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from close; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list playback seek close export delete' -a 'export' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from export' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from export; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and not __fish_seen_subcommand_from list playback seek close export delete' -a 'delete' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from delete' -f -l id -r -d 'Replay `ID`' +complete -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from delete' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from replay; and __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_lk_no_subcommand' -a 'perf' -d 'Performance testing commands' complete -c lk -n '__fish_seen_subcommand_from perf' -f -l help -s h -d 'show help' complete -x -c lk -n '__fish_seen_subcommand_from perf; and not __fish_seen_subcommand_from load-test agent-load-test help h' -a 'load-test' -d 'Run load tests against LiveKit with simulated publishers & subscribers' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l room -r -d '`NAME` of the room (default to random name)' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l duration -r -d '`TIME` duration to run, 1m, 1h (by default will run until canceled)' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l video-publishers -s publishers -r -d '`NUMBER` of participants that would publish video tracks' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l audio-publishers -r -d '`NUMBER` of participants that would publish audio tracks' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l subscribers -r -d '`NUMBER` of participants that would subscribe to tracks' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l identity-prefix -r -d 'Identity `PREFIX` of tester participants (defaults to a random prefix)' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l video-resolution -r -d 'Resolution `QUALITY` of video to publish ("high", "medium", or "low")' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l video-codec -r -d '`CODEC` "h264" or "vp8", both will be used when unset' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l num-per-second -r -d '`NUMBER` of testers to start every second' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l layout -r -d '`LAYOUT` to simulate, choose from "speaker", "3x3", "4x4", "5x5"' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l no-simulcast -d 'Disables simulcast publishing (simulcast is enabled by default)' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l simulate-speakers -d 'Fire random speaker events to simulate speaker changes' -complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from load-test; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l room -r -d '`NAME` of the room (default to random name)' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l duration -r -d '`TIME` duration to run, 1m, 1h (by default will run until canceled)' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l video-publishers -s publishers -r -d '`NUMBER` of participants that would publish video tracks' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l audio-publishers -r -d '`NUMBER` of participants that would publish audio tracks' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l subscribers -r -d '`NUMBER` of participants that would subscribe to tracks' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l identity-prefix -r -d 'Identity `PREFIX` of tester participants (defaults to a random prefix)' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l video-resolution -r -d 'Resolution `QUALITY` of video to publish ("high", "medium", or "low")' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l video-codec -r -d '`CODEC` "h264" or "vp8", both will be used when unset' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l num-per-second -r -d '`NUMBER` of testers to start every second' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l layout -r -d '`LAYOUT` to simulate, choose from "speaker", "3x3", "4x4", "5x5"' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l no-simulcast -d 'Disables simulcast publishing (simulcast is enabled by default)' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l simulate-speakers -d 'Fire random speaker events to simulate speaker changes' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from load-test; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from perf; and not __fish_seen_subcommand_from load-test agent-load-test help h' -a 'agent-load-test' -d 'Run load tests for a running agent' -complete -c lk -n '__fish_seen_subcommand_from agent-load-test' -f -l rooms -r -d '`NUMBER` of rooms to open' -complete -c lk -n '__fish_seen_subcommand_from agent-load-test' -f -l agent-name -r -d 'name of the running agent to dispatch to the rooom' -complete -c lk -n '__fish_seen_subcommand_from agent-load-test' -f -l echo-speech-delay -r -d 'delay between when the echo track speaks and when the agent starts speaking (e.g. 5s, 1m)' -complete -c lk -n '__fish_seen_subcommand_from agent-load-test' -f -l duration -r -d '`TIME` duration to run, 1m, 1h (by default will run until canceled)' -complete -c lk -n '__fish_seen_subcommand_from agent-load-test' -f -l help -s h -d 'show help' -complete -x -c lk -n '__fish_seen_subcommand_from agent-load-test; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test' -f -l rooms -r -d '`NUMBER` of rooms to open' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test' -f -l agent-name -r -d 'name of the running agent to dispatch to the rooom' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test' -f -l echo-speech-delay -r -d 'delay between when the echo track speaks and when the agent starts speaking (e.g. 5s, 1m)' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test' -f -l duration -r -d '`TIME` duration to run, 1m, 1h (by default will run until canceled)' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test' -f -l attribute -r -d 'set attributes in key=value format, can be used multiple times' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test' -l attribute-file -r -d 'read attributes from a `JSON` file' +complete -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test' -f -l help -s h -d 'show help' +complete -x -c lk -n '__fish_seen_subcommand_from perf; and __fish_seen_subcommand_from agent-load-test; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -x -c lk -n '__fish_seen_subcommand_from perf; and not __fish_seen_subcommand_from load-test agent-load-test help h' -a 'help' -d 'Shows a list of commands or help for one command' complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l room -r -d '`NAME` of the room (default to random name)' complete -c lk -n '__fish_seen_subcommand_from load-test' -f -l duration -r -d '`TIME` duration to run, 1m, 1h (by default will run until canceled)' diff --git a/cmd/lk/agent.go b/cmd/lk/agent.go index e1973aae..e65b742c 100644 --- a/cmd/lk/agent.go +++ b/cmd/lk/agent.go @@ -491,8 +491,8 @@ func initAgent(ctx context.Context, cmd *cli.Command) error { }); err != nil { return fmt.Errorf("failed to create sandbox: %w", err) } else { - fmt.Println("Creating sandbox app...") - fmt.Printf("Created sandbox app [%s]\n", util.Accented(sandboxID)) + out.Status("Creating sandbox app...") + out.Statusf("Created sandbox app [%s]", util.Accented(sandboxID)) } } @@ -506,7 +506,7 @@ func initAgent(ctx context.Context, cmd *cli.Command) error { } // Deploy if requested if shouldDeploy { - fmt.Println("Deploying agent...") + out.Status("Deploying agent...") if err := createAgent(ctx, cmd); err != nil { return fmt.Errorf("failed to deploy agent: %w", err) } @@ -526,11 +526,13 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { if !cmd.IsSet("project") { useProject := true if !SkipPrompts(cmd) { - if err := huh.NewForm(huh.NewGroup(huh.NewConfirm(). + if err := huh.NewForm(huh.NewGroup(util.Confirm(). Title(fmt.Sprintf("Use project [%s] (%s) to create agent deployment?", project.Name, project.URL)). Value(&useProject). - Negative("Select another"). - Inline(false). + Options( + huh.NewOption("Yes", true), + huh.NewOption("No, select another...", false), + ). WithTheme(util.Theme))). Run(); err != nil { return err @@ -540,6 +542,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { if _, err := selectProject(ctx, cmd); err != nil { return err } + (&resolvedProject{project: project, source: sourceSelected}).announce() var err error // Recreate the client with the new project agentsClient, err = cloudagents.New(cloudagents.WithProject(project.URL, project.APIKey, project.APISecret)) @@ -565,13 +568,13 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { if configExists && lkConfig.Agent != nil { if !silent { - fmt.Printf("Using agent configuration [%s]\n", util.Accented(tomlFilename)) + out.Statusf("Using agent configuration [%s]", util.Accented(tomlFilename)) } } else { lkConfig = config.NewLiveKitTOML(subdomainMatches[1]).WithDefaultAgent() } if !silent { - fmt.Printf("Creating new agent deployment\n") + out.Status("Creating new agent deployment") } secrets, err := requireSecrets(ctx, cmd, false, false) @@ -606,7 +609,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { if err := lkConfig.SaveTOMLFile(workingDir, tomlFilename); err != nil { return err } - fmt.Printf("Created agent with ID [%s]\n", util.Accented(agentID)) + out.Statusf("Created agent with ID [%s]", util.Accented(agentID)) return deployPrebuiltImage(buildContext, agentID, imageRef, imageTar) } @@ -614,7 +617,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { if err != nil { return noAgentError() } - fmt.Printf("Detected agent language [%s]\n", util.Accented(string(projectType))) + out.Statusf("Detected agent language [%s]", util.Accented(string(projectType))) if err := requireDockerfile(ctx, cmd, workingDir, projectType, settingsMap); err != nil { return err @@ -622,7 +625,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { if err := agentfs.CheckSDKVersion(workingDir, projectType, settingsMap); err != nil { if cmd.Bool("skip-sdk-check") { - fmt.Printf("Error checking SDK version: %v, skipping...\n", err) + out.Warnf("Error checking SDK version: %v, skipping...", err) } else { return err } @@ -654,15 +657,15 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Printf("Created agent with ID [%s]\n", util.Accented(resp.AgentId)) + out.Statusf("Created agent with ID [%s]", util.Accented(resp.AgentId)) - fmt.Println("Build completed - You can view build logs later with `lk agent logs --log-type=build`") + out.Status("Build completed - You can view build logs later with `lk agent logs --log-type=build`") if !silent && !SkipPrompts(cmd) { viewLogs := true if err := huh.NewForm( huh.NewGroup( - huh.NewConfirm(). + util.Confirm(). Title("Agent deploying. Would you like to view logs?"). Description("You can view logs later with `lk agent logs`"). Value(&viewLogs). @@ -671,7 +674,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { ).Run(); err != nil { return err } else if viewLogs { - fmt.Println("Tailing runtime logs...safe to exit at any time") + out.Status("Tailing runtime logs...safe to exit at any time") return agentsClient.StreamLogs(ctx, "deploy", lkConfig.Agent.ID, "", os.Stdout, resp.ServerRegions[0]) } } @@ -687,7 +690,7 @@ func createAgentConfig(ctx context.Context, cmd *cli.Command) error { var overwriteVal bool if err := huh.NewForm( huh.NewGroup( - huh.NewConfirm(). + util.Confirm(). Title( fmt.Sprintf("Config file [%s] file already exists. Overwrite?", tomlFilename), ). @@ -769,7 +772,7 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error { if err := deployPrebuiltImage(buildContext, agentId, imageRef, imageTar); err != nil { return fmt.Errorf("unable to deploy prebuilt image: %w", err) } - fmt.Println("Deployed agent") + out.Status("Deployed agent") return nil } @@ -782,7 +785,7 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error { if err != nil { return noAgentError() } - fmt.Printf("Detected agent language [%s]\n", util.Accented(string(projectType))) + out.Statusf("Detected agent language [%s]", util.Accented(string(projectType))) settingsMap, err := getClientSettings(ctx, cmd.Bool("silent")) if err != nil { @@ -791,7 +794,7 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error { if err := agentfs.CheckSDKVersion(workingDir, projectType, settingsMap); err != nil { if cmd.Bool("skip-sdk-check") { - fmt.Printf("Error checking SDK version: %v, skipping...\n", err) + out.Warnf("Error checking SDK version: %v, skipping...", err) } else { return err } @@ -805,7 +808,7 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error { return fmt.Errorf("unable to deploy agent: %w", err) } - fmt.Println("Deployed agent") + out.Status("Deployed agent") return nil } @@ -820,7 +823,7 @@ func deployPrebuiltImage(ctx context.Context, agentID, imageRef, imageTar string var img v1.Image if imageRef != "" { imageRef = strings.TrimSpace(imageRef) - fmt.Printf("Loading image from Docker daemon [%s]\n", util.Accented(imageRef)) + out.Statusf("Loading image from Docker daemon [%s]", util.Accented(imageRef)) var dockerCloser io.Closer img, dockerCloser, err = agentfs.LoadDockerDaemonImage(ctx, imageRef) if err != nil { @@ -828,7 +831,7 @@ func deployPrebuiltImage(ctx context.Context, agentID, imageRef, imageTar string } defer dockerCloser.Close() } else { - fmt.Printf("Loading image from [%s]\n", util.Accented(imageTar)) + out.Statusf("Loading image from [%s]", util.Accented(imageTar)) img, err = crane.Load(imageTar) if err != nil { return fmt.Errorf("failed to load image: %w", err) @@ -836,7 +839,7 @@ func deployPrebuiltImage(ctx context.Context, agentID, imageRef, imageTar string } proxyRef := fmt.Sprintf("%s/%s:%s", target.ProxyHost, target.Name, target.Tag) - fmt.Printf("Pushing image [%s]\n", util.Accented(proxyRef)) + out.Statusf("Pushing image [%s]", util.Accented(proxyRef)) rt := agentsClient.NewRegistryTransport() if err := crane.Push(img, proxyRef, @@ -903,7 +906,7 @@ func getAgentStatus(ctx context.Context, cmd *cli.Command) error { Headers("ID", "Version", "Region", "Status", "CPU", "Mem", "Replicas", "Deployed At"). Rows(rows...) - fmt.Println(t) + out.Result(t) return nil } @@ -923,7 +926,7 @@ func restartAgent(ctx context.Context, cmd *cli.Command) error { return fmt.Errorf("failed to restart agent: %s", resp.Message) } - fmt.Printf("Restarted agent [%s]\n", util.Accented(agentID)) + out.Statusf("Restarted agent [%s]", util.Accented(agentID)) return nil } @@ -965,7 +968,7 @@ func updateAgent(ctx context.Context, cmd *cli.Command) error { } if resp.Success { - fmt.Printf("Updated agent [%s]\n", util.Accented(lkConfig.Agent.ID)) + out.Statusf("Updated agent [%s]", util.Accented(lkConfig.Agent.ID)) err = lkConfig.SaveTOMLFile("", tomlFilename) return err } @@ -1000,7 +1003,7 @@ func rollbackAgent(ctx context.Context, cmd *cli.Command) error { return fmt.Errorf("failed to rollback agent %s", resp.Message) } - fmt.Printf("Rolled back agent [%s] to version [%s]\n", util.Accented(agentID), util.Accented(cmd.String("version"))) + out.Statusf("Rolled back agent [%s] to version [%s]", util.Accented(agentID), util.Accented(cmd.String("version"))) return nil } @@ -1036,10 +1039,9 @@ func deleteAgent(ctx context.Context, cmd *cli.Command) error { var confirmDelete bool if err := huh.NewForm( huh.NewGroup( - huh.NewConfirm(). + util.Confirm(). Title(fmt.Sprintf("Are you sure you want to delete agent [%s]?", agentID)). Value(&confirmDelete). - Inline(false). WithTheme(util.Theme), ), ).Run(); err != nil { @@ -1075,7 +1077,7 @@ func deleteAgent(ctx context.Context, cmd *cli.Command) error { return fmt.Errorf("failed to delete agent %s", res.Message) } - fmt.Printf("Deleted agent [%s]\n", util.Accented(agentID)) + out.Statusf("Deleted agent [%s]", util.Accented(agentID)) return nil } @@ -1130,7 +1132,7 @@ func listAgentVersions(ctx context.Context, cmd *cli.Command) error { table.Row(row...) } - fmt.Println(table) + out.Result(table) return nil } @@ -1164,7 +1166,7 @@ func listAgents(ctx context.Context, cmd *cli.Command) error { } if len(items) == 0 { - fmt.Println("No agents found") + out.Status("No agents found") return nil } @@ -1191,7 +1193,7 @@ func listAgents(ctx context.Context, cmd *cli.Command) error { Headers("ID", "Dispatch Name", "Regions", "Version", "Deployed At"). Rows(rows...) - fmt.Println(t) + out.Result(t) return nil } @@ -1225,7 +1227,7 @@ func listAgentSecrets(ctx context.Context, cmd *cli.Command) error { table.Row(secret.Name, secret.CreatedAt.AsTime().Format(time.RFC3339), secret.UpdatedAt.AsTime().Format(time.RFC3339)) } - fmt.Println(table) + out.Result(table) return nil } @@ -1246,10 +1248,9 @@ func updateAgentSecrets(ctx context.Context, cmd *cli.Command) error { if !SkipPrompts(cmd) { if err := huh.NewForm( huh.NewGroup( - huh.NewConfirm(). + util.Confirm(). Title(fmt.Sprintf("This will remove all existing secrets. Are you sure you want to proceed [%s]?", agentID)). Value(&confirmOverwrite). - Inline(false). WithTheme(util.Theme), ), ).Run(); err != nil { @@ -1276,7 +1277,7 @@ func updateAgentSecrets(ctx context.Context, cmd *cli.Command) error { } if resp.Success { - fmt.Println("Updated agent secrets") + out.Status("Updated agent secrets") return nil } @@ -1309,7 +1310,7 @@ func getAgentID(ctx context.Context, cmd *cli.Command, agentDir string, tomlFile return "", fmt.Errorf("agent ID or [%s] required", util.Accented(tomlFileName)) } - fmt.Printf("Using agent [%s]\n", util.Accented(agentID)) + out.Statusf("Using agent [%s]", util.Accented(agentID)) return agentID, nil } @@ -1414,7 +1415,7 @@ func requireSecrets(_ context.Context, cmd *cli.Command, required, lazy bool) ([ return nil, err } if file != "" && !silent { - fmt.Printf("Using secrets file [%s]\n", util.Accented(file)) + out.Statusf("Using secrets file [%s]", util.Accented(file)) } ignoreEmpty := cmd.Bool("ignore-empty-secrets") @@ -1444,7 +1445,7 @@ func requireSecrets(_ context.Context, cmd *cli.Command, required, lazy bool) ([ // Log skipped secrets if any (unless silent) if len(skippedEmpty) > 0 && !silent { skippedNames := strings.Join(skippedEmpty, ", ") - fmt.Printf("Skipped %d empty secret(s): %s\n", len(skippedEmpty), util.Dimmed(skippedNames)) + out.Statusf("Skipped %d empty secret(s): %s", len(skippedEmpty), util.Dimmed(skippedNames)) } } @@ -1492,7 +1493,7 @@ func requireDockerfile(ctx context.Context, cmd *cli.Command, workingDir string, if err != nil { return err } - fmt.Println("Created [" + util.Accented("Dockerfile") + "]") + out.Statusf("Created [%s]", util.Accented("Dockerfile")) } else { if err := agentfs.CreateDockerfile(workingDir, projectType, settingsMap, SkipPrompts(cmd)); err != nil { return err @@ -1500,21 +1501,21 @@ func requireDockerfile(ctx context.Context, cmd *cli.Command, workingDir string, } } else { if !cmd.Bool("silent") { - fmt.Println("Using existing Dockerfile") + out.Status("Using existing Dockerfile") } } if !dockerIgnoreExists { if !cmd.Bool("silent") { - fmt.Println("Creating .dockerignore...") + out.Status("Creating .dockerignore...") } if err := agentfs.CreateDockerIgnoreFile(workingDir, projectType); err != nil { return err } - fmt.Println("Created [" + util.Accented(".dockerignore") + "]") + out.Statusf("Created [%s]", util.Accented(".dockerignore")) } else { if !cmd.Bool("silent") { - fmt.Println("Using existing .dockerignore") + out.Status("Using existing .dockerignore") } } @@ -1593,7 +1594,7 @@ func resolveRegion(cmd *cli.Command, settingsMap map[string]string, title string Run(); err != nil { return "", err } - fmt.Fprintf(os.Stderr, "Using region [%s]\n", util.Accented(region)) + out.Statusf("Using region [%s]", util.Accented(region)) return region, nil } @@ -1626,7 +1627,7 @@ func generateAgentDockerfile(ctx context.Context, cmd *cli.Command) error { if err != nil { return noAgentError() } - fmt.Printf("Detected agent language [%s]\n", util.Accented(string(projectType))) + out.Statusf("Detected agent language [%s]", util.Accented(string(projectType))) dockerfilePath := filepath.Join(workingDir, "Dockerfile") dockerignorePath := filepath.Join(workingDir, ".dockerignore") @@ -1636,11 +1637,11 @@ func generateAgentDockerfile(ctx context.Context, cmd *cli.Command) error { writeDockerignore := true if !overwrite { if _, err := os.Stat(dockerfilePath); err == nil { - fmt.Println(util.Accented("Dockerfile") + " already exists; skipping. Use --overwrite to replace.") + out.Statusf("%s already exists; skipping. Use --overwrite to replace.", util.Accented("Dockerfile")) writeDockerfile = false } if _, err := os.Stat(dockerignorePath); err == nil { - fmt.Println(util.Accented(".dockerignore") + " already exists; skipping. Use --overwrite to replace.") + out.Statusf("%s already exists; skipping. Use --overwrite to replace.", util.Accented(".dockerignore")) writeDockerignore = false } } @@ -1660,14 +1661,14 @@ func generateAgentDockerfile(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Printf("Wrote new %s\n", util.Accented("Dockerfile")) + out.Statusf("Wrote new %s", util.Accented("Dockerfile")) } if writeDockerignore { if err := os.WriteFile(dockerignorePath, dockerignoreContent, 0644); err != nil { return err } - fmt.Printf("Wrote new %s\n", util.Accented(".dockerignore")) + out.Statusf("Wrote new %s", util.Accented(".dockerignore")) } return nil diff --git a/cmd/lk/agent_private_link.go b/cmd/lk/agent_private_link.go index 76e141aa..477dd24e 100644 --- a/cmd/lk/agent_private_link.go +++ b/cmd/lk/agent_private_link.go @@ -209,19 +209,19 @@ func createPrivateLink(ctx context.Context, cmd *cli.Command) error { } if resp.PrivateLink == nil { - fmt.Println("Private link created") + out.Status("Private link created") return nil } - fmt.Printf("Created private link [%s]\n", util.Accented(resp.PrivateLink.PrivateLinkId)) + out.Statusf("Created private link [%s]", util.Accented(resp.PrivateLink.PrivateLinkId)) if resp.PrivateLink.Endpoint != "" { - fmt.Printf("Endpoint [%s]\n", util.Accented(resp.PrivateLink.Endpoint)) + out.Statusf("Endpoint [%s]", util.Accented(resp.PrivateLink.Endpoint)) } if resp.PrivateLink.ConnectionEndpoint != "" { - fmt.Printf("Gateway DNS [%s]\n", util.Accented(resp.PrivateLink.ConnectionEndpoint)) + out.Statusf("Gateway DNS [%s]", util.Accented(resp.PrivateLink.ConnectionEndpoint)) } if resp.PrivateLink.CloudRegion != "" { - fmt.Printf("Cloud Region [%s]\n", util.Accented(resp.PrivateLink.CloudRegion)) + out.Statusf("Cloud Region [%s]", util.Accented(resp.PrivateLink.CloudRegion)) } return nil } @@ -275,13 +275,13 @@ func listPrivateLinks(ctx context.Context, cmd *cli.Command) error { } if len(resp.Items) == 0 { - fmt.Println("No private links found") + out.Status("No private links found") return nil } rows := buildPrivateLinkListRows(resp.Items, healthByID, healthErrByID) table := util.CreateTable().Headers("ID", "Name", "Region", "Cloud Region", "Port", "Endpoint", "DNS", "Health", "Updated At", "Reason").Rows(rows...) - fmt.Println(table) + out.Result(table) return nil } @@ -298,7 +298,7 @@ func deletePrivateLink(ctx context.Context, cmd *cli.Command) error { util.PrintJSON(resp) return nil } - fmt.Printf("Deleted private link [%s]\n", util.Accented(privateLinkID)) + out.Statusf("Deleted private link [%s]", util.Accented(privateLinkID)) return nil } @@ -328,6 +328,6 @@ func getPrivateLinkHealthStatus(ctx context.Context, cmd *cli.Command) error { table := util.CreateTable(). Headers("ID", "Health", "Updated At", "Reason"). Row(privateLinkID, formatPrivateLinkHealthStatus(resp.Value.Status), updatedAt, reason) - fmt.Println(table) + out.Result(table) return nil } diff --git a/cmd/lk/agent_reload.go b/cmd/lk/agent_reload.go index 9115a21d..b5a18293 100644 --- a/cmd/lk/agent_reload.go +++ b/cmd/lk/agent_reload.go @@ -1,5 +1,3 @@ -//go:build console - package main import ( @@ -46,13 +44,13 @@ func (rs *reloadServer) captureJobs(conn net.Conn) { }, } if err := ipc.WriteProto(conn, req); err != nil { - fmt.Printf("reload: failed to send capture request: %v\n", err) + out.Warnf("reload: failed to send capture request: %v", err) return } resp := &agent.AgentDevMessage{} if err := ipc.ReadProto(conn, resp); err != nil { - fmt.Printf("reload: failed to read capture response: %v\n", err) + out.Warnf("reload: failed to read capture response: %v", err) return } @@ -60,7 +58,7 @@ func (rs *reloadServer) captureJobs(conn net.Conn) { rs.mu.Lock() rs.savedJobs = jobs rs.mu.Unlock() - fmt.Printf("reload: captured %d running job(s)\n", len(jobs.Jobs)) + out.Statusf("reload: captured %d running job(s)", len(jobs.Jobs)) } } @@ -90,9 +88,9 @@ func (rs *reloadServer) serveNewProcess(conn net.Conn) { }, } if err := ipc.WriteProto(conn, resp); err != nil { - fmt.Printf("reload: failed to send restore response: %v\n", err) + out.Warnf("reload: failed to send restore response: %v", err) } else if len(saved.Jobs) > 0 { - fmt.Printf("reload: restored %d job(s) to new process\n", len(saved.Jobs)) + out.Statusf("reload: restored %d job(s) to new process", len(saved.Jobs)) } } diff --git a/cmd/lk/agent_run.go b/cmd/lk/agent_run.go index 7f2eadaf..404bf2b3 100644 --- a/cmd/lk/agent_run.go +++ b/cmd/lk/agent_run.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +17,6 @@ package main import ( "context" "fmt" - "io" "os" "os/signal" "path/filepath" @@ -35,15 +32,6 @@ func init() { AgentCommands[0].Commands = append(AgentCommands[0].Commands, startCommand, devCommand) } -var ( - outputToStderr = func(p *loadParams) { - p.output = os.Stderr - } - quietOutput = func(p *loadParams) { - p.output = io.Discard - } -) - var agentRunFlags = []cli.Flag{ &cli.StringFlag{ Name: "log-level", @@ -166,9 +154,9 @@ func runAgentStart(ctx context.Context, cmd *cli.Command) error { if err != nil { return err } - fmt.Fprintf(os.Stderr, "Detected %s agent (%s in %s)\n", projectType.Lang(), entrypoint, projectDir) + out.Statusf("Detected %s agent (%s in %s)", projectType.Lang(), entrypoint, projectDir) - cliArgs, err := buildCLIArgs("start", cmd, quietOutput) + cliArgs, err := buildCLIArgs("start", cmd) if err != nil { return err } @@ -209,7 +197,7 @@ func runAgentDev(ctx context.Context, cmd *cli.Command) error { return err } - cliArgs, err := buildCLIArgs("start", cmd, outputToStderr) + cliArgs, err := buildCLIArgs("start", cmd) if err != nil { return err } @@ -226,7 +214,7 @@ func runAgentDev(ctx context.Context, cmd *cli.Command) error { ForwardOutput: os.Stdout, } - fmt.Fprintf(os.Stderr, "Detected %s agent (%s in %s)\n", projectType.Lang(), entrypoint, projectDir) + out.Statusf("Detected %s agent (%s in %s)", projectType.Lang(), entrypoint, projectDir) // Take over signal handling from the global NotifyContext. signal.Reset(syscall.SIGINT, syscall.SIGTERM) diff --git a/cmd/lk/agent_watcher.go b/cmd/lk/agent_watcher.go index d81f9e5f..cdab465e 100644 --- a/cmd/lk/agent_watcher.go +++ b/cmd/lk/agent_watcher.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2021-2024 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -135,7 +133,7 @@ func (aw *agentWatcher) restart() error { aw.agent.Kill() } - fmt.Fprintln(os.Stderr, "Reloading agent...") + out.Status("Reloading agent...") // 3. Start new process agent, err := startAgent(aw.config) @@ -227,10 +225,10 @@ func (aw *agentWatcher) Run(done <-chan struct{}) error { case <-debounceCh: debounceTimer = nil debounceCh = nil - fmt.Fprintf(os.Stderr, "File changed: %s\n", changedFile) + out.Statusf("File changed: %s", changedFile) if err := aw.restart(); err != nil { - fmt.Fprintf(os.Stderr, "Failed to restart agent: %v\n", err) - fmt.Fprintln(os.Stderr, "Waiting for file changes...") + out.Warnf("Failed to restart agent: %v", err) + out.Status("Waiting for file changes...") } else { exitCh = aw.agent.exitCh } @@ -239,7 +237,7 @@ func (aw *agentWatcher) Run(done <-chan struct{}) error { if !ok { return nil } - fmt.Fprintf(os.Stderr, "Watcher error: %v\n", err) + out.Warnf("Watcher error: %v", err) case <-exitCh: // Nil the channel so this case won't fire again (nil channels block forever) @@ -250,7 +248,7 @@ func (aw *agentWatcher) Run(done <-chan struct{}) error { debounceTimer = nil debounceCh = nil } - fmt.Fprintln(os.Stderr, "Agent exited. Waiting for file changes to restart...") + out.Status("Agent exited. Waiting for file changes to restart...") } } } diff --git a/cmd/lk/app.go b/cmd/lk/app.go index 7b81deaf..0b985b71 100644 --- a/cmd/lk/app.go +++ b/cmd/lk/app.go @@ -130,26 +130,66 @@ func requireProject(ctx context.Context, cmd *cli.Command) (context.Context, err } func requireProjectWithOpts(ctx context.Context, cmd *cli.Command, opts ...loadOption) (context.Context, error) { - var err error if project != nil { + // already resolved (and announced) earlier in this command return ctx, nil } + var err error if ctx, err = loadProjectConfig(ctx, cmd); err != nil { // something is wrong with CLI config file return ctx, err } - if project, err = loadProjectDetails(cmd, opts...); err != nil { - // something is wrong with project config file - if errors.Is(err, config.ErrInvalidConfig) { + + p := loadParams{requireURL: true} + for _, opt := range opts { + opt(&p) + } + + rp, err := resolveProject(cmd, p) + switch { + case errors.Is(err, config.ErrInvalidConfig): + // something is wrong with the project config file + return ctx, err + case err != nil: + // no project could be resolved automatically; choose from existing + // credentials or authenticate, then announce once below. + if ctx, err = selectProject(ctx, cmd); err != nil { return ctx, err } - // choose from existing credentials or authenticate - return selectProject(ctx, cmd) + rp = &resolvedProject{project: project, source: sourceSelected} + default: + // when asked to confirm, let the user accept the resolved default or pick another + if p.confirmProject && rp.source == sourceDefault && !SkipPrompts(cmd) && + !cmd.Bool("silent") && cliConfig != nil && len(cliConfig.Projects) > 1 { + useDefault := true + if err = huh.NewForm(huh.NewGroup(util.Confirm(). + Title(fmt.Sprintf("Use project [%s] (%s)?", rp.project.Name, rp.project.URL)). + Value(&useDefault). + Options( + huh.NewOption("Yes", true), + huh.NewOption("No, select another...", false), + ). + WithTheme(util.Theme))). + Run(); err != nil { + return ctx, fmt.Errorf("failed to confirm project: %w", err) + } + if !useDefault { + if ctx, err = selectProject(ctx, cmd); err != nil { + return ctx, err + } + rp = &resolvedProject{project: project, source: sourceSelected} + } + } + project = rp.project } - return ctx, err + rp.announce() + return ctx, nil } +// selectProject resolves the package-level `project` interactively: it picks from the +// configured projects, or (when none exist) offers to authenticate one via `lk cloud auth`. +// It does not print a confirmation; the caller announces the result exactly once. func selectProject(ctx context.Context, cmd *cli.Command) (context.Context, error) { var err error @@ -157,7 +197,6 @@ func selectProject(ctx context.Context, cmd *cli.Command) (context.Context, erro if SkipPrompts(cmd) { if len(cliConfig.Projects) == 1 { project = &cliConfig.Projects[0] - fmt.Fprintf(os.Stderr, "Using project [%s]\n", util.Accented(project.Name)) return ctx, nil } return nil, fmt.Errorf("multiple projects configured; set --project in non-interactive mode") @@ -176,31 +215,33 @@ func selectProject(ctx context.Context, cmd *cli.Command) (context.Context, erro Run(); err != nil { return nil, fmt.Errorf("no project selected: %w", err) } - fmt.Fprintf(os.Stderr, "Using project [%s]\n", util.Accented(project.Name)) - } else { - if SkipPrompts(cmd) { - return nil, fmt.Errorf("no projects configured; run `lk cloud auth` in an interactive terminal or set --project") - } - shouldAuth := true - if err = huh.NewForm(huh.NewGroup(huh.NewConfirm(). - Title("No local projects found. Authenticate one?"). - Inline(true). - Value(&shouldAuth). - WithTheme(util.Theme))). - Run(); err != nil { - return nil, fmt.Errorf("no project selected: %w", err) - } - if shouldAuth { - initAuth(ctx, cmd) - if err = tryAuthIfNeeded(ctx, cmd); err != nil { - return nil, fmt.Errorf("authentication failed: %w", err) - } - return requireProject(ctx, cmd) - } else { - return nil, ErrNoProjectSelected - } + return ctx, nil } + if SkipPrompts(cmd) { + return nil, fmt.Errorf("no projects configured; run `lk cloud auth` in an interactive terminal or set --project") + } + shouldAuth := true + if err = huh.NewForm(huh.NewGroup(util.Confirm(). + Title("No local projects found. Authenticate one?"). + Value(&shouldAuth). + WithTheme(util.Theme))). + Run(); err != nil { + return nil, fmt.Errorf("no project selected: %w", err) + } + if !shouldAuth { + return nil, ErrNoProjectSelected + } + initAuth(ctx, cmd) + if err = tryAuthIfNeeded(ctx, cmd); err != nil { + return nil, fmt.Errorf("authentication failed: %w", err) + } + // pick up the project just added by `lk cloud auth` + dp, err := config.LoadDefaultProject() + if err != nil { + return nil, ErrNoProjectSelected + } + project = dp return ctx, nil } @@ -224,7 +265,7 @@ func listTemplates(ctx context.Context, cmd *cli.Command) error { desc+"\n\n"+url+"\n"+tags, ) } - fmt.Println(table) + out.Result(table) } return nil } @@ -347,7 +388,7 @@ func setupTemplate(ctx context.Context, cmd *cli.Command) error { os.Setenv("LIVEKIT_AGENT_NAME", appName) os.Setenv("LIVEKIT_PROJECT_ID", project.ProjectId) - fmt.Println("Cloning template...") + out.Status("Cloning template...") if err := cloneTemplate(ctx, cmd, templateURL, appName); err != nil { return err } @@ -357,7 +398,7 @@ func setupTemplate(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Println("Instantiating environment...") + out.Status("Instantiating environment...") addlEnv := &map[string]string{ "LIVEKIT_SANDBOX_ID": sandboxID, "NEXT_PUBLIC_LIVEKIT_SANDBOX_ID": sandboxID, @@ -384,19 +425,18 @@ func setupTemplate(ctx context.Context, cmd *cli.Command) error { bootstrap.WriteDotEnv(appName, envOutputFile, env, true) if !cmd.IsSet("install") && !SkipPrompts(cmd) { - if err := huh.NewConfirm(). + if err := huh.NewForm(huh.NewGroup(util.Confirm(). Title("Install dependencies?"). Value(&install). - Inline(true). - WithTheme(util.Theme). + WithTheme(util.Theme))). Run(); err != nil { return err } } if install { - fmt.Println("Installing template...") + out.Status("Installing template...") if err := doInstall(ctx, bootstrap.TaskInstall, appName, verbose); err != nil { - fmt.Fprintf(os.Stderr, "Warning: installation failed: %v\n", err) + out.Warnf("Warning: installation failed: %v", err) } } if err := doPostCreate(ctx, cmd, appName, verbose); err != nil { @@ -424,11 +464,15 @@ func cloneTemplate(ctx context.Context, cmd *cli.Command, url, appName string) e ) // err is handled after checking stdout and stderr - if len(stdout) > 0 && cmd.Bool("verbose") { - fmt.Println(string(stdout)) - } - if len(stderr) > 0 && cmd.Bool("verbose") { - fmt.Fprintln(os.Stderr, string(stderr)) + if cmd.Bool("verbose") { + // Subprocess output forwarded verbatim under --verbose; raw writes preserve + // any embedded formatting and skip the Printer's quiet/newline handling. + if len(stdout) > 0 { + fmt.Fprint(out.Out, stdout) + } + if len(stderr) > 0 { + fmt.Fprint(out.Err, stderr) + } } if err != nil { @@ -542,7 +586,7 @@ func doPostCreate(ctx context.Context, _ *cli.Command, rootPath string, verbose return nil } - fmt.Println("Cleaning up...") + out.Status("Cleaning up...") return task() } diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go index d7a5b0bf..30f19d04 100644 --- a/cmd/lk/cloud.go +++ b/cmd/lk/cloud.go @@ -269,10 +269,10 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { if err := cliConfig.PersistIfNeeded(); err != nil { return err } - fmt.Printf("Device [%s]\n", util.Accented(cliConfig.DeviceName)) + out.Statusf("Device [%s]", util.Accented(cliConfig.DeviceName)) // request token - fmt.Println("Requesting verification token...") + out.Status("Requesting verification token...") token, err := authClient.GetVerificationToken(cliConfig.DeviceName) if err != nil { return err @@ -284,7 +284,7 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { } // poll for keys - fmt.Printf("Please confirm access by visiting:\n\n %s\n\n", authURL.String()) + out.Statusf("Please confirm access by visiting:\n\n %s\n", authURL.String()) _ = browser.OpenURL(authURL.String()) // discard result; this will fail in headless environments var ak *ClaimAccessKeyResponse @@ -305,16 +305,15 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { return errors.New("operation cancelled") } - fmt.Printf("Authenticated project [%s]\n", util.Accented(ak.ProjectName)) + out.Statusf("Authenticated project [%s]", util.Accented(ak.ProjectName)) // if other authed projects, ask if this should be the default project isDefault := len(cliConfig.Projects) == 0 if !isDefault { - if err := huh.NewConfirm(). + if err := huh.NewForm(huh.NewGroup(util.Confirm(). Title("Make this project default?"). Value(&isDefault). - Inline(true). - WithTheme(util.Theme). + WithTheme(util.Theme))). Run(); err != nil { return err } diff --git a/cmd/lk/console.go b/cmd/lk/console.go index 11d5b86a..990ef13f 100644 --- a/cmd/lk/console.go +++ b/cmd/lk/console.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -126,8 +124,8 @@ func runConsole(ctx context.Context, cmd *cli.Command) error { actualAddr := server.Addr().String() if inputDev != nil { - fmt.Fprintf(os.Stderr, "Input: %s\n", inputDev.Name) - fmt.Fprintf(os.Stderr, "Output: %s\n", outputDev.Name) + out.Statusf("Input: %s", inputDev.Name) + out.Statusf("Output: %s", outputDev.Name) } projectDir, projectType, entrypoint, err := detectProject(cmd) @@ -135,7 +133,7 @@ func runConsole(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Fprintf(os.Stderr, "Detected %s agent (%s in %s)\n", projectType.Lang(), entrypoint, projectDir) + out.Statusf("Detected %s agent (%s in %s)", projectType.Lang(), entrypoint, projectDir) // Show spinner while starting agent stopSpinner := startSpinner("Starting agent") @@ -253,8 +251,8 @@ func listDevices() error { headerStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("6")) defaultStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("2")) - fmt.Println(headerStyle.Render(fmt.Sprintf(" %-4s %-8s %-45s %s", "#", "Type", "Name", "Default"))) - fmt.Println(strings.Repeat("─", 70)) + out.Result(headerStyle.Render(fmt.Sprintf(" %-4s %-8s %-45s %s", "#", "Type", "Name", "Default"))) + out.Result(strings.Repeat("─", 70)) for _, d := range devices { devType := "" @@ -277,9 +275,8 @@ func listDevices() error { defStr += defaultStyle.Render("✓ output") } - fmt.Printf(" %-4d %-8s %-45s %s\n", d.Index, devType, d.Name, defStr) + out.Resultf(" %-4d %-8s %-45s %s\n", d.Index, devType, d.Name, defStr) } return nil } - diff --git a/cmd/lk/console_stub.go b/cmd/lk/console_stub.go deleted file mode 100644 index 9b3deb31..00000000 --- a/cmd/lk/console_stub.go +++ /dev/null @@ -1,6 +0,0 @@ -//go:build !console - -package main - -// No-op: start, dev, console, and simulate commands are only available -// when built with the console tag (go build -tags console). diff --git a/cmd/lk/console_tui.go b/cmd/lk/console_tui.go index 668d8530..a074d08d 100644 --- a/cmd/lk/console_tui.go +++ b/cmd/lk/console_tui.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cmd/lk/dispatch.go b/cmd/lk/dispatch.go index 52569614..7e573915 100644 --- a/cmd/lk/dispatch.go +++ b/cmd/lk/dispatch.go @@ -17,7 +17,6 @@ package main import ( "context" "errors" - "fmt" "github.com/urfave/cli/v3" @@ -156,7 +155,7 @@ func listDispatchAndPrint(cmd *cli.Command, req *livekit.ListAgentDispatchReques item.Metadata, ) } - fmt.Println(table) + out.Result(table) } return nil } @@ -190,7 +189,7 @@ func createAgentDispatch(ctx context.Context, cmd *cli.Command) error { if cmd.Bool("json") { util.PrintJSON(info) } else { - fmt.Printf("Dispatch created: %v\n", info) + out.Resultf("Dispatch created: %v\n", info) } return nil @@ -221,7 +220,7 @@ func deleteAgentDispatch(ctx context.Context, cmd *cli.Command) error { if cmd.Bool("json") { util.PrintJSON(info) } else { - fmt.Printf("Dispatch deleted: %v\n", info) + out.Resultf("Dispatch deleted: %v\n", info) } return nil } diff --git a/cmd/lk/docs.go b/cmd/lk/docs.go index 241bc9d5..5d9511ec 100644 --- a/cmd/lk/docs.go +++ b/cmd/lk/docs.go @@ -19,7 +19,6 @@ import ( "errors" "fmt" "net/http" - "os" "strconv" "strings" "time" @@ -429,7 +428,7 @@ func callDocsToolAndPrint(ctx context.Context, cmd *cli.Command, tool string, ar for _, c := range result.Content { if tc, ok := c.(*mcp.TextContent); ok { - fmt.Println(tc.Text) + out.Result(tc.Text) } } return nil @@ -509,8 +508,8 @@ func checkServerVersion(session *mcp.ClientSession) { return } if major > expectedServerVersion[0] || (major == expectedServerVersion[0] && minor > expectedServerVersion[1]) { - fmt.Fprintf(os.Stderr, - "warning: the LiveKit docs server is version %s but this CLI was built for %d.%d.x — consider updating lk to the latest version\n\n", + out.Warnf( + "warning: the LiveKit docs server is version %s but this CLI was built for %d.%d.x — consider updating lk to the latest version\n", info.ServerInfo.Version, expectedServerVersion[0], expectedServerVersion[1], ) } diff --git a/cmd/lk/egress.go b/cmd/lk/egress.go index 0680743f..8d7ecdfc 100644 --- a/cmd/lk/egress.go +++ b/cmd/lk/egress.go @@ -641,7 +641,7 @@ func listEgress(ctx context.Context, cmd *cli.Command) error { item.Error, ) } - fmt.Println(table) + out.Result(table) } return nil @@ -691,9 +691,9 @@ func stopEgress(ctx context.Context, cmd *cli.Command) error { }) if err != nil { errors = append(errors, err) - fmt.Println("Error stopping Egress", id, err) + out.Warnf("Error stopping Egress %s: %v", id, err) } else { - fmt.Println("Stopping Egress", id) + out.Statusf("Stopping Egress %s", id) } } if len(errors) != 0 { @@ -767,7 +767,7 @@ func testEgressTemplate(ctx context.Context, cmd *cli.Command) error { Testers: testers, }) sim.Start() - fmt.Println("simulating speakers...") + out.Status("simulating speakers...") <-done @@ -780,8 +780,8 @@ func testEgressTemplate(ctx context.Context, cmd *cli.Command) error { func printInfo(info *livekit.EgressInfo) { if info.Error == "" { - fmt.Printf("EgressID: %v Status: %v\n", info.EgressId, info.Status) + out.Resultf("EgressID: %v Status: %v\n", info.EgressId, info.Status) } else { - fmt.Printf("EgressID: %v Error: %v\n", info.EgressId, info.Error) + out.Resultf("EgressID: %v Error: %v\n", info.EgressId, info.Error) } } diff --git a/cmd/lk/ingress.go b/cmd/lk/ingress.go index 61823a52..9e84472e 100644 --- a/cmd/lk/ingress.go +++ b/cmd/lk/ingress.go @@ -16,7 +16,6 @@ package main import ( "context" - "fmt" "github.com/urfave/cli/v3" @@ -247,7 +246,7 @@ func listIngress(ctx context.Context, cmd *cli.Command) error { errorStr, ) } - fmt.Println(table) + out.Result(table) } return nil @@ -278,9 +277,9 @@ func printIngressInfo(info *livekit.IngressInfo) { } if errorStr == "" { - fmt.Printf("IngressID: %v Status: %v\n", info.IngressId, status) - fmt.Printf("URL: %v Stream Key: %s\n", info.Url, info.StreamKey) + out.Resultf("IngressID: %v Status: %v\n", info.IngressId, status) + out.Resultf("URL: %v Stream Key: %s\n", info.Url, info.StreamKey) } else { - fmt.Printf("IngressID: %v Error: %v\n", info.IngressId, errorStr) + out.Resultf("IngressID: %v Error: %v\n", info.IngressId, errorStr) } } diff --git a/cmd/lk/join.go b/cmd/lk/join.go index a00c46f8..a62db304 100644 --- a/cmd/lk/join.go +++ b/cmd/lk/join.go @@ -184,7 +184,7 @@ func _deprecatedJoinRoom(ctx context.Context, cmd *cli.Command) error { return } if pub != nil { - fmt.Printf("finished writing %s\n", pub.Name()) + out.Statusf("finished writing %s", pub.Name()) _ = room.LocalParticipant.UnpublishTrack(pub.SID()) } } @@ -618,6 +618,6 @@ func handleSimulcastPublish(room *lksdk.Room, urls []string, fps float64, h26xSt return fmt.Errorf("failed to publish simulcast track: %w", err) } - fmt.Printf("Successfully published %s simulcast track with qualities: %v\n", strings.ToUpper(codec), trackNames) + out.Statusf("Successfully published %s simulcast track with qualities: %v", strings.ToUpper(codec), trackNames) return nil } diff --git a/cmd/lk/main.go b/cmd/lk/main.go index 5c491e6e..1e59c142 100644 --- a/cmd/lk/main.go +++ b/cmd/lk/main.go @@ -29,6 +29,7 @@ import ( lksdk "github.com/livekit/server-sdk-go/v2" livekitcli "github.com/livekit/livekit-cli/v2" + "github.com/livekit/livekit-cli/v2/pkg/util" ) func main() { @@ -99,6 +100,9 @@ func main() { func checkForLegacyName() { if !strings.HasSuffix(os.Args[0], "lk") && !strings.HasSuffix(os.Args[0], "lk.exe") { + // Stays on raw os.Stderr: this runs before the cli command parses (so the + // Printer isn't initialized yet) and is a deprecation warning that should + // not be suppressed by --quiet. fmt.Fprintf( os.Stderr, "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPRECATION NOTICE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"+ @@ -123,11 +127,15 @@ func initLogger(ctx context.Context, cmd *cli.Command) (context.Context, error) logger.InitFromConfig(logConfig, "lk") lksdk.SetLogger(logger.GetLogger()) + // Bind the human-facing output sink to the root command's writers (cli/v3 + // defaults them to os.Stdout / os.Stderr, but they're overridable in tests). + out = util.NewPrinter(cmd.Root().Writer, cmd.Root().ErrWriter, cmd.Bool("quiet")) + return nil, nil } func generateFishCompletion(ctx context.Context, cmd *cli.Command) error { - fishScript, err := cmd.ToFishCompletion() + fishScript, err := cmd.Root().ToFishCompletion() if err != nil { return err } @@ -138,7 +146,7 @@ func generateFishCompletion(ctx context.Context, cmd *cli.Command) error { return err } } else { - fmt.Println(fishScript) + out.Result(fishScript) } return nil diff --git a/cmd/lk/phone_number.go b/cmd/lk/phone_number.go index 124421e5..d4be2b0a 100644 --- a/cmd/lk/phone_number.go +++ b/cmd/lk/phone_number.go @@ -21,6 +21,7 @@ import ( "github.com/livekit/livekit-cli/v2/pkg/util" "github.com/livekit/protocol/livekit" + "github.com/livekit/protocol/logger" lksdk "github.com/livekit/server-sdk-go/v2" "github.com/urfave/cli/v3" ) @@ -158,11 +159,7 @@ func createPhoneNumberClient(ctx context.Context, cmd *cli.Command) (*lksdk.Phon return nil, err } - // Debug: Print the URL being used - if cmd.Bool("verbose") { - fmt.Printf("Using phone number service URL: %s\n", project.URL) - } - + logger.Debugw("phone number client", "service-url", project.URL) return lksdk.NewPhoneNumberClient(project.URL, project.APIKey, project.APISecret, withDefaultClientOpts(project)...), nil } @@ -250,13 +247,13 @@ func purchasePhoneNumbers(ctx context.Context, cmd *cli.Command) error { return nil } - fmt.Printf("Successfully purchased %d phone numbers:\n", len(resp.PhoneNumbers)) + out.Resultf("Successfully purchased %d phone numbers:\n", len(resp.PhoneNumbers)) for _, phoneNumber := range resp.PhoneNumbers { ruleInfo := "" if len(phoneNumber.SipDispatchRuleIds) > 0 { ruleInfo = fmt.Sprintf(" (SIP Dispatch Rules: %s)", strings.Join(phoneNumber.SipDispatchRuleIds, ", ")) } - fmt.Printf(" %s (%s) - %s%s\n", phoneNumber.E164Format, phoneNumber.Id, strings.TrimPrefix(phoneNumber.Status.String(), "PHONE_NUMBER_STATUS_"), ruleInfo) + out.Resultf(" %s (%s) - %s%s\n", phoneNumber.E164Format, phoneNumber.Id, strings.TrimPrefix(phoneNumber.Status.String(), "PHONE_NUMBER_STATUS_"), ruleInfo) } return nil @@ -305,20 +302,20 @@ func listPhoneNumbers(ctx context.Context, cmd *cli.Command) error { return nil } - fmt.Printf("Total phone numbers: %d", resp.TotalCount) + out.Resultf("Total phone numbers: %d", resp.TotalCount) if resp.OfflineCount > 0 { - fmt.Printf(" (%d offline)", resp.OfflineCount) + out.Resultf(" (%d offline)", resp.OfflineCount) } - fmt.Printf("\n") + out.Resultf("\n") // Show pagination info if offset > 0 { - fmt.Printf("Showing results from offset %d\n", offset) + out.Resultf("Showing results from offset %d\n", offset) } if resp.NextPageToken != nil { nextOffset, _, err := livekit.DecodeTokenPagination(resp.NextPageToken) if err == nil { - fmt.Printf("More results available. Use --offset %d to see the next page.\n", nextOffset) + out.Resultf("More results available. Use --offset %d to see the next page.\n", nextOffset) } } @@ -389,19 +386,19 @@ func getPhoneNumber(ctx context.Context, cmd *cli.Command) error { dispatchRulesStr = "-" } - fmt.Printf("Phone Number Details:\n") - fmt.Printf(" ID: %s\n", item.Id) - fmt.Printf(" E164 Format: %s\n", item.E164Format) - fmt.Printf(" Country: %s\n", item.CountryCode) - fmt.Printf(" Area Code: %s\n", item.AreaCode) - fmt.Printf(" Type: %s\n", strings.TrimPrefix(item.NumberType.String(), "PHONE_NUMBER_TYPE_")) - fmt.Printf(" Locality: %s\n", item.Locality) - fmt.Printf(" Region: %s\n", item.Region) - fmt.Printf(" Capabilities: %s\n", strings.Join(item.Capabilities, ",")) - fmt.Printf(" Status: %s\n", strings.TrimPrefix(item.Status.String(), "PHONE_NUMBER_STATUS_")) - fmt.Printf(" SIP Dispatch Rules: %s\n", dispatchRulesStr) + out.Resultf("Phone Number Details:\n") + out.Resultf(" ID: %s\n", item.Id) + out.Resultf(" E164 Format: %s\n", item.E164Format) + out.Resultf(" Country: %s\n", item.CountryCode) + out.Resultf(" Area Code: %s\n", item.AreaCode) + out.Resultf(" Type: %s\n", strings.TrimPrefix(item.NumberType.String(), "PHONE_NUMBER_TYPE_")) + out.Resultf(" Locality: %s\n", item.Locality) + out.Resultf(" Region: %s\n", item.Region) + out.Resultf(" Capabilities: %s\n", strings.Join(item.Capabilities, ",")) + out.Resultf(" Status: %s\n", strings.TrimPrefix(item.Status.String(), "PHONE_NUMBER_STATUS_")) + out.Resultf(" SIP Dispatch Rules: %s\n", dispatchRulesStr) if item.ReleasedAt != nil { - fmt.Printf(" Released At: %s\n", item.ReleasedAt.AsTime().Format("2006-01-02 15:04:05")) + out.Resultf(" Released At: %s\n", item.ReleasedAt.AsTime().Format("2006-01-02 15:04:05")) } return nil @@ -453,11 +450,11 @@ func updatePhoneNumber(ctx context.Context, cmd *cli.Command) error { dispatchRulesStr = "-" } - fmt.Printf("Successfully updated phone number:\n") - fmt.Printf(" ID: %s\n", item.Id) - fmt.Printf(" E164 Format: %s\n", item.E164Format) - fmt.Printf(" Status: %s\n", strings.TrimPrefix(item.Status.String(), "PHONE_NUMBER_STATUS_")) - fmt.Printf(" SIP Dispatch Rules: %s\n", dispatchRulesStr) + out.Resultf("Successfully updated phone number:\n") + out.Resultf(" ID: %s\n", item.Id) + out.Resultf(" E164 Format: %s\n", item.E164Format) + out.Resultf(" Status: %s\n", strings.TrimPrefix(item.Status.String(), "PHONE_NUMBER_STATUS_")) + out.Resultf(" SIP Dispatch Rules: %s\n", dispatchRulesStr) return nil } @@ -491,9 +488,9 @@ func releasePhoneNumbers(ctx context.Context, cmd *cli.Command) error { } if len(ids) > 0 { - fmt.Printf("Successfully released %d phone numbers by ID: %s\n", len(ids), strings.Join(ids, ", ")) + out.Resultf("Successfully released %d phone numbers by ID: %s\n", len(ids), strings.Join(ids, ", ")) } else { - fmt.Printf("Successfully released %d phone numbers: %s\n", len(phoneNumbers), strings.Join(phoneNumbers, ", ")) + out.Resultf("Successfully released %d phone numbers: %s\n", len(phoneNumbers), strings.Join(phoneNumbers, ", ")) } return nil diff --git a/cmd/lk/proc_unix.go b/cmd/lk/proc_unix.go index 1d2a8927..23b24a80 100644 --- a/cmd/lk/proc_unix.go +++ b/cmd/lk/proc_unix.go @@ -1,4 +1,4 @@ -//go:build console && !windows +//go:build !windows package main diff --git a/cmd/lk/proc_windows.go b/cmd/lk/proc_windows.go index f827c68f..f102eb48 100644 --- a/cmd/lk/proc_windows.go +++ b/cmd/lk/proc_windows.go @@ -1,4 +1,4 @@ -//go:build console && windows +//go:build windows package main diff --git a/cmd/lk/project.go b/cmd/lk/project.go index cfaeadd8..85039005 100644 --- a/cmd/lk/project.go +++ b/cmd/lk/project.go @@ -17,7 +17,6 @@ package main import ( "context" "errors" - "fmt" "net/url" "regexp" @@ -162,7 +161,7 @@ func addProject(ctx context.Context, cmd *cli.Command) error { if err = validateName(p.Name); err != nil { return err } - fmt.Println(" Project Name:", p.Name) + out.Statusf(" Project Name: %s", p.Name) } else { prompts = append(prompts, huh.NewInput(). Title("Project Name"). @@ -183,7 +182,7 @@ func addProject(ctx context.Context, cmd *cli.Command) error { if err = validateURL(p.URL); err != nil { return err } - fmt.Println(" URL:", p.URL) + out.Statusf(" URL: %s", p.URL) } else { prompts = append(prompts, huh.NewInput(). Title("Project URL"). @@ -203,7 +202,7 @@ func addProject(ctx context.Context, cmd *cli.Command) error { if err = validateKey(p.APIKey); err != nil { return err } - fmt.Println(" API Key:", p.APIKey) + out.Statusf(" API Key: %s", p.APIKey) } else { prompts = append(prompts, huh.NewInput(). Title("API Key"). @@ -217,7 +216,7 @@ func addProject(ctx context.Context, cmd *cli.Command) error { if err = validateKey(p.APISecret); err != nil { return err } - fmt.Println(" API Secret:", p.APISecret) + out.Statusf(" API Secret: %s", p.APISecret) } else { prompts = append(prompts, huh.NewInput(). Title("API Secret"). @@ -231,10 +230,9 @@ func addProject(ctx context.Context, cmd *cli.Command) error { if cmd.Bool("default") || defaultProject == nil { cliConfig.DefaultProject = p.Name } else if !cmd.IsSet("default") { - prompts = append(prompts, huh.NewConfirm(). + prompts = append(prompts, util.Confirm(). Title("Make this project default?"). Value(&isDefault). - Inline(true). WithTheme(util.Theme)) } @@ -268,7 +266,7 @@ func addProject(ctx context.Context, cmd *cli.Command) error { func listProjects(ctx context.Context, cmd *cli.Command) error { if len(cliConfig.Projects) == 0 { - fmt.Println("No projects configured, use `lk cloud auth` to authenticate a new project.") + out.Status("No projects configured, use `lk cloud auth` to authenticate a new project.") return nil } @@ -300,7 +298,7 @@ func listProjects(ctx context.Context, cmd *cli.Command) error { } table.Row(pName, p.ProjectId, p.URL, p.APIKey) } - fmt.Println(table) + out.Result(table) } return nil @@ -331,7 +329,7 @@ func setDefaultProject(ctx context.Context, cmd *cli.Command) error { if err := cliConfig.PersistIfNeeded(); err != nil { return err } - fmt.Println("Default project set to [" + util.Theme.Focused.Title.Render(p.Name) + "]") + out.Statusf("Default project set to [%s]", util.Accented(p.Name)) return nil } diff --git a/cmd/lk/proto.go b/cmd/lk/proto.go index adda4ea7..8e3f9705 100644 --- a/cmd/lk/proto.go +++ b/cmd/lk/proto.go @@ -243,7 +243,7 @@ func listAndPrint[ } table.Row(row...) } - fmt.Println(table) + out.Result(table) } return nil diff --git a/cmd/lk/replay.go b/cmd/lk/replay.go index 917f10a7..aa314838 100644 --- a/cmd/lk/replay.go +++ b/cmd/lk/replay.go @@ -181,7 +181,7 @@ func listReplays(ctx context.Context, cmd *cli.Command) error { for _, info := range res.Replays { table.Row(info.ReplayId, info.RoomName, fmt.Sprint(time.Unix(0, info.StartTime))) } - fmt.Println(table) + out.Result(table) } return nil @@ -210,7 +210,7 @@ func playback(ctx context.Context, cmd *cli.Command) error { if err != nil { return err } - fmt.Println("PlaybackID:", res.PlaybackId) + out.Resultf("PlaybackID: %s\n", res.PlaybackId) return nil } diff --git a/cmd/lk/room.go b/cmd/lk/room.go index 529cdc47..1b79913d 100644 --- a/cmd/lk/room.go +++ b/cmd/lk/room.go @@ -22,7 +22,6 @@ import ( "os" "os/signal" "regexp" - "strings" "syscall" "github.com/pion/webrtc/v4" @@ -677,32 +676,32 @@ func createRoom(ctx context.Context, cmd *cli.Command) error { } if cmd.Uint("min-playout-delay") != 0 { - fmt.Printf("setting min playout delay: %d\n", cmd.Uint("min-playout-delay")) + out.Statusf("setting min playout delay: %d", cmd.Uint("min-playout-delay")) req.MinPlayoutDelay = uint32(cmd.Uint("min-playout-delay")) } if maxPlayoutDelay := cmd.Uint("max-playout-delay"); maxPlayoutDelay != 0 { - fmt.Printf("setting max playout delay: %d\n", maxPlayoutDelay) + out.Statusf("setting max playout delay: %d", maxPlayoutDelay) req.MaxPlayoutDelay = uint32(maxPlayoutDelay) } if syncStreams := cmd.Bool("sync-streams"); syncStreams { - fmt.Printf("setting sync streams: %t\n", syncStreams) + out.Statusf("setting sync streams: %t", syncStreams) req.SyncStreams = syncStreams } if emptyTimeout := cmd.Uint("empty-timeout"); emptyTimeout != 0 { - fmt.Printf("setting empty timeout: %d\n", emptyTimeout) + out.Statusf("setting empty timeout: %d", emptyTimeout) req.EmptyTimeout = uint32(emptyTimeout) } if departureTimeout := cmd.Uint("departure-timeout"); departureTimeout != 0 { - fmt.Printf("setting departure timeout: %d\n", departureTimeout) + out.Statusf("setting departure timeout: %d", departureTimeout) req.DepartureTimeout = uint32(departureTimeout) } if replayEnabled := cmd.Bool("replay-enabled"); replayEnabled { - fmt.Printf("setting replay enabled: %t\n", replayEnabled) + out.Statusf("setting replay enabled: %t", replayEnabled) req.ReplayEnabled = replayEnabled } @@ -717,11 +716,8 @@ func createRoom(ctx context.Context, cmd *cli.Command) error { func listRooms(ctx context.Context, cmd *cli.Command) error { names, _ := extractArgs(cmd) - if cmd.Bool("verbose") && len(names) > 0 { - fmt.Printf( - "Querying rooms matching %s", - strings.Join(util.MapStrings(names, util.WrapWith("\"")), ", "), - ) + if len(names) > 0 { + logger.Debugw("querying rooms", "names", names) } req := livekit.ListRoomsRequest{} @@ -746,7 +742,7 @@ func listRooms(ctx context.Context, cmd *cli.Command) error { fmt.Sprintf("%d", rm.NumPublishers), ) } - fmt.Println(table) + out.Result(table) } return nil @@ -760,7 +756,7 @@ func _deprecatedListRoom(ctx context.Context, cmd *cli.Command) error { return err } if len(res.Rooms) == 0 { - fmt.Printf("there is no matching room with name: %s\n", cmd.String("room")) + out.Statusf("there is no matching room with name: %s", cmd.String("room")) return nil } rm := res.Rooms[0] @@ -781,7 +777,7 @@ func deleteRoom(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Println("deleted room", roomId) + out.Statusf("deleted room %s", roomId) return nil } @@ -795,7 +791,7 @@ func updateRoomMetadata(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Println("Updated room metadata") + out.Status("Updated room metadata") util.PrintJSON(res) return nil } @@ -810,7 +806,7 @@ func _deprecatedUpdateRoomMetadata(ctx context.Context, cmd *cli.Command) error return err } - fmt.Println("Updated room metadata") + out.Status("Updated room metadata") util.PrintJSON(res) return nil } @@ -864,7 +860,7 @@ func joinRoom(ctx context.Context, cmd *cli.Command) error { participantIdentity := cmd.String("identity") if participantIdentity == "" { participantIdentity = util.ExpandTemplate("participant-%x") - fmt.Printf("Using generated participant identity [%s]\n", util.Accented(participantIdentity)) + out.Statusf("Using generated participant identity [%s]", util.Accented(participantIdentity)) } autoSubscribe := cmd.Bool("auto-subscribe") @@ -1015,7 +1011,7 @@ func joinRoom(ctx context.Context, cmd *cli.Command) error { return } if pub != nil { - fmt.Printf("finished simulcast stream %s\n", pub.Name()) + out.Statusf("finished simulcast stream %s", pub.Name()) _ = room.LocalParticipant.UnpublishTrack(pub.SID()) } } @@ -1034,7 +1030,7 @@ func joinRoom(ctx context.Context, cmd *cli.Command) error { return } if pub != nil { - fmt.Printf("finished writing %s\n", pub.Name()) + out.Statusf("finished writing %s", pub.Name()) _ = room.LocalParticipant.UnpublishTrack(pub.SID()) } } @@ -1104,7 +1100,7 @@ func listParticipants(ctx context.Context, cmd *cli.Command) error { } for _, p := range res.Participants { - fmt.Printf("%s (%s)\t tracks: %d\n", p.Identity, p.State.String(), len(p.Tracks)) + out.Resultf("%s (%s)\t tracks: %d\n", p.Identity, p.State.String(), len(p.Tracks)) } return nil } @@ -1119,7 +1115,7 @@ func _deprecatedListParticipants(ctx context.Context, cmd *cli.Command) error { } for _, p := range res.Participants { - fmt.Printf("%s (%s)\t tracks: %d\n", p.Identity, p.State.String(), len(p.Tracks)) + out.Resultf("%s (%s)\t tracks: %d\n", p.Identity, p.State.String(), len(p.Tracks)) } return nil } @@ -1171,12 +1167,12 @@ func updateParticipant(ctx context.Context, cmd *cli.Command) error { } } - fmt.Println("updating participant...") + out.Status("updating participant...") util.PrintJSON(req) if _, err := roomClient.UpdateParticipant(ctx, req); err != nil { return err } - fmt.Println("participant updated.") + out.Status("participant updated.") return nil } @@ -1192,7 +1188,7 @@ func removeParticipant(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Println("successfully removed participant", identity) + out.Statusf("successfully removed participant %s", identity) return nil } @@ -1213,7 +1209,7 @@ func forwardParticipant(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Println("successfully forwarded participant", identity, "from", roomName, "to", destinationRoomName) + out.Statusf("successfully forwarded participant %s from %s to %s", identity, roomName, destinationRoomName) return nil } @@ -1234,7 +1230,7 @@ func moveParticipant(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Println("successfully moved participant", identity, "from", roomName, "to", destinationRoomName) + out.Statusf("successfully moved participant %s from %s to %s", identity, roomName, destinationRoomName) return nil } @@ -1259,7 +1255,7 @@ func muteTrack(ctx context.Context, cmd *cli.Command) error { if !muted { verb = "Unmuted" } - fmt.Printf("%s track [%s]\n", verb, trackSid) + out.Statusf("%s track [%s]", verb, trackSid) return nil } @@ -1284,7 +1280,7 @@ func updateSubscriptions(ctx context.Context, cmd *cli.Command) error { if !subscribe { verb = "Unsubscribed from" } - fmt.Printf("%s tracks %v\n", verb, trackSids) + out.Statusf("%s tracks %v", verb, trackSids) return nil } @@ -1311,7 +1307,7 @@ func sendData(ctx context.Context, cmd *cli.Command) error { return err } - fmt.Println("successfully sent data to room", roomName) + out.Statusf("successfully sent data to room %s", roomName) return nil } diff --git a/cmd/lk/simulate.go b/cmd/lk/simulate.go index d33df528..404283f3 100644 --- a/cmd/lk/simulate.go +++ b/cmd/lk/simulate.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -293,8 +291,8 @@ func uploadSource(ctx context.Context, client *lksdk.AgentSimulationClient, runI return fmt.Errorf("failed to upload source: %w", err) } if _, err := client.ConfirmSimulationSourceUpload(ctx, &livekit.SimulationRun_ConfirmSourceUpload_Request{ - SimulationRunId: runID, - CodeEntrypoint: entrypoint, + SimulationRunId: runID, + CodeEntrypoint: entrypoint, }); err != nil { return fmt.Errorf("failed to confirm upload: %w", err) } @@ -330,9 +328,9 @@ func cancelSimulationRun(client *lksdk.AgentSimulationClient, runID string) { if _, err := client.CancelSimulationRun(ctx, &livekit.SimulationRun_Cancel_Request{ SimulationRunId: runID, }); err != nil { - fmt.Fprintf(os.Stderr, "Warning: failed to cancel run: %v\n", err) + out.Warnf("Warning: failed to cancel run: %v", err) } else { - fmt.Fprintf(os.Stderr, "Run cancelled\n") + out.Status("Run cancelled") } } diff --git a/cmd/lk/simulate_ci.go b/cmd/lk/simulate_ci.go index ce7d185f..59656476 100644 --- a/cmd/lk/simulate_ci.go +++ b/cmd/lk/simulate_ci.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cmd/lk/simulate_matrix.go b/cmd/lk/simulate_matrix.go index 2621a7c9..7160f277 100644 --- a/cmd/lk/simulate_matrix.go +++ b/cmd/lk/simulate_matrix.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cmd/lk/simulate_save.go b/cmd/lk/simulate_save.go index 8ae7928d..d67c79b0 100644 --- a/cmd/lk/simulate_save.go +++ b/cmd/lk/simulate_save.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cmd/lk/simulate_subprocess.go b/cmd/lk/simulate_subprocess.go index a08a2b29..3a33c0a2 100644 --- a/cmd/lk/simulate_subprocess.go +++ b/cmd/lk/simulate_subprocess.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cmd/lk/simulate_tui.go b/cmd/lk/simulate_tui.go index 30cef4d5..611701b1 100644 --- a/cmd/lk/simulate_tui.go +++ b/cmd/lk/simulate_tui.go @@ -1,5 +1,3 @@ -//go:build console - // Copyright 2025 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cmd/lk/sip.go b/cmd/lk/sip.go index b6ef87d0..994caa56 100644 --- a/cmd/lk/sip.go +++ b/cmd/lk/sip.go @@ -23,6 +23,7 @@ import ( "strings" "time" + "github.com/livekit/livekit-cli/v2/pkg/util" "github.com/livekit/protocol/livekit" lksdk "github.com/livekit/server-sdk-go/v2" "github.com/urfave/cli/v3" @@ -853,7 +854,7 @@ func deleteSIPTrunk(ctx context.Context, cmd *cli.Command) error { if err != nil { return err } - printSIPTrunkID(info) + out.Resultf("SIP Trunk [%s] deleted\n", util.Accented(info.GetSipTrunkId())) return nil }) } @@ -869,20 +870,16 @@ func deleteSIPTrunkLegacy(ctx context.Context, cmd *cli.Command) error { if err != nil { return err } - printSIPTrunkID(info) + out.Resultf("SIP Trunk [%s] deleted\n", util.Accented(info.GetSipTrunkId())) return nil } -func printSIPTrunkID(info *livekit.SIPTrunkInfo) { - fmt.Printf("SIPTrunkID: %v\n", info.GetSipTrunkId()) -} - func printSIPInboundTrunkID(info *livekit.SIPInboundTrunkInfo) { - fmt.Printf("SIPTrunkID: %v\n", info.GetSipTrunkId()) + out.Resultf("SIPTrunkID: %v\n", info.GetSipTrunkId()) } func printSIPOutboundTrunkID(info *livekit.SIPOutboundTrunkInfo) { - fmt.Printf("SIPTrunkID: %v\n", info.GetSipTrunkId()) + out.Resultf("SIPTrunkID: %v\n", info.GetSipTrunkId()) } func createSIPDispatchRule(ctx context.Context, cmd *cli.Command) error { @@ -1120,7 +1117,7 @@ func deleteSIPDispatchRuleLegacy(ctx context.Context, cmd *cli.Command) error { } func printSIPDispatchRuleID(info *livekit.SIPDispatchRuleInfo) { - fmt.Printf("SIPDispatchRuleID: %v\n", info.SipDispatchRuleId) + out.Resultf("SIPDispatchRuleID: %v\n", info.SipDispatchRuleId) } func createSIPParticipant(ctx context.Context, cmd *cli.Command) error { @@ -1204,8 +1201,8 @@ func createSIPParticipant(ctx context.Context, cmd *cli.Command) error { if msg == "" { msg = e.Code.ShortName() } - fmt.Printf("SIPStatusCode: %d\n", e.Code) - fmt.Printf("SIPStatus: %s\n", msg) + out.Resultf("SIPStatusCode: %d\n", e.Code) + out.Resultf("SIPStatus: %s\n", msg) } return resp, err }, printSIPParticipantInfo) @@ -1252,8 +1249,8 @@ func transferSIPParticipant(ctx context.Context, cmd *cli.Command) error { } func printSIPParticipantInfo(info *livekit.SIPParticipantInfo) { - fmt.Printf("SIPCallID: %v\n", info.SipCallId) - fmt.Printf("ParticipantID: %v\n", info.ParticipantId) - fmt.Printf("ParticipantIdentity: %v\n", info.ParticipantIdentity) - fmt.Printf("RoomName: %v\n", info.RoomName) + out.Resultf("SIPCallID: %v\n", info.SipCallId) + out.Resultf("ParticipantID: %v\n", info.ParticipantId) + out.Resultf("ParticipantIdentity: %v\n", info.ParticipantIdentity) + out.Resultf("RoomName: %v\n", info.RoomName) } diff --git a/cmd/lk/utils.go b/cmd/lk/utils.go index 85166eb6..b8e2e4d3 100644 --- a/cmd/lk/utils.go +++ b/cmd/lk/utils.go @@ -15,20 +15,18 @@ package main import ( - "context" "errors" "fmt" - "io" "maps" "os" "strings" - "github.com/charmbracelet/huh" "github.com/joho/godotenv" "github.com/mattn/go-isatty" "github.com/twitchtv/twirp" "github.com/urfave/cli/v3" + "github.com/livekit/protocol/logger" "github.com/livekit/protocol/utils/interceptors" "github.com/livekit/server-sdk-go/v2/signalling" @@ -93,6 +91,12 @@ var ( Usage: "Run installation after creating the application", } + // out is the process-wide sink for human-facing CLI output. It is initialized + // in main.go's root Before hook from the parsed root command, so all status, + // warning, and result lines share consistent streams (stderr/stdout) and + // --quiet gating. Before init it is nil and all methods no-op safely. + out *util.Printer + openFlag = util.OpenFlag globalFlags = []cli.Flag{ &cli.StringFlag{ @@ -145,6 +149,11 @@ var ( Aliases: []string{"y"}, Usage: "Assume yes for confirmations; fail or use default for other prompts (use in CI/non-interactive)", }, + &cli.BoolFlag{ + Name: "quiet", + Aliases: []string{"q"}, + Usage: "Suppress informational output to stderr (warnings and errors still print)", + }, &cli.StringFlag{ Name: "server-url", Value: cloudAPIServerURL, @@ -239,7 +248,6 @@ func parseKeyValuePairs(c *cli.Command, flag string) (map[string]string, error) type loadParams struct { requireURL bool confirmProject bool - output io.Writer } type loadOption func(*loadParams) @@ -253,28 +261,70 @@ var ( } ) -// attempt to load connection config, it'll prioritize -// 1. command line flags (or env var) -// 2. config file (by default, livekit.toml) -// 3. default project config -func loadProjectDetails(c *cli.Command, opts ...loadOption) (*config.ProjectConfig, error) { - p := loadParams{requireURL: true, confirmProject: false, output: os.Stdout} - for _, opt := range opts { - opt(&p) - } - w := p.output - logDetails := func(c *cli.Command, pc *config.ProjectConfig) { - if c.Bool("verbose") { - fmt.Fprintf(w, "URL: %s, api-key: %s, api-secret: %s\n", - pc.URL, - pc.APIKey, - "************", - ) - } +// projectSource records how a project's credentials were resolved. It feeds two things: +// the confirm-default prompt (only triggers for sourceDefault) and the notice string +// composed in resolveProject and emitted by callers via out.Status. +type projectSource int +const ( + sourceFlag projectSource = iota // --project NAME + sourceSubdomain // --subdomain SUBDOMAIN + sourceEnv // credentials from LIVEKIT_* environment variables + sourceInlineFlags // credentials from --url/--api-key/--api-secret (name-less; silent) + sourceDev // --dev + sourceTOML // livekit.toml in the working directory + sourceDefault // configured default project + sourceSelected // interactively picked, or added via `lk cloud auth` +) + +// resolvedProject is the outcome of project resolution: the chosen credentials, how they +// were resolved, and (for sourceEnv) which env vars came through. Call rp.announce() to +// surface the outcome to the user — that is the single hand-off from resolution to output. +type resolvedProject struct { + project *config.ProjectConfig + source projectSource + envVars []string // which LIVEKIT_* vars were used, for sourceEnv +} + +// announce surfaces how the project was resolved: a one-line breadcrumb through the +// package-level Printer (stderr, suppressed by --quiet), plus a structured debug log via +// protocol/logger (gated to --verbose). Centralizing the source→message mapping here keeps +// the resolver pure and gives us one place to evolve wording or wire color/decoration. +func (rp *resolvedProject) announce() { + if rp == nil { + return + } + switch rp.source { + case sourceEnv: + out.Statusf("Using %s from environment", strings.Join(rp.envVars, ", ")) + case sourceDev: + out.Status("Using dev credentials") + case sourceInlineFlags: + // name-less credentials supplied directly via flags; nothing to surface + default: // sourceFlag, sourceSubdomain, sourceTOML, sourceDefault, sourceSelected + out.Statusf("Using project [%s]", util.Accented(rp.project.Name)) + } + if rp.project != nil && rp.source != sourceDev { + logger.Debugw("project resolved", + "source", rp.source, + "url", rp.project.URL, + "api-key", rp.project.APIKey, + ) } +} - // if explicit project is defined, then use it +// resolveProject determines which project's credentials to use, in priority order: +// 1. --project flag +// 2. --subdomain flag +// 3. --url/--api-key/--api-secret flags or LIVEKIT_* env vars +// 4. --dev credentials +// 5. livekit.toml in the working directory +// 6. the configured default project +// +// It performs no prompting and no printing: callers print rp.notice via out.Status, and +// handle the no-project case (a returned error) by offering interactive selection. +func resolveProject(c *cli.Command, p loadParams) (*resolvedProject, error) { + // 1. explicit project if c.String("project") != "" { if c.Bool("dev") { return nil, errors.New("both project and dev flags are set") @@ -283,12 +333,10 @@ func loadProjectDetails(c *cli.Command, opts ...loadOption) (*config.ProjectConf if err != nil { return nil, err } - fmt.Fprintln(w, "Using project ["+util.Accented(c.String("project"))+"]") - logDetails(c, pc) - return pc, nil + return &resolvedProject{project: pc, source: sourceFlag}, nil } - // if explicit subdomain is provided, use it + // 2. explicit subdomain if c.String("subdomain") != "" { if c.Bool("dev") { return nil, errors.New("both subdomain and dev flags are set") @@ -297,11 +345,10 @@ func loadProjectDetails(c *cli.Command, opts ...loadOption) (*config.ProjectConf if err != nil { return nil, err } - fmt.Fprintln(w, "Using project ["+util.Accented(pc.Name)+"]") - logDetails(c, pc) - return pc, nil + return &resolvedProject{project: pc, source: sourceSubdomain}, nil } + // 3. inline credentials (flags or environment) pc := &config.ProjectConfig{} if val := c.String("url"); val != "" { pc.URL = val @@ -331,57 +378,33 @@ func loadProjectDetails(c *cli.Command, opts ...loadOption) (*config.ProjectConf envVars = append(envVars, "api-secret") } if len(envVars) > 0 { - fmt.Fprintf(w, "Using %s from environment\n", strings.Join(envVars, ", ")) - logDetails(c, pc) + return &resolvedProject{project: pc, source: sourceEnv, envVars: envVars}, nil } - return pc, nil + return &resolvedProject{project: pc, source: sourceInlineFlags}, nil } + + // 4. dev credentials if c.Bool("dev") { pc.APIKey = "devkey" pc.APISecret = "secret" - fmt.Fprintln(w, "Using dev credentials") - return pc, nil + return &resolvedProject{project: pc, source: sourceDev}, nil } - // load from config file - _, err := requireConfig(workingDir, tomlFilename) - if errors.Is(err, config.ErrInvalidConfig) { + // 5. livekit.toml in the working directory + if _, err := requireConfig(workingDir, tomlFilename); errors.Is(err, config.ErrInvalidConfig) { return nil, err } if lkConfig != nil { - return config.LoadProjectBySubdomain(lkConfig.Project.Subdomain) - } - - // load default project - dp, err := config.LoadDefaultProject() - if err == nil { - if p.confirmProject { - if dp != nil && len(cliConfig.Projects) > 1 && !c.Bool("silent") && !SkipPrompts(c) { - useDefault := true - if err := huh.NewForm(huh.NewGroup(huh.NewConfirm(). - Title(fmt.Sprintf("Use project [%s] (%s) to create agent?", dp.Name, dp.URL)). - Value(&useDefault). - Negative("Select another"). - Inline(false). - WithTheme(util.Theme))). - Run(); err != nil { - return nil, fmt.Errorf("failed to confirm project: %w", err) - } - if !useDefault { - if _, err = selectProject(context.Background(), c); err != nil { - return nil, err - } - fmt.Fprintf(w, "Using project [%s]\n", util.Accented(project.Name)) - return project, nil - } - } - } else { - if !c.Bool("silent") && !SkipPrompts(c) { - fmt.Fprintln(w, "Using default project ["+util.Theme.Focused.Title.Render(dp.Name)+"]") - logDetails(c, dp) - } + pc, err := config.LoadProjectBySubdomain(lkConfig.Project.Subdomain) + if err != nil { + return nil, err } - return dp, nil + return &resolvedProject{project: pc, source: sourceTOML}, nil + } + + // 6. configured default project + if dp, err := config.LoadDefaultProject(); err == nil { + return &resolvedProject{project: dp, source: sourceDefault}, nil } if p.requireURL && pc.URL == "" { @@ -395,7 +418,24 @@ func loadProjectDetails(c *cli.Command, opts ...loadOption) (*config.ProjectConf } // cannot happen - return pc, nil + return &resolvedProject{project: pc, source: sourceInlineFlags}, nil +} + +// loadProjectDetails resolves project credentials for commands that consume the result +// directly (egress, ingress, token, …) and announces the resolution. Commands that rely on +// the package-level `project` (app/agent) go through requireProject instead, which layers +// interactive selection on top of the same resolver before announcing. +func loadProjectDetails(c *cli.Command, opts ...loadOption) (*config.ProjectConfig, error) { + p := loadParams{requireURL: true} + for _, opt := range opts { + opt(&p) + } + rp, err := resolveProject(c, p) + if err != nil { + return nil, err + } + rp.announce() + return rp.project, nil } type TemplateStringFlag = cli.FlagBase[string, cli.StringConfig, templateStringValue] diff --git a/cmd/lk/utils_test.go b/cmd/lk/utils_test.go index 776416ab..6b5b638f 100644 --- a/cmd/lk/utils_test.go +++ b/cmd/lk/utils_test.go @@ -15,11 +15,121 @@ package main import ( + "bytes" + "context" + "io" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/urfave/cli/v3" + + "github.com/livekit/livekit-cli/v2/pkg/util" ) +// withCapturedAnnounce swaps the package-level Printer for a buffer-backed one for the +// duration of the test, returning the buffer that captures status output. The Printer's +// nil-safety means we don't have to worry about state from other tests. +func withCapturedAnnounce(t *testing.T) *bytes.Buffer { + t.Helper() + prev := out + var buf bytes.Buffer + out = util.NewPrinter(io.Discard, &buf, false) + t.Cleanup(func() { out = prev }) + return &buf +} + +// resolveWith parses the given args against a fresh copy of the credential-related global +// flags and returns the resolveProject outcome. Fresh flags per call avoid state leaking +// between subtests, and isolating to these flags keeps the test independent of the +// on-disk CLI config (the branches exercised here return before any config is read). +func resolveWith(t *testing.T, args ...string) (*resolvedProject, error) { + t.Helper() + var rp *resolvedProject + var rerr error + app := &cli.Command{ + Name: "lk", + Flags: []cli.Flag{ + &cli.StringFlag{Name: "url", Sources: cli.EnvVars("LIVEKIT_URL"), Value: "http://localhost:7880"}, + &cli.StringFlag{Name: "api-key", Sources: cli.EnvVars("LIVEKIT_API_KEY")}, + &cli.StringFlag{Name: "api-secret", Sources: cli.EnvVars("LIVEKIT_API_SECRET")}, + &cli.BoolFlag{Name: "dev"}, + &cli.StringFlag{Name: "project"}, + &cli.StringFlag{Name: "subdomain"}, + }, + Action: func(_ context.Context, cmd *cli.Command) error { + rp, rerr = resolveProject(cmd, loadParams{requireURL: true}) + return nil + }, + } + require.NoError(t, app.Run(context.Background(), append([]string{"lk"}, args...))) + return rp, rerr +} + +func TestResolveProjectSource(t *testing.T) { + // Isolate from any ambient LIVEKIT_* credentials in the dev's environment. + t.Setenv("LIVEKIT_URL", "") + t.Setenv("LIVEKIT_API_KEY", "") + t.Setenv("LIVEKIT_API_SECRET", "") + + t.Run("dev credentials", func(t *testing.T) { + buf := withCapturedAnnounce(t) + rp, err := resolveWith(t, "--dev") + require.NoError(t, err) + require.NotNil(t, rp) + assert.Equal(t, sourceDev, rp.source) + assert.Equal(t, "devkey", rp.project.APIKey) + + rp.announce() + assert.Equal(t, "Using dev credentials\n", buf.String()) + }) + + t.Run("inline flags are name-less and silent", func(t *testing.T) { + buf := withCapturedAnnounce(t) + rp, err := resolveWith(t, "--url", "ws://x", "--api-key", "k", "--api-secret", "s") + require.NoError(t, err) + require.NotNil(t, rp) + assert.Equal(t, sourceInlineFlags, rp.source) + assert.Empty(t, rp.envVars) + + rp.announce() + assert.Empty(t, buf.String(), "name-less sources surface nothing to the user") + }) + + t.Run("env credentials are reported", func(t *testing.T) { + t.Setenv("LIVEKIT_URL", "ws://env-url") + t.Setenv("LIVEKIT_API_KEY", "envkey") + t.Setenv("LIVEKIT_API_SECRET", "envsecret") + buf := withCapturedAnnounce(t) + rp, err := resolveWith(t) + require.NoError(t, err) + require.NotNil(t, rp) + assert.Equal(t, sourceEnv, rp.source) + assert.ElementsMatch(t, []string{"url", "api-key", "api-secret"}, rp.envVars) + + rp.announce() + assert.Equal(t, "Using url, api-key, api-secret from environment\n", buf.String()) + }) + + t.Run("project and dev conflict", func(t *testing.T) { + _, err := resolveWith(t, "--project", "foo", "--dev") + require.Error(t, err) + assert.Contains(t, err.Error(), "both project and dev flags are set") + }) + + t.Run("--quiet suppresses the breadcrumb", func(t *testing.T) { + prev := out + var buf bytes.Buffer + out = util.NewPrinter(io.Discard, &buf, true /* quiet */) + t.Cleanup(func() { out = prev }) + + rp, err := resolveWith(t, "--dev") + require.NoError(t, err) + rp.announce() + assert.Empty(t, buf.String(), "--quiet suppresses status output") + }) +} + func TestOptionalFlag(t *testing.T) { requiredFlag := &cli.StringFlag{ Name: "test", diff --git a/install-cli.sh b/install-cli.sh index 70ab9d6a..7cb13482 100755 --- a/install-cli.sh +++ b/install-cli.sh @@ -13,7 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# LiveKit install script for Linux +# LiveKit CLI installer for Linux. Downloads the latest GitHub release archive +# and installs the binary + completions system-wide. set -u set -o errtrace @@ -27,102 +28,59 @@ BASH_COMPLETION_PATH="/usr/share/bash-completion/completions" ZSH_COMPLETION_PATH="/usr/share/zsh/site-functions" FISH_COMPLETION_PATH="/usr/share/fish/vendor_completions.d" -log() { printf "%b\n" "$*"; } -abort() { - printf "%s\n" "$@" >&2 - exit 1 -} - -# returns the latest version according to GH -# i.e. 1.0.0 -get_latest_version() -{ - latest_version=$(curl -s https://api.github.com/repos/livekit/$REPO/releases/latest | jq -r '.tag_name' | sed 's/^v//') - printf "%s" "$latest_version" -} - -# Ensure bash is used -if [ -z "${BASH_VERSION:-}" ] -then - abort "This script requires bash" -fi +log() { printf "%b\n" "$*"; } +abort() { printf "%s\n" "$@" >&2; exit 1; } -# Check if $INSTALL_PATH exists -if [ ! -d ${INSTALL_PATH} ] -then - abort "Could not install, ${INSTALL_PATH} doesn't exist" -fi +[ -n "${BASH_VERSION:-}" ] || abort "This script requires bash" +[ -d "$INSTALL_PATH" ] || abort "Could not install, $INSTALL_PATH doesn't exist" +command -v curl >/dev/null || abort "cURL is required and is not found" + +OS="$(uname)" +case "$OS" in + Darwin) abort "Installer not supported on MacOS, please install using Homebrew." ;; + Linux) ;; + *) abort "Installer is only supported on Linux." ;; +esac + +case "$(uname -m)" in + x86_64) ARCH="amd64" ;; + aarch64) ARCH="arm64" ;; + *) abort "Unsupported architecture: $(uname -m)" ;; +esac -# Needs SUDO if no permissions to write SUDO_PREFIX="" -if [ ! -w ${INSTALL_PATH} ] -then +if [ ! -w "$INSTALL_PATH" ]; then SUDO_PREFIX="sudo" - log "sudo is required to install to ${INSTALL_PATH}" -fi - -# Check cURL is installed -if ! command -v curl >/dev/null -then - abort "cURL is required and is not found" -fi - -# OS check -OS="$(uname)" -if [[ "${OS}" == "Darwin" ]] -then - abort "Installer not supported on MacOS, please install using Homebrew." -elif [[ "${OS}" != "Linux" ]] -then - abort "Installer is only supported on Linux." + log "sudo is required to install to $INSTALL_PATH" fi -ARCH="$(uname -m)" +VERSION=$(curl -fsSL https://api.github.com/repos/livekit/$REPO/releases/latest \ + | jq -r '.tag_name' | sed 's/^v//') -# fix arch on linux -if [[ "${ARCH}" == "aarch64" ]] -then - ARCH="arm64" -elif [[ "${ARCH}" == "x86_64" ]] -then - ARCH="amd64" -fi +[[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || abort "Invalid version: $VERSION" -VERSION=$(get_latest_version) ARCHIVE_URL="https://github.com/livekit/$REPO/releases/download/v${VERSION}/${BIN_NAME}_${VERSION}_linux_${ARCH}.tar.gz" -# Ensure version follows SemVer -if ! [[ "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] -then - abort "Invalid version: ${VERSION}" -fi - -log "Installing ${REPO} ${VERSION}" -log "Downloading from ${ARCHIVE_URL}..." - -TEMP_DIR_PATH="$(mktemp -d)" - -curl -s -L "${ARCHIVE_URL}" | tar xzf - -C "${TEMP_DIR_PATH}" --wildcards --no-anchored "$BIN_NAME*" +log "Installing $REPO $VERSION" +log "Downloading from $ARCHIVE_URL..." -${SUDO_PREFIX} mv "${TEMP_DIR_PATH}/lk" "${INSTALL_PATH}/lk" -${SUDO_PREFIX} ln -sf "${INSTALL_PATH}/lk" "${INSTALL_PATH}/livekit-cli" +TEMP_DIR=$(mktemp -d) +trap 'rm -rf "$TEMP_DIR"' EXIT -if [ -d "${TEMP_DIR_PATH}/autocomplete" ] -then - if [ -d "${BASH_COMPLETION_PATH}" ] - then - mv "${TEMP_DIR_PATH}/autocomplete/bash_autocomplete" "${BASH_COMPLETION_PATH}/livekit-cli" - fi +curl -fsSL "$ARCHIVE_URL" | tar xzf - -C "$TEMP_DIR" - if [ -d "${ZSH_COMPLETION_PATH}" ] - then - mv "${TEMP_DIR_PATH}/autocomplete/zsh_autocomplete" "${ZSH_COMPLETION_PATH}/_livekit-cli" - fi +$SUDO_PREFIX mv "$TEMP_DIR/$BIN_NAME" "$INSTALL_PATH/$BIN_NAME" +$SUDO_PREFIX ln -sf "$INSTALL_PATH/$BIN_NAME" "$INSTALL_PATH/livekit-cli" - if [ -d "${FISH_COMPLETION_PATH}" ] - then - lk generate-fish-completion -o "${FISH_COMPLETION_PATH}/livekit-cli.fish" - fi +# Install completions if the corresponding system directories exist. The fish +# completion ships in the archive (no need to invoke lk to regenerate it). +if [ -d "$TEMP_DIR/autocomplete" ]; then + [ -d "$BASH_COMPLETION_PATH" ] && \ + $SUDO_PREFIX install -m 0644 "$TEMP_DIR/autocomplete/bash_autocomplete" "$BASH_COMPLETION_PATH/livekit-cli" || true + [ -d "$ZSH_COMPLETION_PATH" ] && \ + $SUDO_PREFIX install -m 0644 "$TEMP_DIR/autocomplete/zsh_autocomplete" "$ZSH_COMPLETION_PATH/_livekit-cli" || true + [ -d "$FISH_COMPLETION_PATH" ] && \ + $SUDO_PREFIX install -m 0644 "$TEMP_DIR/autocomplete/fish_autocomplete" "$FISH_COMPLETION_PATH/livekit-cli.fish" || true fi log "\n$BIN_NAME is installed to $INSTALL_PATH\n" diff --git a/pkg/apm/apm.go b/pkg/apm/apm.go index b8f219d6..12f2e13d 100644 --- a/pkg/apm/apm.go +++ b/pkg/apm/apm.go @@ -1,5 +1,3 @@ -//go:build console - // Package apm provides Go bindings for the WebRTC Audio Processing Module (APM). // It supports echo cancellation (AEC3), noise suppression, automatic gain control, // and high-pass filtering. Audio must be 48kHz int16 PCM in 10ms frames (480 samples/channel). diff --git a/pkg/apm/bridge.go b/pkg/apm/bridge.go index ea15eb0d..e1a9decd 100644 --- a/pkg/apm/bridge.go +++ b/pkg/apm/bridge.go @@ -1,5 +1,3 @@ -//go:build console - package apm // #cgo CXXFLAGS: -I${SRCDIR}/webrtc -I${SRCDIR}/webrtc/third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/api/api.go b/pkg/apm/webrtc/api/api.go index 99ce769c..4047617a 100644 --- a/pkg/apm/webrtc/api/api.go +++ b/pkg/apm/webrtc/api/api.go @@ -1,5 +1,3 @@ -//go:build console - package api // #cgo CXXFLAGS: -I${SRCDIR}/.. -I${SRCDIR}/../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/api/audio/audio.go b/pkg/apm/webrtc/api/audio/audio.go index 8b3f44b8..46ed27ce 100644 --- a/pkg/apm/webrtc/api/audio/audio.go +++ b/pkg/apm/webrtc/api/audio/audio.go @@ -1,5 +1,3 @@ -//go:build console - package audio // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/api/environment/environment.go b/pkg/apm/webrtc/api/environment/environment.go index bd5c25aa..fa2cea10 100644 --- a/pkg/apm/webrtc/api/environment/environment.go +++ b/pkg/apm/webrtc/api/environment/environment.go @@ -1,5 +1,3 @@ -//go:build console - package environment // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/api/numerics/numerics.go b/pkg/apm/webrtc/api/numerics/numerics.go index e61a6f66..c668842f 100644 --- a/pkg/apm/webrtc/api/numerics/numerics.go +++ b/pkg/apm/webrtc/api/numerics/numerics.go @@ -1,5 +1,3 @@ -//go:build console - package numerics // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/api/task_queue/gcd/gcd.go b/pkg/apm/webrtc/api/task_queue/gcd/gcd.go index 5aabb282..6b67772a 100644 --- a/pkg/apm/webrtc/api/task_queue/gcd/gcd.go +++ b/pkg/apm/webrtc/api/task_queue/gcd/gcd.go @@ -1,4 +1,4 @@ -//go:build console && darwin +//go:build darwin package gcd diff --git a/pkg/apm/webrtc/api/task_queue/stdlib/stdlib.go b/pkg/apm/webrtc/api/task_queue/stdlib/stdlib.go index 49af39bd..ea8d757d 100644 --- a/pkg/apm/webrtc/api/task_queue/stdlib/stdlib.go +++ b/pkg/apm/webrtc/api/task_queue/stdlib/stdlib.go @@ -1,4 +1,4 @@ -//go:build console && !darwin +//go:build !darwin package stdlib diff --git a/pkg/apm/webrtc/api/task_queue/task_queue.go b/pkg/apm/webrtc/api/task_queue/task_queue.go index 6419e7e4..02092efc 100644 --- a/pkg/apm/webrtc/api/task_queue/task_queue.go +++ b/pkg/apm/webrtc/api/task_queue/task_queue.go @@ -1,5 +1,3 @@ -//go:build console - package task_queue // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/api/transport/transport.go b/pkg/apm/webrtc/api/transport/transport.go index f122b4d3..2699315c 100644 --- a/pkg/apm/webrtc/api/transport/transport.go +++ b/pkg/apm/webrtc/api/transport/transport.go @@ -1,5 +1,3 @@ -//go:build console - package transport // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/api/units/units.go b/pkg/apm/webrtc/api/units/units.go index 6e234727..bac32eea 100644 --- a/pkg/apm/webrtc/api/units/units.go +++ b/pkg/apm/webrtc/api/units/units.go @@ -1,5 +1,3 @@ -//go:build console - package units // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/common_audio/avx2/avx2.go b/pkg/apm/webrtc/common_audio/avx2/avx2.go index d2952ca2..44906f18 100644 --- a/pkg/apm/webrtc/common_audio/avx2/avx2.go +++ b/pkg/apm/webrtc/common_audio/avx2/avx2.go @@ -1,4 +1,4 @@ -//go:build console && amd64 +//go:build amd64 package avx2 diff --git a/pkg/apm/webrtc/common_audio/common_audio.go b/pkg/apm/webrtc/common_audio/common_audio.go index 38eb6ac8..2519f1c7 100644 --- a/pkg/apm/webrtc/common_audio/common_audio.go +++ b/pkg/apm/webrtc/common_audio/common_audio.go @@ -1,5 +1,3 @@ -//go:build console - package common_audio // #cgo CXXFLAGS: -I${SRCDIR}/.. -I${SRCDIR}/../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/common_audio/common_audio_amd64.go b/pkg/apm/webrtc/common_audio/common_audio_amd64.go index 12acc896..8ab45267 100644 --- a/pkg/apm/webrtc/common_audio/common_audio_amd64.go +++ b/pkg/apm/webrtc/common_audio/common_audio_amd64.go @@ -1,4 +1,4 @@ -//go:build console && amd64 +//go:build amd64 package common_audio diff --git a/pkg/apm/webrtc/common_audio/resampler/avx2/avx2.go b/pkg/apm/webrtc/common_audio/resampler/avx2/avx2.go index 3c693a2e..75001265 100644 --- a/pkg/apm/webrtc/common_audio/resampler/avx2/avx2.go +++ b/pkg/apm/webrtc/common_audio/resampler/avx2/avx2.go @@ -1,4 +1,4 @@ -//go:build console && amd64 +//go:build amd64 package avx2 diff --git a/pkg/apm/webrtc/common_audio/resampler/resampler.go b/pkg/apm/webrtc/common_audio/resampler/resampler.go index 86a19059..5177786f 100644 --- a/pkg/apm/webrtc/common_audio/resampler/resampler.go +++ b/pkg/apm/webrtc/common_audio/resampler/resampler.go @@ -1,5 +1,3 @@ -//go:build console - package resampler // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/common_audio/signal_processing/sp.go b/pkg/apm/webrtc/common_audio/signal_processing/sp.go index 9bb1f9ad..5a941850 100644 --- a/pkg/apm/webrtc/common_audio/signal_processing/sp.go +++ b/pkg/apm/webrtc/common_audio/signal_processing/sp.go @@ -1,5 +1,3 @@ -//go:build console - package signal_processing // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_128/fft_size_128.go b/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_128/fft_size_128.go index b243e9fd..a65a965c 100644 --- a/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_128/fft_size_128.go +++ b/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_128/fft_size_128.go @@ -1,5 +1,3 @@ -//go:build console - package fft_size_128 // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_256/fft_size_256.go b/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_256/fft_size_256.go index 84805d5b..91f96397 100644 --- a/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_256/fft_size_256.go +++ b/pkg/apm/webrtc/common_audio/third_party/ooura/fft_size_256/fft_size_256.go @@ -1,5 +1,3 @@ -//go:build console - package fft_size_256 // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.go b/pkg/apm/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.go index ba8f2ed2..e456f9ad 100644 --- a/pkg/apm/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.go +++ b/pkg/apm/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.go @@ -1,5 +1,3 @@ -//go:build console - package spl_sqrt_floor diff --git a/pkg/apm/webrtc/common_audio/vad/vad.go b/pkg/apm/webrtc/common_audio/vad/vad.go index 3120e15b..55ddaff0 100644 --- a/pkg/apm/webrtc/common_audio/vad/vad.go +++ b/pkg/apm/webrtc/common_audio/vad/vad.go @@ -1,5 +1,3 @@ -//go:build console - package vad // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_coding/codecs/isac/main/source/isac.go b/pkg/apm/webrtc/modules/audio_coding/codecs/isac/main/source/isac.go index f09044b7..9fb19bf5 100644 --- a/pkg/apm/webrtc/modules/audio_coding/codecs/isac/main/source/isac.go +++ b/pkg/apm/webrtc/modules/audio_coding/codecs/isac/main/source/isac.go @@ -1,5 +1,3 @@ -//go:build console - package source // #cgo CFLAGS: -I${SRCDIR}/../../../../../.. -std=c11 -Wno-unused-parameter -Wno-sign-compare -Wno-deprecated-declarations diff --git a/pkg/apm/webrtc/modules/audio_processing/aec3/aec3.go b/pkg/apm/webrtc/modules/audio_processing/aec3/aec3.go index 1c450b9e..3f054c96 100644 --- a/pkg/apm/webrtc/modules/audio_processing/aec3/aec3.go +++ b/pkg/apm/webrtc/modules/audio_processing/aec3/aec3.go @@ -1,5 +1,3 @@ -//go:build console - package aec3 // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/aec3/avx2/avx2.go b/pkg/apm/webrtc/modules/audio_processing/aec3/avx2/avx2.go index 9bc38772..40b34900 100644 --- a/pkg/apm/webrtc/modules/audio_processing/aec3/avx2/avx2.go +++ b/pkg/apm/webrtc/modules/audio_processing/aec3/avx2/avx2.go @@ -1,4 +1,4 @@ -//go:build console && amd64 +//go:build amd64 package avx2 diff --git a/pkg/apm/webrtc/modules/audio_processing/aec_dump/aec_dump.go b/pkg/apm/webrtc/modules/audio_processing/aec_dump/aec_dump.go index 24b5af8b..fae5a193 100644 --- a/pkg/apm/webrtc/modules/audio_processing/aec_dump/aec_dump.go +++ b/pkg/apm/webrtc/modules/audio_processing/aec_dump/aec_dump.go @@ -1,5 +1,3 @@ -//go:build console - package aec_dump // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/aecm/aecm.go b/pkg/apm/webrtc/modules/audio_processing/aecm/aecm.go index 8b452a03..fcbcac25 100644 --- a/pkg/apm/webrtc/modules/audio_processing/aecm/aecm.go +++ b/pkg/apm/webrtc/modules/audio_processing/aecm/aecm.go @@ -1,5 +1,3 @@ -//go:build console - package aecm // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/agc/agc.go b/pkg/apm/webrtc/modules/audio_processing/agc/agc.go index 40002767..f1ee2936 100644 --- a/pkg/apm/webrtc/modules/audio_processing/agc/agc.go +++ b/pkg/apm/webrtc/modules/audio_processing/agc/agc.go @@ -1,5 +1,3 @@ -//go:build console - package agc // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/agc/legacy/legacy.go b/pkg/apm/webrtc/modules/audio_processing/agc/legacy/legacy.go index f6999b97..385f1157 100644 --- a/pkg/apm/webrtc/modules/audio_processing/agc/legacy/legacy.go +++ b/pkg/apm/webrtc/modules/audio_processing/agc/legacy/legacy.go @@ -1,5 +1,3 @@ -//go:build console - package legacy // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/agc2/agc2.go b/pkg/apm/webrtc/modules/audio_processing/agc2/agc2.go index 4a8c17ce..e5eb70c2 100644 --- a/pkg/apm/webrtc/modules/audio_processing/agc2/agc2.go +++ b/pkg/apm/webrtc/modules/audio_processing/agc2/agc2.go @@ -1,5 +1,3 @@ -//go:build console - package agc2 // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/avx2/avx2.go b/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/avx2/avx2.go index 2217ca34..0d1ac21b 100644 --- a/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/avx2/avx2.go +++ b/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/avx2/avx2.go @@ -1,4 +1,4 @@ -//go:build console && amd64 +//go:build amd64 package avx2 diff --git a/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad.go b/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad.go index 6a1b5f4a..88dff9ad 100644 --- a/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad.go +++ b/pkg/apm/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad.go @@ -1,5 +1,3 @@ -//go:build console - package rnn_vad // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/apm.go b/pkg/apm/webrtc/modules/audio_processing/apm.go index e8400c88..269e1340 100644 --- a/pkg/apm/webrtc/modules/audio_processing/apm.go +++ b/pkg/apm/webrtc/modules/audio_processing/apm.go @@ -1,5 +1,3 @@ -//go:build console - package audio_processing // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/apm_amd64.go b/pkg/apm/webrtc/modules/audio_processing/apm_amd64.go index 51895b8e..36cbc315 100644 --- a/pkg/apm/webrtc/modules/audio_processing/apm_amd64.go +++ b/pkg/apm/webrtc/modules/audio_processing/apm_amd64.go @@ -1,4 +1,4 @@ -//go:build console && amd64 +//go:build amd64 package audio_processing diff --git a/pkg/apm/webrtc/modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.go b/pkg/apm/webrtc/modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.go index 19f42952..d6fa065a 100644 --- a/pkg/apm/webrtc/modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.go +++ b/pkg/apm/webrtc/modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.go @@ -1,5 +1,3 @@ -//go:build console - package capture_levels_adjuster // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/echo_detector/echo_detector.go b/pkg/apm/webrtc/modules/audio_processing/echo_detector/echo_detector.go index acdbe0e9..493a2c11 100644 --- a/pkg/apm/webrtc/modules/audio_processing/echo_detector/echo_detector.go +++ b/pkg/apm/webrtc/modules/audio_processing/echo_detector/echo_detector.go @@ -1,5 +1,3 @@ -//go:build console - package echo_detector // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/include/include.go b/pkg/apm/webrtc/modules/audio_processing/include/include.go index a84bc198..bd443aa6 100644 --- a/pkg/apm/webrtc/modules/audio_processing/include/include.go +++ b/pkg/apm/webrtc/modules/audio_processing/include/include.go @@ -1,5 +1,3 @@ -//go:build console - package include // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/logging/logging.go b/pkg/apm/webrtc/modules/audio_processing/logging/logging.go index 9d2b4a63..81ad5a68 100644 --- a/pkg/apm/webrtc/modules/audio_processing/logging/logging.go +++ b/pkg/apm/webrtc/modules/audio_processing/logging/logging.go @@ -1,5 +1,3 @@ -//go:build console - package logging // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/ns/ns.go b/pkg/apm/webrtc/modules/audio_processing/ns/ns.go index 25631999..64aafc40 100644 --- a/pkg/apm/webrtc/modules/audio_processing/ns/ns.go +++ b/pkg/apm/webrtc/modules/audio_processing/ns/ns.go @@ -1,5 +1,3 @@ -//go:build console - package ns // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/utility/utility.go b/pkg/apm/webrtc/modules/audio_processing/utility/utility.go index ee7ef97e..66b13052 100644 --- a/pkg/apm/webrtc/modules/audio_processing/utility/utility.go +++ b/pkg/apm/webrtc/modules/audio_processing/utility/utility.go @@ -1,5 +1,3 @@ -//go:build console - package utility // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/modules/audio_processing/vad/vad.go b/pkg/apm/webrtc/modules/audio_processing/vad/vad.go index 20e53da2..6681c101 100644 --- a/pkg/apm/webrtc/modules/audio_processing/vad/vad.go +++ b/pkg/apm/webrtc/modules/audio_processing/vad/vad.go @@ -1,5 +1,3 @@ -//go:build console - package vad // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/containers/containers.go b/pkg/apm/webrtc/rtc_base/containers/containers.go index c9a22c95..d700a81d 100644 --- a/pkg/apm/webrtc/rtc_base/containers/containers.go +++ b/pkg/apm/webrtc/rtc_base/containers/containers.go @@ -1,5 +1,3 @@ -//go:build console - package containers // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/experiments/experiments.go b/pkg/apm/webrtc/rtc_base/experiments/experiments.go index 3998e583..3a49e287 100644 --- a/pkg/apm/webrtc/rtc_base/experiments/experiments.go +++ b/pkg/apm/webrtc/rtc_base/experiments/experiments.go @@ -1,5 +1,3 @@ -//go:build console - package experiments // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/memory/memory.go b/pkg/apm/webrtc/rtc_base/memory/memory.go index 660110d0..822f468c 100644 --- a/pkg/apm/webrtc/rtc_base/memory/memory.go +++ b/pkg/apm/webrtc/rtc_base/memory/memory.go @@ -1,5 +1,3 @@ -//go:build console - package memory // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/numerics/numerics.go b/pkg/apm/webrtc/rtc_base/numerics/numerics.go index e61a6f66..c668842f 100644 --- a/pkg/apm/webrtc/rtc_base/numerics/numerics.go +++ b/pkg/apm/webrtc/rtc_base/numerics/numerics.go @@ -1,5 +1,3 @@ -//go:build console - package numerics // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/rtc_base.go b/pkg/apm/webrtc/rtc_base/rtc_base.go index 3b37bcb3..6e3f12cd 100644 --- a/pkg/apm/webrtc/rtc_base/rtc_base.go +++ b/pkg/apm/webrtc/rtc_base/rtc_base.go @@ -1,5 +1,3 @@ -//go:build console - package rtc_base // #cgo CXXFLAGS: -I${SRCDIR}/.. -I${SRCDIR}/../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/strings/strings.go b/pkg/apm/webrtc/rtc_base/strings/strings.go index a0b85bc0..57591f07 100644 --- a/pkg/apm/webrtc/rtc_base/strings/strings.go +++ b/pkg/apm/webrtc/rtc_base/strings/strings.go @@ -1,5 +1,3 @@ -//go:build console - package strings // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/synchronization/sync.go b/pkg/apm/webrtc/rtc_base/synchronization/sync.go index 6455eb49..38294292 100644 --- a/pkg/apm/webrtc/rtc_base/synchronization/sync.go +++ b/pkg/apm/webrtc/rtc_base/synchronization/sync.go @@ -1,5 +1,3 @@ -//go:build console - package synchronization // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/rtc_base/system/system.go b/pkg/apm/webrtc/rtc_base/system/system.go index 5611e735..b4fcaf4d 100644 --- a/pkg/apm/webrtc/rtc_base/system/system.go +++ b/pkg/apm/webrtc/rtc_base/system/system.go @@ -1,5 +1,3 @@ -//go:build console - package system // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/system_wrappers/source/system.go b/pkg/apm/webrtc/system_wrappers/source/system.go index d4a53283..e75537a3 100644 --- a/pkg/apm/webrtc/system_wrappers/source/system.go +++ b/pkg/apm/webrtc/system_wrappers/source/system.go @@ -1,5 +1,3 @@ -//go:build console - package source // #cgo CXXFLAGS: -I${SRCDIR}/../.. -I${SRCDIR}/../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/base/base.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/base/base.go index d8af2104..187075d0 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/base/base.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/base/base.go @@ -1,5 +1,3 @@ -//go:build console - package base // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/container/container.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/container/container.go index d14fa28b..c55f1144 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/container/container.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/container/container.go @@ -1,5 +1,3 @@ -//go:build console - package container // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/crc/crc.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/crc/crc.go index 6090c125..4cfa5cdc 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/crc/crc.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/crc/crc.go @@ -1,5 +1,3 @@ -//go:build console - package crc // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/debugging/debugging.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/debugging/debugging.go index 6438ccc5..43c08e06 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/debugging/debugging.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/debugging/debugging.go @@ -1,5 +1,3 @@ -//go:build console - package debugging // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/flags/flags.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/flags/flags.go index 567e0131..36ebd43f 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/flags/flags.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/flags/flags.go @@ -1,5 +1,3 @@ -//go:build console - package flags // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/hash/hash.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/hash/hash.go index a23ce5e4..dd73d8b3 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/hash/hash.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/hash/hash.go @@ -1,5 +1,3 @@ -//go:build console - package hash // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/log/log.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/log/log.go index 4c81f98d..a03532a4 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/log/log.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/log/log.go @@ -1,5 +1,3 @@ -//go:build console - package log // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/numeric/numeric.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/numeric/numeric.go index d175449c..4333e15b 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/numeric/numeric.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/numeric/numeric.go @@ -1,5 +1,3 @@ -//go:build console - package numeric // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/profiling/profiling.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/profiling/profiling.go index 23bc7353..ef7975f4 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/profiling/profiling.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/profiling/profiling.go @@ -1,5 +1,3 @@ -//go:build console - package profiling // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/random/random.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/random/random.go index 0aae1914..a497e7e8 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/random/random.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/random/random.go @@ -1,5 +1,3 @@ -//go:build console - package random // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/status/status.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/status/status.go index 243626a6..c3ccdab1 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/status/status.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/status/status.go @@ -1,5 +1,3 @@ -//go:build console - package status // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/strings/strings.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/strings/strings.go index 66f2dfee..20fbe7e8 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/strings/strings.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/strings/strings.go @@ -1,5 +1,3 @@ -//go:build console - package strings // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/synchronization/sync.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/synchronization/sync.go index 95aee9a9..a12614ab 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/synchronization/sync.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/synchronization/sync.go @@ -1,5 +1,3 @@ -//go:build console - package synchronization // #cgo CXXFLAGS: -I${SRCDIR}/../../../.. -I${SRCDIR}/../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/abseil-cpp/absl/time/src/src.go b/pkg/apm/webrtc/third_party/abseil-cpp/absl/time/src/src.go index 9d67259c..009e28e5 100644 --- a/pkg/apm/webrtc/third_party/abseil-cpp/absl/time/src/src.go +++ b/pkg/apm/webrtc/third_party/abseil-cpp/absl/time/src/src.go @@ -1,5 +1,3 @@ -//go:build console - package src // #cgo CXXFLAGS: -I${SRCDIR}/../../../../.. -I${SRCDIR}/../../../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/third_party/pffft/src/pffft.go b/pkg/apm/webrtc/third_party/pffft/src/pffft.go index f7c5e66c..dc7e8300 100644 --- a/pkg/apm/webrtc/third_party/pffft/src/pffft.go +++ b/pkg/apm/webrtc/third_party/pffft/src/pffft.go @@ -1,5 +1,3 @@ -//go:build console - package src // #cgo CFLAGS: -Wno-unused-parameter -Wno-sign-compare diff --git a/pkg/apm/webrtc/third_party/rnnoise/src/src.go b/pkg/apm/webrtc/third_party/rnnoise/src/src.go index b1bd0eb6..722b4221 100644 --- a/pkg/apm/webrtc/third_party/rnnoise/src/src.go +++ b/pkg/apm/webrtc/third_party/rnnoise/src/src.go @@ -1,5 +1,3 @@ -//go:build console - package src // #cgo CXXFLAGS: -I${SRCDIR}/../../.. -I${SRCDIR}/../../../third_party/abseil-cpp -std=c++17 -fno-rtti -DWEBRTC_APM_DEBUG_DUMP=0 -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -DNDEBUG -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-deprecated-declarations -Wno-nullability-completeness -Wno-shorten-64-to-32 diff --git a/pkg/apm/webrtc/webrtc.go b/pkg/apm/webrtc/webrtc.go index c67225ea..b396054e 100644 --- a/pkg/apm/webrtc/webrtc.go +++ b/pkg/apm/webrtc/webrtc.go @@ -1,5 +1,3 @@ -//go:build console - // Package webrtc provides WebRTC audio processing module (APM) source compiled via CGo. // This package and its sub-packages contain the extracted WebRTC APM C++ source. // Import this package (typically via blank import) to link all WebRTC APM object files. diff --git a/pkg/apm/webrtc/webrtc_darwin.go b/pkg/apm/webrtc/webrtc_darwin.go index 952fc952..66ab9cf6 100644 --- a/pkg/apm/webrtc/webrtc_darwin.go +++ b/pkg/apm/webrtc/webrtc_darwin.go @@ -1,5 +1,3 @@ -//go:build console - package webrtc import _ "github.com/livekit/livekit-cli/v2/pkg/apm/webrtc/api/task_queue/gcd" diff --git a/pkg/apm/webrtc/webrtc_linux.go b/pkg/apm/webrtc/webrtc_linux.go index 835db605..52d6ea1e 100644 --- a/pkg/apm/webrtc/webrtc_linux.go +++ b/pkg/apm/webrtc/webrtc_linux.go @@ -1,5 +1,3 @@ -//go:build console - package webrtc import _ "github.com/livekit/livekit-cli/v2/pkg/apm/webrtc/api/task_queue/stdlib" diff --git a/pkg/apm/webrtc/webrtc_windows.go b/pkg/apm/webrtc/webrtc_windows.go index 835db605..52d6ea1e 100644 --- a/pkg/apm/webrtc/webrtc_windows.go +++ b/pkg/apm/webrtc/webrtc_windows.go @@ -1,5 +1,3 @@ -//go:build console - package webrtc import _ "github.com/livekit/livekit-cli/v2/pkg/apm/webrtc/api/task_queue/stdlib" diff --git a/pkg/config/config.go b/pkg/config/config.go index 21b0cebf..42d444fe 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -72,7 +72,6 @@ func LoadProjectBySubdomain(subdomain string) (*ProjectConfig, error) { for _, p := range conf.Projects { projectSubdomain := util.ExtractSubdomain(p.URL) if projectSubdomain == subdomain { - fmt.Printf("Using project [%s]\n", util.Accented(p.Name)) return &p, nil } } diff --git a/pkg/console/fft.go b/pkg/console/fft.go index b1ac4983..dd800e7a 100644 --- a/pkg/console/fft.go +++ b/pkg/console/fft.go @@ -1,5 +1,3 @@ -//go:build console - package console import ( diff --git a/pkg/console/pipeline.go b/pkg/console/pipeline.go index 89a7c6db..933c4c97 100644 --- a/pkg/console/pipeline.go +++ b/pkg/console/pipeline.go @@ -1,5 +1,3 @@ -//go:build console - // Package console implements the audio pipeline for the lk console command. // It connects microphone input and speaker output via PortAudio, applies // WebRTC audio processing (echo cancellation, noise suppression), and diff --git a/pkg/console/ringbuffer.go b/pkg/console/ringbuffer.go index 29648bb4..b4b7eba1 100644 --- a/pkg/console/ringbuffer.go +++ b/pkg/console/ringbuffer.go @@ -1,5 +1,3 @@ -//go:build console - package console import ( diff --git a/pkg/console/tcp.go b/pkg/console/tcp.go index 6b3efbad..2a30c1fa 100644 --- a/pkg/console/tcp.go +++ b/pkg/console/tcp.go @@ -1,5 +1,3 @@ -//go:build console - package console import ( diff --git a/pkg/portaudio/portaudio.go b/pkg/portaudio/portaudio.go index 5670e538..c5ba06ab 100644 --- a/pkg/portaudio/portaudio.go +++ b/pkg/portaudio/portaudio.go @@ -1,5 +1,3 @@ -//go:build console - // Package portaudio provides Go bindings for PortAudio, compiled from vendored source. package portaudio diff --git a/pkg/portaudio/portaudio_darwin.go b/pkg/portaudio/portaudio_darwin.go index 5a989cb5..cb340a6b 100644 --- a/pkg/portaudio/portaudio_darwin.go +++ b/pkg/portaudio/portaudio_darwin.go @@ -1,5 +1,3 @@ -//go:build console - package portaudio /* diff --git a/pkg/portaudio/portaudio_linux.go b/pkg/portaudio/portaudio_linux.go index f66fbb5d..f9ffbeec 100644 --- a/pkg/portaudio/portaudio_linux.go +++ b/pkg/portaudio/portaudio_linux.go @@ -1,5 +1,3 @@ -//go:build console - package portaudio /* diff --git a/pkg/portaudio/portaudio_windows.go b/pkg/portaudio/portaudio_windows.go index a91e00fe..7a4e362f 100644 --- a/pkg/portaudio/portaudio_windows.go +++ b/pkg/portaudio/portaudio_windows.go @@ -1,5 +1,3 @@ -//go:build console - package portaudio /* diff --git a/pkg/util/printer.go b/pkg/util/printer.go new file mode 100644 index 00000000..dc81eb6f --- /dev/null +++ b/pkg/util/printer.go @@ -0,0 +1,97 @@ +// Copyright 2026 LiveKit, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Conventional CLI output: results go to stdout, everything else (status, +// diagnostics, warnings) goes to stderr. The stream split alone keeps redirected +// or piped result data clean; --quiet silences informational status without +// touching warnings or errors. TTY-gated decoration (color, spinners) is handled +// by lipgloss/termenv and the huh spinner respectively. + +package util + +import ( + "fmt" + "io" + "os" +) + +// Printer is a single sink for human-facing CLI output. One instance per process +// is initialized from the root command and reused everywhere, so all status, +// warning, and result lines share consistent streams and gating. +type Printer struct { + Out io.Writer // primary output: data the user might pipe or redirect + Err io.Writer // status, warnings, diagnostics + Quiet bool // suppresses Status (warnings and errors still print) +} + +// NewPrinter builds a Printer targeting the given writers. Pass nil to default +// to os.Stdout / os.Stderr; this is the path tests use with bytes.Buffer. +func NewPrinter(out, err io.Writer, quiet bool) *Printer { + if out == nil { + out = os.Stdout + } + if err == nil { + err = os.Stderr + } + return &Printer{Out: out, Err: err, Quiet: quiet} +} + +// Status writes an informational breadcrumb to stderr ("Using project [X]", +// "Cloning template…"). Suppressed by --quiet. A trailing newline is appended. +func (p *Printer) Status(a ...any) { + if p == nil || p.Quiet { + return + } + fmt.Fprintln(p.Err, a...) +} + +// Statusf is Printf-style Status. +func (p *Printer) Statusf(format string, a ...any) { + if p == nil || p.Quiet { + return + } + fmt.Fprintf(p.Err, ensureNewline(format), a...) +} + +// Warnf writes a warning to stderr. NOT suppressed by --quiet — warnings are +// always worth surfacing. +func (p *Printer) Warnf(format string, a ...any) { + if p == nil { + return + } + fmt.Fprintf(p.Err, ensureNewline(format), a...) +} + +// Result writes the command's primary output to stdout. Always printed. +func (p *Printer) Result(a ...any) { + if p == nil { + return + } + fmt.Fprintln(p.Out, a...) +} + +// Resultf is Printf-style Result. +func (p *Printer) Resultf(format string, a ...any) { + if p == nil { + return + } + fmt.Fprintf(p.Out, format, a...) +} + +func ensureNewline(s string) string { + if len(s) == 0 || s[len(s)-1] != '\n' { + return s + "\n" + } + return s +} diff --git a/pkg/util/printer_test.go b/pkg/util/printer_test.go new file mode 100644 index 00000000..21de46c6 --- /dev/null +++ b/pkg/util/printer_test.go @@ -0,0 +1,64 @@ +// Copyright 2026 LiveKit, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPrinter_StreamsAndQuiet(t *testing.T) { + var out, err bytes.Buffer + p := NewPrinter(&out, &err, false) + + p.Result("data") + p.Resultf("%d items\n", 3) + p.Status("doing thing") + p.Statusf("using %s", "x") + p.Warnf("permissions look off: %o", 0644) + + assert.Equal(t, "data\n3 items\n", out.String(), "Result* writes only to stdout") + assert.Equal(t, + "doing thing\nusing x\npermissions look off: 644\n", + err.String(), + "Status* and Warnf write only to stderr, with trailing newlines", + ) +} + +func TestPrinter_QuietSuppressesOnlyStatus(t *testing.T) { + var out, err bytes.Buffer + p := NewPrinter(&out, &err, true) + + p.Status("breadcrumb") + p.Statusf("formatted %s", "breadcrumb") + p.Warnf("warn %d", 1) + p.Resultf("result\n") + + assert.Empty(t, "", err.String()[:0], "sanity") + assert.NotContains(t, err.String(), "breadcrumb", "--quiet suppresses Status") + assert.Contains(t, err.String(), "warn 1", "--quiet does NOT suppress warnings") + assert.Equal(t, "result\n", out.String(), "results unaffected by --quiet") +} + +func TestPrinter_NilSafe(t *testing.T) { + var p *Printer // calling on a nil receiver should be a no-op + p.Status("x") + p.Statusf("y %d", 1) + p.Warnf("z") + p.Result("a") + p.Resultf("b\n") +} diff --git a/pkg/util/theme.go b/pkg/util/theme.go index 247168d2..d9988f7a 100644 --- a/pkg/util/theme.go +++ b/pkg/util/theme.go @@ -37,4 +37,14 @@ var ( Fg = lipgloss.AdaptiveColor{Light: "235", Dark: "252"} FormBaseStyle = Theme.Form.Base.Foreground(Fg).Padding(0, 1) FormHeaderStyle = FormBaseStyle.Bold(true) + + // Form helpers + Confirm = func() *huh.Select[bool] { + return huh.NewSelect[bool](). + Options( + huh.NewOption("Yes", true), + huh.NewOption("No", false), + ). + Inline(false) + } ) diff --git a/scripts/setup-cross.sh b/scripts/setup-cross.sh new file mode 100755 index 00000000..ef534f3c --- /dev/null +++ b/scripts/setup-cross.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +# Prepare per-target cross-compile inputs for `go build` / `goreleaser build`. +# +# Usage: scripts/setup-cross.sh +# target: linux/amd64 | linux/arm64 | windows/amd64 | windows/arm64 | darwin/arm64 +# +# Outputs (under .cross//): +# include/ — headers for the target (linux only) +# lib/ — static libraries for the target (linux only) +# +# For windows targets, also pre-generates MinGW import libraries in zig's lib +# dir (lld needs .a, but zig only bundles .def files). +# +# Idempotent: re-runs skip work if outputs already exist. + +set -euo pipefail + +ALSA_VERSION="1.2.12" +ALSA_URL="https://www.alsa-project.org/files/pub/lib/alsa-lib-${ALSA_VERSION}.tar.bz2" + +target="${1:-}" +if [ -z "$target" ]; then + echo "usage: $0 " >&2 + echo " target: linux/{amd64,arm64} | windows/{amd64,arm64} | darwin/arm64" >&2 + exit 2 +fi + +root="$(cd "$(dirname "$0")/.." && pwd)" +out_dir="$root/.cross/${target//\//_}" +mkdir -p "$out_dir" + +build_alsa() { + local zig_target="$1" host="$2" + local prefix="$out_dir" + local stamp="$prefix/.alsa-${ALSA_VERSION}.stamp" + + if [ -f "$stamp" ] && [ -f "$prefix/lib/libasound.a" ]; then + echo "[$target] alsa-lib ${ALSA_VERSION} already built" + return + fi + + echo "[$target] building alsa-lib ${ALSA_VERSION} with zig cc -target $zig_target" + + local work + work="$(mktemp -d)" + trap "rm -rf '$work'" RETURN + + ( + cd "$work" + curl -fsSL "$ALSA_URL" | tar xjf - + cd "alsa-lib-${ALSA_VERSION}" + + # zig cc wraps clang and accepts a -target triple; we make it look like + # a single binary to configure scripts that don't quote $CC. + local cc_wrap="$work/zigcc" + cat > "$cc_wrap" </dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)" \ + || make -j1 + make install + ) + + touch "$stamp" + echo "[$target] alsa-lib installed to $prefix" +} + +generate_mingw_libs() { + local machine="$1" + local zig_lib def_dir + # zig 0.14 outputs JSON ("lib_dir": "..."); zig 0.16 outputs ZON + # (.lib_dir = "..."). This pattern matches both. + zig_lib="$(zig env | sed -n 's/.*lib_dir[^"]*"\([^"]*\)".*/\1/p')" + def_dir="$zig_lib/libc/mingw/lib-common" + + if [ ! -d "$def_dir" ]; then + echo "[$target] zig lib dir not found at $def_dir" >&2 + return 1 + fi + + local mingw_out="$out_dir/mingw_lib" + mkdir -p "$mingw_out" + local stamp="$mingw_out/.generated.stamp" + + if [ -f "$stamp" ]; then + echo "[$target] MinGW import libs already generated" + return + fi + + # Go's compiled objects embed COFF /DEFAULTLIB directives (dbghelp, bcrypt, + # ...) that lld resolves directly, bypassing zig's lazy .def→.a generation. + # Generate into a per-arch directory so windows/amd64 and windows/arm64 can + # build in the same goreleaser run without clobbering each other. + local generated=0 + for def in "$def_dir"/*.def; do + local lib + lib="$(basename "$def" .def)" + if zig dlltool -d "$def" -l "$mingw_out/lib${lib}.a" -m "$machine" 2>/dev/null; then + generated=$((generated + 1)) + fi + done + touch "$stamp" + echo "[$target] generated $generated MinGW import libs in $mingw_out" +} + +case "$target" in + linux/amd64) + build_alsa "x86_64-linux-gnu.2.28" "x86_64-linux-gnu" + ;; + linux/arm64) + build_alsa "aarch64-linux-gnu.2.28" "aarch64-linux-gnu" + ;; + windows/amd64) + generate_mingw_libs "i386:x86-64" + ;; + windows/arm64) + generate_mingw_libs "arm64" + ;; + darwin/arm64|darwin/amd64) + echo "[$target] no cross setup needed (native build)" + ;; + *) + echo "unknown target: $target" >&2 + exit 2 + ;; +esac