# Foxglove CLI Interact with Foxglove, directly from the command line. Once you've installed the CLI tool, run `foxglove -h` from the command line for a complete list of subcommands, arguments, and usage details. More information can also be found in the [Foxglove API docs](https://docs.foxglove.dev/api). ## Installation Download the latest release for your OS and architecture: | OS/Arch | | | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | | linux/amd64 | curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-linux-amd64 -o foxglove && chmod +x foxglove | | macos/amd64 | curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-macos-amd64 -o foxglove && chmod +x foxglove | | windows/amd64 | curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-windows-amd64.exe -o foxglove.exe | | linux/arm64 | curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-linux-arm64 -o foxglove && chmod +x foxglove | | macos/arm64 | curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-macos-arm64 -o foxglove && chmod +x foxglove | | windows/arm64 | curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-windows-arm64.exe -o foxglove.exe | To install a specific release, see the [releases page](https://github.com/foxglove/foxglove-cli/releases). Alternatively, install the CLI tool from source (requires Go >= 1.21) – this will install it to `$GOPATH/bin`: $ git clone git@github.com:foxglove/foxglove-cli.git $ make install ## Getting started Create a [free Foxglove account](https://app.foxglove.dev/signup) to start importing and interacting with data. ### Authentication Log in to your Foxglove account from the command line: ``` $ foxglove auth login ``` Alternatively, you can configure the tool to use a [Foxglove API key](https://docs.foxglove.dev/docs/organization-setup/settings/#api-keys): ``` $ foxglove auth configure-api-key ``` This will overwrite any previously set credential. Use the [API key settings page](https://app.foxglove.dev/~/settings/apikeys) to add the capabilities you intend to use (e.g. `data.upload` for importing data, `data.stream` for exporting, etc.). ### Devices Before importing data, you must first create a device: ``` $ foxglove devices add --name RobotA Device created: dev_drpLqjBZYUzus3gv ``` List all devices: ``` $ foxglove devices list | ID | NAME | CREATED AT | UPDATED AT | |----------------------|--------------------|----------------------|----------------------| | dev_mHH1Cp4gPybCPR8y | Adrian's Robot | 2021-10-28T17:20:55Z | 2021-10-28T17:20:55Z | | dev_WEJUVEOVApoIpe1M | GPS | 2021-11-01T17:38:55Z | 2021-11-01T17:38:55Z | | dev_drpLqjBZYUzus3gv | updog | 2021-11-25T02:22:45Z | 2021-11-25T02:22:45Z | | dev_lwjzOMxryMmP3yXg | nuScenes-v1.0-mini | 2021-12-09T21:45:51Z | 2021-12-09T21:45:51Z | ``` ### Projects Projects provide data isolation and access control to resources. See if your organization's plan supports [Projects](https://docs.foxglove.dev/docs/projects). List all projects: ``` $ foxglove projects list | ID | NAME | MEMBER COUNT | LAST RECORDING UPLOADED AT | |----------------------|--------------------|--------------|----------------------------| | prj_mHH1Cp4gPybCPR8y | | 7 | 2021-10-28T17:20:55Z | | prj_WEJUVEOVApoIpe1M | My First Project | 11 | 2021-11-01T17:38:55Z | ``` ### Imports Import ROS 1 bag and [MCAP](https://mcap.dev) files into the Foxglove platform: ``` $ foxglove data import ~/data/bags/gps.bag --device-name RobotA ``` List all imports: ``` $ foxglove data imports list | IMPORT ID | DEVICE ID | FILENAME | IMPORT TIME | START | END | INPUT TYPE | OUTPUT TYPE | INPUT SIZE | TOTAL OUTPUT SIZE | |--------------------------------------|----------------------|------------------------------------|----------------------|----------------------|----------------------|------------|-------------|------------|-------------------| | 55c8480b-0fef-243a-ea74-f07063f51c6e | dev_flm75pLkfzUBX2DH | demo.bag | 2022-01-28T22:37:44Z | 2017-03-22T02:26:20Z | 2017-03-22T02:26:27Z | bag1 | mcap0 | 70311473 | 68833788 | | 31285b3d-3f97-ea58-3751-a1597ae3f16f | dev_Wm1gvryKJmREqnVT | transbot_2022-02-21-21-58-17_1.bag | 2022-02-21T22:03:32Z | 2022-02-21T21:58:17Z | 2022-02-21T21:58:21Z | bag1 | mcap0 | 12823 | 8847 | | 837cfa3e-541e-9540-1c7a-a1f1b3ef3694 | dev_jCuXYeFwCkZowpHs | gps4.bag | 2022-03-17T12:34:34Z | 2021-03-22T15:03:38Z | 2021-03-22T15:09:18Z | bag1 | mcap0 | 5321782 | 1619916 | | 820e51d8-9f1d-8ec5-f586-41bbaa87d45d | dev_JOgi4YiCRgaoszKw | input.bag | 2021-11-02T16:34:49Z | 2016-11-18T23:46:10Z | 2016-11-18T23:51:25Z | bag1 | mcap0 | 1770886024 | 1571403963 | | 8f563534-264d-ad79-b404-684c8639d4a0 | dev_Wm1gvryKJmREqnVT | transbot_2022-02-21-19-44-47_1.bag | 2022-02-21T20:12:54Z | 2022-02-21T19:44:47Z | 2022-02-21T19:44:47Z | bag1 | mcap0 | 10964 | 8196 | | b8c45da6-2110-8c77-370f-a6ec482cdcf6 | dev_Wm1gvryKJmREqnVT | transbot_2022-02-21-22-49-04_0.bag | 2022-02-21T22:50:48Z | 2022-02-21T22:49:05Z | 2022-02-21T22:49:23Z | bag1 | mcap0 | 16734 | 10688 | | 0a400ef1-3892-1c6c-3a38-c0a80ed85749 | dev_JtSXCGiM0RC2YHDO | nuscenes.bag | 2022-02-24T15:13:32Z | 2018-07-24T03:28:47Z | 2018-07-24T03:29:06Z | bag1 | mcap0 | 87397054 | 85923915 | | 0a400ef1-3892-1c6c-3a38-c0a80ed85749 | dev_mHH1Cp4gPybCPR8y | nuscenes-0061-v1.bag | 2022-01-11T22:05:09Z | 2018-07-24T03:28:47Z | 2018-07-24T03:29:06Z | bag1 | mcap0 | 87397054 | 85923915 | | 5ad56d95-7dcc-f12a-9b09-0f4d4ec9e2e5 | dev_mHH1Cp4gPybCPR8y | input.bag | 2021-11-03T23:21:37Z | 2017-03-22T02:26:20Z | 2017-03-22T02:26:26Z | bag1 | mcap0 | 32761 | 38542 | ``` ### Exports Retrieve data for a device, time range, and optional list of topics, and export it directly to the console (`--output-format json`) or to a new file (`--output-format mcap0` or `--output-format bag1`): ``` # Output JSON (directly to console) $ foxglove data export --device-name RobotA --start 2001-01-01T00:00:00Z --end 2022-01-01T00:00:00Z --topics /tf --output-format json | head -n 5 {"topic":"/tf","sequence":0,"log_time":1490149580.103843113,"publish_time":1490149580.103843113,"data":{"transforms":[{"header":{"seq":0,"stamp":1490149580.117017840,"frame_id":"base_link"},"child_frame_id":"radar","transform":{"translation":{"x":3.835,"y":0,"z":0},"rotation":{"x":0,"y":0,"z":0,"w":1}}}]}} {"topic":"/tf","sequence":0,"log_time":1490149580.113944947,"publish_time":1490149580.113944947,"data":{"transforms":[{"header":{"seq":0,"stamp":1490149580.127078895,"frame_id":"base_link"},"child_frame_id":"radar","transform":{"translation":{"x":3.835,"y":0,"z":0},"rotation":{"x":0,"y":0,"z":0,"w":1}}}]}} {"topic":"/tf","sequence":0,"log_time":1490149580.124028613,"publish_time":1490149580.124028613,"data":{"transforms":[{"header":{"seq":0,"stamp":1490149580.137141823,"frame_id":"base_link"},"child_frame_id":"radar","transform":{"translation":{"x":3.835,"y":0,"z":0},"rotation":{"x":0,"y":0,"z":0,"w":1}}}]}} {"topic":"/tf","sequence":0,"log_time":1490149580.134219155,"publish_time":1490149580.134219155,"data":{"transforms":[{"header":{"seq":0,"stamp":1490149580.147199242,"frame_id":"base_link"},"child_frame_id":"radar","transform":{"translation":{"x":3.835,"y":0,"z":0},"rotation":{"x":0,"y":0,"z":0,"w":1}}}]}} {"topic":"/tf","sequence":0,"log_time":1490149580.144292780,"publish_time":1490149580.144292780,"data":{"transforms":[{"header":{"seq":0,"stamp":1490149580.157286100,"frame_id":"base_link"},"child_frame_id":"radar","transform":{"translation":{"x":3.835,"y":0,"z":0},"rotation":{"x":0,"y":0,"z":0,"w":1}}}]}} # Output MCAP file (output.mcap) $ foxglove data export --device-name RobotA --start 2001-01-01T00:00:00Z --end 2022-01-01T00:00:00Z --output-format mcap0 --topics /gps/fix,/gps/fix_velocity > output.mcap # Output ROS 1 bag file (output.bag) $ foxglove data export --device-name RobotA --start 2001-01-01T00:00:00Z --end 2022-01-01T00:00:00Z --output-format bag1 --topics /gps/fix,/gps/fix_velocity > output.bag ``` If you've output a file, inspect its contents: ``` # MCAP file $ mcap info output.mcap library: mcap go #(devel); fg-data-platform-db07abe7 profile: ros1 messages: 6728 duration: 5m39.304931438s start: 2021-03-22T08:03:38.473036858-07:00 (1616425418.473036858) end: 2021-03-22T08:09:17.777968296-07:00 (1616425757.777968296) compression: lz4: [1/1 chunks] (86.05%) channels: (1) /gps/fix 3364 msgs (9.91 Hz) : sensor_msgs/NavSatFix [ros1msg] (2) /gps/fix_velocity 3364 msgs (9.91 Hz) : geometry_msgs/TwistWithCovarianceStamped [ros1msg] attachments: 0 # ROS 1 bag file $ rosbag reindex output.bag $ rosbag info output.bag path: output.bag version: 2.0 duration: 5:39s (339s) start: Mar 22 2021 08:03:38.47 (1616425418.47) end: Mar 22 2021 08:09:17.78 (1616425757.78) size: 328.6 KB messages: 6728 compression: lz4 [1/1 chunks; 12.87%] uncompressed: 1.8 MB @ 5.5 KB/s compressed: 240.0 KB @ 0.7 KB/s (12.87%) types: geometry_msgs/TwistWithCovarianceStamped [b00b6ce36bf21f646151de97da2c485c] sensor_msgs/NavSatFix [7f6e605ad1e52d05162190ff17be80b6] topics: /gps/fix 3364 msgs : sensor_msgs/NavSatFix /gps/fix_velocity 3364 msgs : geometry_msgs/TwistWithCovarianceStamped ``` ### Events Create events to denote instances or time ranges of interest: ``` $ foxglove events add --device-id dev_mHH1Cp4gPybCPR8y \ --start 2023-04-19T13:26:37.030302Z --end 2023-04-19T13:26:37.030302Z \ --metadata requires-labeling:true ``` List all events: ``` $ foxglove events list | ID | DEVICE ID | START | END | CREATED AT | UPDATED AT | METADATA | |----------------------|----------------------|-----------------------------|-----------------------------|--------------------------|--------------------------|------------------------------| | evt_N6doUtPYh8i7iZxf | dev_jCuXYeFwCkZowpHs | 2023-04-19T13:22:44.194041Z | 2023-04-19T13:22:44.194041Z | 2023-04-19T13:22:44.263Z | 2023-04-19T13:22:44.263Z | {} | | evt_idMGJImlICYP4dcy | dev_mHH1Cp4gPybCPR8y | 2023-04-19T13:26:37.030302Z | 2023-04-19T13:26:37.030302Z | 2023-04-19T13:26:37.080Z | 2023-04-19T13:26:37.080Z | {"requires-labeling":"true"} | ``` ### Extensions With a Foxglove [Team plan](https://foxglove.dev/pricing), you can upload and share [extensions](https://foxglove.dev/docs/studio/extensions/getting-started) within your organization. Create and package an extension with the [`foxglove-extension`](https://github.com/foxglove/create-foxglove-extension/) tool. Publish an extension to install it for all Foxglove organization members: ``` $ foxglove extensions publish ./my-extension.1.0.0.foxe ``` Use this same command to update an existing extension with a newer version – the last published version of an extension will be installed across your organization. List all extensions: ``` $ foxglove extensions list [ { "id": "ext_BsGXKGsZ9c4WQF1", "name": "my_new_panel", "publisher": "panel-publisher", "displayName": "My New Panel", "description": "Creates a panel", "activeVersion": "1.0.0", "sha256Sum": "395c3af8745ab104cd902d937366719a402bda4677ed3671cb38522c1ba13cbe" } ] ``` Unpublish an extension by its ID to **delete** its files and uninstall it for all Foxglove organization members: ``` $ foxglove extensions unpublish ext_BsGXKGsZ9c4WQF1 ``` ## Shell autocompletion Certain shells (bash, zsh, fish, and PowerShell) support autocompletion for subcommands and certain parameters (like device IDs). To enable this, consult your shell instructions under `$ foxglove completion -h`. ## Development To build and test locally ```sh cd foxglove make build # run tests make test # or run the local version of the cli ./foxglove --help ``` To release a new version 1. Draft a new [release](https://github.com/foxglove/foxglove-cli/releases) 2. Create a new tag via the UI following the `v1.0.31` format 3. Auto generate release notes and review them 4. Publish the release. An action will build the assets ## Stay in touch Join our [Discord community](https://foxglove.dev/chat) to ask questions, share feedback, and stay up to date on what our team is working on.