@dk/jolly 0.1.10 → 0.2.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 +5 -1
- package/assets/skills/jolly/SKILL.md +115 -0
- package/assets/skills/jolly/recipe.yml +307 -0
- package/bin/jolly +49 -2
- package/package.json +4 -3
- package/src/index.ts +1760 -1844
- package/src/lib/cloud-api.ts +38 -10
package/README.md
CHANGED
|
@@ -4,9 +4,13 @@ Ahoy, agent. Go build a store.
|
|
|
4
4
|
|
|
5
5
|
Jolly is a homepage + `npx` CLI + agent setup workflow that helps a customer's own agent set up and iterate on an end-to-end Saleor Cloud storefront.
|
|
6
6
|
|
|
7
|
+
Jolly is a tool by Dmytri Kleiner that helps agents set up a store quickly using
|
|
8
|
+
Saleor, Vercel and Stripe. It is not an official product of Saleor, Vercel, or
|
|
9
|
+
Stripe. The package is `@dk/jolly`; the homepage is https://jolly.cool.
|
|
10
|
+
|
|
7
11
|
## Agent workflow
|
|
8
12
|
|
|
9
|
-
This repository uses Shipshape for its three-role, spec-driven agent workflow.
|
|
13
|
+
This repository uses [Shipshape](https://github.com/dmytri/shipshape) for its three-role, spec-driven agent workflow.
|
|
10
14
|
|
|
11
15
|
Before substantive agent work, install or load Shipshape:
|
|
12
16
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jolly
|
|
3
|
+
description: End-to-end playbook for setting up a Saleor Cloud storefront with Jolly — teaches the customer's own agent to drive the official CLIs (Vercel, @saleor/configurator, git, pnpm) plus Jolly's thin helpers, from `jolly start` to a live, deployed store.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Jolly setup playbook
|
|
7
|
+
|
|
8
|
+
You are the customer's own agent. **Jolly does not replace you** — it gives you a thin CLI
|
|
9
|
+
for plumbing (auth, store provisioning, secret writing, diagnostics) and this playbook. You
|
|
10
|
+
run the official CLIs yourself. Jolly never shells out to the Vercel CLI or
|
|
11
|
+
`@saleor/configurator`; you do.
|
|
12
|
+
|
|
13
|
+
Reach the goal — a real, deployed, working storefront (browsing, cart, and checkout to the
|
|
14
|
+
Stripe test payment step) — in as few human interruptions as possible. Pause only for the
|
|
15
|
+
unavoidable human steps: new-account creation, browser OAuth/login consent, and pasting secret
|
|
16
|
+
values. Everything else, automate.
|
|
17
|
+
|
|
18
|
+
> Exact upstream commands and flags (Vercel CLI, `@saleor/configurator`, Paper's
|
|
19
|
+
> `saleor/storefront`) change over time. Re-check the current upstream docs/`--help` at run
|
|
20
|
+
> time rather than trusting memorized invocations. The Jolly skill describes the *flow*; the
|
|
21
|
+
> tools own the *specifics*.
|
|
22
|
+
|
|
23
|
+
## Before each action
|
|
24
|
+
|
|
25
|
+
Every Jolly command emits one structured envelope (`command`, `status`, `summary`, `data`,
|
|
26
|
+
`checks`, `nextSteps`, `errors`) and, before any create/modify/deploy action, a `riskContext`
|
|
27
|
+
(`action`, `target`, `riskLevel`, `categories`, `reversible`, `sideEffects`, `dryRunAvailable`).
|
|
28
|
+
**You** decide whether to seek the customer's approval based on that risk context and the
|
|
29
|
+
customer's policies — Jolly never hardcodes the decision. Parse `--json` output to branch.
|
|
30
|
+
|
|
31
|
+
## Stages
|
|
32
|
+
|
|
33
|
+
1. **Bootstrap** — the customer ran `jolly start` (or you did). It installed this skill and the
|
|
34
|
+
Saleor agent-skills via `npx skills add`, wrote `.mcp.json` (local mcp-graphql against the
|
|
35
|
+
customer's own endpoint), scaffolded, ran `jolly doctor`, and emitted the playbook. Read its
|
|
36
|
+
`data` and `nextSteps`.
|
|
37
|
+
|
|
38
|
+
2. **Authenticate to Saleor Cloud** — if not already authed, run `jolly login`. It prefers the
|
|
39
|
+
browser OAuth flow and falls back to a pasted token; pause for the human's browser consent.
|
|
40
|
+
The Saleor Cloud token is stored as `JOLLY_SALEOR_CLOUD_TOKEN` in `.env`.
|
|
41
|
+
|
|
42
|
+
3. **Provision the store** — run `jolly create store` (creates/reuses the Saleor Cloud
|
|
43
|
+
organization, project, and environment via the Cloud API). For a brand-new Saleor account,
|
|
44
|
+
direct the human to sign up at cloud.saleor.io first, then resume with the store URL.
|
|
45
|
+
|
|
46
|
+
4. **App token** — run `jolly create app-token` to acquire a Saleor app token (all permissions
|
|
47
|
+
in v1) for configuration.
|
|
48
|
+
|
|
49
|
+
5. **Storefront** — clone the Paper template yourself:
|
|
50
|
+
`git clone https://github.com/saleor/storefront.git ./storefront` (the `main` branch),
|
|
51
|
+
remove the upstream `.git`, run `git init`, `cp .env.example .env`, and `pnpm install`. If the
|
|
52
|
+
local Node version is incompatible with Paper, tell the human (don't switch Node yourself). In
|
|
53
|
+
the storefront's `.env`, set `NEXT_PUBLIC_SALEOR_API_URL` to your store's GraphQL endpoint and
|
|
54
|
+
`NEXT_PUBLIC_DEFAULT_CHANNEL=us` (the channel the starter recipe creates).
|
|
55
|
+
|
|
56
|
+
6. **Configure the store** — the Jolly starter recipe ships with this skill as `recipe.yml`
|
|
57
|
+
(alongside this `SKILL.md`): a pirate-themed US/USD/English catalog with shipping and the `us`
|
|
58
|
+
channel Paper points at. Copy it into the storefront repo as `saleor-config.yml` (keep it
|
|
59
|
+
version-controlled and reviewable), then apply it with `@saleor/configurator`'s safe
|
|
60
|
+
workflow — `diff` to preview, then `deploy` — passing
|
|
61
|
+
`--url "$NEXT_PUBLIC_SALEOR_API_URL" --token "$JOLLY_SALEOR_APP_TOKEN" --config saleor-config.yml`
|
|
62
|
+
(or set `SALEOR_URL`/`SALEOR_TOKEN`). Add `--fail-on-breaking` on `deploy`. Show the diff and
|
|
63
|
+
seek the customer's approval before deploying writes. Jolly never runs the configurator; you do.
|
|
64
|
+
|
|
65
|
+
7. **Stripe (test mode)** — get the test keys the fast way, via the official Stripe CLI's
|
|
66
|
+
browser OAuth login (no hunting through the Dashboard):
|
|
67
|
+
- Run `npx @stripe/cli login` — it prints a URL; have the human open it and approve in the
|
|
68
|
+
browser (one click). If they have no Stripe account, send them to
|
|
69
|
+
https://dashboard.stripe.com/register first (test mode works immediately after signup —
|
|
70
|
+
no business details needed). The CLI cannot create the account; that signup is the human's.
|
|
71
|
+
- Read the test-mode keys from the CLI config (`npx @stripe/cli config --list` /
|
|
72
|
+
`~/.config/stripe/config.toml`): `test_mode_pub_key` (`pk_test_…`) and `test_mode_api_key`
|
|
73
|
+
(`sk_test_…`). Pass them to `jolly create stripe --publishable-key … --secret-key …`, which
|
|
74
|
+
writes them to `.env` (never printed). Jolly never runs the Stripe CLI itself — you do.
|
|
75
|
+
- **These CLI-issued keys are test-mode and expire (~90 days — see `test_mode_key_expires_at`).**
|
|
76
|
+
That is the right tradeoff to get started fast, but the expiry is yours to handle: before it
|
|
77
|
+
hits, generate durable keys in the Stripe Dashboard (Developers → API keys), re-run
|
|
78
|
+
`jolly create stripe`, and update the Saleor Stripe app config. Flag the expiry date to the
|
|
79
|
+
human now and own the follow-up — do not let checkout silently break at the 90-day mark.
|
|
80
|
+
- Durable-from-the-start alternative: if the human prefers, skip the CLI and paste standard
|
|
81
|
+
Dashboard keys straight into `jolly create stripe`. Live mode (out of v1 scope) always uses
|
|
82
|
+
Dashboard keys.
|
|
83
|
+
Then configure Saleor's **Stripe app** — the Saleor-supported payment path, *not* the
|
|
84
|
+
configurator (which manages catalog only): in the Saleor Dashboard → Extensions, install or
|
|
85
|
+
open the Stripe app, add a configuration with those keys, and **map it to the `us` channel**.
|
|
86
|
+
The Stripe app registers its own Stripe webhooks automatically. This Dashboard step needs the
|
|
87
|
+
human's click — guide them through it.
|
|
88
|
+
|
|
89
|
+
8. **Deploy to Vercel** — deploy with the official Vercel CLI: `npx vercel`. Authentication is
|
|
90
|
+
the Vercel CLI's own `vercel login` session — if `npx vercel whoami` fails, pause and have
|
|
91
|
+
the human run `npx vercel login` (browser), then resume. Set the project's env vars
|
|
92
|
+
(`NEXT_PUBLIC_SALEOR_API_URL`, `NEXT_PUBLIC_DEFAULT_CHANNEL=us`) with the Vercel CLI
|
|
93
|
+
(`npx vercel env add …`), deploy to production (`npx vercel --prod`), and capture the deployed
|
|
94
|
+
URL. Do not use any other deployment mechanism.
|
|
95
|
+
|
|
96
|
+
9. **Wire trusted origins** — update Saleor's allowed/trusted origins to include the deployed
|
|
97
|
+
storefront URL.
|
|
98
|
+
|
|
99
|
+
10. **Verify** — run `jolly doctor` (all groups) to confirm operational readiness: Saleor
|
|
100
|
+
connectivity, storefront env, deployment reachability, and that checkout reaches the Stripe
|
|
101
|
+
test payment step. Report the live URL, the doctor results, and any remaining manual steps.
|
|
102
|
+
|
|
103
|
+
## If a step fails or you're unsure
|
|
104
|
+
|
|
105
|
+
Run `npx @dk/jolly doctor` — it tells you what is wrong and the concrete next action (a
|
|
106
|
+
command to run, a CLI to authenticate, a value to ask your human for). Fix that, then
|
|
107
|
+
continue. Re-running `jolly start` is safe: Jolly detects what you (and it) already did —
|
|
108
|
+
the cloned storefront, the configured store, the deployment — and resumes from the first
|
|
109
|
+
outstanding step rather than redoing work. Never treat a failed command as success.
|
|
110
|
+
|
|
111
|
+
## Honesty
|
|
112
|
+
|
|
113
|
+
Never claim a step succeeded that you did not actually perform and confirm. If a CLI is missing
|
|
114
|
+
or unauthenticated, stop and tell the human exactly what to do (e.g. `npx vercel login`) — do
|
|
115
|
+
not fabricate success or invent a fallback. Jolly's own commands follow the same rule.
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Jolly starter recipe — a @saleor/configurator config that turns a freshly
|
|
2
|
+
# created Saleor Cloud environment into a working, browsable, checkout-ready
|
|
3
|
+
# storefront for the Paper template. Playful pirate-themed demo catalog, single
|
|
4
|
+
# US / USD / English market (v1).
|
|
5
|
+
#
|
|
6
|
+
# This file ships with the Jolly skill. The agent copies it into the cloned
|
|
7
|
+
# storefront repo (keep it version-controlled and reviewable) and applies it
|
|
8
|
+
# with the official Configurator safe workflow — Jolly never runs Configurator:
|
|
9
|
+
#
|
|
10
|
+
# npx @saleor/configurator diff --url "$NEXT_PUBLIC_SALEOR_API_URL" \
|
|
11
|
+
# --token "$JOLLY_SALEOR_APP_TOKEN" --config saleor-config.yml
|
|
12
|
+
# npx @saleor/configurator deploy --url "$NEXT_PUBLIC_SALEOR_API_URL" \
|
|
13
|
+
# --token "$JOLLY_SALEOR_APP_TOKEN" --config saleor-config.yml --fail-on-breaking
|
|
14
|
+
#
|
|
15
|
+
# Then point the Paper storefront at this channel: NEXT_PUBLIC_DEFAULT_CHANNEL=us
|
|
16
|
+
#
|
|
17
|
+
# Customize freely — rename the shop, swap in your own catalog. If Configurator
|
|
18
|
+
# rejects a field, re-check its current example.yml schema; the tool owns the
|
|
19
|
+
# specifics, this recipe owns the starting point.
|
|
20
|
+
|
|
21
|
+
shop:
|
|
22
|
+
defaultMailSenderName: "Jolly Roger Outfitters"
|
|
23
|
+
displayGrossPrices: true
|
|
24
|
+
trackInventoryByDefault: false # demo catalog sells without stock counts
|
|
25
|
+
defaultWeightUnit: KG
|
|
26
|
+
|
|
27
|
+
# Single US / USD market. CHARGE flow so test-mode Stripe captures immediately.
|
|
28
|
+
channels:
|
|
29
|
+
- name: United States
|
|
30
|
+
slug: us
|
|
31
|
+
currencyCode: USD
|
|
32
|
+
defaultCountry: US
|
|
33
|
+
isActive: true
|
|
34
|
+
settings:
|
|
35
|
+
automaticallyConfirmAllNewOrders: true
|
|
36
|
+
markAsPaidStrategy: TRANSACTION_FLOW
|
|
37
|
+
defaultTransactionFlowStrategy: CHARGE
|
|
38
|
+
taxConfiguration:
|
|
39
|
+
taxCalculationStrategy: FLAT_RATES
|
|
40
|
+
chargeTaxes: false
|
|
41
|
+
displayGrossPrices: true
|
|
42
|
+
pricesEnteredWithTax: true
|
|
43
|
+
|
|
44
|
+
# One simple shippable product type — no custom attributes to keep the happy
|
|
45
|
+
# path robust. Add attributes/variants later when you customize.
|
|
46
|
+
productTypes:
|
|
47
|
+
- name: Pirate Goods
|
|
48
|
+
isShippingRequired: true
|
|
49
|
+
|
|
50
|
+
categories:
|
|
51
|
+
- name: Weapons
|
|
52
|
+
slug: weapons
|
|
53
|
+
- name: Navigation
|
|
54
|
+
slug: navigation
|
|
55
|
+
- name: Apparel
|
|
56
|
+
slug: apparel
|
|
57
|
+
- name: Treasure
|
|
58
|
+
slug: treasure
|
|
59
|
+
- name: Ship Supplies
|
|
60
|
+
slug: ship-supplies
|
|
61
|
+
|
|
62
|
+
warehouses:
|
|
63
|
+
- name: Port Royal Warehouse
|
|
64
|
+
slug: port-royal
|
|
65
|
+
email: quartermaster@jolly.example
|
|
66
|
+
isPrivate: false
|
|
67
|
+
clickAndCollectOption: DISABLED
|
|
68
|
+
address:
|
|
69
|
+
streetAddress1: "1 Mallory Square"
|
|
70
|
+
city: Key West
|
|
71
|
+
postalCode: "33040"
|
|
72
|
+
country: US
|
|
73
|
+
countryArea: FL
|
|
74
|
+
companyName: "Jolly Roger Outfitters"
|
|
75
|
+
|
|
76
|
+
# A default US shipping zone so checkout can reach the payment step.
|
|
77
|
+
shippingZones:
|
|
78
|
+
- name: United States
|
|
79
|
+
description: "Shipping within the United States"
|
|
80
|
+
default: true
|
|
81
|
+
countries:
|
|
82
|
+
- US
|
|
83
|
+
warehouses:
|
|
84
|
+
- port-royal
|
|
85
|
+
channels:
|
|
86
|
+
- us
|
|
87
|
+
shippingMethods:
|
|
88
|
+
- name: Standard Shipping
|
|
89
|
+
type: PRICE
|
|
90
|
+
minimumDeliveryDays: 3
|
|
91
|
+
maximumDeliveryDays: 7
|
|
92
|
+
channelListings:
|
|
93
|
+
- channel: us
|
|
94
|
+
price: 5.00
|
|
95
|
+
minimumOrderPrice: 0
|
|
96
|
+
- name: Free Shipping
|
|
97
|
+
type: PRICE
|
|
98
|
+
minimumDeliveryDays: 5
|
|
99
|
+
maximumDeliveryDays: 10
|
|
100
|
+
channelListings:
|
|
101
|
+
- channel: us
|
|
102
|
+
price: 0
|
|
103
|
+
minimumOrderPrice: 50
|
|
104
|
+
|
|
105
|
+
# Pirate catalog — single-variant products, each published and priced in USD so
|
|
106
|
+
# Paper can list, cart, and check them out immediately.
|
|
107
|
+
products:
|
|
108
|
+
- name: "Cutlass"
|
|
109
|
+
slug: cutlass
|
|
110
|
+
description: "A trusty curved blade, forged for close-quarters boarding actions."
|
|
111
|
+
productType: Pirate Goods
|
|
112
|
+
category: weapons
|
|
113
|
+
channelListings:
|
|
114
|
+
- channel: us
|
|
115
|
+
isPublished: true
|
|
116
|
+
visibleInListings: true
|
|
117
|
+
isAvailableForPurchase: true
|
|
118
|
+
variants:
|
|
119
|
+
- name: Default
|
|
120
|
+
sku: CUTLASS-001
|
|
121
|
+
channelListings:
|
|
122
|
+
- channel: us
|
|
123
|
+
price: 89.00
|
|
124
|
+
|
|
125
|
+
- name: "Flintlock Pistol"
|
|
126
|
+
slug: flintlock-pistol
|
|
127
|
+
description: "One shot, one chance — make it count, then swing the cutlass."
|
|
128
|
+
productType: Pirate Goods
|
|
129
|
+
category: weapons
|
|
130
|
+
channelListings:
|
|
131
|
+
- channel: us
|
|
132
|
+
isPublished: true
|
|
133
|
+
visibleInListings: true
|
|
134
|
+
isAvailableForPurchase: true
|
|
135
|
+
variants:
|
|
136
|
+
- name: Default
|
|
137
|
+
sku: FLINTLOCK-001
|
|
138
|
+
channelListings:
|
|
139
|
+
- channel: us
|
|
140
|
+
price: 149.00
|
|
141
|
+
|
|
142
|
+
- name: "Brass Spyglass"
|
|
143
|
+
slug: brass-spyglass
|
|
144
|
+
description: "Spot the king's frigates — and the merchantmen — long before they spot you."
|
|
145
|
+
productType: Pirate Goods
|
|
146
|
+
category: navigation
|
|
147
|
+
channelListings:
|
|
148
|
+
- channel: us
|
|
149
|
+
isPublished: true
|
|
150
|
+
visibleInListings: true
|
|
151
|
+
isAvailableForPurchase: true
|
|
152
|
+
variants:
|
|
153
|
+
- name: Default
|
|
154
|
+
sku: SPYGLASS-001
|
|
155
|
+
channelListings:
|
|
156
|
+
- channel: us
|
|
157
|
+
price: 59.00
|
|
158
|
+
|
|
159
|
+
- name: "Pirate's Compass"
|
|
160
|
+
slug: pirates-compass
|
|
161
|
+
description: "Points not north, but toward what your heart wants most. Usually rum."
|
|
162
|
+
productType: Pirate Goods
|
|
163
|
+
category: navigation
|
|
164
|
+
channelListings:
|
|
165
|
+
- channel: us
|
|
166
|
+
isPublished: true
|
|
167
|
+
visibleInListings: true
|
|
168
|
+
isAvailableForPurchase: true
|
|
169
|
+
variants:
|
|
170
|
+
- name: Default
|
|
171
|
+
sku: COMPASS-001
|
|
172
|
+
channelListings:
|
|
173
|
+
- channel: us
|
|
174
|
+
price: 39.00
|
|
175
|
+
|
|
176
|
+
- name: "Tricorne Hat"
|
|
177
|
+
slug: tricorne-hat
|
|
178
|
+
description: "Three corners of pure intimidation. Feather not included."
|
|
179
|
+
productType: Pirate Goods
|
|
180
|
+
category: apparel
|
|
181
|
+
channelListings:
|
|
182
|
+
- channel: us
|
|
183
|
+
isPublished: true
|
|
184
|
+
visibleInListings: true
|
|
185
|
+
isAvailableForPurchase: true
|
|
186
|
+
variants:
|
|
187
|
+
- name: Default
|
|
188
|
+
sku: TRICORNE-001
|
|
189
|
+
channelListings:
|
|
190
|
+
- channel: us
|
|
191
|
+
price: 45.00
|
|
192
|
+
|
|
193
|
+
- name: "Leather Eyepatch"
|
|
194
|
+
slug: leather-eyepatch
|
|
195
|
+
description: "Keeps one eye dark-adapted for going below decks. Also: very dashing."
|
|
196
|
+
productType: Pirate Goods
|
|
197
|
+
category: apparel
|
|
198
|
+
channelListings:
|
|
199
|
+
- channel: us
|
|
200
|
+
isPublished: true
|
|
201
|
+
visibleInListings: true
|
|
202
|
+
isAvailableForPurchase: true
|
|
203
|
+
variants:
|
|
204
|
+
- name: Default
|
|
205
|
+
sku: EYEPATCH-001
|
|
206
|
+
channelListings:
|
|
207
|
+
- channel: us
|
|
208
|
+
price: 12.00
|
|
209
|
+
|
|
210
|
+
- name: "Treasure Map (Authentic Replica)"
|
|
211
|
+
slug: treasure-map
|
|
212
|
+
description: "X marks the spot. We make no guarantees about what's under the X."
|
|
213
|
+
productType: Pirate Goods
|
|
214
|
+
category: treasure
|
|
215
|
+
channelListings:
|
|
216
|
+
- channel: us
|
|
217
|
+
isPublished: true
|
|
218
|
+
visibleInListings: true
|
|
219
|
+
isAvailableForPurchase: true
|
|
220
|
+
variants:
|
|
221
|
+
- name: Default
|
|
222
|
+
sku: MAP-001
|
|
223
|
+
channelListings:
|
|
224
|
+
- channel: us
|
|
225
|
+
price: 25.00
|
|
226
|
+
|
|
227
|
+
- name: "Pieces of Eight (Coin Set)"
|
|
228
|
+
slug: pieces-of-eight
|
|
229
|
+
description: "A handful of gleaming doubloons. Spend them, bury them, bite them to check."
|
|
230
|
+
productType: Pirate Goods
|
|
231
|
+
category: treasure
|
|
232
|
+
channelListings:
|
|
233
|
+
- channel: us
|
|
234
|
+
isPublished: true
|
|
235
|
+
visibleInListings: true
|
|
236
|
+
isAvailableForPurchase: true
|
|
237
|
+
variants:
|
|
238
|
+
- name: Default
|
|
239
|
+
sku: COINS-001
|
|
240
|
+
channelListings:
|
|
241
|
+
- channel: us
|
|
242
|
+
price: 30.00
|
|
243
|
+
|
|
244
|
+
- name: "Oak Rum Barrel"
|
|
245
|
+
slug: oak-rum-barrel
|
|
246
|
+
description: "Provisions for a long voyage. The most important supply on any ship."
|
|
247
|
+
productType: Pirate Goods
|
|
248
|
+
category: ship-supplies
|
|
249
|
+
channelListings:
|
|
250
|
+
- channel: us
|
|
251
|
+
isPublished: true
|
|
252
|
+
visibleInListings: true
|
|
253
|
+
isAvailableForPurchase: true
|
|
254
|
+
variants:
|
|
255
|
+
- name: Default
|
|
256
|
+
sku: RUMBARREL-001
|
|
257
|
+
channelListings:
|
|
258
|
+
- channel: us
|
|
259
|
+
price: 120.00
|
|
260
|
+
|
|
261
|
+
- name: "Jolly Roger Flag"
|
|
262
|
+
slug: jolly-roger-flag
|
|
263
|
+
description: "Run it up the mast and watch the prices — and the prizes — surrender."
|
|
264
|
+
productType: Pirate Goods
|
|
265
|
+
category: ship-supplies
|
|
266
|
+
channelListings:
|
|
267
|
+
- channel: us
|
|
268
|
+
isPublished: true
|
|
269
|
+
visibleInListings: true
|
|
270
|
+
isAvailableForPurchase: true
|
|
271
|
+
variants:
|
|
272
|
+
- name: Default
|
|
273
|
+
sku: FLAG-001
|
|
274
|
+
channelListings:
|
|
275
|
+
- channel: us
|
|
276
|
+
price: 35.00
|
|
277
|
+
|
|
278
|
+
# A featured collection for Paper's storefront merchandising.
|
|
279
|
+
collections:
|
|
280
|
+
- name: "Crew Favorites"
|
|
281
|
+
slug: crew-favorites
|
|
282
|
+
description: "What every well-equipped pirate carries aboard."
|
|
283
|
+
products:
|
|
284
|
+
- cutlass
|
|
285
|
+
- brass-spyglass
|
|
286
|
+
- tricorne-hat
|
|
287
|
+
- jolly-roger-flag
|
|
288
|
+
channelListings:
|
|
289
|
+
- channelSlug: us
|
|
290
|
+
isPublished: true
|
|
291
|
+
|
|
292
|
+
menus:
|
|
293
|
+
- name: Main Navigation
|
|
294
|
+
slug: main-nav
|
|
295
|
+
items:
|
|
296
|
+
- name: Weapons
|
|
297
|
+
category: weapons
|
|
298
|
+
- name: Navigation
|
|
299
|
+
category: navigation
|
|
300
|
+
- name: Apparel
|
|
301
|
+
category: apparel
|
|
302
|
+
- name: Treasure
|
|
303
|
+
category: treasure
|
|
304
|
+
- name: Ship Supplies
|
|
305
|
+
category: ship-supplies
|
|
306
|
+
- name: Crew Favorites
|
|
307
|
+
collection: crew-favorites
|
package/bin/jolly
CHANGED
|
@@ -1,2 +1,49 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// Jolly CLI launcher (feature 006, decision 2026-06-12): the published Jolly
|
|
5
|
+
// CLI is a Node.js program. This launcher runs `src/index.ts` under
|
|
6
|
+
// Node.js >= 23 via native type stripping and never invokes or requires Bun
|
|
7
|
+
// (Bun is the project's development environment only).
|
|
8
|
+
//
|
|
9
|
+
// Deliberately plain CommonJS-compatible JavaScript so that an old Node can
|
|
10
|
+
// parse it and reach the version guard below instead of dying with a raw
|
|
11
|
+
// syntax or module error.
|
|
12
|
+
|
|
13
|
+
var MIN_NODE_MAJOR = 23;
|
|
14
|
+
|
|
15
|
+
var nodeVersion = process.versions.node;
|
|
16
|
+
var nodeMajor = parseInt(nodeVersion.split(".")[0], 10);
|
|
17
|
+
|
|
18
|
+
if (!(nodeMajor >= MIN_NODE_MAJOR)) {
|
|
19
|
+
console.error(
|
|
20
|
+
"jolly requires Node.js >= " +
|
|
21
|
+
MIN_NODE_MAJOR +
|
|
22
|
+
", but this is Node.js " +
|
|
23
|
+
nodeVersion +
|
|
24
|
+
". Please upgrade Node.js (https://nodejs.org) and try again.",
|
|
25
|
+
);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
import("../src/index.ts").catch(function (error) {
|
|
30
|
+
if (error && error.code === "ERR_UNKNOWN_FILE_EXTENSION") {
|
|
31
|
+
// Node >= 23 but before 23.6: type stripping exists behind a flag rather
|
|
32
|
+
// than by default. Re-run the entry point with the flag enabled.
|
|
33
|
+
rerunWithStripTypes();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
function rerunWithStripTypes() {
|
|
40
|
+
var path = require("node:path");
|
|
41
|
+
var spawnSync = require("node:child_process").spawnSync;
|
|
42
|
+
var entry = path.join(__dirname, "..", "src", "index.ts");
|
|
43
|
+
var result = spawnSync(
|
|
44
|
+
process.execPath,
|
|
45
|
+
["--experimental-strip-types", entry].concat(process.argv.slice(2)),
|
|
46
|
+
{ stdio: "inherit" },
|
|
47
|
+
);
|
|
48
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
49
|
+
}
|
package/package.json
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dk/jolly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Ahoy, agent. Go build a Saleor storefront.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"jolly": "
|
|
7
|
+
"jolly": "bin/jolly"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
11
11
|
"src/",
|
|
12
|
+
"assets/skills/",
|
|
12
13
|
"README.md"
|
|
13
14
|
],
|
|
14
15
|
"publishConfig": {
|
|
15
16
|
"access": "public"
|
|
16
17
|
},
|
|
17
18
|
"engines": {
|
|
18
|
-
"
|
|
19
|
+
"node": ">=23.0.0"
|
|
19
20
|
},
|
|
20
21
|
"scripts": {
|
|
21
22
|
"dev": "bun run --watch src/index.ts",
|