flipstream

中文文档
0.11.1发布于 2026/11/03Apache-2.0TypeScriptES Module

Flipstream CLI — query your Flipstream data from the terminal.

原始使用文档
文档目录8 节
  1. Install
  2. Usage
  3. For agents (Claude Code / Codex / MCP)
  4. Development
  5. Security
  6. Where CI runs
  7. Uninstall / purge
  8. Commands

flipstream

Flipstream CLI — query your Flipstream data from the terminal. A thin OAuth2 client that authenticates once and prints clean structured JSON for AI coding agents.

Architecture: this supersedes flipstream-cli-kickoff.md. See CLAUDE.md for the corrected model (thin client, two hosts, no natural-language "ask").

Install

npm i -g flipstream   # requires Node.js 20.19+ or 22.12+

Usage

flipstream --help
flipstream --version
flipstream version --json  # {version,node,platform,contractVersion,sdkVersion}
flipstream auth login      # opens the browser to sign in (OAuth2 + PKCE)
flipstream whoami          # your organization and you, with full IDs
flipstream ws list         # list your organization's workspaces
flipstream ds show <id>    # one dataset: status, workspace, export

For agents (Claude Code / Codex / MCP)

The CLI is self-describing. Discover the whole surface in one call, then invoke:

flipstream commands --json   # full machine-readable catalog: every command's
                             # id, summary, description, flags, args, aliases
flipstream <command> --help  # detail for one command

Output is a deterministic agent contract — stdout = data (JSON via --json, NDJSON via --ndjson), stderr = diagnostics, and on failure a single {"error":{"code","message","exit"}} envelope on stdout so flipstream <cmd> --json 2>/dev/null | jq . works on success and failure. Branch on error.code + the exit code: every code comes from one closed list the CLI owns, never from a class name. The full contract (exit codes, that error taxonomy, per-command shapes, CONTRACT_VERSION) lives in docs/AGENT-CONTRACT.md and is enforced by a conformance suite.

Every request also says which client, which agent and which conversation sent it, for your organisation's query log, and carries a request id that a failure reports as request_id. An agent the CLI doesn't detect should set FLIPSTREAM_AGENT. flipstream config set identify off (or DO_NOT_TRACK=1) leaves out the agent and the conversation.

Development

Built with Bun; the published CLI runs under Node.js 20.19+ or 22.12+.

bun install
bun run build
./bin/run.js --help        # run from source (or during dev: bun bin/dev.js --help)

Scripts:

  • bun run build — compile TypeScript to dist/
  • bun run lint — eslint (flat config)
  • bun run check:secrets — static deny-list gate over src/lib/auth (CI-enforced)
  • bun run format — prettier
  • bun test — run the test suite
  • bun run smoke — pack the tarball + run the packaged binary (E5-4)
  • bun run dev — run the CLI from source (./bin/dev.js)

Security

The CLI is a public OAuth2 client (Authorization Code + PKCE, a fixed first-party client_id) — it holds no client secret.

  • Tokens live only in the OS keychain (through @flipstream/sdk's keychain store, service id io.flipstream.cli.tokens, one item per sign-in host); nothing is written to disk in plaintext, and the non-secret config under ~/.config/flipstream-cli never contains tokens. FLIPSTREAM_NO_KEYRING=1 keeps them in memory for one command instead.
  • Commands running at once refresh one at a time. Each sign-in host has a lock file under ~/.config/flipstream-cli/locks/ (it holds no token), so two commands never spend the same refresh token, which would sign you out. A command killed while refreshing makes the next one wait up to 10 seconds. auth clear-all leaves only a lock file a running command still holds; it goes when that command finishes.
  • Updating from 0.9.x signs you out once. Earlier versions kept the sign-in under io.flipstream.cli; this one never reads it. Run flipstream auth login once; auth logout and auth clear-all delete the old item.
  • Tokens are never printed. Every log/error/--json path is routed through a redactor that masks JWT-shaped values, Authorization: Bearer headers, and secret URL/form params. auth login prints only the decoded (display-only) claims.
  • Sign-in runs on @flipstream/sdk's loopback: PKCE S256 only, the redirect's state and iss checked before its code is exchanged, and the redirect port bound to 127.0.0.1 only (RFC 8252), never 0.0.0.0/::. Where the browser can't reach that port (SSH, tmux), paste the address it ended on: auth login offers that prompt on a terminal.
  • No command exposes a --token/--secret/--verifier/--bearer flag.
  • No telemetry, no phone-home. The CLI collects no analytics and makes no network calls beyond the OAuth provider and the data host you query. There is no update-notifier dependency; were one ever added, its notice would go to stderr only (never stdout — it would corrupt --json/NDJSON), honor NO_COLOR, and be disableable via FLIPSTREAM_DISABLE_UPDATE_CHECK.

bun run check:secrets (a CI gate) and test/security/no-secrets.test.ts enforce these invariants on every change.

Where CI runs

Every job runs on our own MacBook M3 runners (runs-on: [self-hosted, macOS, ARM64]), not on GitHub's machines: GitHub-hosted minutes are too expensive, and the organisation's Actions budget ran out on 30 Oct 2026 (Michel, 31 Oct 2026). The IONOS cube runners are not used.

  • Exceptions: two jobs in release.yml, both only when Release Please has just made a release.
    • publish stays on ubuntu-latest: npm's Trusted Publishing works only on GitHub-hosted runners.
    • windows runs the tests, a global install and flipstream --version on windows-latest, at the release's tag, so Windows is checked once per release for a few hosted minutes. publish waits for it, so a Windows failure stops that version reaching npm. By then the tag and the GitHub release exist, so a real Windows bug ships its fix as the next patch. No PR runs Windows.
    • After a flake in windows, use Re-run failed jobs on that Release run. It keeps Release Please's outputs, so windows and then publish run again at the same tag. Re-run all jobs runs Release Please again, which then makes no release: both jobs are skipped and nothing is staged, and no failure says so.
  • Linux runs on the Mac too, in containers pinned by digest: test (linux) in oven/bun:1.4.3-debian, and the package job's Linux install in node:22.23.2-bookworm-slim.
  • Four runners serve every repository, on purpose: more made the laptop too heavy. A job waits when all four are busy.
  • Each job starts clean: an empty workspace, its own HOME and TMPDIR in $RUNNER_TEMP, and the workspace emptied again at the end.
  • It also keeps git off Michel's login Keychain: GIT_CONFIG_NOSYSTEM=1, GIT_TERMINAL_PROMPT=0 and GCM_INTERACTIVE=never, set before the checkout (os D1358). macOS's system git config sets credential.helper=osxkeychain, which a job's own HOME doesn't keep out. On 31 Oct an os job's git blocked on that Keychain for over 10 minutes, and every git push on the laptop hung behind it.
  • Where a job ran: its "Set up job" log says Runner name: 'actions-runner…'.

test/workflows/runners.test.ts holds all of this.

Uninstall / purge

flipstream auth clear-all removes every keychain entry under io.flipstream.cli.tokens (then best-effort revoking each host's sign-in at the sign-in service), and 0.9.x's under io.flipstream.cli, and deletes ~/.config/flipstream-cli. Run it before removing the binary — uninstalling the package/Homebrew/Scoop artifact does not clean these up, so without it the keychain items and config dir are orphaned.

If you already removed the binary, clean up manually:

  • macOS: Keychain Access → search io.flipstream.cli → delete the items (both io.flipstream.cli.tokens and 0.9.x's io.flipstream.cli).
  • Linux: secret-tool clear service io.flipstream.cli.tokens and secret-tool clear service io.flipstream.cli (libsecret).
  • Windows: Credential Manager → remove the io.flipstream.cli.tokens and io.flipstream.cli entries.
  • All: rm -rf ~/.config/flipstream-cli.

Commands

The full reference — every command, flag, argument and example — is generated from the commands themselves and lives in docs/COMMANDS.md.

For a quick look without leaving the terminal:

flipstream --help            # topics and commands
flipstream catalog --help    # one command's flags
flipstream commands --json   # the whole surface, machine-readable (agents want this)

版本与发布记录

flipstream 共发布 12 个版本,首次发布于 2026/06/30;过去 12 个月发布了 12 个版本。

版本发布日期距今
0.11.1latest2026/11/03今天
0.11.02026/11/013 天前
0.10.22026/10/304 天前
0.10.12026/10/2410 天前
0.10.02026/10/2411 天前
0.9.02026/10/1222 天前

关于 flipstream 的常见问题

flipstream 是什么?

Flipstream CLI -从终端查询你的Flipstream数据。

如何安装 flipstream?

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

flipstream 支持 TypeScript 吗?

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

flipstream 支持 ESM 还是 CommonJS?

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

flipstream 需要什么版本的 Node.js?

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

flipstream 可以商用吗?

flipstream 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

flipstream 还在维护吗?

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