Package Exports
- @farthershore/cli
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@farthershore/cli) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@farthershore/cli
Create and manage FartherShore software products
from the terminal. Designed for AI agents and humans alike — every command
supports --format json for non-TTY scripting.
Install
npm install -g @farthershore/cliOr use directly with npx:
npx @farthershore/cli --helpThe package also ships an MCP stdio server for agents:
FARTHERSHORE_TOKEN=mk_xxx npx -p @farthershore/cli farthershore-mcpAuthentication
Create a maker token at farthershore.com/settings/tokens, then store it locally:
# Interactive — prompts for the token
farthershore auth login
# Non-interactive — pass it directly
farthershore auth login --token mk_xxx
# Or skip the file entirely with an env var (CI / agents)
export FARTHERSHORE_TOKEN=mk_xxxTokens are stored in ~/.farthershore/credentials.json. Maker tokens are
exchanged for a short-lived CLI access token on first authenticated request.
farthershore auth whoami # Show current org, role, scopes
farthershore auth logout # Clear stored credentialsGlobal flags
| Flag | Description |
|---|---|
--token <token> |
Override auth token for this command |
--api-url <url> |
Override platform Core API URL |
--env <environment> |
Environment scope (use production/prod/main) |
--format <format> |
json for machine-readable output (default for non-TTY) |
--version |
Show version |
--help |
Show help |
Environment variables
| Variable | Description |
|---|---|
FARTHERSHORE_TOKEN |
API token (overrides stored credentials) |
FARTHERSHORE_API_URL |
Platform Core API URL (default: https://core.farthershore.com) |
FARTHERSHORE_ENV |
Default environment scope when --env is omitted |
Commands
farthershore init
Scaffold a starter software-product repo from a named plan preset. Each preset
fills in the 5-knob spec through product/plans.ts, with
product/product.config.ts composing meters.ts, features.ts, and plans.ts.
The command also creates a customer frontend/ project, repo-local
product/package.json, product/tsconfig.json, and .gitignore, matching the
two-root shape generated by dashboard product creation.
# Interactive walkthrough (TTY only) — pick a preset by number/name + path
farthershore init
# Non-interactive — pass --template explicitly (required when not a TTY)
farthershore init --template free
farthershore init --template starter --force
farthershore init --template metered --format json
farthershore init --template starter --surface frontend --surface agentTemplates (sourced from shared-types listPlanPresets()):
| Template | Shape |
|---|---|
free |
$0 plan, hard-enforced 1k requests/month limit |
starter |
$20/mo + $20 included usage, $0.001/request overage |
pro |
$100/mo + $200 included usage, 14-day trial, $0.0005/request |
prepaid |
$50 one-time signup credit, then PAYG |
metered |
Pure pay-as-you-go at $0.001/request |
After init, edit the fs.product(...) product name and origin in
product/product.config.ts. origin is the business logic destination Farther
Shore calls for customer-facing actions. Keep the generated module split or
reorganize the product into any imported files you want. Pass repeatable
--surface <frontend|api|docs|widget|dashboard|webhook|worker|agent> to seed a
frontend-only, agent, worker, API, or hybrid product. Omitting --surface
keeps the default frontend + api starter and its sample gateway route. Run
npm install in product/ once, then run farthershore build from the repo
root to confirm the scaffolded product compiles locally. Customize frontend/
for signup, pricing, account, and usage screens.
farthershore build
Build a product-as-code product/product.config.ts with the Product SDK
manifest builder. The CLI first uses the builder installed under product/,
then falls back to a root install. The command emits a Manifest IR envelope to
manifest-ir.json by default. Server-side validation and accepted lifecycle
state are handled by the GitHub bot when product/** changes are pushed to the
repo-backed product.
farthershore build
farthershore build --entry product/product.config.ts --out manifest-ir.json
farthershore build --format jsonfarthershore product
Product lifecycle commands. Creation requires a connected GitHub account because
Farther Shore always provisions the editable frontend/ starter repo for a new
product.
farthershore product list --format json
farthershore product show weather-api --format json
farthershore product show weather-api --env preview --format json
farthershore product create \
--name weather-api \
--display-name "Weather API" \
--origin https://api.example.com \
--format json
# Meter templates — the same smart defaults the dashboard offers:
# requests (default) | ai-tokens | credits | spend | compute
farthershore product create \
--name llm-api \
--origin https://api.llm.example.com \
--meters ai-tokens \
--format json
# Or a fully custom meter list (key[:display[:unit]], repeatable):
farthershore product create --name image-api \
--origin https://api.images.example.com \
--meter requests \
--meter images:Images:image \
--format json
# Seed initial Product SDK surfaces (repeatable). Defaults to frontend + API.
farthershore product create \
--name support-agent \
--origin https://app.example.com \
--repo-owner acme \
--repo-name support-agent \
--surface frontend \
--surface agent \
--format json
farthershore product update weather-api --display-name "Weather" --format json
farthershore product publish weather-api --format json
farthershore product delete weather-api --yes --format jsonproduct create provisions a managed GitHub repo and returns clone-URL +
agent bootstrap instructions in the response. That repo is required for the
starter frontend/ project and normal customization workflow. Product SDK
changes can be built locally with farthershore build; accepted changes are
compiled and published by the GitHub bot after they are committed and pushed.
Plan pricing lives on the plan (see farthershore plan create below) — the
product itself no longer carries a billingStrategy. Omitting both meter flags
gives the product a requests meter. Plain request counting is
platform-managed. Variable-value meters such as tokens, credits, or compute must
be declared in the Product SDK as route reports and reported by the upstream
with @farthershore/backend.
A new product starts as a DRAFT with a generated frontend/ project ready for
customization. Going live mirrors the dashboard's "Finish setting up" checklist:
farthershore product create \
--name llm-api \
--origin https://api.example.com \
--meters ai-tokens # 1. create
farthershore connect stripe llm-api # 2. connect billing
farthershore plan create llm-api --key pro --name "Pro" \
--recurring-fee-cents 2900 # 3. how you charge
farthershore product publish llm-api # 4. go liveproduct publish enforces the same gates as the dashboard: at least one
plan, an origin, and a verified Stripe connection (clear remediation is
printed for STRIPE_NOT_CONNECTED / STRIPE_NOT_VERIFIED /
BILLING_TAX_NOT_ENROLLED).
farthershore env
Manage preview/production environments. Production is the default scope
when --env is omitted; production, prod, and main are aliases.
farthershore env list weather-api --format json
farthershore env create weather-api --name preview --branch env/preview --format json
farthershore env delete weather-api preview --yes --format jsonfarthershore plan
Plan CRUD via the management API. The body uses the unified 5-knob shape (see "Plan knobs" below) — pass cents-denominated flags for whichever knobs the plan flavor needs.
# Human-readable table (default in TTY)
farthershore plan list weather-api
farthershore plan list weather-api --format table
# JSON envelope (default outside TTY; suitable for jq pipelines)
farthershore plan list weather-api --format json
# Flat subscription: recurring fee only
farthershore plan create weather-api \
--key pro \
--name "Pro" \
--recurring-fee-cents 2900 \
--format json
# Included usage: fee + monthly credit grant
farthershore plan create weather-api \
--key included \
--name "Included" \
--recurring-fee-cents 2000 \
--grant recurring:2000 \
--format json
# Free plan
farthershore plan create weather-api --key free --name "Free" --free --format json
farthershore plan update weather-api <planId> --recurring-fee-cents 3900 --format json
farthershore plan delete weather-api <planId> --yes --env preview --format jsonfarthershore persona
Test-environment personas — mint fresh fsk_test_* API keys so an agent
can exercise the gateway end-to-end. Only works in test-strategy envs.
farthershore persona bootstrap weather-api --env preview --plan pro --format json
farthershore persona list weather-api --env preview --format json
farthershore persona revoke weather-api <personaId> --env preview --format jsonfarthershore usage
Read recent usage off the management API.
farthershore usage summary weather-api --format jsonfarthershore backend
Create BYO backends and provision runtime tokens for upstream services. Core
stores only token hashes; the raw token is returned once and should be deployed
as FS_RUNTIME_TOKEN.
farthershore backend list weather-api --format json
farthershore backend create weather-api \
--name "Production API" \
--origin-url https://api.example.com \
--format json
farthershore backend tokens list weather-api --format json
farthershore backend tokens create weather-api --backend <backendId> --format json
farthershore backend tokens rotate weather-api <tokenId> --format json
farthershore backend tokens revoke weather-api <tokenId> --yes --format json
farthershore backend delete weather-api <backendId> --yes --format jsonPair the token with @farthershore/backend in the upstream:
import { fartherShore, withUsage } from "@farthershore/backend";
const fs = fartherShore.initFromEnv();
export async function POST(request: Request) {
const url = new URL(request.url);
const body = await request.clone().arrayBuffer();
await fs.verifyRequest({
method: request.method,
path: url.pathname,
query: url.search,
headers: request.headers,
body: new Uint8Array(body),
});
const result = await runWorkflow(await request.json());
return withUsage(request, Response.json(result), {
tokens_used: result.tokensUsed,
});
}farthershore connect
GitHub OAuth and Stripe Connect flows are browser-only. These commands report status so an agent can poll until the user finishes the flow.
farthershore connect github --format json
farthershore connect stripe weather-api --format jsonfarthershore token
Manage maker tokens for the current org.
farthershore token list --format json
farthershore token create --name "ci-bot" --scope products:update products:publish --format json
farthershore token revoke <tokenId> --yes --format jsonPlan knobs
Every plan is a configuration of orthogonal billing knobs. Older shapes with
pricing.{model, monthlyPriceCents}, top-level billing.strategy, or scalar
credit grant fields are no longer accepted by the validator.
| Knob | Cents/unit | Meaning |
|---|---|---|
meters[] |
micros/unit | Per-dimension usage price (zero or more dimensions) |
recurring_fee_cents |
cents | Charged each billing period (recurring subscription) |
grants[] |
varies by kind | Credit grants, top-ups, rollover, and recharge policy |
trial_days |
days | Waive everything for N days at the start |
max_monthly_spend_cents |
cents (optional) | Hard cap; the gateway blocks once exceeded (orthogonal) |
Billing math (handled by Stripe Billing v2 at invoice finalization):
bill = recurring_fee + max(0, total_meter_cost − applied_credit_balance).
Every plan flavor — free, flat, included, overage, prepaid, trial, pay-as-you-go — is a knob combination. Examples:
# Free plan: explicit `free: true` flag + hard-enforced limit
plans:
- key: free
name: Free
free: true
recurring_fee_cents: 0
limits:
- dimension: requests
window: { type: named, name: month }
capacity: 1000
enforcement: enforce
# Flat subscription: recurring fee only
- key: starter
name: Starter
recurring_fee_cents: 2900
# Included usage: fee + monthly credit grant + metered
- key: pro
name: Pro
recurring_fee_cents: 2000
grants:
- kind: recurring
amount_cents: 2000
meters:
- dimension: requests
price_per_unit_micros: 1000 # $0.001/request
# Overage: fee + metered, no credit
- key: growth
name: Growth
recurring_fee_cents: 4900
meters:
- dimension: requests
price_per_unit_micros: 500
# Prepaid: one-time grant + metered
- key: prepaid
name: Prepaid
grants:
- kind: one_time
amount_cents: 10000
meters:
- dimension: requests
price_per_unit_micros: 1000
# Trial: trial_days + recurring fee
- key: trial
name: Trial
recurring_fee_cents: 2900
trial_days: 14
# Pay-as-you-go: metered only (no recurring fee)
- key: metered
name: Metered
meters:
- dimension: tokens
price_per_unit_micros: 100grants[] array
Plans accept a typed grants[] array. It is the only public credit surface.
For CLI plan create/update, pass one or more canonical grants with
--grant <kind:amount_cents>.
Valid kind values:
| Kind | Required fields | Use case |
|---|---|---|
recurring |
amount_cents |
Monthly credit (e.g. $20 included usage) |
one_time |
amount_cents |
Signup bonus / prepaid balance |
promotional |
amount_cents, label, optional expires_after_days |
Launch bonus, win-back, holiday promo |
trial |
(none) | Trial entry — requires trial_days > 0 on the plan |
rollover |
percent (0–100) |
"Unused balance rolls over X% to the next period" |
top_up |
sku, label, price_cents, credit_cents |
Buy-extra-credit SKU exposed in checkout |
auto_recharge |
threshold_cents, refill_cents |
"When balance < $X auto-purchase $Y" |
recurring, one_time, rollover, and trial are single-shot per plan;
declaring more than one entry of the same kind triggers a warning
(only the first is honored).
Example:
plans:
- key: pro
name: Pro
recurring_fee_cents: 10000
trial_days: 14
meters:
- dimension: requests
price_per_unit_micros: 500
grants:
- kind: recurring
amount_cents: 20000
- kind: trial
- kind: promotional
amount_cents: 1000
label: launch-bonus
expires_after_days: 30
- kind: rollover
percent: 25
- kind: auto_recharge
threshold_cents: 500
refill_cents: 5000Validation surfaces:
- error — invalid
kindis rewritten toUnknown grant kind. Valid kinds: … - warning —
{ kind: trial }declared buttrial_daysis 0 - warning — singleton kinds (
recurring,one_time,rollover,trial) declared more than once
Deprecation window (Phase 3b)
The product top-level lifecycle.breaking_changes block declares the
breaking-change governance policy validated by the GitHub bot/Core release
path:
lifecycle:
breaking_changes:
require_deprecation_window_days: 90
require_successor_route: trueWhen the policy is set, Core emits a route_removed change for every route
dropped from features.<x>.routes[] and warns when the server-side
breaking-change-safety-check cron will gate publish via ConsumerActivity
lookup. When require_successor_route is true, it also adds a
successor-required warning.
The CLI never blocks on the window itself — the per-consumer lookup
lives server-side (Phase 1c ConsumerActivity table + Phase 3b cron).
Agent workflow
A typical agent flow:
export FARTHERSHORE_TOKEN=mk_xxx
farthershore product create \
--name weather-api \
--origin https://api.example.com \
--format json
farthershore plan create weather-api --key free --name "Free" --free --format json
farthershore plan create weather-api \
--key pro --name "Pro" --recurring-fee-cents 2900 --format json
farthershore build --format json
farthershore product show weather-api --format jsonFor product updates, edit product/product.config.ts or any modules it imports
and build locally with:
farthershore build --format jsonMCP server
The MCP server (farthershore-mcp) projects tool definitions from the same
operation registry that generates the CLI command groups. Tool names use the
fs_* prefix and cover the agent-writable product surface:
- Products:
fs_product_list,fs_brand_update,fs_product_publish - Environments:
fs_env_list,fs_env_create - Plans:
fs_plan_list - Backends:
fs_backend_list,fs_backend_create,fs_backend_delete - Runtime tokens:
fs_runtime_token_list,fs_runtime_token_mint,fs_runtime_token_rotate,fs_runtime_token_revoke - Personas:
fs_persona_bootstrap,fs_persona_list,fs_persona_revoke - Usage and maker tokens:
fs_usage_read,fs_maker_token_list
Every MCP tool has a sibling CLI operation by construction; the parity test in
apps/cli/src/operations/mcp-cli-parity.test.ts enforces that invariant.
Errors and exit codes
The CLI exits 0 on success and 1 on any failure (including
commander-level argument errors). When the API returns a 4XX/5XX, the
CLI prints the canonical error code in brackets and a one-line
remediation hint when one is registered:
Error [STRIPE_NOT_CONFIGURED]: connect Stripe before running billing operations
Hint: Stripe isn't connected on this product. Connect it in the dashboard before running billing operations.The bracketed code is stable across releases — quote it in support threads.
farthershore auth whoami --format json emits a stable JSON shape suitable
for CI scripts.
CI / agent usage
The CLI is non-interactive whenever a token is available via the
--token flag or FARTHERSHORE_TOKEN env var — auth login only
prompts when stdin is a TTY and no token argument was passed, so it's
safe to script. farthershore build is CI-safe and can be run under CI /
GITHUB_ACTIONS for local Product SDK compilation.