npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@loftyai/flow-cli

v0.3.0

Published

CLI for the PapagoAI Flow API - manage agents, preview chat, conversations, run-chain logs, and more

Readme

flow-cli

CLI for the PapagoAI Flow workspace open API — manage agent projects, edit agent config, preview-chat, publish, and inspect conversations and run-chain execution traces.

The full OpenAPI contract ships inside the package as contract/workspace-api.json (find it under $(npm root -g)/@loftyai/flow-cli/ after a global install) — useful when you need exact request/response schemas beyond what --help shows.

Install

Prerequisite: Node.js ≥ 18.

npm i -g @loftyai/flow-cli

The package ships a single bundled file plus an AI skill (skills/flow-cli/) that coding agents such as Claude Code can load to drive the CLI.

Authentication

flow-cli authenticates with a workspace API key (a key id + secret pair).

Getting an API key

  1. Log in to the Flow web console.
  2. Open Workspace Settings → API Keys (visible to workspace admins/owners only).
  3. Click Create API Key. You get a key id (fwk_...) and a secret.
  4. Copy the secret immediately — it is shown only once. If lost, revoke the key and create a new one.

The key is scoped to its workspace: it can only see and modify that workspace's projects and resources.

Method 1: Save to local config (recommended for humans)

flow-cli auth set <keyId> <secret>

Credentials are stored in ~/.config/flow/config.json. Multiple keys (e.g. one per workspace) are stored as profiles — save with -p team-b auth set ... and select per command with -p/--profile team-b.

Method 2: Environment variables (CI/CD & automation — highest priority)

export FLOW_API_KEY_ID="fwk_..."
export FLOW_API_KEY_SECRET="..."

Env vars override the config file per field.

Verify Authentication

flow-cli auth status   # where each credential comes from + target endpoint
flow-cli auth test     # verify with a real API call

Environment Variables

| Variable | Required | Description | |---|---|---| | FLOW_API_KEY_ID | No | Workspace API key id (overrides the config file) | | FLOW_API_KEY_SECRET | No | Workspace API key secret (overrides the config file) | | FLOW_BASE_URL | No | Override the API base URL (default: production). For staging/private deployments; must match the environment that issued your key | | FLOW_CONFIG | No | Alternative config file path (default: ~/.config/flow/config.json) |

A profile can also pin its own baseUrl in the config file:

{
  "defaultProfile": "default",
  "profiles": {
    "default": { "keyId": "fwk_aaa", "secret": "..." },
    "stage":   { "baseUrl": "https://api.s.papagoai.com/core/api/open/v1", "keyId": "fwk_bbb", "secret": "..." }
  }
}

Usage

# View all available resources
flow-cli --help

# Projects (agents)
flow-cli project list --mode MultiAgentV3
flow-cli project get <projectId> --config
flow-cli project create --name "My Agent" --mode SingleAgent
flow-cli project update <projectId> --name "New Name" --streaming true \
  --spend-limit '{"enabled":true,"period":"DAILY","costLimit":5}'
flow-cli project config get <projectId>
flow-cli project config patch <projectId> --body '{"agents":[{"prompt":"..."}]}'
flow-cli project chat <projectId> "hello" --var lead_first_name=Bob
flow-cli project chat <projectId> "and then?" --conversation <conversationId>
flow-cli project publish <projectId>

# Conversations & execution traces
flow-cli conversation list <projectId> --begin 2026-07-01T00:00:00Z --end 2026-07-20T00:00:00Z
flow-cli conversation messages <conversationId>
flow-cli run-chain <messageId>                # per-node trace incl. each tool call's input/output
flow-cli run-chain <messageId> <runChainId>   # one node's raw provider payload

# Daily token usage & model cost (USD); range at most 10 days, data from 2026-06-25 (UTC)
flow-cli usage <projectId> --start 2026-07-28 --end 2026-07-31

# Read-only catalogs (the ids they list are what a project config references)
flow-cli model list          # incl. each model's supported reply formats + max output tokens
flow-cli skill list
flow-cli kb list
flow-cli workflow list
flow-cli plugin-group list
flow-cli plugin list <groupId>

Pagination is 0-based, mirroring the API. The client retries 429/5xx with backoff — except chat, which is never retried (a turn is not idempotent).

Project Lifecycle

create (Draft skeleton) → config patch (edits land in a DRAFT) → chat (try the draft) → publish (go live)

Config edits are not live until project publish. project chat always runs the draft — the API twin of the web preview panel — so a config patch can be verified before publishing. publish returns an error when the current version is already published (nothing new to release).

| Mode | Description | Notes | |---|---|---| | SingleAgent | One agent, optional voice via media stream | | | VoiceAgent | Realtime voice agent | No welcomeMessage; chat is rejected (voice-only preview) | | SingleBatchAgent | Batch-processing agent | | | MultiAgentV3 | Multi-agent graph (classifier/taskforce/agents + edges) | agents bucket is a full replace — see below |

Config Write Semantics

Config is written bucket-by-bucket. Top-level buckets: name, featureSettings, welcomeMessage, memory, voiceCfg, agents, edges, variables.

  • config patch — a present bucket replaces that bucket; absent buckets are untouched.
  • config put — same, except absent list buckets (agents/edges/variables) are cleared. Only for deliberate full replaces.

Safe agents writes

The server treats a present agents bucket as a full replace: on multi-agent projects, any agent you omit is deleted. config patch protects you — it reads the current config first and re-sends every unreferenced existing agent as a bare {agentId} (preserved verbatim by the server). Pass --no-merge to send your payload as-is. Two server-side guarantees on top: single-agent projects pin the bucket to the sole agent (exactly one element; an omitted agentId binds to it, a mismatched one is rejected), and the startV2 entry node of a multi-agent graph is always preserved.

Model config

model is selected by modelId (a model list row id) — model/provider names are derived server-side and caller-sent values are ignored. Validated at write time (explicit 400s):

| Rule | Detail | |---|---| | replyFormat ∈ model's outputFormat | text / json_object / json_schema, per model — shown by model list. Also enforced when switching models while keeping a stored format: send replyFormat together with modelId | | maxOutputToken ≤ model's maxCompletionTokens | The web silently clamps; the API rejects | | json_schema requires jsonSchema | {name, description, schema, strict} in the same write | | temperature 0–2, topP 0–1 | -1 unsets either |

flow-cli project config patch <id> --body '{"agents":[{"model":{
  "modelId":"459","replyFormat":"json_schema",
  "jsonSchema":{"name":"charge","description":"Extract a charge","strict":false,
    "schema":"{\"type\":\"object\",\"properties\":{\"serviceType\":{\"type\":\"string\"}},\"required\":[\"serviceType\"],\"additionalProperties\":false}"}
}}]}'

Welcome message & variables

welcomeMessage.variables is derived by the server from the {{placeholders}} in content — every referenced name must be a defined project variable (existing, or written in the same request), otherwise the write is rejected.

Metadata updates (project update)

Omitted flags keep current values. aiAssistSettings is merge-patched per key: --spend-limit null removes the limit without touching streaming_mode; --spend-limit '{"enabled":true,...}' requires costLimit > 0. --tags takes tag ids and replaces the whole tag set.

Chat (Preview)

flow-cli project chat <projectId> "hello" --var lead_first_name=Bob
flow-cli project chat <projectId> "and then?" --conversation <conversationId>

Conversation context lives server-side — continuing needs only the returned conversationId, never the history. Reply fields (text output renders all of them losslessly; --json for raw values):

| Field | Content | |---|---| | content | Reply text (single-style agents) | | trace | Per-node reply list (multi-agent graphs): agent name + content | | contents | Multimodal reply items | | files | Generated files (name + URL) | | toolCalls / toolOutputs | Function-tool handshake — execute the calls, then send the next turn with both echoed back | | workflowMessages | Workflow progress messages | | responseMetadata | model_name, finish_reason, token_usage | | conversationId / messageId | Continuation key / trace key (run-chain <messageId>) |

VoiceAgent projects are rejected (voice-only preview). Chat is never retried by the client — on a timeout, check conversation messages before resending.

Debugging with run-chain

flow-cli run-chain <messageId> returns the execution trace: one entry per node (type, title, tokens) with each node's input/output — for tool nodes that is the tool call's parameters and return value. flow-cli run-chain <messageId> <runChainId> fetches one node's raw provider payload. The messageId comes from a chat reply or conversation messages.

List Filters

| Command | Flags | |---|---| | project list | --mode <SingleAgent\|VoiceAgent\|SingleBatchAgent\|MultiAgentV3>, --page, --size | | project get | --config (include the draft configuration) | | conversation list | --begin <iso> (inclusive), --end <iso> (exclusive) — defaults to the last 7 days; --page, --size | | model list | --all (include disabled models) | | skill list | --name, --page, --size | | kb list | --search, --page, --size | | workflow list | --name, --status, --page, --size | | plugin-group list | --name, --type, --status, --page, --size |

Resources

| Resource | Description | |---|---| | project | Agent project lifecycle: list, get, create, update, config get/patch/put, chat, publish | | conversation | Conversation history: list <projectId>, messages <conversationId> | | run-chain | Execution trace of a message, incl. tool call inputs/outputs | | model | Models available to the workspace (reply formats, token limits) | | skill | Skill catalog (read-only) | | kb | Knowledge base catalog (read-only) | | workflow | Workflow catalog (read-only) | | plugin-group / plugin | Plugin catalogs (read-only) | | auth | Credential management (see below) |

Run flow-cli <resource> --help for detailed commands and options.

Auth Commands

| Command | Description | |---|---| | flow-cli auth set <keyId> <secret> | Save an API key to the local config file | | flow-cli auth show | Display the current key (secret masked) | | flow-cli auth show --raw | Display the full secret | | flow-cli auth remove | Delete the profile's credentials | | flow-cli auth status | Show where credentials come from and the target endpoint | | flow-cli auth test | Verify auth by making a real API call |

Update Notifications

flow-cli checks for new versions in the background (at most once every 24 hours). If a newer version is available, a one-line upgrade hint is printed to stderr:

Update available: 0.2.0 → 0.3.0
Run: npm install -g @loftyai/flow-cli

Global Flags

All commands support:

| Flag | Description | |---|---| | --json | Output as JSON | | --format <type> | Output format: text, json, yaml | | -p, --profile <name> | Credential profile from the config file | | --no-color | Disable colored output | | --no-header | Omit table headers |

Output Format

The default text output is field-complete: every field is rendered, but long values are truncated for readability (a hint is shown when that happens). For full, untruncated content use --json, which returns a standardized envelope:

{ "ok": true, "data": { ... }, "meta": { "total": 42 } }

On error: { "ok": false, "error": { "message": "...", "status": 401 } } — and on the default text format, a one-line message on stderr.

Exit codes: 0 success, 1 API error, 2 usage error.

Boolean Flags

Flags shown as --flag <bool> in --help require an explicit true or false value:

flow-cli project update <id> --streaming true
flow-cli project update <id> --streaming false

Omitting the flag keeps the current value. Boolean flags do not use --no-flag syntax (the real toggles --no-merge, --no-color, --no-header are the exceptions).

Development

npm install
npm run dev -- <args>   # run from source (tsx)
npm test                # vitest
npm run typecheck
npm run build           # esbuild single-file bundle → dist/flow-cli.js
npm link                # global `flow-cli` for development

Publish (maintainers)

Releases go to the public npm registry under the @loftyai scope. CI publishes automatically on a vX.Y.Z tag; to release, bump the version and push the tag:

npm version patch|minor|major
git push --follow-tags

prepublishOnly runs typecheck + tests + build, so a broken bundle can't ship.