ship-create 1.7.2 → 1.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/create.mjs CHANGED
@@ -55,6 +55,14 @@ const LANGUAGES = [
55
55
  { code: "th", name: "Thai (ภาษาไทย)", desc: "ข้อความ label และ copy ในระบบเป็นภาษาไทย" },
56
56
  ];
57
57
 
58
+ const REVENUE_MODELS = [
59
+ { key: "SUBSCRIPTION", name: "Subscription", desc: "รายเดือน / รายปี — recurring revenue", descEn: "monthly or annual recurring payments" },
60
+ { key: "ONE_TIME", name: "One-time payment", desc: "จ่ายครั้งเดียว เข้าถึงตลอด", descEn: "pay once, access forever" },
61
+ { key: "FREEMIUM", name: "Freemium", desc: "ใช้ฟรีได้ + paid tier สำหรับ feature เพิ่ม", descEn: "free tier + paid upgrade for more features" },
62
+ { key: "MARKETPLACE", name: "Marketplace fee", desc: "เก็บ % จาก transaction ระหว่าง buyer กับ seller", descEn: "take a % cut from each transaction" },
63
+ { key: "FREE", name: "Free / not yet", desc: "ยังไม่มี monetization ตอนนี้", descEn: "no monetization planned yet" },
64
+ ];
65
+
58
66
  const I18N = {
59
67
  en: {
60
68
  sectionIdea: "── About your idea ────────────────────────────",
@@ -65,6 +73,7 @@ const I18N = {
65
73
  qUserDefault: "small business owners",
66
74
  qProblem: "What is the #1 problem they face today?",
67
75
  qValue: "What makes them say 'I need this'? (the aha moment)",
76
+ qRevenue: "How will this make money?",
68
77
  scaffolding: (slug) => `Scaffolding ./${slug} ...`,
69
78
  installing: (pm) => `Installing packages with ${pm} ...`,
70
79
  installFail: (slug, pm) => `${pm} install failed. Run it manually:\n cd ${slug} && ${pm} install`,
@@ -96,6 +105,7 @@ const I18N = {
96
105
  qUserDefault: "เจ้าของธุรกิจขนาดเล็ก",
97
106
  qProblem: "ปัญหาอันดับ 1 ที่พวกเขาเจออยู่ทุกวันคืออะไร?",
98
107
  qValue: "อะไรทำให้พวกเขาบอกว่า 'ฉันต้องการสิ่งนี้!'? (จุด aha moment)",
108
+ qRevenue: "แผนหาเงินของโปรเจคนี้คืออะไร?",
99
109
  scaffolding: (slug) => `กำลัง scaffold ./${slug} ...`,
100
110
  installing: (pm) => `กำลังติดตั้ง packages ด้วย ${pm} ...`,
101
111
  installFail: (slug, pm) => `${pm} install ล้มเหลว รันเองได้ที่:\n cd ${slug} && ${pm} install`,
@@ -299,7 +309,15 @@ function toKebabCase(str) {
299
309
 
300
310
  // ─── Doc builders ─────────────────────────────────────────────────────────────
301
311
 
302
- function buildProjectMd(projectName, productTypeName, { targetUser, problem, valueProp, idea, uiLanguage }) {
312
+ const REVENUE_SCREENS = {
313
+ SUBSCRIPTION: "Pricing page with tier comparison + Stripe subscription checkout",
314
+ ONE_TIME: "Product page with one-time payment CTA + Stripe checkout",
315
+ FREEMIUM: "Free vs paid tier comparison page + upgrade flow",
316
+ MARKETPLACE: "Transaction page showing platform fee + seller/buyer checkout",
317
+ FREE: "No payment screens needed for MVP",
318
+ };
319
+
320
+ function buildProjectMd(projectName, productTypeName, { targetUser, problem, valueProp, idea, uiLanguage, revenueModel }) {
303
321
  return `# PROJECT.md
304
322
 
305
323
  **Phase:** S — Structure
@@ -381,7 +399,9 @@ ${projectName} is a ${productTypeName.toLowerCase()} that helps **${targetUser}*
381
399
 
382
400
  ## 8. Revenue Model
383
401
 
384
- - **Pricing model:** [subscription / one-time / freemium / marketplace fee / etc.]
402
+ - **Pricing model:** ${revenueModel ? revenueModel.name : "[fill in]"}
403
+ - **How it works:** ${revenueModel ? revenueModel.descEn : "[fill in]"}
404
+ - **Revenue screen to build:** ${revenueModel ? (REVENUE_SCREENS[revenueModel.key] || "[fill in]") : "[fill in]"}
385
405
  - **Price point:** [fill in]
386
406
  - **Revenue goal (Month 3):** [fill in]
387
407
 
@@ -510,9 +530,15 @@ async function main() {
510
530
  // ── Interactive selections (no readline needed) ────────────────────────────
511
531
  let productType, uiLanguage;
512
532
 
533
+ let revenueModel;
534
+
513
535
  if (isTTY) {
514
- productType = await selectInteractive("What type of system are you building?", PRODUCT_TYPES);
515
- uiLanguage = await selectInteractive("UI language — what will your app display to users?", LANGUAGES);
536
+ productType = await selectInteractive("What type of system are you building?", PRODUCT_TYPES);
537
+ uiLanguage = await selectInteractive("UI language — what will your app display to users?", LANGUAGES);
538
+ revenueModel = await selectInteractive(
539
+ uiLanguage.code === "th" ? "แผนหาเงินของโปรเจคนี้คืออะไร?" : "How will this make money?",
540
+ REVENUE_MODELS.map(r => ({ ...r, desc: uiLanguage.code === "th" ? r.desc : r.descEn }))
541
+ );
516
542
  }
517
543
 
518
544
  // ── Text questions (readline) — switch language after uiLanguage is known ──
@@ -520,8 +546,9 @@ async function main() {
520
546
  const nextLine = makeLineReader(rl);
521
547
 
522
548
  if (!isTTY) {
523
- productType = await selectFallback("What type of system are you building?", PRODUCT_TYPES, nextLine);
524
- uiLanguage = await selectFallback("UI language — what will your app display to users?", LANGUAGES, nextLine);
549
+ productType = await selectFallback("What type of system are you building?", PRODUCT_TYPES, nextLine);
550
+ uiLanguage = await selectFallback("UI language — what will your app display to users?", LANGUAGES, nextLine);
551
+ revenueModel = await selectFallback("How will this make money?", REVENUE_MODELS, nextLine);
525
552
  }
526
553
 
527
554
  const t = I18N[uiLanguage.code] ?? I18N.en;
@@ -576,7 +603,7 @@ async function main() {
576
603
 
577
604
  fs.writeFileSync(
578
605
  path.join(docsDir, "PROJECT.md"),
579
- buildProjectMd(projectNameRaw, productType.name, { targetUser, problem, valueProp, idea, uiLanguage: uiLanguage.name })
606
+ buildProjectMd(projectNameRaw, productType.name, { targetUser, problem, valueProp, idea, uiLanguage: uiLanguage.name, revenueModel })
580
607
  );
581
608
 
582
609
  fs.writeFileSync(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ship-create",
3
- "version": "1.7.2",
3
+ "version": "1.8.0",
4
4
  "description": "Scaffold a new project the SHIP Method way — Structure, Human Flow, Instruction, Publish. No git clone, no API key, just one command.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -44,7 +44,16 @@ Rules for the diagram:
44
44
  - Keep node labels short (3–5 words max)
45
45
 
46
46
  ### Step 3 — Build prototype
47
- Generate a fresh theme from scratch based on the product type — **never reuse the default colors already in `app/globals.css`**. Overwrite the entire `:root` and `.dark` blocks with new values derived from `theme-guide.md` and the product context. Apply to `app/globals.css` and `app/layout.tsx`. Replace `app/page.tsx` with the real home screen based on `HUMAN_FLOW.md`. Build the first 1–2 screens that matter most for this product type. Record the theme choice in `docs/DESIGN_SYSTEM.md`.
47
+ Generate a fresh theme from scratch based on the product type — **never reuse the default colors already in `app/globals.css`**. Overwrite the entire `:root` and `.dark` blocks with new values derived from `theme-guide.md` and the product context. Apply to `app/globals.css` and `app/layout.tsx`. Record the theme choice in `docs/DESIGN_SYSTEM.md`.
48
+
49
+ Build these screens (in priority order):
50
+ 1. **Home screen** — replace `app/page.tsx` with the real entry point from `HUMAN_FLOW.md`
51
+ 2. **Revenue screen** — read Section 8 of `PROJECT.md` for the revenue model, then build the matching screen:
52
+ - Subscription → pricing page with tier comparison + Stripe checkout stub
53
+ - One-time → product page with buy CTA + Stripe checkout stub
54
+ - Freemium → free vs paid tier comparison + upgrade CTA
55
+ - Marketplace fee → transaction page showing platform fee structure
56
+ - Free / not yet → skip, build the next most important screen instead
48
57
 
49
58
  ### Step 4 — Run
50
59
  Run `npm run dev` (or `pnpm dev` if pnpm is available). Confirm the app compiles and is accessible at localhost:3000.