@farthershore/cli 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +233 -396
- package/dist/index.js +55 -55
- package/dist/mcp.js +14 -14
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
# @farthershore/cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
Create and operate [FartherShore](https://farthershore.com) software businesses
|
|
4
|
+
from the terminal.
|
|
5
|
+
|
|
6
|
+
**Status: `0.16.0`.** Pre-1.0 — the command surface is stable but may still
|
|
7
|
+
change between minor versions. Pin an exact version in CI.
|
|
8
|
+
|
|
9
|
+
FartherShore lets you define a software business as code, then sells, meters,
|
|
10
|
+
and bills access to it at the edge. Product behavior — plans, pricing, limits,
|
|
11
|
+
routes, meters, and origins — is authored in your GitHub repo with
|
|
12
|
+
[`@farthershore/business`](https://www.npmjs.com/package/@farthershore/business)
|
|
13
|
+
and applied automatically when you push. This CLI is the tool layer around that
|
|
14
|
+
repo: scaffold a new business, validate it locally before you push, connect
|
|
15
|
+
billing, publish it live, and run day-to-day operations (consumers, secrets,
|
|
16
|
+
backends, webhooks, promo codes, usage). It is designed to be safe for both
|
|
17
|
+
humans and agents — every command takes `--format json` for non-interactive
|
|
18
|
+
scripting, and the same surface is exposed as an MCP server.
|
|
10
19
|
|
|
11
20
|
## Install
|
|
12
21
|
|
|
@@ -14,7 +23,7 @@ those flows.
|
|
|
14
23
|
npm install -g @farthershore/cli
|
|
15
24
|
```
|
|
16
25
|
|
|
17
|
-
Or
|
|
26
|
+
Or run it directly with npx:
|
|
18
27
|
|
|
19
28
|
```bash
|
|
20
29
|
npx @farthershore/cli --help
|
|
@@ -43,79 +52,84 @@ farthershore auth login --token mk_xxx
|
|
|
43
52
|
export FARTHERSHORE_TOKEN=mk_xxx
|
|
44
53
|
```
|
|
45
54
|
|
|
46
|
-
Tokens are stored in `~/.farthershore/credentials.json`.
|
|
47
|
-
exchanged for a short-lived CLI access token on first authenticated request.
|
|
55
|
+
Tokens are stored in `~/.farthershore/credentials.json`. A maker token is
|
|
56
|
+
exchanged for a short-lived CLI access token on the first authenticated request.
|
|
48
57
|
|
|
49
58
|
```bash
|
|
50
|
-
farthershore auth whoami # Show current org, role, scopes
|
|
59
|
+
farthershore auth whoami # Show current org, role, and scopes
|
|
51
60
|
farthershore auth logout # Clear stored credentials
|
|
52
61
|
```
|
|
53
62
|
|
|
54
|
-
|
|
63
|
+
GitHub account linking and Stripe Connect/KYC are browser-hosted flows; the CLI
|
|
64
|
+
reports their status (see `connect`) so you — or an agent — can continue once the
|
|
65
|
+
flow is finished in the dashboard.
|
|
55
66
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
`@farthershore/farthershore-js` skill update, or the reverse.
|
|
67
|
+
## Quickstart
|
|
68
|
+
|
|
69
|
+
Scaffold a business, validate it, connect billing, and publish:
|
|
60
70
|
|
|
61
71
|
```bash
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
export FARTHERSHORE_TOKEN=mk_xxx
|
|
73
|
+
|
|
74
|
+
# 1. Create the managed repo (provisions GitHub repo + starter frontend)
|
|
75
|
+
farthershore business create --name weather-api --display-name "Weather API"
|
|
76
|
+
|
|
77
|
+
# 2. Edit business behavior in the repo
|
|
78
|
+
gh repo clone acme/weather-api
|
|
79
|
+
cd weather-api
|
|
80
|
+
# ...edit business/business.config.ts with @farthershore/business...
|
|
81
|
+
|
|
82
|
+
# 3. Validate the same way the PR check will, before pushing
|
|
83
|
+
farthershore preflight --business weather-api
|
|
84
|
+
|
|
85
|
+
# 4. Push — the GitHub bot compiles + applies your manifest
|
|
86
|
+
git push --set-upstream origin feature/pricing
|
|
87
|
+
farthershore change-set list weather-api # inspect checks + apply state
|
|
65
88
|
|
|
66
|
-
#
|
|
67
|
-
farthershore
|
|
68
|
-
|
|
89
|
+
# 5. Connect billing, then go live
|
|
90
|
+
farthershore connect stripe weather-api
|
|
91
|
+
farthershore business publish weather-api
|
|
69
92
|
```
|
|
70
93
|
|
|
94
|
+
Plans, prices, limits, routes, meters, and origins are **repo-controlled**:
|
|
95
|
+
change them by editing `business/business.config.ts` and pushing. The CLI's
|
|
96
|
+
write commands cover **operational** state that lives outside the manifest
|
|
97
|
+
(consumers, secrets, backends, webhooks, promo codes, brand presentation).
|
|
98
|
+
|
|
71
99
|
## Global flags
|
|
72
100
|
|
|
73
101
|
| Flag | Description |
|
|
74
102
|
| --------------------- | -------------------------------------------------------- |
|
|
75
103
|
| `--token <token>` | Override auth token for this command |
|
|
76
104
|
| `--api-url <url>` | Override platform Core API URL |
|
|
77
|
-
| `--env <environment>` | Environment scope (
|
|
105
|
+
| `--env <environment>` | Environment scope (`production`/`prod`/`main` aliases) |
|
|
78
106
|
| `--format <format>` | `json` for machine-readable output (default for non-TTY) |
|
|
79
|
-
| `--no-input` | Never prompt; use non-interactive agent-safe paths
|
|
107
|
+
| `--no-input` | Never prompt; use non-interactive, agent-safe paths |
|
|
80
108
|
| `--version` | Show version |
|
|
81
109
|
| `--help` | Show help |
|
|
82
110
|
|
|
83
111
|
## Environment variables
|
|
84
112
|
|
|
85
|
-
| Variable | Description
|
|
86
|
-
| ---------------------- |
|
|
87
|
-
| `FARTHERSHORE_TOKEN` | API token (overrides stored credentials)
|
|
88
|
-
| `FARTHERSHORE_API_URL` | Platform Core API URL (default
|
|
89
|
-
| `FARTHERSHORE_ENV` | Default environment scope when `--env` is omitted
|
|
113
|
+
| Variable | Description |
|
|
114
|
+
| ---------------------- | --------------------------------------------------------------- |
|
|
115
|
+
| `FARTHERSHORE_TOKEN` | API token (overrides stored credentials) |
|
|
116
|
+
| `FARTHERSHORE_API_URL` | Platform Core API URL (default `https://core.farthershore.com`) |
|
|
117
|
+
| `FARTHERSHORE_ENV` | Default environment scope when `--env` is omitted |
|
|
90
118
|
|
|
91
119
|
## Commands
|
|
92
120
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
Print the machine-readable action boundary before an agent attempts a change:
|
|
96
|
-
repo-authored product behavior, API-controlled runtime operations, dual
|
|
97
|
-
repo/API operations, and browser-only prerequisites.
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
farthershore operations list --format json
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
`contract` rows are changed in `business/business.config.ts` and pushed through
|
|
104
|
-
GitHub. `operate` rows are CLI/Core API actions. `dual` rows reconcile through
|
|
105
|
-
either path. `browserOnlyPrerequisites` currently includes GitHub account
|
|
106
|
-
linking and Stripe Connect onboarding, both status-only from the CLI.
|
|
121
|
+
Run `farthershore <group> --help` for the full flag set of any command.
|
|
107
122
|
|
|
108
123
|
### `farthershore init`
|
|
109
124
|
|
|
110
|
-
Scaffold a starter
|
|
111
|
-
fills in
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
two-root shape generated by dashboard product creation.
|
|
125
|
+
Scaffold a starter business repo locally from a named plan preset. Each preset
|
|
126
|
+
fills in a single decorated `business/business.config.ts` (one `@Business` class
|
|
127
|
+
with `@Meter`/`@Feature`/`@Plan` members) and creates the matching customer
|
|
128
|
+
`frontend/` project, repo-local `business/package.json`, `business/tsconfig.json`,
|
|
129
|
+
and `.gitignore`.
|
|
116
130
|
|
|
117
131
|
```bash
|
|
118
|
-
# Interactive walkthrough (TTY only) — pick a preset
|
|
132
|
+
# Interactive walkthrough (TTY only) — pick a preset and a path
|
|
119
133
|
farthershore init
|
|
120
134
|
|
|
121
135
|
# Non-interactive — pass --template explicitly (required when not a TTY)
|
|
@@ -125,35 +139,28 @@ farthershore init --template metered --format json
|
|
|
125
139
|
farthershore init --template starter --surface frontend --surface agent
|
|
126
140
|
```
|
|
127
141
|
|
|
128
|
-
Templates (sourced from shared-types `listPlanPresets()`):
|
|
129
|
-
|
|
130
142
|
| Template | Shape |
|
|
131
143
|
| --------- | ------------------------------------------------------------ |
|
|
132
144
|
| `free` | $0 plan, hard-enforced 1k requests/month limit |
|
|
133
145
|
| `starter` | $20/mo + $20 included usage, $0.001/request overage |
|
|
134
146
|
| `pro` | $100/mo + $200 included usage, 14-day trial, $0.0005/request |
|
|
135
|
-
| `prepaid` | $50 one-time signup credit, then
|
|
147
|
+
| `prepaid` | $50 one-time signup credit, then pay-as-you-go |
|
|
136
148
|
| `metered` | Pure pay-as-you-go at $0.001/request |
|
|
137
149
|
|
|
138
|
-
After `init`, edit the `@Business({ name, origin })` decorator
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
members to the class to grow the business. Pass repeatable
|
|
150
|
+
After `init`, edit the `@Business({ name, origin })` decorator — `origin` is the
|
|
151
|
+
business-logic destination FartherShore calls for customer-facing actions — and
|
|
152
|
+
add `@Meter`/`@Feature`/`@Plan` members to grow the business. Pass repeatable
|
|
142
153
|
`--surface <frontend|api|docs|widget|dashboard|webhook|worker|agent>` to seed a
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
root to confirm the scaffolded business compiles locally. Customize `frontend/`
|
|
147
|
-
for signup, pricing, account, and usage screens.
|
|
154
|
+
specific shape; omitting it keeps the default `frontend + api` starter. Run
|
|
155
|
+
`npm install` in `business/`, then `farthershore build` from the repo root to
|
|
156
|
+
confirm it compiles.
|
|
148
157
|
|
|
149
158
|
### `farthershore build`
|
|
150
159
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
state are handled by the GitHub bot when `business/**` changes are pushed to the
|
|
156
|
-
repo-backed business.
|
|
160
|
+
Compile `business/business.config.ts` to a Manifest IR envelope locally (default
|
|
161
|
+
output `business-build.json`). The CLI uses the Business SDK installed under
|
|
162
|
+
`business/`, falling back to a root install. This is local compilation only;
|
|
163
|
+
server-side validation and apply happen when you push `business/**` changes.
|
|
157
164
|
|
|
158
165
|
```bash
|
|
159
166
|
farthershore build
|
|
@@ -161,11 +168,26 @@ farthershore build --entry business/business.config.ts --out business-build.json
|
|
|
161
168
|
farthershore build --format json
|
|
162
169
|
```
|
|
163
170
|
|
|
171
|
+
### `farthershore preflight`
|
|
172
|
+
|
|
173
|
+
Run the same verdict the GitHub `farthershore/validate` PR check produces, before
|
|
174
|
+
you push. It builds the manifest twice and compares the IR hash (the determinism
|
|
175
|
+
check the build runner enforces), then — when you pass `--business` — submits the
|
|
176
|
+
IR for a server dry-run that returns compile diagnostics, the semantic diff, and
|
|
177
|
+
an economic-change verdict.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
farthershore preflight # local build + determinism only
|
|
181
|
+
farthershore preflight --business weather-api # + full server verdict
|
|
182
|
+
farthershore preflight --local-only --format json
|
|
183
|
+
```
|
|
184
|
+
|
|
164
185
|
### `farthershore business`
|
|
165
186
|
|
|
166
|
-
Business lifecycle
|
|
167
|
-
|
|
168
|
-
|
|
187
|
+
Business lifecycle. Creation provisions a managed GitHub repo (the source of
|
|
188
|
+
truth for product behavior) under your connected GitHub account and returns the
|
|
189
|
+
clone URL plus bootstrap instructions. A new business starts as a DRAFT with a
|
|
190
|
+
generated `frontend/` ready to customize.
|
|
169
191
|
|
|
170
192
|
```bash
|
|
171
193
|
farthershore business list --format json
|
|
@@ -177,12 +199,9 @@ farthershore business create \
|
|
|
177
199
|
--display-name "Weather API" \
|
|
178
200
|
--format json
|
|
179
201
|
|
|
180
|
-
#
|
|
202
|
+
# Seed a meter from the same templates the dashboard offers:
|
|
181
203
|
# requests (default) | ai-tokens | credits | spend | compute
|
|
182
|
-
farthershore business create
|
|
183
|
-
--name llm-api \
|
|
184
|
-
--meters ai-tokens \
|
|
185
|
-
--format json
|
|
204
|
+
farthershore business create --name llm-api --meters ai-tokens --format json
|
|
186
205
|
|
|
187
206
|
# Or a fully custom meter list (key[:display[:unit]], repeatable):
|
|
188
207
|
farthershore business create --name image-api \
|
|
@@ -190,71 +209,51 @@ farthershore business create --name image-api \
|
|
|
190
209
|
--meter images:Images:image \
|
|
191
210
|
--format json
|
|
192
211
|
|
|
193
|
-
# Seed initial Business SDK surfaces (repeatable
|
|
212
|
+
# Seed initial Business SDK surfaces (repeatable; defaults to frontend + api):
|
|
194
213
|
farthershore business create \
|
|
195
214
|
--name support-agent \
|
|
196
215
|
--surface frontend \
|
|
197
216
|
--surface agent \
|
|
198
217
|
--format json
|
|
199
218
|
|
|
200
|
-
farthershore business
|
|
219
|
+
farthershore business publish weather-api --format json
|
|
220
|
+
farthershore business delete weather-api --yes --format json
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`business update` is presentation-only — it changes display name, description,
|
|
224
|
+
icon, and logo (icon/logo accept PNG, JPEG, or WEBP). Plans, prices, limits,
|
|
225
|
+
routes, meters, and origins are repo-controlled and must be changed through the
|
|
226
|
+
Business SDK code path.
|
|
227
|
+
|
|
228
|
+
```bash
|
|
201
229
|
farthershore business update weather-api \
|
|
202
230
|
--display-name "Weather" \
|
|
203
231
|
--description "Weather API for agents" \
|
|
204
|
-
--primary-color '#22c55e' \
|
|
205
232
|
--icon-file ./brand/icon.png \
|
|
206
233
|
--logo-file ./brand/logo.webp \
|
|
207
234
|
--format json
|
|
208
235
|
farthershore business update weather-api \
|
|
209
|
-
--clear-
|
|
210
|
-
farthershore business publish weather-api --format json
|
|
211
|
-
farthershore business delete weather-api --yes --format json
|
|
236
|
+
--clear-icon --clear-logo --format json
|
|
212
237
|
```
|
|
213
238
|
|
|
214
|
-
`business
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
`business update` is deliberately presentation-only. It updates operate-state
|
|
224
|
-
fields that are not the product contract: display name, description, primary
|
|
225
|
-
brand color, icon, and logo. Local icon/logo uploads accept PNG, JPEG, or WEBP
|
|
226
|
-
files. Plans, prices, limits, routes, meters, policies, workflows, origins, and
|
|
227
|
-
backend definitions are repo-controlled and must be changed through the Business
|
|
228
|
-
SDK code path.
|
|
229
|
-
|
|
230
|
-
Omitting both meter flags during bootstrap gives the starter business a
|
|
231
|
-
`requests` meter. Plain request counting is platform-managed. Variable-value
|
|
232
|
-
meters such as tokens, credits, or compute must be declared in the Business SDK
|
|
233
|
-
as route `reports` and reported by the upstream with `@farthershore/backend`.
|
|
234
|
-
|
|
235
|
-
A new product starts as a DRAFT with a generated `frontend/` project ready for
|
|
236
|
-
customization. Going live mirrors the dashboard's "Finish setting up" checklist:
|
|
239
|
+
`business publish` enforces the same go-live gates as the dashboard: at least one
|
|
240
|
+
plan, an origin, and a verified Stripe connection (clear remediation is printed
|
|
241
|
+
for `STRIPE_NOT_CONNECTED` / `STRIPE_NOT_VERIFIED` / `BILLING_TAX_NOT_ENROLLED`).
|
|
242
|
+
|
|
243
|
+
### `farthershore change-set`
|
|
244
|
+
|
|
245
|
+
Inspect repo-backed change sets — PRs, pushes, releases, checks, semantic diffs,
|
|
246
|
+
and apply state — for a business.
|
|
237
247
|
|
|
238
248
|
```bash
|
|
239
|
-
farthershore
|
|
240
|
-
|
|
241
|
-
gh repo clone acme/llm-api # 2. edit business/
|
|
242
|
-
farthershore build --format json # 3. validate locally
|
|
243
|
-
git push --set-upstream origin feature/pricing # 4. open PR
|
|
244
|
-
farthershore change-set list llm-api --format json # 5. inspect checks
|
|
245
|
-
farthershore connect stripe llm-api # 6. connect billing
|
|
246
|
-
farthershore business publish llm-api # 7. go live
|
|
249
|
+
farthershore change-set list weather-api --format json
|
|
250
|
+
farthershore change-set inspect weather-api 42 --format json # by id, PR #, branch, or SHA
|
|
247
251
|
```
|
|
248
252
|
|
|
249
|
-
`business publish` enforces the same gates as the dashboard: at least one
|
|
250
|
-
plan, an origin, and a verified Stripe connection (clear remediation is
|
|
251
|
-
printed for `STRIPE_NOT_CONNECTED` / `STRIPE_NOT_VERIFIED` /
|
|
252
|
-
`BILLING_TAX_NOT_ENROLLED`).
|
|
253
|
-
|
|
254
253
|
### `farthershore env`
|
|
255
254
|
|
|
256
|
-
Manage preview/production environments. Production is the default scope
|
|
257
|
-
|
|
255
|
+
Manage preview/production environments. Production is the default scope when
|
|
256
|
+
`--env` is omitted (`production`, `prod`, and `main` are aliases).
|
|
258
257
|
|
|
259
258
|
```bash
|
|
260
259
|
farthershore env list weather-api --format json
|
|
@@ -264,26 +263,40 @@ farthershore env delete weather-api preview --yes --format json
|
|
|
264
263
|
|
|
265
264
|
### `farthershore plan`
|
|
266
265
|
|
|
267
|
-
Read code-managed plans and operate live subscriber migrations. The CLI does
|
|
268
|
-
|
|
269
|
-
|
|
266
|
+
Read code-managed plans and operate live subscriber migrations. The CLI does not
|
|
267
|
+
create, update, or delete plan definitions — edit the Business SDK program for
|
|
268
|
+
that.
|
|
270
269
|
|
|
271
270
|
```bash
|
|
272
|
-
|
|
273
|
-
farthershore plan list weather-api
|
|
274
|
-
farthershore plan list weather-api --format table
|
|
275
|
-
|
|
276
|
-
# JSON envelope (default outside TTY; suitable for jq pipelines)
|
|
271
|
+
farthershore plan list weather-api # table (default in TTY)
|
|
277
272
|
farthershore plan list weather-api --format json
|
|
278
273
|
|
|
279
|
-
#
|
|
274
|
+
# Migrate live subscribers after a repo-authored plan version is released
|
|
280
275
|
farthershore plan migrate weather-api pro --from 1 --to head --policy next_renewal --format json
|
|
281
276
|
```
|
|
282
277
|
|
|
278
|
+
### `farthershore frontend`
|
|
279
|
+
|
|
280
|
+
Managed Frontend Hosting operations plus a local preview. `deploy`, `status`,
|
|
281
|
+
`rollback`, and `env` operate the hosted build; `preview` runs the generated
|
|
282
|
+
`frontend/`'s `vite dev` with an injected `window.__FS_CONFIG__` shim so the
|
|
283
|
+
portal renders locally exactly as it serves in production.
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
farthershore frontend status weather-api --format json
|
|
287
|
+
farthershore frontend deploy weather-api --format json
|
|
288
|
+
farthershore frontend rollback weather-api --release-id <hash> --format json
|
|
289
|
+
farthershore frontend env list weather-api --format json
|
|
290
|
+
farthershore frontend env set weather-api VITE_PUBLIC_FOO bar --target BUILD --format json
|
|
291
|
+
|
|
292
|
+
# Local preview (shells out to vite; needs a frontend/ project)
|
|
293
|
+
farthershore frontend preview --core-url http://localhost:8787
|
|
294
|
+
```
|
|
295
|
+
|
|
283
296
|
### `farthershore persona`
|
|
284
297
|
|
|
285
|
-
|
|
286
|
-
|
|
298
|
+
Mint fresh `fsk_test_*` API keys in a test-strategy environment so you can
|
|
299
|
+
exercise the gateway end-to-end.
|
|
287
300
|
|
|
288
301
|
```bash
|
|
289
302
|
farthershore persona bootstrap weather-api --env preview --plan pro --format json
|
|
@@ -301,47 +314,42 @@ farthershore usage summary weather-api --format json
|
|
|
301
314
|
|
|
302
315
|
### `farthershore consumer`
|
|
303
316
|
|
|
304
|
-
Manage live business users
|
|
305
|
-
|
|
317
|
+
Manage live business users. These are operational actions, not repo-authored
|
|
318
|
+
behavior.
|
|
306
319
|
|
|
307
320
|
```bash
|
|
308
321
|
farthershore consumer list weather-api --format json
|
|
309
|
-
farthershore consumer list weather-api --env preview --format json
|
|
310
322
|
farthershore consumer block weather-api <subscriberId> --yes --format json
|
|
311
323
|
farthershore consumer remove weather-api <subscriberId> --yes --format json
|
|
312
324
|
```
|
|
313
325
|
|
|
314
|
-
Use `consumer list` first to
|
|
315
|
-
|
|
316
|
-
|
|
326
|
+
Use `consumer list` first to find a `subscriberId`. `block` suspends a user and
|
|
327
|
+
revokes active API keys. `remove` is irreversible and tears down subscriber state
|
|
328
|
+
across billing, edge credentials, and subscriptions.
|
|
317
329
|
|
|
318
330
|
### `farthershore secret`
|
|
319
331
|
|
|
320
|
-
Manage private business secrets.
|
|
321
|
-
not repo-authored product behavior. Values are encrypted at rest and list/read
|
|
332
|
+
Manage private business secrets. Values are encrypted at rest; list/read
|
|
322
333
|
responses return metadata only.
|
|
323
334
|
|
|
324
335
|
```bash
|
|
325
336
|
farthershore secret list weather-api --format json
|
|
326
337
|
printf '%s' "$CLERK_SECRET_KEY" | farthershore secret set weather-api \
|
|
327
|
-
CLERK_SECRET_KEY
|
|
328
|
-
--from-stdin \
|
|
329
|
-
--target RUNTIME \
|
|
330
|
-
--format json
|
|
338
|
+
CLERK_SECRET_KEY --from-stdin --target RUNTIME --format json
|
|
331
339
|
farthershore secret delete weather-api CLERK_SECRET_KEY --yes --format json
|
|
332
340
|
```
|
|
333
341
|
|
|
334
|
-
Use `frontend env` for public browser-visible variables
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
342
|
+
Use `frontend env` for public, browser-visible variables (`VITE_PUBLIC_*`,
|
|
343
|
+
analytics keys). Use `secret` for server runtime and private build values.
|
|
344
|
+
`BUILD` secrets are injected into managed frontend builds and require a redeploy;
|
|
345
|
+
`RUNTIME` secrets are for trusted server/backend code and are never exposed to
|
|
346
|
+
the browser.
|
|
339
347
|
|
|
340
348
|
### `farthershore backend`
|
|
341
349
|
|
|
342
|
-
Create
|
|
343
|
-
|
|
344
|
-
as `FS_RUNTIME_TOKEN`.
|
|
350
|
+
Create bring-your-own backends and provision runtime tokens for your upstream
|
|
351
|
+
services. Only token hashes are stored; the raw token is returned once and should
|
|
352
|
+
be deployed as `FS_RUNTIME_TOKEN`.
|
|
345
353
|
|
|
346
354
|
```bash
|
|
347
355
|
farthershore backend list weather-api --format json
|
|
@@ -349,14 +357,14 @@ farthershore backend create weather-api \
|
|
|
349
357
|
--name "Production API" \
|
|
350
358
|
--origin-url https://api.example.com \
|
|
351
359
|
--format json
|
|
352
|
-
farthershore backend tokens list weather-api --format json
|
|
353
360
|
farthershore backend tokens create weather-api --backend <backendId> --format json
|
|
354
361
|
farthershore backend tokens rotate weather-api <tokenId> --format json
|
|
355
362
|
farthershore backend tokens revoke weather-api <tokenId> --yes --format json
|
|
356
|
-
farthershore backend delete weather-api <backendId> --yes --format json
|
|
357
363
|
```
|
|
358
364
|
|
|
359
|
-
Pair the token with
|
|
365
|
+
Pair the token with
|
|
366
|
+
[`@farthershore/backend`](https://www.npmjs.com/package/@farthershore/backend) in
|
|
367
|
+
your upstream:
|
|
360
368
|
|
|
361
369
|
```ts
|
|
362
370
|
import { fartherShore, withUsage } from "@farthershore/backend";
|
|
@@ -384,10 +392,9 @@ export async function POST(request: Request) {
|
|
|
384
392
|
|
|
385
393
|
### `farthershore webhook`
|
|
386
394
|
|
|
387
|
-
Provision outbound webhook endpoints and inspect delivery health.
|
|
388
|
-
|
|
389
|
-
`
|
|
390
|
-
the repo remains canonical.
|
|
395
|
+
Provision outbound webhook endpoints and inspect delivery health. If the business
|
|
396
|
+
declares webhooks in `business/business.config.ts`, writes return
|
|
397
|
+
`409 MANAGED_BY_CODE` so the repo stays canonical.
|
|
391
398
|
|
|
392
399
|
```bash
|
|
393
400
|
farthershore webhook list weather-api --format json
|
|
@@ -401,50 +408,32 @@ farthershore webhook deliveries weather-api <webhookId> --limit 20 --format json
|
|
|
401
408
|
farthershore webhook delete weather-api <webhookId> --yes --format json
|
|
402
409
|
```
|
|
403
410
|
|
|
404
|
-
`webhook create` returns the signing secret once
|
|
405
|
-
subsequent list/delivery commands never return the secret.
|
|
411
|
+
`webhook create` returns the signing secret once; store it in the receiving app.
|
|
406
412
|
|
|
407
413
|
### `farthershore promo-code`
|
|
408
414
|
|
|
409
|
-
Manage checkout promo codes
|
|
410
|
-
not part of `business/business.config.ts`, so agents can manage them through the
|
|
411
|
-
CLI just like the dashboard.
|
|
415
|
+
Manage checkout promo codes (operational state, not part of the manifest).
|
|
412
416
|
|
|
413
417
|
```bash
|
|
414
418
|
farthershore promo-code list weather-api --format json
|
|
415
419
|
farthershore promo-code create weather-api \
|
|
416
|
-
--code LAUNCH25 \
|
|
417
|
-
--
|
|
418
|
-
--percent 25 \
|
|
419
|
-
--duration-months 3 \
|
|
420
|
-
--plan <planId> \
|
|
421
|
-
--format json
|
|
420
|
+
--code LAUNCH25 --kind percent_off --percent 25 --duration-months 3 \
|
|
421
|
+
--plan <planId> --format json
|
|
422
422
|
farthershore promo-code create weather-api \
|
|
423
|
-
--code SAVE500
|
|
424
|
-
--kind amount_off \
|
|
425
|
-
--amount-cents 500 \
|
|
426
|
-
--duration-months 1 \
|
|
427
|
-
--format json
|
|
428
|
-
farthershore promo-code update weather-api <promoCodeId> \
|
|
429
|
-
--code LAUNCH30 \
|
|
430
|
-
--kind percent_off \
|
|
431
|
-
--percent 30 \
|
|
432
|
-
--duration-months 3 \
|
|
433
|
-
--all-plans \
|
|
434
|
-
--format json
|
|
423
|
+
--code SAVE500 --kind amount_off --amount-cents 500 --duration-months 1 --format json
|
|
435
424
|
farthershore promo-code archive weather-api <promoCodeId> --format json
|
|
436
425
|
farthershore promo-code reactivate weather-api <promoCodeId> --format json
|
|
437
426
|
```
|
|
438
427
|
|
|
439
|
-
Stripe coupon
|
|
440
|
-
requires `--kind`, `--duration-months`, and the
|
|
441
|
-
|
|
428
|
+
Because a Stripe coupon change requires a complete discount spec, `promo-code
|
|
429
|
+
update` requires `--kind`, `--duration-months`, and the amount flag for that kind
|
|
430
|
+
whenever you change the code, amount, dates, plan scope, or redemption limits.
|
|
442
431
|
Use `--all-plans` to clear plan scoping.
|
|
443
432
|
|
|
444
433
|
### `farthershore connect`
|
|
445
434
|
|
|
446
|
-
GitHub OAuth and Stripe Connect
|
|
447
|
-
|
|
435
|
+
GitHub OAuth and Stripe Connect are browser-only. These commands report status so
|
|
436
|
+
you can poll until the flow is finished in the dashboard.
|
|
448
437
|
|
|
449
438
|
```bash
|
|
450
439
|
farthershore connect github --format json
|
|
@@ -460,239 +449,87 @@ farthershore token list --format json
|
|
|
460
449
|
farthershore token create --name "ci-bot" --scope products:update products:publish --format json
|
|
461
450
|
farthershore token rotate <tokenId> --sync-to-github --format json
|
|
462
451
|
farthershore token revoke <tokenId> --yes --format json
|
|
463
|
-
farthershore token delete <tokenId> --yes --format json
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
#### Plan knobs
|
|
467
|
-
|
|
468
|
-
Every repo-authored plan is a configuration of orthogonal billing knobs. Older
|
|
469
|
-
shapes with `pricing.{model, monthlyPriceCents}`, top-level `billing.strategy`,
|
|
470
|
-
or scalar credit grant fields are no longer accepted by the validator.
|
|
471
|
-
|
|
472
|
-
| Knob | Cents/unit | Meaning |
|
|
473
|
-
| ------------------------- | ---------------- | ------------------------------------------------------- |
|
|
474
|
-
| `meters[]` | micros/unit | Per-dimension usage price (zero or more dimensions) |
|
|
475
|
-
| `recurring_fee_cents` | cents | Charged each billing period (recurring subscription) |
|
|
476
|
-
| `grants[]` | varies by kind | Credit grants, top-ups, rollover, and recharge policy |
|
|
477
|
-
| `trial_days` | days | Waive everything for N days at the start |
|
|
478
|
-
| `max_monthly_spend_cents` | cents (optional) | Hard cap; the gateway blocks once exceeded (orthogonal) |
|
|
479
|
-
|
|
480
|
-
Billing math (handled by Stripe Billing v2 at invoice finalization):
|
|
481
|
-
`bill = recurring_fee + max(0, total_meter_cost − applied_credit_balance)`.
|
|
482
|
-
|
|
483
|
-
Every plan flavor — free, flat, included, overage, prepaid, trial,
|
|
484
|
-
pay-as-you-go — is a knob combination. Examples:
|
|
485
|
-
|
|
486
|
-
```yaml
|
|
487
|
-
# Free plan: explicit `free: true` flag + hard-enforced limit
|
|
488
|
-
plans:
|
|
489
|
-
- key: free
|
|
490
|
-
name: Free
|
|
491
|
-
free: true
|
|
492
|
-
recurring_fee_cents: 0
|
|
493
|
-
limits:
|
|
494
|
-
- dimension: requests
|
|
495
|
-
window: { type: named, name: month }
|
|
496
|
-
capacity: 1000
|
|
497
|
-
enforcement: enforce
|
|
498
|
-
|
|
499
|
-
# Flat subscription: recurring fee only
|
|
500
|
-
- key: starter
|
|
501
|
-
name: Starter
|
|
502
|
-
recurring_fee_cents: 2900
|
|
503
|
-
|
|
504
|
-
# Included usage: fee + monthly credit grant + metered
|
|
505
|
-
- key: pro
|
|
506
|
-
name: Pro
|
|
507
|
-
recurring_fee_cents: 2000
|
|
508
|
-
grants:
|
|
509
|
-
- kind: recurring
|
|
510
|
-
amount_cents: 2000
|
|
511
|
-
meters:
|
|
512
|
-
- dimension: requests
|
|
513
|
-
price_per_unit_micros: 1000 # $0.001/request
|
|
514
|
-
|
|
515
|
-
# Overage: fee + metered, no credit
|
|
516
|
-
- key: growth
|
|
517
|
-
name: Growth
|
|
518
|
-
recurring_fee_cents: 4900
|
|
519
|
-
meters:
|
|
520
|
-
- dimension: requests
|
|
521
|
-
price_per_unit_micros: 500
|
|
522
|
-
|
|
523
|
-
# Prepaid: one-time grant + metered
|
|
524
|
-
- key: prepaid
|
|
525
|
-
name: Prepaid
|
|
526
|
-
grants:
|
|
527
|
-
- kind: one_time
|
|
528
|
-
amount_cents: 10000
|
|
529
|
-
meters:
|
|
530
|
-
- dimension: requests
|
|
531
|
-
price_per_unit_micros: 1000
|
|
532
|
-
|
|
533
|
-
# Trial: trial_days + recurring fee
|
|
534
|
-
- key: trial
|
|
535
|
-
name: Trial
|
|
536
|
-
recurring_fee_cents: 2900
|
|
537
|
-
trial_days: 14
|
|
538
|
-
|
|
539
|
-
# Pay-as-you-go: metered only (no recurring fee)
|
|
540
|
-
- key: metered
|
|
541
|
-
name: Metered
|
|
542
|
-
meters:
|
|
543
|
-
- dimension: tokens
|
|
544
|
-
price_per_unit_micros: 100
|
|
545
452
|
```
|
|
546
453
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
Plans accept a typed `grants[]` array. It is the only public credit surface.
|
|
550
|
-
Declare grants in the Business SDK program and push the repo change through the
|
|
551
|
-
normal change-set flow.
|
|
552
|
-
|
|
553
|
-
Valid `kind` values:
|
|
554
|
-
|
|
555
|
-
| Kind | Required fields | Use case |
|
|
556
|
-
| --------------- | ------------------------------------------------------ | --------------------------------------------------- |
|
|
557
|
-
| `recurring` | `amount_cents` | Monthly credit (e.g. $20 included usage) |
|
|
558
|
-
| `one_time` | `amount_cents` | Signup bonus / prepaid balance |
|
|
559
|
-
| `promotional` | `amount_cents`, `label`, optional `expires_after_days` | Launch bonus, win-back, holiday promo |
|
|
560
|
-
| `trial` | (none) | Trial entry — requires `trial_days > 0` on the plan |
|
|
561
|
-
| `rollover` | `percent` (0–100) | "Unused balance rolls over X% to the next period" |
|
|
562
|
-
| `top_up` | `sku`, `label`, `price_cents`, `credit_cents` | Buy-extra-credit SKU exposed in checkout |
|
|
563
|
-
| `auto_recharge` | `threshold_cents`, `refill_cents` | "When balance < $X auto-purchase $Y" |
|
|
564
|
-
|
|
565
|
-
`recurring`, `one_time`, `rollover`, and `trial` are single-shot per plan;
|
|
566
|
-
declaring more than one entry of the same kind triggers a warning
|
|
567
|
-
(only the first is honored).
|
|
568
|
-
|
|
569
|
-
Example:
|
|
570
|
-
|
|
571
|
-
```yaml
|
|
572
|
-
plans:
|
|
573
|
-
- key: pro
|
|
574
|
-
name: Pro
|
|
575
|
-
recurring_fee_cents: 10000
|
|
576
|
-
trial_days: 14
|
|
577
|
-
meters:
|
|
578
|
-
- dimension: requests
|
|
579
|
-
price_per_unit_micros: 500
|
|
580
|
-
grants:
|
|
581
|
-
- kind: recurring
|
|
582
|
-
amount_cents: 20000
|
|
583
|
-
- kind: trial
|
|
584
|
-
- kind: promotional
|
|
585
|
-
amount_cents: 1000
|
|
586
|
-
label: launch-bonus
|
|
587
|
-
expires_after_days: 30
|
|
588
|
-
- kind: rollover
|
|
589
|
-
percent: 25
|
|
590
|
-
- kind: auto_recharge
|
|
591
|
-
threshold_cents: 500
|
|
592
|
-
refill_cents: 5000
|
|
593
|
-
```
|
|
454
|
+
### `farthershore skills`
|
|
594
455
|
|
|
595
|
-
|
|
456
|
+
Inside a business repo, recommend agent skills matching the FartherShore SDK
|
|
457
|
+
versions the repo actually uses. The Business SDK and Frontend SDK tracks are
|
|
458
|
+
recommended independently, so updating one does not force a skill update for the
|
|
459
|
+
other.
|
|
596
460
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
461
|
+
```bash
|
|
462
|
+
farthershore skills recommend --format json
|
|
463
|
+
SKILLS_CMD=$(farthershore skills recommend --format json | jq -r '.data.recommendation.command')
|
|
464
|
+
eval "$SKILLS_CMD"
|
|
465
|
+
```
|
|
600
466
|
|
|
601
|
-
|
|
467
|
+
### `farthershore operations`
|
|
602
468
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
path
|
|
469
|
+
Print the machine-readable action boundary: which operations are repo-authored
|
|
470
|
+
(`contract`), which are CLI/API operations (`operate`), which reconcile through
|
|
471
|
+
either path (`dual`), and which are browser-only prerequisites (GitHub linking,
|
|
472
|
+
Stripe Connect).
|
|
606
473
|
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
breaking_changes:
|
|
610
|
-
require_deprecation_window_days: 90
|
|
611
|
-
require_successor_route: true
|
|
474
|
+
```bash
|
|
475
|
+
farthershore operations list --format json
|
|
612
476
|
```
|
|
613
477
|
|
|
614
|
-
|
|
615
|
-
dropped from `features.<x>.routes[]` and warns when the server-side
|
|
616
|
-
`breaking-change-safety-check` cron will gate publish via `ConsumerActivity`
|
|
617
|
-
lookup. When `require_successor_route` is true, it also adds a
|
|
618
|
-
successor-required warning.
|
|
478
|
+
## Errors and exit codes
|
|
619
479
|
|
|
620
|
-
|
|
621
|
-
|
|
480
|
+
In `--format json` mode, every command prints a single canonical envelope to
|
|
481
|
+
stdout — `{ ok, op, data }` on success, or `{ ok: false, op, error }` on failure,
|
|
482
|
+
where `error` carries a stable `code`, `message`, HTTP `status`, a `retryable`
|
|
483
|
+
flag, and a remediation `hint` when one is registered. Diagnostics go to stderr.
|
|
622
484
|
|
|
623
|
-
|
|
485
|
+
In table mode, failures print `Error [CODE]: message` plus a `Hint:` line:
|
|
624
486
|
|
|
625
|
-
|
|
487
|
+
```text
|
|
488
|
+
Error [STRIPE_NOT_CONFIGURED]: connect Stripe before running billing operations
|
|
489
|
+
Hint: Stripe isn't connected on this product. Connect it in the dashboard before running billing operations.
|
|
490
|
+
```
|
|
626
491
|
|
|
627
|
-
|
|
628
|
-
export FARTHERSHORE_TOKEN=mk_xxx
|
|
492
|
+
The bracketed code is stable across releases — quote it in support threads.
|
|
629
493
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
--format json
|
|
494
|
+
Exit codes are a branchable taxonomy so a script can tell failure classes apart
|
|
495
|
+
without parsing text:
|
|
633
496
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
497
|
+
| Exit | Meaning |
|
|
498
|
+
| ---- | ------------------------------------------------------------ |
|
|
499
|
+
| `0` | Success |
|
|
500
|
+
| `2` | Validation error (HTTP 400/422) — fix your input |
|
|
501
|
+
| `3` | Auth / permission error (401/403) — re-authenticate |
|
|
502
|
+
| `4` | Conflict / managed-by-code (409) — change it in the repo |
|
|
503
|
+
| `5` | Server error (5xx) — retry |
|
|
504
|
+
| `1` | Any other failure (local error, 402/404, argument errors, …) |
|
|
642
505
|
|
|
643
|
-
|
|
644
|
-
and build locally with:
|
|
506
|
+
## CI and agent usage
|
|
645
507
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
508
|
+
The CLI is non-interactive whenever a token is available via `--token` or
|
|
509
|
+
`FARTHERSHORE_TOKEN` — `auth login` only prompts when stdin is a TTY and no token
|
|
510
|
+
was passed, so it is safe to script. `farthershore build` and `farthershore
|
|
511
|
+
preflight --local-only` need no network or auth and are safe to run in CI.
|
|
649
512
|
|
|
650
513
|
## MCP server
|
|
651
514
|
|
|
652
|
-
The MCP server (`farthershore-mcp`) projects
|
|
653
|
-
|
|
654
|
-
`fs_*` prefix and cover the agent-operable
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
- Environments: `fs_env_list`, `fs_env_create`
|
|
658
|
-
- Plans: `fs_plan_list`
|
|
659
|
-
- Backends: `fs_backend_list`, `fs_backend_create`, `fs_backend_delete`
|
|
660
|
-
- Runtime tokens: `fs_runtime_token_list`, `fs_runtime_token_mint`,
|
|
661
|
-
`fs_runtime_token_rotate`, `fs_runtime_token_revoke`
|
|
662
|
-
- Webhooks: `fs_webhook_list`, `fs_webhook_create`, `fs_webhook_update`,
|
|
663
|
-
`fs_webhook_delete`, `fs_webhook_test`, `fs_webhook_deliveries`
|
|
664
|
-
- Promo codes: `fs_promo_code_list`, `fs_promo_code_create`,
|
|
665
|
-
`fs_promo_code_update`, `fs_promo_code_archive`,
|
|
666
|
-
`fs_promo_code_reactivate`
|
|
667
|
-
- Consumers: `fs_consumer_list`, `fs_consumer_block`, `fs_consumer_remove`
|
|
668
|
-
- Secrets: `fs_secret_list`, `fs_secret_set`, `fs_secret_delete`
|
|
669
|
-
- Personas: `fs_persona_bootstrap`, `fs_persona_list`, `fs_persona_revoke`
|
|
670
|
-
- Usage and maker tokens: `fs_usage_read`, `fs_maker_token_list`
|
|
671
|
-
|
|
672
|
-
Every MCP tool has a sibling CLI operation by construction; the parity test in
|
|
673
|
-
`apps/cli/src/operations/mcp-cli-parity.test.ts` enforces that invariant.
|
|
674
|
-
|
|
675
|
-
## Errors and exit codes
|
|
676
|
-
|
|
677
|
-
The CLI exits `0` on success and `1` on any failure (including
|
|
678
|
-
commander-level argument errors). When the API returns a 4XX/5XX, the
|
|
679
|
-
CLI prints the canonical error code in brackets and a one-line
|
|
680
|
-
remediation hint when one is registered:
|
|
515
|
+
The MCP server (`farthershore-mcp`) projects its tools from the same operation
|
|
516
|
+
registry that defines the CLI commands, so every MCP tool has a CLI sibling. Tool
|
|
517
|
+
names use the `fs_*` prefix and cover the agent-operable surface: businesses,
|
|
518
|
+
environments, plans, frontends, backends, runtime tokens, webhooks, promo codes,
|
|
519
|
+
consumers, secrets, personas, usage, and maker tokens.
|
|
681
520
|
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
Hint: Stripe isn't connected on this product. Connect it in the dashboard before running billing operations.
|
|
521
|
+
```bash
|
|
522
|
+
FARTHERSHORE_TOKEN=mk_xxx farthershore-mcp
|
|
685
523
|
```
|
|
686
524
|
|
|
687
|
-
|
|
525
|
+
## Learn more
|
|
688
526
|
|
|
689
|
-
|
|
690
|
-
|
|
527
|
+
- Platform documentation: [farthershore.com](https://farthershore.com)
|
|
528
|
+
- Author product behavior:
|
|
529
|
+
[`@farthershore/business`](https://www.npmjs.com/package/@farthershore/business)
|
|
530
|
+
- Report usage from your backend:
|
|
531
|
+
[`@farthershore/backend`](https://www.npmjs.com/package/@farthershore/backend)
|
|
691
532
|
|
|
692
|
-
##
|
|
533
|
+
## License
|
|
693
534
|
|
|
694
|
-
|
|
695
|
-
`--token` flag or `FARTHERSHORE_TOKEN` env var — `auth login` only
|
|
696
|
-
prompts when stdin is a TTY and no token argument was passed, so it's
|
|
697
|
-
safe to script. `farthershore build` is CI-safe and can be run under `CI` /
|
|
698
|
-
`GITHUB_ACTIONS` for local Business SDK compilation.
|
|
535
|
+
MIT
|