@fluid-app/fluid-cli

中文文档
0.1.752发布于 2026/11/15TypeScriptES Module近 30 天下载 27.6万

Core CLI for Fluid Commerce — auth, config, and plugin system

原始使用文档
文档目录11 节
  1. Installation
  2. Sign up
  3. Authentication
  4. Without a terminal
  5. Companies on Fluid's identity sign-in
  6. Plugins
  7. Discovering commands
  8. Shell completion
  9. Updates
  10. Environment Variables
  11. Development

@fluid-app/fluid-cli

The Fluid Commerce CLI. Provides authentication, profile management, and a plugin system for extending with domain-specific commands.

Installation

npm install -g @fluid-app/fluid-cli

Sign up

fluid signup creates a company with Fluid's public signup, before any sign-in:

fluid signup --email [email protected] --first-name Maya --last-name Lee \
  --company-name "Acme" --subdomain acme --yes --json

It sends the subdomain in the form the server stores (lowercase letters, digits and hyphens, at most 63), prints the company's fluidShop, and the two fluid login steps below that sign in to it. The second step saves the sign-in under a profile named after the subdomain (--name), so it never silently replaces a profile you already have. Fluid emails the address a link to confirm the signup; signing in with the emailed code confirms it too.

It sends one request and never retries it: every attempt, failed or not, counts toward the signup limits (per IP address and per email), and a failure can come after the company was saved. Errors say which case applies: SUBDOMAIN_TAKEN, SIGNUP_MAY_EXIST (run the same command once more; a taken subdomain then means it exists), RATE_LIMITED (with retryAfter in seconds), SIGNUP_FORBIDDEN or SIGNUP_OUTCOME_UNKNOWN. A second signup for the same email within an hour normally sends no new email. Without --yes it asks at a terminal, and refuses when there is no terminal or with --json, which prints one object (status is signed_up or error).

--agent-access [name] also asks for a credential an administrator of the new company approves for an agent; the command waits, then saves it as a profile. It is available when enabled: see AGENT_ACCESS.md.

Authentication

# Email MFA flow
fluid login

# API token (avoids shell history exposure)
FLUID_TOKEN=your-token-here fluid login

# Manage profiles
fluid whoami            # Show active profile
fluid switch            # Switch between profiles
fluid logout            # Remove stored authentication

Profiles are stored at ~/.fluid/config.json.

--shop <shop> signs in to one company (acme or acme.fluid.app). For an admin, finishing the sign-in with a code sent for that shop also confirms a new company's signup.

Without a terminal

fluid login asks for the email and code at a prompt, so a script or agent with no terminal signs in in two steps instead:

# 1. Email a code for one company and save the sign-in (prints how to finish)
fluid login --send-code --email [email protected] --shop acme

# 2. Finish with the emailed code from FLUID_LOGIN_CODE
FLUID_LOGIN_CODE=123456 fluid login --code --email [email protected] --yes

#    or read it from stdin with --code -
echo 123456 | fluid login --code - --email [email protected] --yes

Step 1 needs --shop: the code is tied to that company, and only such a code confirms a new signup (fluid signup prints the shop as fluidShop; the API's signup response names it fluid_shop). Step 2 signs in to the same company; a --shop given there must match it.

The code expires after 30 minutes, and five wrong codes lock it. Step 1 saves the server's id for the sign-in under ~/.fluid/pending-logins/ until step 2 finishes it; the id alone cannot sign in. A code given as --code 123456 works but is visible in shell history.

Without a terminal (and with --code -, which takes stdin), step 2 needs --yes, which replaces a profile named after the company, or --name <profile>, which is refused before the code is spent if that profile exists. Either way the code is never used up on a profile it cannot write. --json prints one JSON object (status is code_sent, signed_in or error, with a code on errors).

With no terminal, fluid login fails at once rather than waiting at a prompt, unless it has a token (--token or FLUID_TOKEN) or runs one of the two steps (--send-code, --code).

Companies on Fluid's identity sign-in

Fluid decides per company whether it signs in through the identity service. For such a company the email has a sign-in link instead of a code. Paste the link at the code prompt, or, without a terminal, give it to --code the same way as a code (in FLUID_LOGIN_CODE or on stdin). fluid login then opens your browser to sign in and receives the result on a one-time server at http://127.0.0.1:<port>/callback. The sign-in URL is printed too (on stderr with --json), for a terminal with no browser to open.

In this mode no token is written to config.json. The refresh token is kept in the operating system credential store (macOS Keychain, Windows Credential Manager, or the Secret Service on Linux), and access tokens only in memory. fluid switch moves company by token exchange, fluid whoami reads the identity session, and fluid logout revokes the session. Every other company signs in exactly as before.

Plugins

Install plugins alongside the core CLI to add commands:

PackageCommandsDescription
@fluid-app/fluid-cli-theme-devfluid theme *Theme dev server, push, pull, init
@fluid-app/fluid-cli-portalfluid portal *Portal app build, deploy, push, pull
@fluid-app/fluid-cli-themesfluid themes *Theme management API commands
@fluid-app/fluid-cli-assetsfluid assets *Digital asset management commands
@fluid-app/fluid-cli-dropletsfluid droplets *Droplet management commands, including install, uninstall and installed
@fluid-app/fluid-cli-productsfluid products *Create a priced catalog product

Example:

npm install -g @fluid-app/fluid-cli @fluid-app/fluid-cli-theme-dev
fluid theme dev

Plugins are auto-discovered from:

  1. node_modules/@fluid-app/ in the current working directory
  2. node_modules/@fluid-app/ where the CLI itself is installed (global installs)
  3. Sibling packages in a pnpm workspace (monorepo development)

Discovering commands

fluid commands                 # every installed command, one line each
fluid commands domains         # only `fluid domains` and its subcommands
fluid commands --json          # the full catalog, for agents and doc generators

The JSON catalog lists every command with its arguments, flags (and the parent commands whose flags it also accepts), whether it changes data, and the API endpoints it calls. writes is true or false when the plugin declares it or the command confirms with --yes, and null when unknown. endpoints is null until a plugin declares them: unknown, not "calls no API". Plugins declare endpoints with describeCommand:

import { describeCommand } from "@fluid-app/fluid-cli";

describeCommand(parent.command("status <domain>"), {
  endpoints: [{ method: "GET", path: "/api/domains/{id}" }],
  writes: false,
});

Shell completion

echo 'eval "$(fluid completion bash)"' >> ~/.bashrc
fluid completion zsh > "${fpath[1]}/_fluid"
fluid completion fish > ~/.config/fish/completions/fluid.fish

Completion asks the installed CLI on each tab, so new plugins complete without reinstalling the script. It completes commands, aliases, flags and values that have a fixed set of choices. The scripts pipe the typed words to the CLI on stdin rather than as arguments, so a typed --token never shows in the process list.

Updates

Once a day an interactive run starts a detached background check of npm for a newer @fluid-app/fluid-cli, and a newer @fluid-app/fluid-cli-member-site (the Sites plugin); no command waits on it. When the last check found one, a short notice prints on stderr after the command finishes. The Sites plugin's notice is about the copy the command loaded, and names the command that updates that copy. A failed check is retried the next day. It never runs in CI, when output is piped, or for a workspace build. Set FLUID_NO_UPDATE_CHECK=1 (or NO_UPDATE_NOTIFIER=1) to turn it off.

Environment Variables

VariableDescription
FLUID_TOKENAPI token (alternative to fluid login)
FLUID_LOGIN_CODEEmailed code read by fluid login --code
FLUID_API_BASEAPI base URL (default: https://api.fluid.app)
FLUID_CONFIG_DIROverride config directory (default: ~/.fluid/)
FLUID_IDENTITY_URLIdentity service origin (default: follows FLUID_API_BASE)
FLUID_NO_BROWSERPrint the sign-in URL without opening a browser
FLUID_NO_UPDATE_CHECKTurn off the daily update notice

Development

For contributors working in this monorepo:

pnpm --filter @fluid-app/fluid-cli build
node packages/cli/core/dist/bin/fluid.mjs --help

版本与发布记录

@fluid-app/fluid-cli 共发布 753 个版本,首次发布于 2026/03/13;过去 12 个月发布了 753 个版本。

版本发布日期距今
0.1.752latest2026/11/15今天
0.1.7512026/11/15今天
0.1.7502026/11/15今天
0.1.7492026/11/141 天前
0.1.7482026/11/141 天前
0.1.7472026/11/141 天前

关于 @fluid-app/fluid-cli 的常见问题

@fluid-app/fluid-cli 是什么?

Core CLI for Fluid Commerce — auth, config, and plugin system

如何安装 @fluid-app/fluid-cli?

在项目目录运行 npm install @fluid-app/fluid-cli,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 fluid,可以用 npx fluid 直接运行。

@fluid-app/fluid-cli 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@fluid-app/fluid-cli 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@fluid-app/fluid-cli 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@fluid-app/fluid-cli 可以商用吗?

@fluid-app/fluid-cli 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@fluid-app/fluid-cli 的下载量有多少?

根据 npm 官方下载统计,@fluid-app/fluid-cli 在 2026/10/15 – 2026/11/13 这 30 天内被下载 275,573 次,日均约 9,186 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@fluid-app/fluid-cli 还在维护吗?

最新版本 0.1.752 发布于 2026/11/15(今天);至今共发布 753 个版本,其中过去 12 个月发布了 753 个;首次发布于 2026/03/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。