Skip to content

CLI

One binary, fsl, with four commands. Run it with npx fsl <command>.

Terminal window
npx fsl help

fsl help, fsl --help or -h after any command prints the usage text and exits 0. An unknown command prints it and exits 1. The CLI loads .env.local from the current folder first.

Terminal window
npx fsl upload-sourcemaps --backend=./functions --embed-sourcemaps
npx fsl upload-sourcemaps --backend=./functions --embed-sourcemaps --bucket=my-maps --prefix=fsl-maps
npx fsl upload-sourcemaps --bucket= --backend=./backend --embed-sourcemaps

Uploads .map files from dist/ to Cloud Storage and deletes them locally. Run it in your deploy script, between the build and the deploy. See Source maps.

Flag Meaning
--bucket=<name> The bucket. Defaults to VITE_FIREBASE_STORAGE_BUCKET, then FIREBASE_STORAGE_BUCKET. An empty --bucket= means no bucket, whatever those two hold.
--backend=<path> The backend folder, such as ./functions or ./backend. --functions is a deprecated alias.
--embed-sourcemaps Copy the maps to {backend}/sourcemaps/current/ for fast lookup of the current release.
--release=<id> The release id. Defaults to VITE_RELEASE_ID, then RELEASE_ID. With none of them set, it exits 1.
--dist=<path> The build folder to read maps from. Defaults to ./dist.
--prefix=<path> The Storage prefix to upload under. Defaults to sourcemaps/.

Maps are stored at gs://<bucket>/sourcemaps/<releaseId>/<filename>.map. The prefix must match sourceMaps: { prefix } on the log function, or maps are not found.

With --embed-sourcemaps and no bucket, it embeds the current release and uploads nothing. Only the deployed release can then be resolved. With neither a bucket nor --embed-sourcemaps, it prints usage and exits 1. If the upload fails but the maps were embedded, it exits 3.

It authenticates with FIREBASE_SERVICE_ACCOUNT_PATH when set, otherwise with application-default credentials.

Terminal window
npx fsl doctor
npx fsl doctor --backend=./server --dist=./dist
npx fsl doctor --strict --json

Checks the setup from disk, with no network and no credentials. It reads firebase.json when present. See fsl doctor.

Flag Meaning
--backend=<path> The backend folder, when there is no firebase.json.
--dist=<path> The web build folder, when there is no firebase.json.
--strict Fail on warnings as well as errors.
--json Print JSON instead of the report.

Exit code 0 with no errors, 1 with an error, or with a warning under --strict.

Terminal window
npx fsl logs --where labels.userId=<uid> --since 2h
npx fsl logs schema
npx fsl logs attachments <logId>

Reads production logs through gcloud logging read, or .fsl-logs/*.jsonl with --local. One JSON entry per line. See fsl logs.

Flag Meaning
--where field=value A condition, repeatable. Operators =, !=, >=, <=, ~.
--select a,b,count Fields to print. With no value, lists the fields.
--group-by field Aggregate per value.
--order-by "field desc" Sort order.
--limit N 100 by default, 1000 at most.
--distinct field Distinct values of a field.
--since 1h 30m, 1h, 2d or an ISO time. 1 hour by default.
--repeats <repeatKey> One repeating error, with its true count.
--local Read .fsl-logs/ instead of Cloud Logging.
--project <id> The project. Read from .firebaserc when not given.
Flag Meaning
--refresh Re-read the logs. --add entries are kept.
--add name [meaning] Record a label your code can write. Repeatable.
--remove name Drop a label recorded with --add. Repeatable.
--json Print JSON.
--local Read the local files.
--project <id> The project.
Terminal window
npx fsl logs attachments <logId> --bucket <name>

Downloads an entry’s files to .fsl-logs/attachments/<logId>/ through gcloud storage. The bucket is --bucket <name>, else FIREBASE_STORAGE_BUCKET, else VITE_FIREBASE_STORAGE_BUCKET. --project <id> names the project.

Terminal window
npx fsl install-skills
npx fsl install-skills --global --force

Copies the package’s skills to .claude/skills/, or ~/.claude/skills/ with --global. It prompts before overwriting, and before removing a skill the package no longer ships (logs, query-logs). --force skips the prompts. With no terminal to answer on and no --force, it asks nothing, installs what needs no answer, lists on stderr what it left, and exits 1. See Skills for coding agents.

Made by Dasasian