@runwell/shopify-toolkit 0.9.0 → 0.11.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/lib/init.js CHANGED
@@ -1,5 +1,20 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import os from 'node:os';
4
+
5
+ function copyRecursive(src, dst) {
6
+ if (src.endsWith('README.md')) return;
7
+ const stat = fs.statSync(src);
8
+ if (stat.isDirectory()) {
9
+ fs.mkdirSync(dst, { recursive: true });
10
+ for (const entry of fs.readdirSync(src)) {
11
+ copyRecursive(path.join(src, entry), path.join(dst, entry));
12
+ }
13
+ } else {
14
+ fs.mkdirSync(path.dirname(dst), { recursive: true });
15
+ fs.copyFileSync(src, dst);
16
+ }
17
+ }
3
18
 
4
19
  /* runwell-shopify init <client> [--baseline <pin>]: scaffold a new
5
20
  tenant theme directory with the minimum required files.
@@ -19,10 +34,30 @@ export async function init(flags) {
19
34
  }
20
35
 
21
36
  fs.mkdirSync(targetDir, { recursive: true });
22
- for (const d of ['layout', 'sections', 'snippets', 'assets', 'config', 'locales', 'templates', 'tenant-overrides']) {
37
+ for (const d of ['layout', 'sections', 'snippets', 'assets', 'config', 'locales', 'templates', 'tenant-overrides', '.github/workflows']) {
23
38
  fs.mkdirSync(path.join(targetDir, d), { recursive: true });
24
39
  }
25
40
 
41
+ // Copy scaffold files from the dawn-runwell baseline package if available
42
+ // locally. Resolution: baseline_path > installed package > skip.
43
+ try {
44
+ const candidates = [
45
+ flags.baselinePath,
46
+ flags.baseline_path,
47
+ path.join(os.homedir(), 'Documents/Code/runwell-dawn-runwell')
48
+ ].filter(Boolean);
49
+ for (const baseRoot of candidates) {
50
+ const scaffoldDir = path.join(baseRoot, 'scaffold');
51
+ if (fs.existsSync(scaffoldDir)) {
52
+ copyRecursive(scaffoldDir, targetDir);
53
+ console.log(`Scaffold files copied from ${scaffoldDir}`);
54
+ break;
55
+ }
56
+ }
57
+ } catch (e) {
58
+ console.warn(`Skipped scaffold copy: ${e.message}`);
59
+ }
60
+
26
61
  const baseline = flags.baseline || '@runwell/dawn-runwell@^1.0.0';
27
62
 
28
63
  const config = {
package/modules/INDEX.md CHANGED
@@ -26,7 +26,7 @@ Total modules: 34.
26
26
  | `delivery-estimate` | pdp | (native build) | snippets:1 | (none) | (none) | (none) |
27
27
  | `editorial-block` | storefront | (native build) | sections:1 | eyebrow, heading, lede, background_color, text_color | (none) | (none) |
28
28
  | `editorial-hero` | storefront | Dawn's image-banner / video-banner | | eyebrow, heading, subheading | video-bg, hero-with-card | (none) |
29
- | `exit-intent` | conversion | (native build) | sections:1 assets:1 | eyebrow, heading, lede | (none) | (none) |
29
+ | `exit-intent` | conversion | Privy / Justuno display layer | sections:1 assets:1 | eyebrow, heading, lede | (none) | (none) |
30
30
  | `faq` | storefront | (native build) | sections:1 | eyebrow, heading, background_color, text_color | (none) | (none) |
31
31
  | `gift-with-purchase` | conversion | (native build) | snippets:1 assets:1 | threshold_cents, gift_handle, unlocked_message, locked_message_suffix | (none) | create-gift-product + create-gift-discount |
32
32
  | `how-it-works` | storefront | (native build) | sections:1 | eyebrow, heading, lede, image, asset_filename, background_color, text_color, cta_label, cta_link | (none) | (none) |
@@ -97,13 +97,13 @@ Total modules: 34.
97
97
  ### delivery-estimate
98
98
 
99
99
  - Category: pdp
100
- - What: delivery-estimate module migrated from Lushi.
100
+ - What: PDP delivery-date estimate (JS-rendered date range based on cutoff time and standard transit).
101
101
  - Files: snippets:1
102
102
 
103
103
  ### editorial-block
104
104
 
105
105
  - Category: storefront
106
- - What: Lushi editorial block module migrated from Lushi.
106
+ - What: Editorial introduction block: eyebrow + serif italic heading + lede + body.
107
107
  - Files: sections:1
108
108
  - Config: eyebrow, heading, lede, background_color, text_color
109
109
 
@@ -118,14 +118,15 @@ Total modules: 34.
118
118
  ### exit-intent
119
119
 
120
120
  - Category: conversion
121
- - What: Lushi exit popup module migrated from Lushi.
121
+ - Replaces: Privy / Justuno display layer
122
+ - What: Exit-intent popup with email capture.
122
123
  - Files: sections:1 assets:1
123
124
  - Config: eyebrow, heading, lede
124
125
 
125
126
  ### faq
126
127
 
127
128
  - Category: storefront
128
- - What: Lushi FAQ module migrated from Lushi.
129
+ - What: FAQ accordion.
129
130
  - Files: sections:1
130
131
  - Config: eyebrow, heading, background_color, text_color
131
132
 
@@ -140,14 +141,14 @@ Total modules: 34.
140
141
  ### how-it-works
141
142
 
142
143
  - Category: storefront
143
- - What: Lushi how it works module migrated from Lushi.
144
+ - What: How-it-works section: side-image + multi-step explainer.
144
145
  - Files: sections:1
145
146
  - Config: eyebrow, heading, lede, image, asset_filename, background_color, text_color, cta_label, cta_link
146
147
 
147
148
  ### inventory-urgency
148
149
 
149
150
  - Category: pdp
150
- - What: inventory-urgency module migrated from Lushi.
151
+ - What: PDP inventory urgency message (Only N left) when stock tracking is enabled and quantity is low.
151
152
  - Files: snippets:1
152
153
 
153
154
  ### loyalty-tiers
@@ -161,21 +162,21 @@ Total modules: 34.
161
162
  ### pdp-ingredients
162
163
 
163
164
  - Category: pdp
164
- - What: Lushi ingredients module migrated from Lushi.
165
+ - What: PDP ingredients block (sources from product metafield list.metaobject).
165
166
  - Files: sections:1
166
167
  - Config: eyebrow, heading, lede, background_color, text_color
167
168
 
168
169
  ### pdp-journal-link
169
170
 
170
171
  - Category: pdp
171
- - What: Lushi PDP journal link module migrated from Lushi.
172
+ - What: PDP journal link.
172
173
  - Files: sections:1
173
174
  - Config: eyebrow, article, background_color, text_color, fallback_title, fallback_body, fallback_link_label, fallback_link_url
174
175
 
175
176
  ### pdp-trust-checks
176
177
 
177
178
  - Category: pdp
178
- - What: Lushi PDP trust module migrated from Lushi.
179
+ - What: PDP trust.
179
180
  - Files: sections:1
180
181
  - Config: eyebrow, heading, lede, background_color, text_color, link_label, link_url
181
182
 
@@ -191,7 +192,7 @@ Total modules: 34.
191
192
  ### press-bar
192
193
 
193
194
  - Category: social-proof
194
- - What: Lushi press bar module migrated from Lushi.
195
+ - What: press bar.
195
196
  - Files: sections:1
196
197
  - Config: eyebrow, background_color, text_color
197
198
 
@@ -219,21 +220,21 @@ Total modules: 34.
219
220
  ### recently-viewed
220
221
 
221
222
  - Category: pdp
222
- - What: Lushi recently viewed module migrated from Lushi.
223
+ - What: recently viewed.
223
224
  - Files: sections:1 assets:1
224
225
  - Config: eyebrow, heading, background_color
225
226
 
226
227
  ### reviews
227
228
 
228
229
  - Category: social-proof
229
- - What: Lushi PDP reviews module migrated from Lushi.
230
+ - What: PDP reviews.
230
231
  - Files: sections:1
231
232
  - Config: heading
232
233
 
233
234
  ### risk-reversal
234
235
 
235
236
  - Category: conversion
236
- - What: Lushi risk reversal module migrated from Lushi.
237
+ - What: risk reversal.
237
238
  - Files: sections:1
238
239
  - Config: icon, heading, body, link_label, link_url, background_color, text_color
239
240
 
@@ -247,7 +248,7 @@ Total modules: 34.
247
248
  ### shipping-bar
248
249
 
249
250
  - Category: conversion
250
- - What: Lushi shipping bar module migrated from Lushi.
251
+ - What: shipping bar.
251
252
  - Files: sections:1
252
253
  - Config: threshold_cents, message_below, message_qualified, message_default, background_color, text_color
253
254
 
@@ -292,7 +293,7 @@ Total modules: 34.
292
293
  ### trust-badges
293
294
 
294
295
  - Category: social-proof
295
- - What: Lushi trust badges module migrated from Lushi.
296
+ - What: trust badges.
296
297
  - Files: sections:1
297
298
  - Config: background_color, text_color
298
299
 
@@ -9,9 +9,9 @@
9
9
  "config": {
10
10
  "schema": {
11
11
  "icon": { "type": "string", "default": "&#10003;", "label": "Bullet icon (HTML entity or emoji)" },
12
- "usp_1": { "type": "string", "default": "30-day satisfaction promise" },
13
- "usp_2": { "type": "string", "default": "Editorially curated, not bulk-stocked" },
14
- "usp_3": { "type": "string", "default": "Every product paired with a journal post" }
12
+ "usp_1": { "type": "string", "default": "Free shipping over $50" },
13
+ "usp_2": { "type": "string", "default": "30-day satisfaction guarantee" },
14
+ "usp_3": { "type": "string", "default": "Secure checkout" }
15
15
  }
16
16
  }
17
17
  }
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "variants": {
17
17
  "feature-columns": {
18
- "description": "Theme Editor blocks are columns (e.g. Lushi pick / Drugstore / Hype brand). Rows come from a textarea (pipe-delimited). Best when comparing many products across the same attributes.",
18
+ "description": "Theme Editor blocks are columns (e.g. Brand pick / Generic / Competitor). Rows come from a textarea (pipe-delimited). Best when comparing many products across the same attributes.",
19
19
  "files": {
20
20
  "sections": ["variants/feature-columns/sections/runwell-comparison-table.liquid"]
21
21
  },
@@ -2,7 +2,7 @@
2
2
  "name": "delivery-estimate",
3
3
  "version": "0.1.0",
4
4
  "category": "pdp",
5
- "description": "delivery-estimate module migrated from Lushi.",
5
+ "description": "PDP delivery-date estimate (JS-rendered date range based on cutoff time and standard transit).",
6
6
  "files": {
7
7
  "snippets": [
8
8
  "snippets/runwell-delivery-estimate.liquid"
@@ -2,7 +2,7 @@
2
2
  "name": "editorial-block",
3
3
  "version": "0.1.0",
4
4
  "category": "storefront",
5
- "description": "Lushi editorial block module migrated from Lushi.",
5
+ "description": "Editorial introduction block: eyebrow + serif italic heading + lede + body. Native replacement for Dawn rich-text section with brand-aware typography.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-editorial-block.liquid"
@@ -17,12 +17,12 @@
17
17
  },
18
18
  "heading": {
19
19
  "type": "string",
20
- "default": "Wellness, made simple.",
20
+ "default": "Why we built this.",
21
21
  "label": "Heading"
22
22
  },
23
23
  "lede": {
24
24
  "type": "string",
25
- "default": "Curated supplements, skincare, and rituals from the brands we trust most. Editorial-first, science-aware, beautifully made.",
25
+ "default": "Brief introduction text. Replace with your brand voice.",
26
26
  "label": "Lede"
27
27
  },
28
28
  "background_color": {
@@ -2,13 +2,13 @@
2
2
  "name": "editorial-hero",
3
3
  "version": "0.2.0",
4
4
  "category": "storefront",
5
- "description": "Editorial hero section. Two variants: video-bg (default) renders a full-bleed background video with eyebrow + heading + subhead + dual CTA, ideal for Lushi-style editorial brands; hero-with-card renders a background image with a centered text card (Hero with Card pattern), ideal for product-led brands. Replaces Dawn's image-banner / video-banner.",
5
+ "description": "Editorial hero section. Two variants: video-bg (default) renders a full-bleed background video with eyebrow + heading + subhead + dual CTA, ideal for editorial brands; hero-with-card renders a background image with a centered text card (Hero with Card pattern), ideal for product-led brands. Replaces Dawn's image-banner / video-banner.",
6
6
  "default_variant": "video-bg",
7
7
  "config": {
8
8
  "schema": {
9
- "eyebrow": { "type": "string", "default": "Wellness, curated", "label": "Eyebrow text" },
10
- "heading": { "type": "string", "default": "Glow from within.", "label": "Headline" },
11
- "subheading": { "type": "string", "default": "Lushi is a modern wellness brand offering curated supplements, skincare, and rituals for everyday health.", "label": "Subheading" }
9
+ "eyebrow": { "type": "string", "default": "Brand eyebrow", "label": "Eyebrow text" },
10
+ "heading": { "type": "string", "default": "Tagline goes here.", "label": "Headline" },
11
+ "subheading": { "type": "string", "default": "Short brand subhead. Replace with your value proposition.", "label": "Subheading" }
12
12
  }
13
13
  },
14
14
  "variants": {
@@ -22,9 +22,9 @@
22
22
  "poster_image": { "type": "string", "label": "Poster image (and fallback)" },
23
23
  "fallback_asset": { "type": "string", "label": "Bundled fallback asset filename (e.g. lushi-hero-bg.jpg)" },
24
24
  "min_height": { "type": "number", "default": 100, "label": "Hero min-height (vh)" },
25
- "button_label_primary": { "type": "string", "default": "Shop wellness", "label": "Primary button label" },
25
+ "button_label_primary": { "type": "string", "default": "Shop now", "label": "Primary button label" },
26
26
  "button_link_primary": { "type": "string", "label": "Primary button link" },
27
- "button_label_secondary": { "type": "string", "default": "Read the journal", "label": "Secondary button label" },
27
+ "button_label_secondary": { "type": "string", "default": "Learn more", "label": "Secondary button label" },
28
28
  "button_link_secondary": { "type": "string", "label": "Secondary button link" }
29
29
  }
30
30
  },
@@ -2,7 +2,7 @@
2
2
  "name": "exit-intent",
3
3
  "version": "0.1.0",
4
4
  "category": "conversion",
5
- "description": "Lushi exit popup module migrated from Lushi.",
5
+ "description": "Exit-intent popup with email capture. Replaces Privy / Justuno display layer.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-exit-intent.liquid"
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "lede": {
27
27
  "type": "string",
28
- "default": "Join the journal and get the founder's take on what we picked, why we picked it, and which products to skip altogether.",
28
+ "default": "Subscribe for early access and exclusive offers.",
29
29
  "label": "Lede"
30
30
  }
31
31
  }
@@ -2,7 +2,7 @@
2
2
  "name": "faq",
3
3
  "version": "0.1.0",
4
4
  "category": "storefront",
5
- "description": "Lushi FAQ module migrated from Lushi.",
5
+ "description": "FAQ accordion. Native replacement for FAQ widgets in Vitals and similar apps.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-faq.liquid"
@@ -2,7 +2,7 @@
2
2
  "name": "how-it-works",
3
3
  "version": "0.1.0",
4
4
  "category": "storefront",
5
- "description": "Lushi how it works module migrated from Lushi.",
5
+ "description": "How-it-works section: side-image + multi-step explainer.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-how-it-works.liquid"
@@ -12,12 +12,12 @@
12
12
  "schema": {
13
13
  "eyebrow": {
14
14
  "type": "string",
15
- "default": "How Lushi works",
15
+ "default": "How it works",
16
16
  "label": "Eyebrow"
17
17
  },
18
18
  "heading": {
19
19
  "type": "string",
20
- "default": "Curated, written, shipped.",
20
+ "default": "How we work.",
21
21
  "label": "Heading"
22
22
  },
23
23
  "lede": {
@@ -2,7 +2,7 @@
2
2
  "name": "inventory-urgency",
3
3
  "version": "0.1.0",
4
4
  "category": "pdp",
5
- "description": "inventory-urgency module migrated from Lushi.",
5
+ "description": "PDP inventory urgency message (Only N left) when stock tracking is enabled and quantity is low.",
6
6
  "files": {
7
7
  "snippets": [
8
8
  "snippets/runwell-inventory-urgency.liquid"
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "config": {
10
10
  "schema": {
11
- "tier_0_name": { "type": "string", "default": "Curator" },
11
+ "tier_0_name": { "type": "string", "default": "Member" },
12
12
  "tier_1_name": { "type": "string", "default": "Insider" },
13
13
  "tier_1_threshold": { "type": "number", "default": 250 },
14
14
  "tier_1_perk_pct": { "type": "number", "default": 10 },
@@ -2,7 +2,7 @@
2
2
  "name": "pdp-ingredients",
3
3
  "version": "0.1.0",
4
4
  "category": "pdp",
5
- "description": "Lushi ingredients module migrated from Lushi.",
5
+ "description": "PDP ingredients block (sources from product metafield list.metaobject).",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-ingredients.liquid"
@@ -2,7 +2,7 @@
2
2
  "name": "pdp-journal-link",
3
3
  "version": "0.1.0",
4
4
  "category": "pdp",
5
- "description": "Lushi PDP journal link module migrated from Lushi.",
5
+ "description": "PDP journal link.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-pdp-journal.liquid"
@@ -12,7 +12,7 @@
12
12
  "schema": {
13
13
  "eyebrow": {
14
14
  "type": "string",
15
- "default": "From the journal",
15
+ "default": "Editorial",
16
16
  "label": "Eyebrow"
17
17
  },
18
18
  "article": {
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "fallback_body": {
38
38
  "type": "string",
39
- "default": "Every product on Lushi pairs with a journal article. Browse the full archive to dig deeper.",
39
+ "default": "Every product pairs with a journal article. Browse the full archive to dig deeper.",
40
40
  "label": "Fallback body"
41
41
  },
42
42
  "fallback_link_label": {
@@ -2,7 +2,7 @@
2
2
  "name": "pdp-trust-checks",
3
3
  "version": "0.1.0",
4
4
  "category": "pdp",
5
- "description": "Lushi PDP trust module migrated from Lushi.",
5
+ "description": "PDP trust.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-pdp-trust.liquid"
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "lede": {
24
24
  "type": "string",
25
- "default": "We do not stock everything. Every product on Lushi has to clear these four checks before it gets a page.",
25
+ "default": "We do not stock everything. Every product has to clear these four checks before it gets a page.",
26
26
  "label": "Lede"
27
27
  },
28
28
  "background_color": {
@@ -2,7 +2,7 @@
2
2
  "name": "press-bar",
3
3
  "version": "0.1.0",
4
4
  "category": "social-proof",
5
- "description": "Lushi press bar module migrated from Lushi.",
5
+ "description": "press bar.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-press-bar.liquid"
@@ -2,7 +2,7 @@
2
2
  "name": "recently-viewed",
3
3
  "version": "0.1.0",
4
4
  "category": "pdp",
5
- "description": "Lushi recently viewed module migrated from Lushi.",
5
+ "description": "recently viewed.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-recently-viewed.liquid"
@@ -2,7 +2,7 @@
2
2
  "name": "reviews",
3
3
  "version": "0.1.0",
4
4
  "category": "social-proof",
5
- "description": "Lushi PDP reviews module migrated from Lushi.",
5
+ "description": "PDP reviews.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-pdp-reviews.liquid"
@@ -2,7 +2,7 @@
2
2
  "name": "risk-reversal",
3
3
  "version": "0.1.0",
4
4
  "category": "conversion",
5
- "description": "Lushi risk reversal module migrated from Lushi.",
5
+ "description": "risk reversal.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-risk-reversal.liquid"
@@ -2,7 +2,7 @@
2
2
  "name": "shipping-bar",
3
3
  "version": "0.1.0",
4
4
  "category": "conversion",
5
- "description": "Lushi shipping bar module migrated from Lushi.",
5
+ "description": "shipping bar.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-shipping-bar.liquid"
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "variants": {
16
16
  "grid-quotes": {
17
- "description": "3 to 6 customer quote cards in a responsive grid. Each block is a quote with author + context + 0-5 star rating. Best for editorial / wellness brands.",
17
+ "description": "3 to 6 customer quote cards in a responsive grid. Each block is a quote with author + context + 0-5 star rating. Best for editorial brands.",
18
18
  "files": {
19
19
  "sections": ["variants/grid-quotes/sections/runwell-testimonials.liquid"]
20
20
  }
@@ -2,7 +2,7 @@
2
2
  "name": "trust-badges",
3
3
  "version": "0.1.0",
4
4
  "category": "social-proof",
5
- "description": "Lushi trust badges module migrated from Lushi.",
5
+ "description": "trust badges.",
6
6
  "files": {
7
7
  "sections": [
8
8
  "sections/runwell-trust-badges.liquid"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runwell/shopify-toolkit",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Reusable Shopify theme modules from Runwell. Replaces typically app-driven features (reviews, wishlist, urgency, FAQ, post-purchase upsell, exit popups, free-ship progress, sticky ATC, testimonials, badges, bundles) with native Liquid + JS + CSS that ship across multiple client themes via a config-driven sync CLI.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -42,4 +42,4 @@
42
42
  "type": "git",
43
43
  "url": "https://github.com/louayelbiche/runwell-shopify-toolkit.git"
44
44
  }
45
- }
45
+ }