Flitzdocs
Integrating Flitz into your workflow

Publish from Claude in Slack

Let Claude Tag publish bundles from its cloud sandbox: allow the Flitz hosts, install the CLI, inject the organization API key at Claude's proxy, and ask in a thread.

Claude Tag puts Claude in your Slack channels, where it works in a cloud sandbox with your repositories. With the setup on this page, anyone in a channel can ask

@Claude publish a flitz bundle from branch main

and Claude checks out the branch, runs flitz publish, and posts the landing page and bundle links back in the thread. A publish, including the SDK download and the build, takes about a minute.

The organization API key never enters the sandbox or the Slack history: Claude's network proxy adds it to requests on their way to the Flitz service.

Prerequisites

  • Claude Tag is set up for your Slack workspace, and Claude can reach the app's repository through the Claude GitHub App.
  • The project pins an SDK in a committed flitz.yaml (flitz sdk use).
  • Your Flitz organization has an API key, from the Settings page of the portal or flitz apikey create. Keep the plaintext at hand for the connection below.
  • An Owner of your Claude organization, or a Claude Tag admin, to add the connection and network settings. Shared cloud environments are managed by Owners only.

Setup steps

  1. Allow network access in the sandbox.
  2. Install the Flitz CLI.
  3. Provide the API key in the environment.
  4. Add the Flitz skill.
  5. Publish the bundle.

Allow network access

The sandbox reaches only the hosts you allow. Flitz needs three:

HostUsed for
*.flitz.devThe CLI installer and update feed (download.flitz.dev), the Flitz service (api.flitz.dev), and the links (d.flitz.dev). The bare flitz.dev is not needed.
storage.googleapis.comThe SDK download and the bundle upload, through short-lived signed URLs.
pub.devYour app's Dart and Flutter package dependencies, fetched during the build.

All use HTTPS on port 443. Add *.flitz.dev to the Custom allowed-domains list of the cloud environment the channel runs in, with the default package-manager list included; storage.googleapis.com and pub.dev are already part of that default list. With customer bundle storage (Enterprise), the bundle upload goes to your own bucket instead. Amazon S3 and Google Cloud Storage hosts are on the default list; for Azure Blob Storage, also allow your storage account's host, <account>.blob.core.windows.net. See network access and which environment a channel uses.

Install the CLI

Claude installs the CLI in the thread before it publishes:

curl -fsSL https://download.flitz.dev/install.sh | sh

To have the CLI ready in every thread, add the same command to the setup script of the cloud environment, where you also set the placeholder key.

See Install for what the script checks. You do not install the SDK: flitz publish --yes downloads the pinned SDK on its first run. It is the Flitz SDK the project pins; a stock Flutter SDK cannot build bundles.

Provide the API key

Store the key as a Claude Tag connection, not as an environment variable. In the Claude Tag admin settings, open the Access bundle that covers the channel and add a custom connection on its Credentials tab (labels in the Claude UI may differ slightly):

  • Credential type: Bearer.
  • Allowed websites: api.flitz.dev.
  • Value: the plaintext organization API key.

When someone else holds the key, send them a setup link instead; the connection is active only after an Owner or admin approves it. See Add a connection.

Claude's proxy now replaces the Authorization header of every request to api.flitz.dev with the real key. The sandbox, the model, and the thread never see it.

Never paste the key into Slack

A key in a message stays in the channel history. A key in an environment variable is readable by every Claude session that uses the environment, in every channel. The connection is the only place it belongs. When you rotate the key, update the connection too.

Set a placeholder key in the sandbox

The CLI still needs FLITZ_APIKEY to hold a value. If the variable is not set, the CLI fails its local login check with [fail] you are not logged in to Flitz (exit 3) and sends no request at all. Give it a placeholder for the proxy to replace:

  1. Open the settings of the cloud environment the channel runs in (see which environment a channel uses).
  2. Add FLITZ_APIKEY=fake-key to its environment variables. Any non-empty value works. Never put the real key there.
  3. Save the environment, then start a new thread: one already running may not pick up the change.

To skip the environment change, prefix the publish command with FLITZ_APIKEY=fake-key instead, as in Publish.

Add the Flitz skill

Claude learns how to publish from the publish-flitz-bundle skill in the lean-flitz plugin, which LeanCode maintains in leancodepl/ai-plugins. The skill tells Claude to find the project's flitz.yaml, install the CLI when it is missing, run flitz publish --yes --json, post the landing page in the thread, and explain a failure by its exit code. Without it, Claude has only the request to go on.

An Owner or Claude Tag admin adds the plugin once: fork leancodepl/ai-plugins as a private repository.

To skip the fork, zip the plugins/lean-flitz folder and upload it as a plugin instead. Keep the fork in sync to pick up skill updates. Either way, the plugin applies to new threads only, so start a fresh thread after adding it. See Attach plugins and Set up a skills repository.

Publish

Name the branch in the request:

@Claude publish a flitz bundle from branch xyz

With the Flitz skill on, Claude checks out that branch and publishes it. Outside a CI system, nothing fills in the publish labels, so pass them explicitly. From the repository root:

branch=xyz  # the branch named in the request
git checkout "$branch"
sha=$(git rev-parse HEAD)
FLITZ_APIKEY=fake-key flitz publish --yes --json \
  --name "$branch" \
  --version-name "$branch-${sha:0:7}" \
  --comment "$branch @ $sha"
  • FLITZ_APIKEY=fake-key: any non-empty value. The CLI refuses to send a request without a credential, so it needs a placeholder for the proxy to replace. Never put the real key here.
  • --yes lets publish download the pinned SDK unattended, and create the app when flitz.yaml names one your organization does not have yet.
  • --json prints { "id", "page_url", "deeplink", "bundle_url", "app", "track", "track_url" } on stdout; Claude posts page_url and bundle_url in the thread. See Output and --json.
  • The track is the checked-out branch, so every publish from xyz lands on the same track, and its track_url always opens that branch's newest build. See App, track, and scheme.
  • --name, --version-name (at most 64 characters), and --comment label the publish in the publish history, where it is recorded as published by the organization API key.

Troubleshooting

You seeWhat it meansRemedy
[fail] you are not logged in to Flitz (exit 3)FLITZ_APIKEY was not set, so the CLI sent nothing.Prefix the command with FLITZ_APIKEY=fake-key.
[fail] the Flitz credential was rejected (exit 3)The placeholder reached the service unchanged: no connection injected the key.Check that a Bearer connection with allowed website api.flitz.dev is active in an Access bundle on the channel's scope. A bundle attached after the thread started may not reach it; start a new thread. If the key was rotated, update the connection.
403 on CONNECT, or Claude reports a host blocked by the network egress proxyThat host is not allowed.Allow the hosts listed above.
flitz: command not foundThe CLI is not installed in this sandbox.Run the install command. If the installer asks you to add a directory to your PATH, do so.

Everything else fails as it would on your own machine; see CLI troubleshooting and Exit codes.

On this page