@farthershore/cli 0.7.1 → 0.8.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 +364 -247
- package/dist/index.js +212 -161
- package/dist/mcp.js +141 -123
- package/package.json +14 -19
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @farthershore/cli
|
|
2
2
|
|
|
3
|
-
Create and manage [FartherShore](https://farthershore.com) API products from
|
|
3
|
+
Create and manage [FartherShore](https://farthershore.com) API products from
|
|
4
|
+
the terminal. Designed for AI agents and humans alike — every command supports
|
|
5
|
+
`--format json` for non-TTY scripting.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
@@ -11,7 +13,7 @@ npm install -g @farthershore/cli
|
|
|
11
13
|
Or use directly with npx:
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
|
-
npx @farthershore/cli
|
|
16
|
+
npx @farthershore/cli --help
|
|
15
17
|
```
|
|
16
18
|
|
|
17
19
|
The package also ships an MCP stdio server for agents:
|
|
@@ -22,225 +24,413 @@ FARTHERSHORE_TOKEN=mk_xxx npx -p @farthershore/cli farthershore-mcp
|
|
|
22
24
|
|
|
23
25
|
## Authentication
|
|
24
26
|
|
|
25
|
-
Create
|
|
27
|
+
Create a maker token at
|
|
28
|
+
[farthershore.com/settings/tokens](https://farthershore.com/settings/tokens),
|
|
29
|
+
then store it locally:
|
|
26
30
|
|
|
27
31
|
```bash
|
|
28
|
-
# Interactive — prompts for token
|
|
29
|
-
farthershore
|
|
32
|
+
# Interactive — prompts for the token
|
|
33
|
+
farthershore auth login
|
|
30
34
|
|
|
31
|
-
# Non-interactive — pass
|
|
32
|
-
farthershore
|
|
35
|
+
# Non-interactive — pass it directly
|
|
36
|
+
farthershore auth login --token mk_xxx
|
|
33
37
|
|
|
34
|
-
#
|
|
35
|
-
farthershore auth set-key mk_xxx
|
|
36
|
-
|
|
37
|
-
# Environment variable (CI / agents)
|
|
38
|
+
# Or skip the file entirely with an env var (CI / agents)
|
|
38
39
|
export FARTHERSHORE_TOKEN=mk_xxx
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
Tokens are stored in `~/.farthershore/credentials.json`.
|
|
42
|
-
|
|
43
|
-
## Environment scope
|
|
44
|
-
|
|
45
|
-
Most product commands can run against production or a named environment.
|
|
46
|
-
Production is the default. `production`, `prod`, and `main` all mean the
|
|
47
|
-
production scope.
|
|
42
|
+
Tokens are stored in `~/.farthershore/credentials.json`. Maker tokens are
|
|
43
|
+
exchanged for a short-lived CLI access token on first authenticated request.
|
|
48
44
|
|
|
49
45
|
```bash
|
|
50
|
-
farthershore
|
|
51
|
-
farthershore
|
|
52
|
-
farthershore plan list --env preview --format json
|
|
53
|
-
farthershore --env preview meter list --format json
|
|
54
|
-
farthershore env run preview -- plan add pro --price-monthly 2900 --format json
|
|
55
|
-
farthershore env use production --format json
|
|
46
|
+
farthershore auth whoami # Show current org, role, scopes
|
|
47
|
+
farthershore auth logout # Clear stored credentials
|
|
56
48
|
```
|
|
57
49
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
## Global flags
|
|
51
|
+
|
|
52
|
+
| Flag | Description |
|
|
53
|
+
| --------------------- | -------------------------------------------------------- |
|
|
54
|
+
| `--token <token>` | Override auth token for this command |
|
|
55
|
+
| `--api-url <url>` | Override API base URL |
|
|
56
|
+
| `--env <environment>` | Environment scope (use `production`/`prod`/`main`) |
|
|
57
|
+
| `--format <format>` | `json` for machine-readable output (default for non-TTY) |
|
|
58
|
+
| `--version` | Show version |
|
|
59
|
+
| `--help` | Show help |
|
|
60
|
+
|
|
61
|
+
## Environment variables
|
|
62
|
+
|
|
63
|
+
| Variable | Description |
|
|
64
|
+
| ---------------------- | ------------------------------------------------------- |
|
|
65
|
+
| `FARTHERSHORE_TOKEN` | API token (overrides stored credentials) |
|
|
66
|
+
| `FARTHERSHORE_API_URL` | API base URL (default: `https://core.farthershore.com`) |
|
|
67
|
+
| `FARTHERSHORE_ENV` | Default environment scope when `--env` is omitted |
|
|
61
68
|
|
|
62
69
|
## Commands
|
|
63
70
|
|
|
64
|
-
### `farthershore init
|
|
71
|
+
### `farthershore init`
|
|
65
72
|
|
|
66
|
-
|
|
73
|
+
Scaffold a starter `product.yaml` from a named plan preset. Each preset
|
|
74
|
+
fills in the 5-knob spec for a common shape so first-time builders skip
|
|
75
|
+
the blank-page problem.
|
|
67
76
|
|
|
68
77
|
```bash
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
# Interactive walkthrough (TTY only) — pick a preset by number/name + path
|
|
79
|
+
farthershore init
|
|
71
80
|
|
|
72
|
-
|
|
81
|
+
# Non-interactive — pass --template explicitly (required when not a TTY)
|
|
82
|
+
farthershore init --template free
|
|
83
|
+
farthershore init --template starter --force
|
|
84
|
+
farthershore init --template metered --format json
|
|
85
|
+
```
|
|
73
86
|
|
|
74
|
-
|
|
75
|
-
- `--description <text>` — Product description
|
|
76
|
-
- `--display-name <name>` — Display name for the product portal
|
|
87
|
+
Templates (sourced from shared-types `listPlanPresets()`):
|
|
77
88
|
|
|
78
|
-
|
|
89
|
+
| Template | Shape |
|
|
90
|
+
| --------- | ------------------------------------------------------------ |
|
|
91
|
+
| `free` | $0 plan, hard-enforced 1k requests/month limit |
|
|
92
|
+
| `starter` | $20/mo + $20 included usage, $0.001/request overage |
|
|
93
|
+
| `pro` | $100/mo + $200 included usage, 14-day trial, $0.0005/request |
|
|
94
|
+
| `prepaid` | $50 one-time signup credit, then PAYG |
|
|
95
|
+
| `metered` | Pure pay-as-you-go at $0.001/request |
|
|
79
96
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
- `docs/` — developer portal documentation
|
|
83
|
-
- `.skills/` — task-specific instructions
|
|
97
|
+
After `init`, edit `product.name` + `product.baseUrl`, then run
|
|
98
|
+
`farthershore validate` to confirm the scaffolded YAML is acceptable.
|
|
84
99
|
|
|
85
|
-
### `farthershore product
|
|
100
|
+
### `farthershore product`
|
|
86
101
|
|
|
87
|
-
|
|
88
|
-
subsequent CLI commands. This is the fastest path for an agent that wants
|
|
89
|
-
to configure a product without opening the UI.
|
|
102
|
+
Product lifecycle commands — direct API, no local `product.yaml` round-trip.
|
|
90
103
|
|
|
91
104
|
```bash
|
|
92
|
-
farthershore product
|
|
105
|
+
farthershore product list --format json
|
|
106
|
+
farthershore product show weather-api --format json
|
|
107
|
+
farthershore product show weather-api --env preview --format json
|
|
108
|
+
|
|
109
|
+
farthershore product create \
|
|
110
|
+
--name weather-api \
|
|
111
|
+
--display-name "Weather API" \
|
|
93
112
|
--base-url https://api.example.com \
|
|
94
|
-
--strategy prepaid_credits \
|
|
95
113
|
--format json
|
|
96
|
-
```
|
|
97
114
|
|
|
98
|
-
|
|
115
|
+
# Meter templates — the same smart defaults the dashboard offers:
|
|
116
|
+
# requests (default) | ai-tokens | credits | spend | compute
|
|
117
|
+
farthershore product create --name llm-api --meters ai-tokens --format json
|
|
99
118
|
|
|
100
|
-
|
|
101
|
-
|
|
119
|
+
# Or a fully custom meter list (key[:display[:unit]], repeatable):
|
|
120
|
+
farthershore product create --name image-api \
|
|
121
|
+
--meter requests \
|
|
122
|
+
--meter images:Images:image \
|
|
123
|
+
--format json
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
farthershore product
|
|
105
|
-
farthershore product
|
|
125
|
+
farthershore product update weather-api --display-name "Weather" --format json
|
|
126
|
+
farthershore product publish weather-api --format json
|
|
127
|
+
farthershore product delete weather-api --yes --format json
|
|
128
|
+
|
|
129
|
+
farthershore product compile weather-api --dry-run --format json
|
|
130
|
+
farthershore product compile weather-api --branch env/preview --format json
|
|
106
131
|
```
|
|
107
132
|
|
|
108
|
-
|
|
133
|
+
`product create` provisions a managed GitHub repo and returns clone-URL +
|
|
134
|
+
agent bootstrap instructions in the response. Plan pricing lives on the
|
|
135
|
+
plan (see `farthershore plan create` below) — the product itself no
|
|
136
|
+
longer carries a `billingStrategy`. Omitting both meter flags gives the
|
|
137
|
+
product a `requests` meter; variable-value meters (tokens, credits, spend)
|
|
138
|
+
are settled from upstream `x-fs-cost-{key}` response headers.
|
|
109
139
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
config path. Accepted config is live; draft config is staged until
|
|
113
|
-
`farthershore apply` publishes it.
|
|
140
|
+
A new product starts as a DRAFT with its portal already live in template
|
|
141
|
+
mode. Going live mirrors the dashboard's "Finish setting up" checklist:
|
|
114
142
|
|
|
115
143
|
```bash
|
|
116
|
-
farthershore product
|
|
117
|
-
farthershore
|
|
118
|
-
|
|
119
|
-
farthershore product
|
|
144
|
+
farthershore product create --name llm-api --meters ai-tokens # 1. create
|
|
145
|
+
farthershore plan create llm-api --key pro --name "Pro" \
|
|
146
|
+
--recurring-fee-cents 2900 # 2. how you charge
|
|
147
|
+
farthershore product update llm-api \
|
|
148
|
+
--base-url https://api.example.com # 3. endpoint
|
|
149
|
+
farthershore product publish llm-api # 4. go live
|
|
120
150
|
```
|
|
121
151
|
|
|
122
|
-
|
|
152
|
+
`product publish` enforces the same gates as the dashboard: at least one
|
|
153
|
+
plan, a base URL, and a verified Stripe connection (clear remediation is
|
|
154
|
+
printed for `STRIPE_NOT_CONNECTED` / `STRIPE_NOT_VERIFIED` /
|
|
155
|
+
`BILLING_TAX_NOT_ENROLLED`).
|
|
156
|
+
|
|
157
|
+
### `farthershore env`
|
|
123
158
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
product state.
|
|
159
|
+
Manage preview/production environments. Production is the default scope
|
|
160
|
+
when `--env` is omitted; `production`, `prod`, and `main` are aliases.
|
|
127
161
|
|
|
128
162
|
```bash
|
|
129
|
-
farthershore
|
|
130
|
-
farthershore
|
|
163
|
+
farthershore env list weather-api --format json
|
|
164
|
+
farthershore env create weather-api --name preview --branch env/preview --format json
|
|
165
|
+
farthershore env delete weather-api preview --yes --format json
|
|
131
166
|
```
|
|
132
167
|
|
|
133
|
-
### `farthershore
|
|
168
|
+
### `farthershore plan`
|
|
134
169
|
|
|
135
|
-
|
|
170
|
+
Plan CRUD via the management API. The body uses the unified 5-knob
|
|
171
|
+
spec (see "`product.yaml` plan shape" below) — pass cents-denominated
|
|
172
|
+
flags for whichever knobs the plan flavor needs.
|
|
136
173
|
|
|
137
174
|
```bash
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
175
|
+
# Human-readable table (default in TTY)
|
|
176
|
+
farthershore plan list weather-api
|
|
177
|
+
farthershore plan list weather-api --format table
|
|
178
|
+
|
|
179
|
+
# JSON envelope (default outside TTY; suitable for jq pipelines)
|
|
180
|
+
farthershore plan list weather-api --format json
|
|
181
|
+
|
|
182
|
+
# Flat subscription: recurring fee only
|
|
183
|
+
farthershore plan create weather-api \
|
|
184
|
+
--key pro \
|
|
185
|
+
--name "Pro" \
|
|
186
|
+
--recurring-fee-cents 2900 \
|
|
187
|
+
--format json
|
|
188
|
+
|
|
189
|
+
# Included usage: fee + monthly credit grant
|
|
190
|
+
farthershore plan create weather-api \
|
|
191
|
+
--key included \
|
|
192
|
+
--name "Included" \
|
|
193
|
+
--recurring-fee-cents 2000 \
|
|
194
|
+
--recurring-credit-grant-cents 2000 \
|
|
144
195
|
--format json
|
|
145
196
|
|
|
146
|
-
|
|
147
|
-
farthershore
|
|
197
|
+
# Free plan
|
|
198
|
+
farthershore plan create weather-api --key free --name "Free" --free --format json
|
|
199
|
+
|
|
200
|
+
farthershore plan update weather-api <planId> --recurring-fee-cents 3900 --format json
|
|
201
|
+
farthershore plan delete weather-api <planId> --yes --env preview --format json
|
|
148
202
|
```
|
|
149
203
|
|
|
150
|
-
### `farthershore
|
|
204
|
+
### `farthershore persona`
|
|
151
205
|
|
|
152
|
-
|
|
206
|
+
Test-environment personas — mint fresh `fsk_test_*` API keys so an agent
|
|
207
|
+
can exercise the gateway end-to-end. Only works in test-strategy envs.
|
|
153
208
|
|
|
154
209
|
```bash
|
|
155
|
-
farthershore
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
farthershore feature bind chat_completions --plan pro --format json
|
|
160
|
-
farthershore feature list --env preview --format json
|
|
210
|
+
farthershore persona bootstrap weather-api --env preview --plan pro --format json
|
|
211
|
+
farthershore persona list weather-api --env preview --format json
|
|
212
|
+
farthershore persona revoke weather-api <personaId> --env preview --format json
|
|
161
213
|
```
|
|
162
214
|
|
|
163
|
-
### `farthershore
|
|
215
|
+
### `farthershore usage`
|
|
164
216
|
|
|
165
|
-
|
|
166
|
-
validation remains authoritative for rules like one free plan, duplicate
|
|
167
|
-
paid prices, and product-level billing strategy consistency before apply
|
|
168
|
-
can publish.
|
|
217
|
+
Read recent usage off the management API.
|
|
169
218
|
|
|
170
219
|
```bash
|
|
171
|
-
farthershore
|
|
172
|
-
--free \
|
|
173
|
-
--limit ai_tokens:month:100000:enforce \
|
|
174
|
-
--feature chat_completions \
|
|
175
|
-
--format json
|
|
176
|
-
|
|
177
|
-
farthershore plan add pro \
|
|
178
|
-
--price-monthly 2900 \
|
|
179
|
-
--credits-monthly-micros 500000000 \
|
|
180
|
-
--meter ai_tokens \
|
|
181
|
-
--feature chat_completions \
|
|
182
|
-
--format json
|
|
183
|
-
|
|
184
|
-
farthershore plan list --env preview --format json
|
|
220
|
+
farthershore usage summary weather-api --format json
|
|
185
221
|
```
|
|
186
222
|
|
|
187
|
-
### `farthershore
|
|
223
|
+
### `farthershore connect`
|
|
188
224
|
|
|
189
|
-
|
|
190
|
-
|
|
225
|
+
GitHub OAuth and Stripe Connect flows are browser-only. These commands
|
|
226
|
+
report status so an agent can poll until the user finishes the flow.
|
|
191
227
|
|
|
192
228
|
```bash
|
|
193
|
-
farthershore
|
|
194
|
-
farthershore
|
|
195
|
-
|
|
196
|
-
farthershore billing strategy set prepaid_credits \
|
|
197
|
-
--transition preserve_current_period \
|
|
198
|
-
--format json
|
|
199
|
-
|
|
200
|
-
farthershore billing policy set \
|
|
201
|
-
--default preserve_current_period \
|
|
202
|
-
--proration none \
|
|
203
|
-
--format json
|
|
229
|
+
farthershore connect github --format json
|
|
230
|
+
farthershore connect stripe weather-api --format json
|
|
204
231
|
```
|
|
205
232
|
|
|
206
|
-
### `farthershore
|
|
233
|
+
### `farthershore token`
|
|
207
234
|
|
|
208
|
-
|
|
209
|
-
subscribers before applying them.
|
|
235
|
+
Manage maker tokens for the current org.
|
|
210
236
|
|
|
211
237
|
```bash
|
|
212
|
-
farthershore
|
|
213
|
-
farthershore
|
|
238
|
+
farthershore token list --format json
|
|
239
|
+
farthershore token create --name "ci-bot" --scope products:update products:publish --format json
|
|
240
|
+
farthershore token revoke <tokenId> --yes --format json
|
|
214
241
|
```
|
|
215
242
|
|
|
216
243
|
### `farthershore validate`
|
|
217
244
|
|
|
218
|
-
Validate the managed repo
|
|
245
|
+
Validate the managed repo (`product.yaml`, `brand.yaml`, `docs/`,
|
|
246
|
+
`skills/`, `.github/workflows/`) through the same backend checks the
|
|
247
|
+
Farther Shore GitHub bot runs.
|
|
219
248
|
|
|
220
249
|
```bash
|
|
221
|
-
# Validate the current managed repo
|
|
222
250
|
farthershore validate
|
|
223
|
-
|
|
224
|
-
# Machine-readable diagnostics
|
|
225
251
|
farthershore validate --format json
|
|
226
252
|
```
|
|
227
253
|
|
|
254
|
+
Emits GitHub Actions-formatted annotations when run under `CI` /
|
|
255
|
+
`GITHUB_ACTIONS`.
|
|
256
|
+
|
|
257
|
+
#### `product.yaml` plan shape
|
|
258
|
+
|
|
259
|
+
Every plan is a configuration of 5 orthogonal knobs (shared-types
|
|
260
|
+
v0.53.0). Older shapes with `pricing.{model, monthlyPriceCents}` and
|
|
261
|
+
top-level `billing.strategy` are no longer accepted by the validator.
|
|
262
|
+
|
|
263
|
+
| Knob | Cents/unit | Meaning |
|
|
264
|
+
| ------------------------------ | ---------------- | ------------------------------------------------------- |
|
|
265
|
+
| `meters[]` | micros/unit | Per-dimension usage price (zero or more dimensions) |
|
|
266
|
+
| `recurring_fee_cents` | cents | Charged each billing period (recurring subscription) |
|
|
267
|
+
| `recurring_credit_grant_cents` | cents | Credit issued each period; drains against meter charges |
|
|
268
|
+
| `one_time_credit_grant_cents` | cents | Prepaid balance at subscription start; drains once |
|
|
269
|
+
| `trial_days` | days | Waive everything for N days at the start |
|
|
270
|
+
| `max_monthly_spend_cents` | cents (optional) | Hard cap; the gateway blocks once exceeded (orthogonal) |
|
|
271
|
+
|
|
272
|
+
Billing math (handled by Stripe Billing v2 at invoice finalization):
|
|
273
|
+
`bill = recurring_fee + max(0, total_meter_cost − applied_credit_balance)`.
|
|
274
|
+
|
|
275
|
+
Every plan flavor — free, flat, included, overage, prepaid, trial,
|
|
276
|
+
pay-as-you-go — is a knob combination. Examples:
|
|
277
|
+
|
|
278
|
+
```yaml
|
|
279
|
+
# Free plan: explicit `free: true` flag + hard-enforced limit
|
|
280
|
+
plans:
|
|
281
|
+
- key: free
|
|
282
|
+
name: Free
|
|
283
|
+
free: true
|
|
284
|
+
recurring_fee_cents: 0
|
|
285
|
+
limits:
|
|
286
|
+
- dimension: requests
|
|
287
|
+
window: { type: named, name: month }
|
|
288
|
+
capacity: 1000
|
|
289
|
+
enforcement: enforce
|
|
290
|
+
|
|
291
|
+
# Flat subscription: recurring fee only
|
|
292
|
+
- key: starter
|
|
293
|
+
name: Starter
|
|
294
|
+
recurring_fee_cents: 2900
|
|
295
|
+
|
|
296
|
+
# Included usage: fee + monthly credit grant + metered
|
|
297
|
+
- key: pro
|
|
298
|
+
name: Pro
|
|
299
|
+
recurring_fee_cents: 2000
|
|
300
|
+
recurring_credit_grant_cents: 2000
|
|
301
|
+
meters:
|
|
302
|
+
- dimension: requests
|
|
303
|
+
price_per_unit_micros: 1000 # $0.001/request
|
|
304
|
+
|
|
305
|
+
# Overage: fee + metered, no credit
|
|
306
|
+
- key: growth
|
|
307
|
+
name: Growth
|
|
308
|
+
recurring_fee_cents: 4900
|
|
309
|
+
meters:
|
|
310
|
+
- dimension: requests
|
|
311
|
+
price_per_unit_micros: 500
|
|
312
|
+
|
|
313
|
+
# Prepaid: one-time grant + metered
|
|
314
|
+
- key: prepaid
|
|
315
|
+
name: Prepaid
|
|
316
|
+
one_time_credit_grant_cents: 10000
|
|
317
|
+
meters:
|
|
318
|
+
- dimension: requests
|
|
319
|
+
price_per_unit_micros: 1000
|
|
320
|
+
|
|
321
|
+
# Trial: trial_days + recurring fee
|
|
322
|
+
- key: trial
|
|
323
|
+
name: Trial
|
|
324
|
+
recurring_fee_cents: 2900
|
|
325
|
+
trial_days: 14
|
|
326
|
+
|
|
327
|
+
# Pay-as-you-go: metered only (no recurring fee)
|
|
328
|
+
- key: metered
|
|
329
|
+
name: Metered
|
|
330
|
+
meters:
|
|
331
|
+
- dimension: tokens
|
|
332
|
+
price_per_unit_micros: 100
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
#### `grants[]` array (shared-types v0.56.0)
|
|
336
|
+
|
|
337
|
+
Plans now accept a typed `grants[]` array that supersedes the two
|
|
338
|
+
legacy grant knobs (`recurring_credit_grant_cents`,
|
|
339
|
+
`one_time_credit_grant_cents`). When `grants[]` is present, the legacy
|
|
340
|
+
knobs are ignored. When absent, the validator silently synthesizes
|
|
341
|
+
entries from the legacy knobs so existing specs keep working.
|
|
342
|
+
|
|
343
|
+
Valid `kind` values:
|
|
344
|
+
|
|
345
|
+
| Kind | Required fields | Use case |
|
|
346
|
+
| --------------- | ------------------------------------------------------ | --------------------------------------------------- |
|
|
347
|
+
| `recurring` | `amount_cents` | Monthly credit (e.g. $20 included usage) |
|
|
348
|
+
| `one_time` | `amount_cents` | Signup bonus / prepaid balance |
|
|
349
|
+
| `promotional` | `amount_cents`, `label`, optional `expires_after_days` | Launch bonus, win-back, holiday promo |
|
|
350
|
+
| `trial` | (none) | Trial entry — requires `trial_days > 0` on the plan |
|
|
351
|
+
| `rollover` | `percent` (0–100) | "Unused balance rolls over X% to the next period" |
|
|
352
|
+
| `top_up` | `sku`, `label`, `price_cents`, `credit_cents` | Buy-extra-credit SKU exposed in checkout |
|
|
353
|
+
| `auto_recharge` | `threshold_cents`, `refill_cents` | "When balance < $X auto-purchase $Y" |
|
|
354
|
+
|
|
355
|
+
`recurring`, `rollover`, and `trial` are single-shot per plan;
|
|
356
|
+
declaring more than one entry of the same kind triggers a warning
|
|
357
|
+
(only the first is honored).
|
|
358
|
+
|
|
359
|
+
Example:
|
|
360
|
+
|
|
361
|
+
```yaml
|
|
362
|
+
plans:
|
|
363
|
+
- key: pro
|
|
364
|
+
name: Pro
|
|
365
|
+
recurring_fee_cents: 10000
|
|
366
|
+
trial_days: 14
|
|
367
|
+
meters:
|
|
368
|
+
- dimension: requests
|
|
369
|
+
price_per_unit_micros: 500
|
|
370
|
+
grants:
|
|
371
|
+
- kind: recurring
|
|
372
|
+
amount_cents: 20000
|
|
373
|
+
- kind: trial
|
|
374
|
+
- kind: promotional
|
|
375
|
+
amount_cents: 1000
|
|
376
|
+
label: launch-bonus
|
|
377
|
+
expires_after_days: 30
|
|
378
|
+
- kind: rollover
|
|
379
|
+
percent: 25
|
|
380
|
+
- kind: auto_recharge
|
|
381
|
+
threshold_cents: 500
|
|
382
|
+
refill_cents: 5000
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
The validator surfaces:
|
|
386
|
+
|
|
387
|
+
- **error** — invalid `kind` is rewritten to `Unknown grant kind. Valid kinds: …`
|
|
388
|
+
- **warning** — `grants[]` declares `recurring`/`one_time` _and_ the matching legacy knob is also non-zero (legacy is silently ignored)
|
|
389
|
+
- **warning** — `{ kind: trial }` declared but `trial_days` is 0
|
|
390
|
+
- **warning** — singleton kinds (`recurring`, `rollover`, `trial`) declared more than once
|
|
391
|
+
|
|
392
|
+
#### Deprecation window (Phase 3b)
|
|
393
|
+
|
|
394
|
+
The product top-level `lifecycle.breaking_changes` block declares the
|
|
395
|
+
breaking-change governance policy enforced on `apply`:
|
|
396
|
+
|
|
397
|
+
```yaml
|
|
398
|
+
lifecycle:
|
|
399
|
+
breaking_changes:
|
|
400
|
+
require_deprecation_window_days: 90
|
|
401
|
+
require_successor_route: true
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
When the policy is set:
|
|
405
|
+
|
|
406
|
+
- `farthershore validate` emits an informational warning so the builder
|
|
407
|
+
sees the active policy locally.
|
|
408
|
+
- `farthershore apply` (which compares the proposed spec against the
|
|
409
|
+
accepted spec) emits a `route_removed` change for every route
|
|
410
|
+
dropped from `features.<x>.routes[]` and warns that the server-side
|
|
411
|
+
`breaking-change-safety-check` cron will gate the publish via
|
|
412
|
+
`ConsumerActivity` lookup. When `require_successor_route` is true,
|
|
413
|
+
the apply path additionally surfaces a successor-required warning.
|
|
414
|
+
|
|
415
|
+
The CLI never blocks on the window itself — the per-consumer lookup
|
|
416
|
+
lives server-side (Phase 1c `ConsumerActivity` table + Phase 3b cron).
|
|
417
|
+
The CLI's job is to surface the policy and the route delta locally so
|
|
418
|
+
the builder knows what the gate will see.
|
|
419
|
+
|
|
228
420
|
### `farthershore apply [product]`
|
|
229
421
|
|
|
230
422
|
Publish the shared server draft as one product release. Core accepts the
|
|
231
|
-
release only after schema validation, transition-safety validation, and
|
|
232
|
-
compiler dry-run pass.
|
|
233
|
-
`feature add`, and `plan set-price` stage draft changes by default; they
|
|
234
|
-
do not create live product or plan versions until `apply`.
|
|
423
|
+
release only after schema validation, transition-safety validation, and
|
|
424
|
+
a compiler dry-run all pass.
|
|
235
425
|
|
|
236
426
|
```bash
|
|
237
427
|
# Publish the current shared draft
|
|
238
428
|
farthershore apply
|
|
239
429
|
|
|
240
|
-
# Or pass the product slug explicitly
|
|
241
|
-
farthershore apply
|
|
430
|
+
# Or pass the product slug/UUID explicitly
|
|
431
|
+
farthershore apply weather-api
|
|
242
432
|
|
|
243
|
-
# Validate and compile
|
|
433
|
+
# Validate and compile without publishing
|
|
244
434
|
farthershore apply --dry-run --format json
|
|
245
435
|
farthershore apply --env preview --dry-run --format json
|
|
246
436
|
|
|
@@ -248,133 +438,62 @@ farthershore apply --env preview --dry-run --format json
|
|
|
248
438
|
farthershore apply --to product.yaml --dry-run --format json
|
|
249
439
|
farthershore apply --to product.yaml --format json
|
|
250
440
|
|
|
251
|
-
# Also
|
|
441
|
+
# Also stage that file as the shared draft before publishing
|
|
252
442
|
farthershore apply --to product.yaml --save-draft --format json
|
|
253
|
-
```
|
|
254
443
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
```bash
|
|
258
|
-
farthershore draft status --format json
|
|
259
|
-
farthershore draft diff --format json
|
|
260
|
-
farthershore draft validate --format json
|
|
261
|
-
farthershore draft reset --format json
|
|
444
|
+
# Pin compilation to a specific branch
|
|
445
|
+
farthershore apply weather-api --branch feature/billing-change --dry-run --format json
|
|
262
446
|
```
|
|
263
447
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
FARTHERSHORE_TOKEN=mk_xxx farthershore-mcp
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
The MCP server exposes the same product-building workflow as the CLI:
|
|
273
|
-
product create/status/config, environment list/create/use, billing strategy
|
|
274
|
-
set, meter add, feature add, plan add, transition preview, and apply.
|
|
275
|
-
Every tool accepts optional `product` and `env` fields where relevant and
|
|
276
|
-
returns secret-free JSON.
|
|
277
|
-
|
|
278
|
-
### `farthershore set-key [token]`
|
|
279
|
-
|
|
280
|
-
Set your API token. Interactive when run in a terminal, or pass the token as an argument for scripts.
|
|
281
|
-
|
|
282
|
-
### `farthershore whoami`
|
|
283
|
-
|
|
284
|
-
Show your current authentication context (organization, auth method).
|
|
285
|
-
|
|
286
|
-
### `farthershore logout`
|
|
287
|
-
|
|
288
|
-
Clear stored credentials.
|
|
289
|
-
|
|
290
|
-
### `farthershore set-url <url>`
|
|
291
|
-
|
|
292
|
-
Override the API base URL (persisted in `~/.farthershore/config.json`).
|
|
448
|
+
JSON output is stable: `{ ok, success, errors, warnings, lifecyclePlan,
|
|
449
|
+
nextActions, ... }`. `lifecyclePlan` is always present (or `null` on
|
|
450
|
+
first deploys / older core builds) and surfaces ADR-0010 per-domain
|
|
451
|
+
subscriber-migration actions.
|
|
293
452
|
|
|
294
|
-
|
|
453
|
+
## Agent workflow
|
|
295
454
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
## Agent Workflow
|
|
299
|
-
|
|
300
|
-
The CLI is designed for AI agents to create and configure API products:
|
|
455
|
+
A typical agent flow:
|
|
301
456
|
|
|
302
457
|
```bash
|
|
303
|
-
|
|
304
|
-
farthershore init weather-api --format json
|
|
458
|
+
export FARTHERSHORE_TOKEN=mk_xxx
|
|
305
459
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
460
|
+
farthershore product create \
|
|
461
|
+
--name weather-api \
|
|
462
|
+
--base-url https://api.example.com \
|
|
463
|
+
--format json
|
|
309
464
|
|
|
310
|
-
|
|
311
|
-
|
|
465
|
+
farthershore plan create weather-api --key free --name "Free" --free --format json
|
|
466
|
+
farthershore plan create weather-api \
|
|
467
|
+
--key pro --name "Pro" --recurring-fee-cents 2900 --format json
|
|
312
468
|
|
|
313
|
-
|
|
314
|
-
farthershore
|
|
315
|
-
|
|
316
|
-
# 5. Agent pushes — product goes live automatically on valid config
|
|
317
|
-
git add -A && git commit -m "Configure product" && git push
|
|
469
|
+
farthershore apply weather-api --dry-run --format json
|
|
470
|
+
farthershore apply weather-api --format json
|
|
471
|
+
farthershore product show weather-api --format json
|
|
318
472
|
```
|
|
319
473
|
|
|
320
|
-
|
|
321
|
-
commands:
|
|
474
|
+
For a YAML-driven flow, edit `product.yaml` in the managed repo, then:
|
|
322
475
|
|
|
323
476
|
```bash
|
|
324
|
-
farthershore
|
|
325
|
-
farthershore product
|
|
326
|
-
|
|
327
|
-
--strategy prepaid_credits \
|
|
328
|
-
--format json
|
|
329
|
-
farthershore meter add ai_tokens \
|
|
330
|
-
--selector model \
|
|
331
|
-
--measure input_tokens \
|
|
332
|
-
--measure output_tokens \
|
|
333
|
-
--rating provider_catalog \
|
|
334
|
-
--catalog llm_models \
|
|
335
|
-
--format json
|
|
336
|
-
farthershore feature add chat_completions \
|
|
337
|
-
--route POST:/v1/chat/completions \
|
|
338
|
-
--format json
|
|
339
|
-
farthershore plan add free \
|
|
340
|
-
--free \
|
|
341
|
-
--limit ai_tokens:month:100000:enforce \
|
|
342
|
-
--feature chat_completions \
|
|
343
|
-
--format json
|
|
344
|
-
farthershore plan add pro \
|
|
345
|
-
--price-monthly 2900 \
|
|
346
|
-
--credits-monthly-micros 500000000 \
|
|
347
|
-
--meter ai_tokens \
|
|
348
|
-
--feature chat_completions \
|
|
349
|
-
--format json
|
|
350
|
-
farthershore draft validate --format json
|
|
351
|
-
farthershore transition preview --format json
|
|
352
|
-
farthershore apply --dry-run --format json
|
|
353
|
-
farthershore apply --format json
|
|
354
|
-
farthershore product status --format json
|
|
477
|
+
farthershore validate --format json
|
|
478
|
+
farthershore apply --to product.yaml --dry-run --format json
|
|
479
|
+
farthershore apply --to product.yaml --format json
|
|
355
480
|
```
|
|
356
481
|
|
|
357
|
-
##
|
|
482
|
+
## MCP server
|
|
358
483
|
|
|
359
|
-
|
|
360
|
-
| ----------------- | ------------------------------------ |
|
|
361
|
-
| `--token <token>` | Override auth token for this command |
|
|
362
|
-
| `--api-url <url>` | Override API base URL |
|
|
363
|
-
| `--format json` | Output as JSON (default for non-TTY) |
|
|
364
|
-
| `--version` | Show version |
|
|
365
|
-
| `--help` | Show help |
|
|
484
|
+
The MCP server (`farthershore-mcp`) exposes two tools:
|
|
366
485
|
|
|
367
|
-
|
|
486
|
+
- `farthershore_draft_validate` — run server-side validation on the shared
|
|
487
|
+
draft.
|
|
488
|
+
- `farthershore_apply` — apply the draft, optionally with a `product.yaml`
|
|
489
|
+
proposal via `toFile`. Defaults to `dryRun: true`.
|
|
368
490
|
|
|
369
|
-
|
|
370
|
-
| ---------------------- | ------------------------------------------------------- |
|
|
371
|
-
| `FARTHERSHORE_TOKEN` | API token (overrides stored credentials) |
|
|
372
|
-
| `FARTHERSHORE_API_URL` | API base URL (default: `https://core.farthershore.com`) |
|
|
491
|
+
Both accept optional `product` and `env` fields and return JSON.
|
|
373
492
|
|
|
374
493
|
## Errors and exit codes
|
|
375
494
|
|
|
376
495
|
The CLI exits `0` on success and `1` on any failure (including
|
|
377
|
-
|
|
496
|
+
commander-level argument errors). When the API returns a 4XX/5XX, the
|
|
378
497
|
CLI prints the canonical error code in brackets and a one-line
|
|
379
498
|
remediation hint when one is registered:
|
|
380
499
|
|
|
@@ -383,17 +502,15 @@ Error [STRIPE_NOT_CONFIGURED]: connect Stripe before running billing operations
|
|
|
383
502
|
Hint: Stripe isn't connected on this product. Connect it in the dashboard before running billing operations.
|
|
384
503
|
```
|
|
385
504
|
|
|
386
|
-
The bracketed code is stable across releases — quote it in support
|
|
387
|
-
threads.
|
|
505
|
+
The bracketed code is stable across releases — quote it in support threads.
|
|
388
506
|
|
|
389
|
-
`farthershore whoami --format json` emits a stable JSON shape suitable
|
|
390
|
-
for CI scripts.
|
|
391
|
-
`{ "authenticated": false }` with exit code `1`.
|
|
507
|
+
`farthershore auth whoami --format json` emits a stable JSON shape suitable
|
|
508
|
+
for CI scripts.
|
|
392
509
|
|
|
393
510
|
## CI / agent usage
|
|
394
511
|
|
|
395
512
|
The CLI is non-interactive whenever a token is available via the
|
|
396
|
-
`--token` flag or `FARTHERSHORE_TOKEN` env var — `
|
|
397
|
-
when stdin is a TTY and no token argument was passed, so it's
|
|
398
|
-
script. `validate` and `apply` emit GitHub Actions-formatted
|
|
399
|
-
when run under `CI` / `GITHUB_ACTIONS`.
|
|
513
|
+
`--token` flag or `FARTHERSHORE_TOKEN` env var — `auth login` only
|
|
514
|
+
prompts when stdin is a TTY and no token argument was passed, so it's
|
|
515
|
+
safe to script. `validate` and `apply` emit GitHub Actions-formatted
|
|
516
|
+
annotations when run under `CI` / `GITHUB_ACTIONS`.
|