@flowmind/cli

中文文档
0.3.13发布于 2026/11/10MITES Module近 30 天下载 2454

Flowmind CLI: log what you and your coding agents ship, with the outcome and the link that proves it. Works with Codex and Claude Code.

原始使用文档
文档目录8 节
  1. Set up coding agents
  2. Projects and repository links
  3. Stage an agent proof
  4. Saved stages
  5. Momentum brief
  6. Project ship log
  7. Response failures
  8. Verify the CLI

Flowmind CLI

The package installs two equal commands, flowmind and fm. On macOS, /usr/bin/fm can be Apple's Foundation Models tool, so agents and hooks call flowmind.

Set up coding agents

npm install -g @flowmind/cli
flowmind auth login
flowmind hooks install

hooks install copies the Flowmind skill to Codex and Claude Code and adds session hooks to ~/.codex/hooks.json and ~/.claude/settings.json. Other hooks in those files stay as they are. When the Flowmind Claude Code plugin (flowmind@flowmind from afgonullu/flowmind-skill) is installed and enabled, the plugin provides the skill in Claude Code: hooks install writes no copy to ~/.claude/skills, removes an unmodified copy it wrote earlier, and still adds the hooks. The hooks run agent hook through the absolute paths of the installing Node binary and CLI file, because hooks start without your shell profile and a version manager may not put node on PATH. Codex on Windows gets a PowerShell command (& '<node>' '<cli>' agent hook --agent codex). After you upgrade Node or move the CLI, hooks status shows outdated; run hooks install again and trust the changed hooks. The hook records each agent turn under the CLI config folder. In a linked repository, the session-start hook tells the agent which project it works on. Once 20 or more minutes of finished agent turns are unstaged, each prompt also carries a reminder with the minutes and the staging command. A successful agent stage resets the count.

In a git repository without .flowmind.json, the session-start hook first reads .flowmind.json from the local remote-tracking refs: the current branch's upstream, then origin/HEAD, origin/main and origin/master. It does not fetch. If a remote ref links the repository, the agent learns the project and is told to run git pull and never to create a new project. Otherwise the agent gets the steps to link the repository: pull, find the existing project, create one only for a new product, link, and commit .flowmind.json, or mark a third-party clone or scratch folder with link --ignore. Once 20 minutes of agent turns are recorded in such a repository, one prompt per session repeats this as a short reminder. Ignored repositories and folders outside git get no context and no reminder. Codex runs new hooks only after you trust them once in /hooks. hooks status shows both installs, and hooks uninstall removes only the Flowmind entries.

Then ask your agent to "set up Flowmind". The skill has it inventory your repositories, propose projects, and create and link them after you approve the list.

flowmind projects --json
flowmind projects add "Bead Focus" --description "Focus timer for iOS" --json
flowmind link "Bead Focus"              # writes .flowmind.json at the repository root
flowmind link <project-id> --dir ~/projects/bead-focus
flowmind link                           # shows the current link
flowmind link --ignore --reason "Third-party clone"
flowmind link --scan ~/projects ~/code --depth 2

A link names the project by id and keeps its name as a label. link accepts an id or an exact project name and checks it against the projects visible to agents. Commit .flowmind.json to share the link with other machines and agents.

One product is one project on every machine. The API owns that rule: projects add sends one request, and the API refuses a name that an existing project already has. The CLI prints the API's message and suggests --allow-duplicate (which creates the second project anyway) or flowmind link <project> for the existing one.

link --ignore writes {"ignore": true, "reason": "..."} as .flowmind.json for a third-party clone or a scratch folder. link then prints Ignored for Flowmind, the hooks stay silent there, and agent stage fails unless you pass --project. Commit the marker so other machines skip it too.

link --scan <dir...> finds git repositories in each directory and up to --depth folder levels below it (default 2). It skips hidden folders and node_modules, and does not search inside a repository. Each repository gets a status: linked, ignored, remote-linked (a local remote-tracking ref has the link; run git pull) or unlinked, with the project and the origin URL without credentials. --json prints { "repositories": [...] }. The scan exits 0 and does not use the network.

Log completed work by project name and duration:

fm log --project Flowmind --hours 1.5 --outcome "Shipped the reader"

Without a start time, the session ends when saved: 90 minutes saved at 10:00 records 08:30–10:00. To supply the actual start, use an ISO 8601 timestamp with a timezone:

fm log --project Flowmind --hours 1.5 --started-at 2026-10-02T08:30:00+02:00 --outcome "Shipped the reader"

Future session ends are rejected before contacting the API. The API enforces the seven-day logging window in your stored timezone. --started-at applies to structured project/hours logging. Natural language logging uses its reviewed AI confirmation time. Run fm log --help for all options.

Stage an agent proof

Agents stage completed work for explicit human approval. In a linked repository with the session hooks installed, the intention and outcome are enough. Write the outcome as one line of at most 120 characters: what changed for the project or its users. Add up to three optional --detail values for proof or open items. Each detail must be one line of at most 100 characters. Keep commits, runs, paths, and open items in details or use --artifact-url for the proof link.

For example:

flowmind agent stage --intention "Fix CLI sign-in" \
  --outcome "Signed-out CLI sign-in now returns to Authorize CLI" --detail "Cause: Supabase rejected the www callbacks" --detail "Still needs: deploy approval" \
  --json

If a proof breaks these rules, the CLI rejects it before any request. The error says exactly what to shorten or split and includes the worked example above. In --json mode, stderr contains an error message and an issues list. API rejections retain the server's exact message. Existing long notes remain readable; this rule applies to new proofs. agent proposals shows details as indented bullets, and --json includes the API's details unchanged.

The CLI reads the project from .flowmind.json and the session from CODEX_THREAD_ID or the one session with a turn in progress in the repository. The duration is the main agent's recorded turn time since the session's last staged proof, in whole minutes; the remaining seconds carry over to the next proof. A stop closes only its matching turn; an unfinished turn counts only through its last recorded activity. Idle time between turns does not count, and neither does sleep: the hooks read the awake clock that Codex uses for "Worked for". Subagent prompts never start a turn, because the main agent's turn already contains their work. Codex runs no prompt hook for a turn that another chat starts (send_message_to_thread, create_thread). For such a turn the CLI reads the start, the end and Codex's own awake time from the Codex session file. It places a time on the awake clock only where the record shows no sleep in between; on macOS that record is the kernel's last wake time. The JSON output gives the recorded unstagedSeconds. When nothing new is recorded, or when a Codex subagent calls the command, it stages nothing, prints "staged": false with a reason and a message, and exits 0. The source kind is codex or claude_code from the recording host. --dry-run prints the request and its retry key without staging anything.

Add --suggest-share only for a shipped outcome with an artifact link in --artifact-url (merged PR, release, deployed page, or published document) that a builder would want to show others. Never suggest routine, private, in-progress, failed, or security-sensitive work, or suggest just to pad. The flag only adds a hint in the review desk. The person decides; agents can never share. --dry-run shows suggestShare: true in the request when the flag is set. Saved stages keep the flag and retry with the exact same body; stages without the flag omit it. A saved stage made with the flag needs CLI 0.3.13 or later to retry; an older CLI reports it as unreadable.

Without hooks, pass observed values:

fm agent stage --project <project-id> --minutes 45 \
  --intention "Finish the reader" --outcome "Shipped the reader" \
  --started-at 2026-10-02T08:30:00+02:00 --source-kind claude_code \
  --artifact-url https://example.com/proof --session-id <stable-session-id> --json

Source kinds: calendar, claude_code, cli, codex, github, linear, manual, session_log, other. claude is not an alias. Use --source-label to override the Claude Code display label. Run fm agent stage --help for all options. Staging adds no hours; approve in Activity individually or confirm Approve all with links (N).

The retry key derives from the session id, project id, and start time, so each work unit in a session gets its own key. agent capabilities, agent projects, agent routines, agent proposals, and agent cancel accept --json. auth status checks the credential with the API and accepts --json. A failed connection reports an error; a revoked key reports authenticated: false.

Saved stages

After login the CLI saves every stage for that API and account before it sends it, so a crash, a timeout or a lost answer never loses it. When Flowmind does not take the stage, because the API is unreachable, answers too slowly (30 seconds), fails, limits the request, or sends an answer the CLI cannot read, the stage stays saved and the command exits 0 with "staged": false, "reason": "saved", the error, and a pendingStageId. The session counts its time as staged, so the next proof does not repeat it. A refused credential for a known account, or an unexpected CLI error, keeps the stage saved but exits 1, because someone must act. A stage that the API refuses for its content is removed, and its time stays unstaged for a corrected proof.

Saved stages are sent with the same retry key and body. The API keeps one proof per account and retry key for the credential that sent it, also after its 24-hour receipt expires, so a stage that reached the server before its answer was lost comes back as the same proposal. After flowmind auth login replaces the stored key, the API answers a stage that the old key already delivered with This stage key is already in use. That key can hold a different body, so the CLI keeps the request, its original credential fingerprint (not the key itself), and its time in conflict. No hook or later stage sends it. Check Activity, then use flowmind agent retry with the original credential or explicitly discard it with flowmind agent discard <id>. Retry reports unresolved items in conflicts; only a returned proposal confirms delivery. Each saved file is checked before sending, including its name, key/body hash, timestamps, source, details and evidence. An unreadable reservation is kept. It blocks measured staging for this account until you repair and retry it, or discard it after checking Activity. Saved stages go out after the next accepted stage (savedStagesSent in the JSON output) and from the session hooks, which start agent retry --due in the background when one is due: 1, 2, 4 … minutes after each failed attempt, at most an hour. agent pending lists them and agent retry sends them now; both accept --json. A saved stage that the API later refuses for its content stays listed as rejected and is not sent again. If a process ends between saving a stage and marking its session, the next stage on the machine restores the mark first. Only one process stages or sends for an account at a time. Returning to the same account after login restores its queue. Signing in to another account never adopts it.

The CLI keeps each account's sign-in periods on this machine, including earlier periods after logout. A whole turn belongs to the account signed in then, even if its first hook in the session came later. A turn crossing a sign-in or sign-out counts only its part within that period, and only when the awake clock places the boundary within the turn. Without that evidence, the uncertain part counts nothing. On hosts without turn IDs, overlapping prompts count nothing until all their stops have arrived. An ordinary prompt and stop still count; a restart or a gap longer than 12 hours adds no unverified time.

Upgrading from 0.3.7 needs no new sign-in. A never-bound profile asks the API which account owns its stored key (GET /v1/me, once). A previously bound key whose credential or origin no longer matches is refused locally. While a profile has only ever been signed in to one account, which is the normal case of one person on their own machine, the session time and saved proofs that 0.3.7 recorded become that account's on the first command or hook after the upgrade: an agent session that was running during the upgrade stages its whole time as before, and saved proofs are sent with the others. On a profile that has switched accounts, 0.3.7 proofs stay in their original location and the unowned list in agent pending shows only neutral metadata. Check Activity before adopting a proof that is yours with flowmind agent adopt <id>, or delete it unsent with flowmind agent discard <id>. A revoked key asks you to sign in; an unreachable API reports that the account could not be verified and changes nothing. On POSIX the config directory is 0700 and its credential file is 0600, including when repairing an older config.

Momentum brief

fm momentum
fm momentum --week 2026-10-12
fm momentum --json

See eight weeks of outcomes, personal and agent hours, project trends, and signals with source outcomes. Brackets mark the selected week; each sparkline uses its own peak. Quiet projects show the age of their last outcome. Commitment ideas are suggestions only and save nothing.

--week requires YYYY-MM-DD. The API checks that it is a Monday and is not in the future. Without it, the API selects your current personal week. --json prints only the response data as pretty JSON. Errors go to stderr and exit with status 1. Colors require a terminal and an unset NO_COLOR variable.

Project ship log

fm ship-log "My Project"
fm ship-log <project-id> --json

Use a project id or an exact project name, ignoring case. Duplicate names require an id; unknown names list the available projects. Both errors exit with status 1. Archived projects remain available.

The text view shows publication status, public title and summary, and the API's public, new, and changed counts. Existing publications include page, card, and Atom feed links, plus README badge Markdown. Unpublished links remain listed, but public readers receive 404 until the log has published outcomes.

Public counts include only selected outcomes that still match their saved digest. Changed counts include edited selections and eligible corrections of selected outcomes. New counts include other eligible, unselected outcomes created after the last save. New is zero before the first publication. Saving clears new counts for omitted outcomes. When new or changed outcomes exist, the command points you to review in the web app.

This command is read-only. A project id accepts a read_only API key; resolving a name uses the existing project list, which requires full_personal. Publish, update, or unpublish in the web app. --json prints the API data unchanged as pretty JSON. Errors go to stderr and exit with status 1.

Response failures

src/api.ts exposes apiRequest(descriptor, args, options) through the shared response decoder. src/contracts.ts binds command workflows to generated descriptors and @flowmind/contracts/wire types. Every API request validates the media type, envelope, status agreement, and response schema. An installed CLI can be older than the API, so it accepts one kind of difference: a response field that its contracts do not declare, inside a closed object. It drops that field before the command reads the response, so the field never reaches the output or --json. Every other difference still fails: a missing, retyped or renamed field, an unknown enum value, a union that matches no branch, and an unknown top-level envelope field. src/response-additions.ts owns this rule; the decision gives the reasons and the limits. The rule is sound only for some schema forms, so the build runs response-forms.mjs and fails when a response that the CLI reads uses another form. See the contract generation flow and endpoint procedure. Do not cast response data, write payload parsers, or add generic request helpers. Commands exit with status 1 when transport, JSON, media type, envelope, or payload checks fail. A valid API rejection also exits with status 1. One diagnostic names the action, operation, schema location, and request ID when available. Diagnostics omit response values, credentials, query values, and server messages.

A personal log with a transport failure, timeout, or unreadable response is not confirmed. The CLI does not retry it automatically. Run the same log command to replay its saved fields and key. A natural log reuses what you already reviewed. After the 24-hour receipt window the same command is refused, because the server may no longer recognize the key. Check Activity, then close the saved log with flowmind pending-logs done <id> when the entry is there, or flowmind pending-logs discard <id> to log the work again. flowmind pending-logs lists the saved logs; neither action posts anything. --hours takes hours or minutes: 1.5, 1,5, 2h, 90m or 1h30m, rounded to the nearest minute. Anything else is refused before a request. Authentication stops immediately on a failed poll. Pending authorization continues polling. Expired authorization exits with status 1. No failed authorization saves a credential. Use fm auth login --no-browser to open the printed authorization URL yourself.

Verify the CLI

Run pnpm --filter @flowmind/cli test from the repository root. This builds the CLI, runs command tests against loopback HTTP fixtures, and tests an installed package. The package check uses npm pack and a local npm install into a temporary prefix. A loopback package fixture serves the runtime dependencies already installed in this workspace. The install uses an empty npm cache and never contacts a public registry. Installed commands run outside the repository.

Reports are saved under tools/cli/test-results/:

  • response-contracts-packed.json: installed command inputs, build hash, results, and request counts.
  • pack-install.txt: package installation and hook lifecycle results.

The response matrix also checks credential persistence, diagnostic redaction, and write counts. Fixtures are synthetic. These tests do not prove production API availability.

版本与发布记录

@flowmind/cli 共发布 17 个版本,首次发布于 2026/10/15;过去 12 个月发布了 17 个版本。

版本发布日期距今
0.3.13latest2026/11/105 天前
0.3.122026/11/096 天前
0.3.112026/11/096 天前
0.3.102026/11/096 天前
0.3.92026/11/097 天前
0.3.82026/11/097 天前

关于 @flowmind/cli 的常见问题

@flowmind/cli 是什么?

Flowmind CLI: log what you and your coding agents ship, with the outcome and the link that proves it. Works with Codex and Claude Code.

如何安装 @flowmind/cli?

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

@flowmind/cli 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/flowmind__cli 是否存在。

@flowmind/cli 支持 ESM 还是 CommonJS?

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

@flowmind/cli 需要什么版本的 Node.js?

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

@flowmind/cli 可以商用吗?

@flowmind/cli 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@flowmind/cli 的下载量有多少?

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

@flowmind/cli 还在维护吗?

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