FunnelsGrove CLI
Install:
npm install -g @funnelsgrove/cli
fgrove login
Update every global installation visible on PATH (including separate NVM and
Homebrew prefixes) with one command:
fgrove update
Use fgrove update --dry-run to inspect the installations first. The updater
runs each installation's sibling npm, so duplicate global installs cannot
silently remain on different CLI versions.
Create a new hosted funnel from one of three starter templates:
fgrove whoami
fgrove projects list
fgrove templates list
fgrove templates show one-page-v2
fgrove funnels create --project fitness --template one-page-v2 --name FitBee --idempotency-key <creation-key> --json
fgrove sync down --funnel <returned-funnel-id> --dir ./fitbee
Template cards include descriptions, suitable journeys, included screens and a
create command. --json works for both list and show. Discovery reads the
offered official catalog through the connected account, preserving its names,
keys and pinned demo/source versions; inspect the demo for the current journey.
Hosted creation requires an existing project; pass --workspace
when selecting a different workspace. Template slugs match the app: default,
one-page, and one-page-v2.
funnels create uses the same API setup workflow as the app. It waits for a
downloadable draft, while the automatic initial preview builds separately.
--timeout defaults to 120 seconds. Progress and recovery identity go to stderr;
stdout contains a tab-separated creation row, or one result object with --json.
Retain the creation key and reuse it if the request outcome is uncertain. A
wait timeout does not cancel or delete the hosted funnel. Download the returned
ID with sync down; funnels clone instead copies an existing funnel.
After downloading, establish the product/audience/offer/brand brief and root
Design.md before customization. The Fstack create-funnel skill owns that
intake workflow; starter artwork, proof and legal/offer copy need adaptation.
The starter preview includes later local changes only after sync and publish.
Find visual examples in the public Funnel Screens library without an account:
fgrove references projects --category 'Self-growth / book summaries'
fgrove references project headway
fgrove references ads --project headway --format social-media-mockup --angle problem_agitation --limit 20
fgrove references ads --before <cursor> --json
fgrove references categories
fgrove references list --category 'Health Fitness' --step-type single-choice
fgrove references show <funnel-id> --json
fgrove references steps <funnel-id>
fgrove references step <funnel-id> <screen-id-or-position> --json
projects lists products and their top ads; project shows a product and its
ads with texts, dates and media links. ads supports exact project, category,
format and angle filters. Its limit is a whole number from 1 to 100; use the
returned nextBefore value as --before to read the next page.
show returns the complete recorded journey; steps gives compact ordered
summaries; step returns one screen with its image link, visible text, button and
option labels, and a brief visual description when available. Positions start
at 1. Every command supports --json and --site-url (default:
https://www.funnelsgrove.com). These commands use the public reference service
independently of your account API and do not change the active funnel. Content
is automatic observation with uncertainty notes; inspect the actual images before
adapting a design. Unavailable observations are marked explicitly.
Sync a funnel into its own local folder:
fgrove sync down --funnel claimbee-ios --dir ./claimbee-ios
cd ./claimbee-ios
Common workflow:
fgrove status
git status --short
fgrove github status
fgrove docs
# if GitHub is connected: git push, then fgrove github pull
# if GitHub is not connected:
fgrove sync up --message 'Update funnel copy'
fgrove publish --env preview
Inside a synced folder, fgrove reads .funnelsgrove-sync.json first, so you do not need to run fgrove use when switching between local funnel directories. Use fgrove use only when you want a global fallback context for commands outside a synced folder.
fgrove funnels clone copies the draft and the funnel's offer-set mapping. The
clone reuses the same project-level offer sets and payment profiles; custom-domain
configuration is not copied into the new preview.
fgrove sync down refuses to overwrite local changes in an existing synced
folder. fgrove sync up sends only changed and deleted paths in one atomic
draft patch. It excludes paths matched by the folder's root .gitignore and
always keeps .claude/settings.local.json local while allowing shared files
such as .claude/settings.json. Disjoint concurrent edits are rebased automatically; if the same
path changed remotely, run fgrove sync rebase: it performs a three-way merge
from the recorded base, preserves CLI-managed files, and leaves the working tree
untouched when it finds conflicts. Review the merged diff, rerun fgrove validate, then sync up again.
sync down --force is the explicit discard path and writes an automatic source
backup under .funnelsgrove/rebase-backups/ before replacing hosted paths.
Changed images below public/ are uploaded directly to asset storage, then the
small immutable asset references are included in the atomic patch. Sync retries
use a deterministic durable idempotency key, so a lost response cannot create a
second draft version. The CLI automatically falls back to candidate sync when
the compatible deployed API lacks the fast procedures or a change set exceeds
patch limits.
fgrove sync up is for funnels without GitHub source sync. When GitHub is
connected, commit and push source changes with normal git, then run fgrove github pull to sync GitHub into the hosted draft. Do not run fgrove sync up
for the same local diff.
Use fgrove env pull from a synced folder to refresh only the ignored local .env file after project settings change, without replacing source files. The generated file identifies the current hosted draft through NEXT_PUBLIC_FUNNEL_VERSION_ID, so transactional steps such as email capture work during local QA.
Offer sets and payment mappings are runtime configuration. They are resolved remotely for preview and published funnels; sync down does not generate or download an offer-set source file.
Create an experiment draft from a strict JSON spec:
fgrove experiments create --spec experiment.json --dir .
fgrove experiments create --spec experiment.json --dir . --json
fgrove experiments start <experiment-uuid>
fgrove experiments stop <experiment-uuid>
fgrove experiments restart <experiment-uuid> --json
fgrove validate
The spec uses a stable id and type: "step", "paywall", or "pricing" with two to five variants, exactly one control, unique metrics and variant keys, and integer traffic totaling 100. Pricing variants also require offerSetKey and must route to the top-level stepId. See docs/funnelsgrove/recipes/add-experiment.md in a synced funnel for complete valid JSON examples and remediation guidance.
Creation is draft-only: it creates no PostHog flag and activates no traffic. The experiment becomes visible in the UI after the API commits its hosted generated snapshot, and the CLI installs those exact generated bytes locally through recoverable staging. .funnelsgrove-sync.json stays local and ignored.
With --json, success output contains only experimentId, experimentKey, draftVersionId, and writtenPaths, with generated paths in canonical order.
For a non-GitHub funnel, deliver the local source with fgrove sync up. For a GitHub-connected funnel, commit and push the generated source with the rest of the change, then run fgrove github pull; do not commit .funnelsgrove-sync.json or use fgrove sync up for that diff.
GitHub sync workflow:
fgrove github status --funnel claimbee-general
fgrove github connect --funnel claimbee-general --account The-Solid-Grove --repo claimbee-funnel
git push
fgrove github pull --funnel claimbee-general
fgrove publish --funnel claimbee-general --env preview
The GitHub commands use the FunnelsGrove API only. fgrove github pull pulls
the repository into the hosted draft after you push normal git commits.
fgrove publish waits for the current draft to reach GitHub before publishing.
It writes validation, GitHub sync, queue, build, image optimization, and upload
progress to stderr while keeping the final URL/version row alone on stdout.
If the exact job is still pending or running when that wait times out, publish
continues with a warning on stderr and asks you to check the eventual result
with fgrove github status. Terminal job failures, missing jobs, and API
failures remain fatal. Use --no-github-sync to skip only that CLI pre-publish
wait when the hosted draft is already known to match GitHub; the publish worker
still performs its normal best-effort post-publish GitHub synchronization.
fgrove github push still exists for explicit hosted-draft-to-GitHub recovery
work, but it is not the normal path for local source changes. Local .env*
files remain CLI-local runtime material from sync down; they are not sent to
GitHub sync.
Analytics workflow:
fgrove analytics conversions --project claimbee --funnel claimbee-ios --date 2026-06-11
fgrove analytics funnel-path --project claimbee --funnel claimbee-ios --date 2026-06-11
fgrove analytics transitions --project claimbee --funnel claimbee-ios --date 2026-06-11
fgrove analytics cohort --project claimbee --date 2026-06-11
Each analytics command accepts --format table|json, --out <path>, --workspace, and --timezone. Use JSON for agents and automations:
fgrove analytics conversions --project claimbee --funnel claimbee-ios --date 2026-06-11 --format json --out conversions.json
conversions downloads conversion totals, primary conversion metrics, full funnel path rows, and step transitions. funnel-path focuses on the ordered path report. transitions focuses on step-by-step advanced/drop-off counts. cohort downloads synced marketing cohort economics for the day. Its annual predictions use the same saved-range midpoint as Cohort Marketing and daily reports. Missing valid prediction ranges yield null JSON values and empty table cells; legacy model points are never a fallback. Cohort Marketing must be enabled for the project. If the requested period has no synced data, or cohort source data is incomplete, the CLI exits non-zero with a human-readable explanation.
conversions, funnel-path, and transitions report one day with --date, or a range with --from and --to (inclusive, totals for the whole range). They use the selected date range across all published funnel versions that had traffic. funnel-path and transitions follow current published flow order. Steps with selected-period traffic that are absent from the current flow appear at the end under “Not in current funnel”; JSON rows mark them with section: "not-in-current-funnel".
fgrove analytics transitions --project claimbee --funnel claimbee-ios --from 2026-06-01 --to 2026-06-14
The package also keeps the longer funnelsgrove command as a compatibility alias.
Follow the project setup guide from the terminal. The steps, instructions and checks are the same as the console guide, so a coding agent can work through it:
fgrove use --project claimbee
fgrove setup # every step, its readiness, what is missing, next step
fgrove setup --json # the same for agents
fgrove setup docs stripe_setup # full instructions for one step
fgrove setup check stripe_setup # confirm the live webhook with Stripe
fgrove setup check meta_pixel --test-event-code TEST12345
fgrove setup complete legal_support
fgrove setup meta-traffic off # the project does not buy Meta traffic
fgrove setup secrets stripe-test # single-use link to a FunnelsGrove form for Stripe keys
Agents never take Stripe keys or the Meta access token. fgrove setup secrets <stripe-test|stripe-live|meta> prints a link that works once for 30 minutes; the
person who opens it enters the values in a FunnelsGrove form.
Stripe, Offer Sets, the domain, Meta and the app-access claim are Readiness
Checks: only observed evidence completes them, and setup complete does not.
The last step, customizing the funnel, can be skipped with setup complete customize_funnel.
Running fgrove setup for a project marks its Connect the CLI step ready.
check, meta-traffic and secrets need the workspace Admin role, like the
matching console buttons; status, docs and completion marks need a member.
Edit profitability expenses through a local JSON file:
fgrove expenses pull --project claimbee --file expenses.json
# edit expenses.json; omit id and updatedAt for new expenses
fgrove expenses publish --project claimbee --file expenses.json
Publishing creates new rows and updates rows already present in the file. It never deletes remote expenses that are absent from the file, and it refuses to overwrite rows changed since the last pull. Pull again to resolve a concurrent edit.
Edit Offer Sets the same way. For discounted intro prices and two-stage discounts,
see the repository guide
docs/guides/edit-offer-sets.md:
fgrove offer-sets pull --project claimbee # writes offer-sets.json
fgrove offer-sets prices --project claimbee --env live
# edit offer-sets.json; for a new set omit id/updatedAt, keep paymentProfileId
fgrove offer-sets publish --project claimbee --dry-run
fgrove offer-sets publish --project claimbee
Only changed sets are sent. Set isActive to false to archive a set, which
fails while a funnel, route, domain or experiment still uses it. Sets absent
from the file are never deleted, and publishing refuses sets changed since the
last pull. Item paymentProfileBindings (for example a PayPal binding) are not
in the file; existing ones are kept, and a new set copied from another starts
without them.
Read chargeback alert and Prevent transaction search history for one UTC month without customer or card data:
fgrove alerts list --project claimbee --month 2026-10 # every alert: ids, dates, service, amount, status, outcome
fgrove alerts stats --project claimbee --month 2026-10 --json # counts by service, refund/cancellation shares, FunnelsGrove cost
fgrove prevent list --project claimbee --month 2026-10 # every transaction search / inquiry: date, program, outcome, amount, scheme, status
fgrove prevent stats --project claimbee --month 2026-10 # searches, found rate, Prevent deflection rate
--month defaults to the current month. List commands download every page
before printing. Outcomes are refunded automatically, refunded manually,
needs review / pending, closed without refund or informational, plus the
subscription cancellation state; percentages in alerts stats are shares of all
alerts received in the month. Merchanto alerts are counted but billed directly
by Merchanto; the cost lines cover FunnelsGrove alerts for the whole project.
The output never includes customer emails, names, phone numbers, IP addresses,
card digits, network references or Stripe identifiers.
Support a user (workspace admins only): find the projects they belong to, look them up by email or funnel user ID, refund chosen payments and cancel their subscription:
fgrove users find --email [email protected] --json # every project you administer where this user exists, each with its lookup
fgrove users lookup --project claimbee --email [email protected] --json # users, live subscriptions, payments with refund eligibility
fgrove users refund --project claimbee --email [email protected] --payment ch_123 --payment pay_456 --dry-run
fgrove users refund --project claimbee --email [email protected] --payment ch_123 --payment pay_456
fgrove users cancel --project claimbee --user-id 8f1c2d # at period end; --now cancels immediately without refunding the remainder
customers remains an alias of users. Pass exactly one of --email or --user-id; --env test reads test-mode
users. find searches every workspace you belong to (narrow it with
--workspace), lists workspaces where you are not an admin as not searched and
exits 1 when a project could not be searched. Stripe charges and subscriptions come live from Stripe; Solidgate
payments come from the FunnelsGrove ledger with refunded amounts read live from
Solidgate. PayPal subscriptions and sales come from the ledger with status read
live from PayPal; refunded amounts come from the ledger, and a sale PayPal shows
refunded differently is not refundable until the refund webhook is recorded.
Refunds are full refunds of each payment's remaining amount, using
the payment IDs printed by lookup (PayPal sale IDs as printed, without a
prefix). Disputed payments are not refundable. Each payment is refunded at most once,
including against Chargeback Prevention refunds of the same payment. A
Solidgate or PayPal refund that is still processing is reported as processing; run
lookup later to confirm it. The command exits 1 if any payment failed. cancel refuses to guess when several
subscriptions are still billing; pass --subscription. PayPal Live
subscriptions cancel at period end only; --now works for PayPal in --env test. When lookup reports a
provider that did not answer, missing data does not mean there is no
subscription.
Report a bug to the FunnelsGrove team:
fgrove bug report "publish hangs at image optimization" --log ./publish.log --dry-run # show what would be sent
fgrove bug report "publish hangs at image optimization" --log ./publish.log
The report carries your message, CLI version, Node version and platform, and
the workspace and funnel from the local sync manifest in --dir (or the
workspace, project and funnel chosen with fgrove use). --log attaches the
last 20,000 characters of a log file as-is, so remove secrets first. The
command prints the reference of the filed report.
Use --api-url or FUNNELSGROVE_API_URL for non-production APIs.
Use --config or FUNNELSGROVE_CONFIG to keep test credentials separate from the default ~/.funnelsgrove/config.json.
Add a content locale
Run fgrove locales add ru --dir ./my-funnel to copy every default content
object into src/localization/ru/, preserving its path relative to src/.
Original content stays in place; translated files import its structural type.
Repeat runs preserve translations, add missing exports and repair registrations.
Translate the new content, run npx tsc --noEmit, review ?locale=ru and the live builder Preview language
selector, then sync and publish through the normal workflow. Run fgrove docs
for the full localization guide. The funnel must use a runtime release supporting
URL locale selection; this command does not upgrade dependencies.
New project and Stripe offers
fgrove projects create --name Canary --reuse-existing --json
fgrove offer-sets create --project canary --key intro --name "Intro offer" --plan weekly=11.99/week --plan monthly=24.99/month --plan yearly=79.99/year --discount 50 --default-plan monthly --featured monthly="Most popular" --env test --assign-funnel canary --dry-run
fgrove offer-sets assign --project canary --funnel canary --offer-set intro
Review the dry run, then remove --dry-run to create. Stripe credentials stay on
the server. Prices renew at the specified regular amount; --discount 50 charges
the first period 50% less (initial offer) and shows the full price struck through.
Repeat the same key with --env live to fill Live mappings. Use --payment-profile
when multiple Stripe profiles exist. Assignment replaces all current funnel sets;
--default chooses one of the repeated --offer-set values. Publish separately.
See docs/product-specs/cli-funnel-editing.md (CLI-BR-008–010, CLI-SC-027–035).