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

@flowapt/flowiq-cli

v0.1.11

Published

Command-line tool for FlowIQ staff: round-trip agent prompts, questionnaires, fine-tuning, pin-board tasks, webhooks, templates, agent-updates, chat exports, and live agent testing without ever touching service-role credentials.

Readme

flowiq

FlowIQ staff CLI. Round-trips agent prompts, questionnaires, fine-tuning, contact chats, platform webhooks, outbound messaging webhooks, FlowMod master-group prompts, Pin Board tasks, WhatsApp templates, agent-update requests, full chat exports, and live agent testing through https://api.flowiq.live/cli/* so the Supabase service role never leaves the server.

Install

npm i -g @flowapt/flowiq-cli
flowiq --version   # should print 0.1.x

Authenticate

Default flow — browser login (like npm login):

flowiq auth login

The CLI shows a short code (e.g. FQ4X-9KTB), opens https://app.flowiq.live/cli-auth when you press ENTER, and waits. A logged-in FlowIQ super admin confirms the code on the page matches the one in your terminal and clicks Approve — the CLI then receives a freshly-minted personal key automatically. Never approve a code you didn't just see in your own terminal.

Fallbacks (CI / no browser):

flowiq auth login --token fiq_staff_…   # supply a key directly
flowiq auth login --paste               # prompt for a key on stdin

Your key is saved to ~/.config/flowiq/auth.json with chmod 600. To verify what you're authenticated as:

flowiq auth whoami

To rotate this device's token (mints a fresh key, revokes the old one server-side — run whenever you want a new secret):

flowiq auth refresh

To log out (deletes the local key file, does NOT revoke the key server-side — use flowiq auth refresh first if you want the old key dead, or ask another super admin to revoke):

flowiq auth logout

Commands

All pull commands write to ./.flowiq/<topic>/<slug>.json relative to your current working directory. We recommend picking a dedicated folder for your CLI work:

mkdir -p ~/flowapt-cli && cd ~/flowapt-cli

Prompts — flowiq prompts pull|push <slug>

Round-trips an org's active WhatsApp agent's system prompt (agents.settings.prompt_sections).

flowiq prompts pull <organization_id>
# edit ./.flowiq/prompts/<slug>.json — modify section titles/content
flowiq prompts push <slug>

Notes:

  • system_prompt is regenerated server-side from prompt_sections on push using the ## SECTION: <title> format.
  • Sections support optional hidden: boolean + channels: string[] (web / whatsapp / messenger / instagram) — validated on push.
  • For legacy agents without a sections array, pull auto-bootstraps a single "Main" section from settings.system_prompt and returns bootstrapped: true. The CLI prints a heads-up before push.

Questionnaires — flowiq questionnaires pull|push <slug> (alias q)

Round-trips agents.questionnaire JSONB.

flowiq q pull <organization_id>
# edit ./.flowiq/questionnaires/<slug>.json — fill in answers
flowiq q push <slug>

If the DB column is null, pull seeds the local file from a default template (9 sections / 23 questions). Optional per-question note field is preserved round-trip.

Fine-tuning — flowiq fine-tuning pull|push <slug> (alias ft)

Round-trips agents.fine_tuning (text instructions) + agents.fine_tuning_entries (structured Q&A entries).

flowiq ft pull <organization_id>
# edit ./.flowiq/fine-tuning/<slug>.json
flowiq ft push <slug>

Each entry has: id, customer_question, correct_answer, agent_answer, notes, date (YYYY-MM-DD), category (Product Info / Pricing / Warranty / Shipping / Returns / Promotions / Technical Support / Tone Adjustment / Other), suggested_tone (Friendly / Professional / Encouraging / Brief / Detailed), status (Pending / Resolved), messages: [], media: [].

Knowledge / text sources — flowiq knowledge pull|push|list (alias kn)

Round-trips an agent's text knowledge sources — the { code, text } entries in agents.additional_config that the agent's get_more_answers tool retrieves on demand (brand references + tethered playbooks; the "Knowledge Sources → Text" tab in the UI).

flowiq knowledge pull <org_id>                 # → ./.flowiq/knowledge/<slug>.json (sources[] = {code,text})
flowiq knowledge pull <org_id> --agent <id>    # a specific (non-active) agent
flowiq knowledge push <slug>                    # FULL-REPLACE sources[] back onto the agent
flowiq knowledge list
  • Codes are UPPER_SNAKE (^[A-Z0-9][A-Z0-9_]{2,63}$), validated server-side. Edit / add / remove entries in sources[], then push (full-replace of the array).
  • Object-shape guard: some agents use additional_config for Flowapt-managed config (external_woo_build, …) rather than text sources — a pull flags that, and a push is refused (never clobbers managed config).
  • --agent + filenames behave like prompts (a non-active agent saves to <org-slug>-<agent-slug>.json). The file carries agent_id, so push targets the agent it was pulled from.

Messages — flowiq messages pull <contact_id> (alias m)

Read-only pull of a contact's helpdesk_messages history. Anchors on the Nth-most-recent user-* message, then grabs every row from that anchor onward (all sender types — bot-, tool-call, member, human-, broadcast, call-*, system, etc).

flowiq m pull <contact_id> --count 25
# writes ./.flowiq/messages/<contact-slug>-<org-slug>.json

--count defaults to 25, max 200.

Webhooks (Shopify/WooCommerce) — flowiq webhooks pull|push|reconnect (alias wh)

Round-trips the inbound Shopify or WooCommerce platform webhooks (the "Active Webhooks" panel on the Configuration page).

flowiq wh pull <organization_id>
# auto-detects platform from the org row
flowiq wh push <slug>            # create any topic in the JSON not currently live
flowiq wh push <slug> --prune    # also delete any live webhook not in the JSON
flowiq wh reconnect <slug> <webhook_id>   # WooCommerce-only: flip back to status=active
  • For orgs with feature_flags.ip_whitelist === true (e.g. customers on Wordfence), all calls are routed via python-render's static-IP proxy.
  • --prune is direct-mode only (python-render proxy has no delete route) — on ip_whitelist orgs prune prints a clear "delete via store admin UI" message instead.
  • Reconnect is WC-only. Shopify webhooks are always active when present.

Messaging webhooks — flowiq messaging-webhooks pull|push (alias mw)

Round-trips the outbound messaging webhooks in the meta_webhooks table (the right-hand panel on the Configuration page — these tell FlowIQ where to POST when a customer messaging event fires).

flowiq mw pull <organization_id>
flowiq mw push <slug> --dry-run   # diff preview, no writes
flowiq mw push <slug>             # FULL-REPLACE: deletes every row, then inserts the JSON

Push is full-replace — if someone added a row via the UI between your pull and your push, it gets wiped. Pull-edit-push within one session.

Validation: platform{whatsapp, web}, type from the per-platform allowed enum, valid http(s) URL, no duplicate (platform, type, url) tuples.

FlowMod prompts — flowiq flowmod pull|push <slug> (alias fm)

Round-trips a FlowMod org's master-group prompts + config. FlowMod groups are a separate system from regular WhatsApp agents — their prompts live in the flowmod_master_groups (model/pre-filter/config/signatures/custom_tools) and flowmod_prompts (the main / extra prompt rows, keyed by master_group_id) tables, read per-message by the flowmod-group-* webhooks.

flowiq flowmod pull <organization_id>
# edit ./.flowiq/flowmod/<slug>.json
flowiq fm push <slug>

The pulled JSON has a master_groups[] array; each entry carries its editable fields plus a prompts[] array ({ id, type, group_ids, text, data }). Push updates only editable columns — prompt text/data/group_ids/type, and master-group name/description/config/pre_filter_prompt/events_markdown/ custom_signature*/custom_tools — scoped by row id; it never touches PKs, FKs, or timestamps, and there's no system_prompt regeneration (FlowMod reads the prompt rows directly).

Common uses: edit a master-group's moderator prompt, or flip its reasoning effort via config.reasoningEffort (none / low / medium / high).

Group chats — flowiq groups list|pull <name-or-jid> (alias grp)

Read-only pull of WhatsApp group chat history (e.g. the … x Flowapt client comms groups) straight out of the FlowMod Evolution Postgres. This is the analogue of messages pull, but for a group instead of a contact, so you can pull a window and summarise it.

⚠️ Unlike every other command, this talks to a database directly (the Evolution DB is not Supabase and not the fiq_staff_… API). To keep this published package secret-free, the connection string comes from your shell environment — set FLOWMOD_EVO_DB_URL (or the five FLOWMOD_DB_* vars the flowmod-copilot edge fn uses) before running. No auth token is needed.

export FLOWMOD_EVO_DB_URL='postgres://user:[email protected]:5555/flowiq-db'

flowiq groups list                               # default instance: flowapt
flowiq groups list --instance FlowMod            # the other connected instance

flowiq groups pull "Phytoceutics x Flowapt" --last 7d
flowiq groups pull "Zorora x Flowapt" --since 2026-06-24 --until "2026-06-25 12:00"
flowiq grp pull [email protected] --last 48h   # or pass the group JID
# writes ./.flowiq/groups/<instance>-<group-slug>.json + prints a timeline
  • Group is matched by JID, exact name, or a unique case-insensitive substring (ambiguous matches list the candidates and exit — pass the JID to disambiguate).
  • Window: --last <48h|7d|2w|90m> (default 48h), or an explicit --since/--until (SAST; --until defaults to now). --limit (default 1000) keeps the most-recent N in the window.
  • --json prints the full payload to stdout instead of the timeline.
  • Read-only — there is no push; group history is a system of record. View-once/disappearing messages and raw media bodies can't be read (captions and text come through); history before the instance joined a group may be gappy.

Pin Board tasks — flowiq pinboard pull|push|list|list-remote (alias pin)

Round-trips a single internal Pin Board task (flowapt_tasks row).

flowiq pin list-remote open          # find the task id you want
flowiq pin pull <task_id>            # → ./.flowiq/pinboard/<slug>.json
flowiq pin push <slug>               # writes editable fields back, stamps updated_at

Editable fields: name, description, status (open / in_progress / done), urgency (low / normal / high / critical), preferred_due_date (YYYY-MM-DD or null), organizations[], media[], messages[], created_by. Array columns are full-replace within the row.

WhatsApp templates — flowiq templates pull|list|create|status (alias tpl)

Read an org's live templates straight from Meta (read-only), and submit new ones through the create-meta-template edge function.

flowiq templates pull <organization_id>   # → ./.flowiq/templates/<slug>.json (Meta-side truth)
flowiq templates create <organization_id> --request-file req.json
flowiq templates status <organization_id> --name booking   # poll approval

req.json holds { template_request, template_data?, media_header?, cards_media? }. Media headers: pass media_header.file_url (a public URL) — the edge function uploads it to Meta server-side. Approval is async; re-pull for the authoritative Meta status.

Org info — flowiq org info <organization_id>

Read-only platform detect + active-agent lookup for an org (raw store/Meta credentials are stripped server-side).

flowiq org info <organization_id>       # platform, storefront url, active agent

Agents — flowiq agent list|create <org>

List an org's agents (to discover ids) and create a new one.

flowiq agent list <organization_id>        # ★ marks the active agent; shows each id
flowiq agent create <organization_id> --name "Zara" \
  --system-prompt-file ./zara-prompt.txt --make-active

create inserts a new agent (created_by = your staff-key identity), optionally seeds its prompt into a single "Main" section, and — with --make-active — sets it as the org's active_whatsapp_agent. New agents start on the app default model; set the house model afterwards with agent config … --model gpt-5.4-mini --use-settings-prompt.

Targeting a specific agent — --agent <id>

By default prompts, questionnaires, fine-tuning, and agent config all act on the org's active agent. To target a different agent, pass --agent <id> (get ids from agent list):

flowiq prompts pull <org> --agent <agent_id>      # pull a NON-active agent's prompt
flowiq prompts push <slug>                          # pushes back to that same agent (id is in the file)
flowiq agent config <org> --agent <agent_id> --model gpt-5.4-mini

pull records the agent id in the JSON, so push always writes back to the exact agent you pulled from (never "whatever is active now").

Filenames: the active agent saves to <org-slug>.json; a non-active agent (pulled with --agent) saves to <org-slug>-<agent-slug>.json. So pulling multiple agents from one org produces distinct files that don't overwrite each other. (Fixed in 0.1.9 — before that, both used <org-slug>.json.)

Agent config — flowiq agent config <organization_id> [flags]

Set an allowlisted set of the active agent's config fields (the prompt-builder "Step 5"). With no flags, prints the current config.

flowiq agent config <organization_id>                        # show current
flowiq agent config <organization_id> --use-settings-prompt --model gpt-5.4-mini \
  --rename Zara --tool woo_order_build=true --tool view_cart_tool=true --discount true

Settable: settings.use_settings_prompt, settings.model, agent --rename, the tool-flag columns (woo_order_build, woo_tip_field, woo_order_note_field, view_cart_tool, restock_tool, block_tool_status, postal_code_tool_status, shopify_products_web_chat), and discount.enabled. Anything else is rejected; every change is reported before → after.

Agent updates — flowiq agent-updates pull|list (alias au)

Read-only pull of an org's client-raised "change the agent" requests (agent_updates), each with the chat context around the triggering message + the linked contact. Attachments are downloaded locally.

flowiq au pull <organization_id>                       # pending, with context
flowiq au pull <organization_id> --status all --titles "EFT, bank"
flowiq au pull <organization_id> --before 20 --after 10 --no-files
# → ./.flowiq/agent-updates/<slug>.json + files/<update-id>/<attachment>

Chat export — flowiq export chats <organization_id> [--out <path>]

Full chat history → TXT, byte-identical to the in-app "Export Settings TXT" (keyset-paginated server-side so it can't time out on big orgs).

flowiq export chats <organization_id>                      # → ./.flowiq/exports/<slug>-chats.txt
flowiq export chats <organization_id> --out ./phyto-chats.txt

Agent testing — flowiq test <subcommand>

Drive an org's live agent through the web/test channel and read the reply back — never sends a real WhatsApp (the web branch only inserts the reply).

flowiq test send <organization_id> "What are your bestsellers?" --clear
flowiq test send <organization_id> "What is this?" --image https://…/photo.jpg
flowiq test qa <organization_id>                     # bundled generic smoke pack
flowiq test scenario <organization_id> ./pack.json   # your own pack (expect/expectNot)
flowiq test clear <organization_id>
# phase 2 — adversarial parallel stress:
flowiq test stress <organization_id> ./stress.json --concurrency 6
flowiq test extract <organization_id>                # rebuild transcripts for a judge
flowiq test cleanup <organization_id> --confirm      # delete the stress contacts

--agent <id> targets a specific (non-active) agent. test stress cleanup is destructive and requires --confirm.

Environment variable overrides

| Var | Default | Use | |---|---|---| | FLOWIQ_API_URL | https://api.flowiq.live | Override the API host (local dev, staging). | | FLOWIQ_TOKEN | (saved in ~/.config/flowiq/auth.json) | Override the auth token, useful for CI. | | FLOWMOD_EVO_DB_URL | (none) | Full postgres:// URL for groups (Evolution DB). Required for groups. | | FLOWMOD_DB_HOST/PORT/USER/PASS/NAME | (none) | Alternative to FLOWMOD_EVO_DB_URL — assembled into a connection string. |

Upgrading

When a new version ships, just re-run:

npm i -g @flowapt/flowiq-cli
flowiq --version

Your saved token in ~/.config/flowiq/auth.json is preserved across upgrades.

License

UNLICENSED. Internal staff tool — install requires a valid fiq_staff_… key issued by a FlowIQ super-admin.