lism-cli 0.8.0 → 0.10.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 CHANGED
@@ -13,6 +13,7 @@ lism-cli create [targetDir] [--template <name|category>] [--lang <ja|en>] # tem
13
13
  lism-cli init [--ui-framework <react|astro>] [--ui-dir <path>] # lism.config ファイルの新規生成
14
14
  lism-cli ui { add <names...> | list } # Lism UI コンポーネントの追加
15
15
  lism-cli skill { add [skill] | check | update } # AI エージェント向け SKILL.md 配置
16
+ lism-cli mockup # 画面モックアップ作成の案内
16
17
  ```
17
18
 
18
19
  ## 使い方
@@ -35,7 +36,7 @@ pnpm dlx lism-cli create --template blog-astro-minimal --lang en ./my-blog
35
36
 
36
37
  同じ動作は `pnpm create lism` / `npm create lism@latest` でも呼び出せます(`create-lism` パッケージ経由)。挙動は両者で共通です。
37
38
 
38
- `--lang <ja|en>` は CLIの表示言語に加えて、**生成されるテンプレート本体の言語**にも反映されます。`--lang` を指定しない場合は、対話端末(TTY)ではほかのどの選択よりも先に言語選択プロンプトが表示され、選んだ言語で以降の表示とテンプレート生成が確定します(非対話環境・CI等では `en` にフォールバック)。対応言語版を持つテンプレート(`blog-astro-minimal` / `blog-astro-personal` / `blog-astro-techlog` / `lp-astro-corporate` / `lp-astro-interior`)では、指定言語のサイト文言・サンプルコンテンツで生成されます。言語版が無いテンプレートは、指定言語に関わらず既存(ベース)の内容で生成されます。
39
+ `--lang <ja|en>` は CLIの表示言語に加えて、**生成されるテンプレート本体の言語**にも反映されます。`--lang` を指定しない場合は、対話端末(TTY)ではほかのどの選択よりも先に言語選択プロンプトが表示され、選んだ言語で以降の表示とテンプレート生成が確定します(非対話環境・CI等では `en` にフォールバック)。対応言語版を持つテンプレート(`blog-astro-minimal` / `blog-astro-personal` / `blog-astro-techlog` / `lp-astro-corporate` / `lp-astro-interior` / `lp-astro-ryokan`)では、指定言語のサイト文言・サンプルコンテンツで生成されます。言語版が無いテンプレートは、指定言語に関わらず既存(ベース)の内容で生成されます。
39
40
 
40
41
  ### lism.config の生成
41
42
 
@@ -91,12 +92,13 @@ pnpm dlx lism-cli ui add accordion --ref dev
91
92
 
92
93
  同梱スキル(`SKILL.md` ほか一式)を各種AIツールの所定ディレクトリへ展開します。
93
94
 
94
- 同梱スキルは以下の2つです:
95
+ 同梱スキルは以下の3つです:
95
96
 
96
97
  | スキル | 説明 |
97
98
  |--------|------|
98
99
  | `lism-css-guide` | Lism CSSでUI・ページを実装・修正する時に使う実装ガイド |
99
100
  | `lism-css-refactor` | 既存の Lism CSSコードを、見た目や挙動を変えずにLismらしい書き方へ整理するリファクタガイド |
101
+ | `lism-mockup-guide` | `@lism-css/mockup`で画面モックアップを組む時のワークフローとデータ契約のガイド(`lism-css-guide`併用前提) |
100
102
 
101
103
  ```bash
102
104
  # 対話モード(使用中のツールを自動検出)
@@ -133,6 +135,24 @@ pnpm dlx lism-cli skill update --claude
133
135
  | `--gemini` | `.gemini/skills/<skill>` |
134
136
  | `--junie` | `.junie/skills/<skill>` |
135
137
 
138
+ ### 画面モックアップの案内
139
+
140
+ `lism-cli mockup` は、画面モックアップを作成するCLI [`@lism-css/mockup`](https://www.npmjs.com/package/@lism-css/mockup) の使い方を表示するだけのコマンドです。`lism-cli` 自体はモックアップ機能を持ちません。
141
+
142
+ ```bash
143
+ pnpm dlx lism-cli mockup
144
+ ```
145
+
146
+ モックアップの作成・検証・プレビューは `@lism-css/mockup` を直接実行してください。
147
+
148
+ ```bash
149
+ npx @lism-css/mockup init [dir] # ひな形+契約説明書の生成
150
+ npx @lism-css/mockup check [dir] # 非対話の検証
151
+ npx @lism-css/mockup dev [dir] # devサーバー起動(ブラウザ確認用)
152
+ ```
153
+
154
+ AIエージェントにモックアップを作らせる場合は、`lism-mockup-guide` スキル(前述の `skill add`)も併せて導入してください。
155
+
136
156
  ## lism.config.js
137
157
 
138
158
  `ui add` が読み込む設定ファイル(新規作成するのは `init`)。CSSの設定(`tokens` 等)とUI設定を同居できます。
@@ -1,5 +1,5 @@
1
1
  // <define:__LISM_PACKAGE_VERSIONS__>
2
- var define_LISM_PACKAGE_VERSIONS_default = { "lism-css": "0.24.0", "@lism-css/ui": "0.24.0", "@lism-css/plugin": "0.3.0" };
2
+ var define_LISM_PACKAGE_VERSIONS_default = { "lism-css": "0.27.0", "@lism-css/ui": "0.27.0", "@lism-css/plugin": "0.4.3" };
3
3
 
4
4
  // src/logger.ts
5
5
  import pc from "picocolors";
@@ -58,6 +58,10 @@ var messages = {
58
58
  ja: "\u65E2\u5B58\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u5F37\u5236\u4E0A\u66F8\u304D",
59
59
  en: "Overwrite existing directory"
60
60
  },
61
+ "cli.create.opt.ref": {
62
+ ja: "\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u53D6\u5F97\u5143\u306E Git ref\uFF08\u30D6\u30E9\u30F3\u30C1 / \u30BF\u30B0 / \u30B3\u30DF\u30C3\u30C8\uFF09",
63
+ en: "Git ref to fetch templates from (branch / tag / commit)"
64
+ },
61
65
  // init
62
66
  "cli.init.description": {
63
67
  ja: "lism.config \u30D5\u30A1\u30A4\u30EB\u3092\u65B0\u898F\u751F\u6210\u3059\u308B",
@@ -100,6 +104,11 @@ var messages = {
100
104
  ja: "\u53D6\u5F97\u5143\u306E Git ref\uFF08\u30D6\u30E9\u30F3\u30C1 / \u30BF\u30B0 / \u30B3\u30DF\u30C3\u30C8\uFF09",
101
105
  en: "Git ref to fetch from (branch / tag / commit)"
102
106
  },
107
+ // mockup
108
+ "cli.mockup.description": {
109
+ ja: "\u753B\u9762\u30E2\u30C3\u30AF\u30A2\u30C3\u30D7\u306E\u6848\u5185\u3092\u8868\u793A\u3059\u308B\uFF08\u5B9F\u4F53\u306F @lism-css/mockup\uFF09",
110
+ en: "Show guidance for mockups (provided by @lism-css/mockup)"
111
+ },
103
112
  // skill
104
113
  "cli.skill.description": {
105
114
  ja: "AI \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u5411\u3051\u30B9\u30AD\u30EB\uFF08SKILL.md\uFF09\u306E\u914D\u7F6E\u3068\u7BA1\u7406",
@@ -350,6 +359,13 @@ var messages = {
350
359
  en: "Total: {count} components"
351
360
  },
352
361
  // ---------------------------------------------------------------------------
362
+ // mockup
363
+ // ---------------------------------------------------------------------------
364
+ "mockup.guide": {
365
+ ja: "\u753B\u9762\u30E2\u30C3\u30AF\u30A2\u30C3\u30D7\u6A5F\u80FD\u306F\u5225\u30D1\u30C3\u30B1\u30FC\u30B8 @lism-css/mockup \u304C\u63D0\u4F9B\u3057\u307E\u3059\u3002\n\n npx @lism-css/mockup init [dir] \u2026 \u3072\u306A\u5F62\uFF0B\u5951\u7D04\u8AAC\u660E\u66F8\u306E\u751F\u6210\n npx @lism-css/mockup dev [dir] \u2026 dev\u30B5\u30FC\u30D0\u30FC\u8D77\u52D5\uFF08\u30D6\u30E9\u30A6\u30B6\u78BA\u8A8D\u7528\uFF09\n npx @lism-css/mockup check [dir] \u2026 \u975E\u5BFE\u8A71\u306E\u691C\u8A3C\n\n\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u6E08\u307F\u306E\u74B0\u5883\u3067\u306F bin \u306E lism-mockup \u3067\u3082\u5B9F\u884C\u3067\u304D\u307E\u3059\u3002",
366
+ en: "Mockup features are provided by a separate package, @lism-css/mockup.\n\n npx @lism-css/mockup init [dir] ... Generate scaffolding and a contract document\n npx @lism-css/mockup dev [dir] ... Start the dev server (for browser preview)\n npx @lism-css/mockup check [dir] ... Run non-interactive checks\n\nIf installed, you can also run it via the lism-mockup bin."
367
+ },
368
+ // ---------------------------------------------------------------------------
353
369
  // skill
354
370
  // ---------------------------------------------------------------------------
355
371
  // skill add
@@ -547,11 +563,11 @@ import { downloadTemplate } from "giget";
547
563
  import { select, input, confirm } from "@inquirer/prompts";
548
564
 
549
565
  // src/version.ts
550
- var LISM_CSS_VERSION = "0.24.0" ? "0.24.0" : "unknown";
566
+ var LISM_CSS_VERSION = "0.27.0" ? "0.27.0" : "unknown";
551
567
  var LISM_PACKAGE_VERSIONS = typeof define_LISM_PACKAGE_VERSIONS_default !== "undefined" && define_LISM_PACKAGE_VERSIONS_default ? define_LISM_PACKAGE_VERSIONS_default : {
552
568
  "lism-css": LISM_CSS_VERSION
553
569
  };
554
- var CLI_VERSION = "0.8.0" ? "0.8.0" : "unknown";
570
+ var CLI_VERSION = "0.10.0" ? "0.10.0" : "unknown";
555
571
 
556
572
  // src/constants.ts
557
573
  var SOURCE_REPO = "lism-css/lism-css";
@@ -564,7 +580,7 @@ var UI_COMPONENTS_PATH = "packages/lism-ui/src/components";
564
580
  var UI_HELPER_PATH = "packages/lism-ui/src/helper";
565
581
  var UI_REGISTRY_INDEX_PATH = "packages/lism-ui/registry-index.json";
566
582
  var SKILL_SOURCE_BASE = "skills";
567
- var SKILL_NAMES = ["lism-css-guide", "lism-css-refactor"];
583
+ var SKILL_NAMES = ["lism-css-guide", "lism-css-refactor", "lism-mockup-guide"];
568
584
  var TEMPLATES_PATH = "templates";
569
585
 
570
586
  // ../../templates/manifest.ts
@@ -613,6 +629,10 @@ var TEMPLATES = [
613
629
  },
614
630
  title: { ja: "Blog Minimal", en: "Blog Minimal" },
615
631
  description: { ja: "\u8A18\u4E8B\u4E00\u89A7 / \u8A73\u7D30 / Tags \u306E\u307F\u306E\u6700\u5C0F\u69CB\u6210\u306E Astro \u30D6\u30ED\u30B0", en: "Minimal Astro blog with posts and tags only" },
632
+ intro: {
633
+ ja: "\u8A18\u4E8B\u4E00\u89A7\u30FB\u8A18\u4E8B\u8A73\u7D30\u30FB\u30BF\u30B0\u30DA\u30FC\u30B8\u3060\u3051\u3067\u69CB\u6210\u3057\u305F\u3001\u3044\u3061\u3070\u3093\u5C0F\u3055\u306A Astro \u30D6\u30ED\u30B0\u3067\u3059\u3002\u4F59\u8A08\u306A\u6A5F\u80FD\u3092\u6301\u305F\u306A\u3044\u306E\u3067\u3001Lism CSS \u3067\u30D6\u30ED\u30B0\u3092\u7D44\u3080\u624B\u9806\u3092\u6700\u77ED\u3067\u8FFD\u3048\u307E\u3059\u3002\u72EC\u81EA\u306E\u6A5F\u80FD\u3092\u8DB3\u3057\u3066\u3044\u304F\u571F\u53F0\u306B\u3082\u304A\u3059\u3059\u3081\u3067\u3059\u3002",
634
+ en: "The smallest Astro blog, made up of only a post list, post pages, and tag pages. With no extra features, it is the quickest way to see how a blog is built with Lism CSS, and a good base to add your own features to."
635
+ },
616
636
  previewUrl: `${PREVIEW_ORIGIN}/blog-astro-minimal/`,
617
637
  previewUrlEn: `${PREVIEW_ORIGIN}/blog-astro-minimal/en/`,
618
638
  features: {
@@ -636,6 +656,10 @@ var TEMPLATES = [
636
656
  ja: "\u500B\u4EBA\u30D6\u30ED\u30B0\u30FB\u30A8\u30C3\u30BB\u30A4\u5411\u3051\u3002\u5E74\u6708\u30A2\u30FC\u30AB\u30A4\u30D6\u3064\u304D\u306E\u843D\u3061\u7740\u3044\u305F Astro \u30D6\u30ED\u30B0",
637
657
  en: "Personal / essay-style Astro blog with monthly archives"
638
658
  },
659
+ intro: {
660
+ ja: "\u500B\u4EBA\u30D6\u30ED\u30B0\u3084\u30A8\u30C3\u30BB\u30A4\u5411\u3051\u306E\u3001\u843D\u3061\u7740\u3044\u305F\u8AAD\u307F\u7269\u7CFB\u30C7\u30B6\u30A4\u30F3\u306E Astro \u30D6\u30ED\u30B0\u3067\u3059\u3002\u30BF\u30B0\u3068\u5E74\u6708\u30A2\u30FC\u30AB\u30A4\u30D6\u3067\u904E\u53BB\u8A18\u4E8B\u3092\u305F\u3069\u308C\u3001\u30B7\u30A7\u30A2\u30DC\u30BF\u30F3\u3068 OGP \u753B\u50CF\u306E\u81EA\u52D5\u751F\u6210\u3082\u5099\u3048\u3066\u3044\u307E\u3059\u3002\u6587\u7AE0\u3092\u4E3B\u5F79\u306B\u3057\u305F\u30B5\u30A4\u30C8\u3092\u3059\u3050\u59CB\u3081\u3089\u308C\u307E\u3059\u3002",
661
+ en: "A calm, reading-focused Astro blog for personal sites and essays. Tags and monthly archives make older posts easy to find, and share buttons and auto-generated OG images are included. Ideal for a site where the writing comes first."
662
+ },
639
663
  previewUrl: `${PREVIEW_ORIGIN}/blog-astro-personal/`,
640
664
  previewUrlEn: `${PREVIEW_ORIGIN}/blog-astro-personal/en/`,
641
665
  features: {
@@ -659,6 +683,10 @@ var TEMPLATES = [
659
683
  ja: "\u6280\u8853\u30D6\u30ED\u30B0\u5411\u3051\u3002\u30B3\u30FC\u30C9\u30CF\u30A4\u30E9\u30A4\u30C8\u30FB\u30AB\u30C6\u30B4\u30EA\u30FB\u30BF\u30B0\u30FBTOC\u30FB\u5E74\u6708\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u691C\u7D22\u3092\u88C5\u5099\u3057\u305F Astro \u30D6\u30ED\u30B0",
660
684
  en: "Tech blog with code highlighting, categories, tags, TOC, monthly archives and search"
661
685
  },
686
+ intro: {
687
+ ja: "\u6280\u8853\u30D6\u30ED\u30B0\u5411\u3051\u306B\u6A5F\u80FD\u3092\u63C3\u3048\u305F Astro \u30D6\u30ED\u30B0\u3067\u3059\u3002\u30B3\u30FC\u30C9\u30CF\u30A4\u30E9\u30A4\u30C8\u3068\u76EE\u6B21\u3001\u30AB\u30C6\u30B4\u30EA\u3068\u30BF\u30B0\u3001\u5E74\u6708\u30A2\u30FC\u30AB\u30A4\u30D6\u306B\u52A0\u3048\u3001Pagefind \u306B\u3088\u308B\u5168\u6587\u691C\u7D22\u3068\u30C0\u30FC\u30AF\u30E2\u30FC\u30C9\u3082\u5099\u3048\u3066\u3044\u307E\u3059\u3002\u8A18\u4E8B\u6570\u304C\u5897\u3048\u3066\u3082\u63A2\u3057\u3084\u3059\u3044\u3001\u672C\u683C\u904B\u7528\u5411\u3051\u306E\u69CB\u6210\u3067\u3059\u3002",
688
+ en: "A fully equipped Astro blog for technical writing. It includes code highlighting, a table of contents, categories and tags, monthly archives, full-text search with Pagefind, and dark mode. Built for blogs that keep growing and need to stay easy to navigate."
689
+ },
662
690
  previewUrl: `${PREVIEW_ORIGIN}/blog-astro-techlog/`,
663
691
  previewUrlEn: `${PREVIEW_ORIGIN}/blog-astro-techlog/en/`,
664
692
  features: {
@@ -696,6 +724,10 @@ var TEMPLATES = [
696
724
  sourcePath: "lp/astro",
697
725
  title: { ja: "LP Corporate", en: "LP Corporate" },
698
726
  description: { ja: "\u30B3\u30FC\u30DD\u30EC\u30FC\u30C8\u30B5\u30A4\u30C8\u5411\u3051\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Astro landing page for corporate sites" },
727
+ intro: {
728
+ ja: "\u4F01\u696D\u30B5\u30A4\u30C8\u5411\u3051\u306E1\u30DA\u30FC\u30B8\u69CB\u6210\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8\u3067\u3059\u3002\u4F1A\u793E\u7D39\u4ECB\u30FB\u7279\u5FB4\u30FB\u5236\u4F5C\u5B9F\u7E3E\u30FB\u304A\u77E5\u3089\u305B\u30FBFAQ\u30FB\u304A\u5BA2\u69D8\u306E\u58F0\u30FB\u4F01\u696D\u60C5\u5831\u30FB\u304A\u554F\u3044\u5408\u308F\u305B\u3068\u3001\u30B3\u30FC\u30DD\u30EC\u30FC\u30C8\u30B5\u30A4\u30C8\u306B\u5FC5\u8981\u306A\u30BB\u30AF\u30B7\u30E7\u30F3\u3092\u4E00\u901A\u308A\u542B\u307F\u307E\u3059\u3002",
729
+ en: "A one-page Astro landing page for corporate sites. It covers the sections a company site needs: about, features, works, news, FAQ, testimonials, company information, and contact."
730
+ },
699
731
  previewUrl: `${PREVIEW_ORIGIN}/lp-astro/corporate/`,
700
732
  previewUrlEn: `${PREVIEW_ORIGIN}/lp-astro/en/corporate/`
701
733
  },
@@ -709,6 +741,10 @@ var TEMPLATES = [
709
741
  sourcePath: "lp/astro",
710
742
  title: { ja: "LP Interior", en: "LP Interior" },
711
743
  description: { ja: "\u30A4\u30F3\u30C6\u30EA\u30A2\u30FB\u66AE\u3089\u3057\u7CFB\u30B5\u30FC\u30D3\u30B9\u5411\u3051\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Astro landing page for interior / lifestyle services" },
744
+ intro: {
745
+ ja: "\u30A4\u30F3\u30C6\u30EA\u30A2\u3084\u66AE\u3089\u3057\u306B\u95A2\u308F\u308B\u30B5\u30FC\u30D3\u30B9\u5411\u3051\u306E\u3001\u5199\u771F\u3092\u5927\u304D\u304F\u898B\u305B\u308B Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8\u3067\u3059\u3002\u30DF\u30C3\u30B7\u30E7\u30F3\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u30FB\u7279\u9577\u30FB\u30B5\u30FC\u30D3\u30B9\u30FB\u3054\u4F9D\u983C\u306E\u6D41\u308C\u30FB\u304A\u5BA2\u69D8\u306E\u58F0\u30FBFAQ\u30FB\u304A\u554F\u3044\u5408\u308F\u305B\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u3067\u69CB\u6210\u3057\u3066\u3044\u307E\u3059\u3002",
746
+ en: "A photo-forward Astro landing page for interior and lifestyle services. It is made up of mission, message, features, services, process, customer voices, FAQ, and contact sections."
747
+ },
712
748
  previewUrl: `${PREVIEW_ORIGIN}/lp-astro/interior/`,
713
749
  previewUrlEn: `${PREVIEW_ORIGIN}/lp-astro/en/interior/`
714
750
  },
@@ -722,7 +758,8 @@ var TEMPLATES = [
722
758
  sourcePath: "lp/astro",
723
759
  title: { ja: "LP Ryokan", en: "LP Ryokan" },
724
760
  description: { ja: "\u65C5\u9928\u30FB\u5BBF\u6CCA\u696D\u5411\u3051\u306E Astro \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8", en: "Astro landing page for ryokan / lodging" },
725
- draft: true
761
+ previewUrl: `${PREVIEW_ORIGIN}/lp-astro/ryokan/`,
762
+ previewUrlEn: `${PREVIEW_ORIGIN}/lp-astro/en/ryokan/`
726
763
  }
727
764
  ];
728
765
 
@@ -754,10 +791,10 @@ var CATEGORIES = [
754
791
  variantPromptKey: "create.promptSelectVariant.web"
755
792
  }
756
793
  ];
757
- async function runCreate({ template, targetDir, force = false, lang }) {
758
- await runCreateWithTemplates({ template, targetDir, force, lang }, TEMPLATES);
794
+ async function runCreate({ template, targetDir, force = false, lang, ref }) {
795
+ await runCreateWithTemplates({ template, targetDir, force, lang, ref }, TEMPLATES);
759
796
  }
760
- async function runCreateWithTemplates({ template, targetDir, force = false, lang }, templates) {
797
+ async function runCreateWithTemplates({ template, targetDir, force = false, lang, ref = DEFAULT_TEMPLATES_REF }, templates) {
761
798
  const resolvedLang = await resolveLang(lang);
762
799
  setLang(resolvedLang);
763
800
  const availableTemplates = templates.filter((tpl2) => !tpl2.draft);
@@ -773,7 +810,6 @@ async function runCreateWithTemplates({ template, targetDir, force = false, lang
773
810
  return;
774
811
  }
775
812
  }
776
- const ref = DEFAULT_TEMPLATES_REF;
777
813
  logger.info(t("create.fetching", { name: tpl.slug, ref }));
778
814
  await downloadTemplateSource(tpl, outDir, ref, force);
779
815
  await applyLangOverlay(tpl, outDir, ref, resolvedLang);
@@ -785,7 +821,7 @@ async function runCreateWithTemplates({ template, targetDir, force = false, lang
785
821
  async function createCommand(targetDir, options, command) {
786
822
  const langOpt = command?.optsWithGlobals().lang;
787
823
  const lang = typeof langOpt === "string" ? langOpt : void 0;
788
- await runCreate({ template: options.template, targetDir, force: options.force, lang });
824
+ await runCreate({ template: options.template, targetDir, force: options.force, lang, ref: options.ref });
789
825
  }
790
826
  async function resolveLang(explicit) {
791
827
  if (explicit === "ja" || explicit === "en") return explicit;
@@ -935,14 +971,14 @@ function cleanupDevArtifacts(projectDir) {
935
971
  fs.rmSync(langDir, { recursive: true, force: true });
936
972
  }
937
973
  }
938
- function resolveVariantDir(srcDir, variant, lang) {
974
+ function resolveLangVariantDir(srcDir, variant, lang) {
939
975
  const langVariant = `${lang}/${variant}`;
940
976
  const hasLangVariant = fs.existsSync(path.join(srcDir, "pages", langVariant, "index.astro"));
941
- return hasLangVariant ? langVariant : variant;
977
+ return hasLangVariant ? langVariant : void 0;
942
978
  }
943
979
  function extractVariantFiles(projectDir, tpl, lang) {
944
980
  const srcDir = path.join(projectDir, "src");
945
- const variant = resolveVariantDir(srcDir, tpl.variant, lang);
981
+ const { variant } = tpl;
946
982
  const pagesVariantIndex = path.join(srcDir, "pages", variant, "index.astro");
947
983
  if (!fs.existsSync(pagesVariantIndex)) {
948
984
  throw new Error(
@@ -953,19 +989,22 @@ function extractVariantFiles(projectDir, tpl, lang) {
953
989
  );
954
990
  }
955
991
  if (!fs.existsSync(srcDir) || !fs.statSync(srcDir).isDirectory()) return;
992
+ const langVariant = resolveLangVariantDir(srcDir, variant, lang);
993
+ const variantDirs = langVariant ? [variant, langVariant] : [variant];
956
994
  for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
957
995
  if (!entry.isDirectory()) continue;
958
996
  const parentDir = path.join(srcDir, entry.name);
959
- const variantDirInside = path.join(parentDir, variant);
960
- if (!fs.existsSync(variantDirInside)) continue;
961
- if (!fs.statSync(variantDirInside).isDirectory()) continue;
962
- mergeDirectory(variantDirInside, parentDir);
997
+ const variantDirsInside = variantDirs.map((dir) => path.join(parentDir, dir)).filter((dir) => fs.existsSync(dir) && fs.statSync(dir).isDirectory());
998
+ if (variantDirsInside.length === 0) continue;
999
+ for (const variantDirInside of variantDirsInside) {
1000
+ mergeDirectory(variantDirInside, parentDir);
1001
+ }
963
1002
  for (const child of fs.readdirSync(parentDir, { withFileTypes: true })) {
964
1003
  if (!child.isDirectory()) continue;
965
1004
  fs.rmSync(path.join(parentDir, child.name), { recursive: true, force: true });
966
1005
  }
967
1006
  }
968
- rewriteVariantAliasImports(srcDir, variant);
1007
+ rewriteVariantAliasImports(srcDir, variantDirs);
969
1008
  }
970
1009
  var ALIAS_REWRITE_EXTENSIONS = /* @__PURE__ */ new Set([
971
1010
  ".astro",
@@ -985,9 +1024,9 @@ var ALIAS_REWRITE_EXTENSIONS = /* @__PURE__ */ new Set([
985
1024
  ".svelte",
986
1025
  ".html"
987
1026
  ]);
988
- function rewriteVariantAliasImports(srcDir, variant) {
1027
+ function rewriteVariantAliasImports(srcDir, variantDirs) {
989
1028
  if (!fs.existsSync(srcDir)) return;
990
- const pattern = new RegExp(`(@/[^/'"\\s\`]+)/${escapeRegExp(variant)}/`, "g");
1029
+ const patterns = variantDirs.map((dir) => new RegExp(`(@/[^/'"\\s\`]+)/${escapeRegExp(dir)}/`, "g"));
991
1030
  walkFiles(srcDir, (filePath) => {
992
1031
  const ext = path.extname(filePath);
993
1032
  if (!ALIAS_REWRITE_EXTENSIONS.has(ext)) return;
@@ -997,8 +1036,11 @@ function rewriteVariantAliasImports(srcDir, variant) {
997
1036
  } catch {
998
1037
  return;
999
1038
  }
1000
- if (!original.includes(`/${variant}/`)) return;
1001
- const replaced = original.replace(pattern, "$1/");
1039
+ if (!variantDirs.some((dir) => original.includes(`/${dir}/`))) return;
1040
+ let replaced = original;
1041
+ for (const pattern of patterns) {
1042
+ replaced = replaced.replace(pattern, "$1/");
1043
+ }
1002
1044
  if (replaced !== original) {
1003
1045
  fs.writeFileSync(filePath, replaced);
1004
1046
  }
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  preScanLang,
15
15
  setLang,
16
16
  t
17
- } from "./chunk-RTEZODLP.js";
17
+ } from "./chunk-CRXMV7GV.js";
18
18
 
19
19
  // src/createProgram.ts
20
20
  import { Command as Command4 } from "commander";
@@ -111,13 +111,7 @@ function renderUiSnippet(cli) {
111
111
  return `ui: ${renderCliObject(cli, "")},`;
112
112
  }
113
113
  function renderCliObject(cli, indent) {
114
- return [
115
- "{",
116
- //
117
- `${indent} framework: ${JSON.stringify(cli.framework)},`,
118
- `${indent} dir: ${JSON.stringify(cli.dir)},`,
119
- `${indent}}`
120
- ].join("\n");
114
+ return ["{", `${indent} framework: ${JSON.stringify(cli.framework)},`, `${indent} dir: ${JSON.stringify(cli.dir)},`, `${indent}}`].join("\n");
121
115
  }
122
116
 
123
117
  // src/commands/ui/fetcher.ts
@@ -853,6 +847,11 @@ async function resolveUiConfig(options) {
853
847
  return useUi ? promptUiConfig(uiOptions) : null;
854
848
  }
855
849
 
850
+ // src/commands/mockup.ts
851
+ function mockupCommand() {
852
+ logger.log(t("mockup.guide"));
853
+ }
854
+
856
855
  // src/createProgram.ts
857
856
  function createLismProgram() {
858
857
  const program2 = new Command4();
@@ -862,11 +861,12 @@ function createLismProgram() {
862
861
  const lang = opts.lang;
863
862
  if (typeof lang === "string") setLang(lang);
864
863
  });
865
- program2.command("create").description(t("cli.create.description")).argument("[targetDir]", t("cli.create.arg.targetDir")).option("-t, --template <name>", t("cli.create.opt.template")).option("-f, --force", t("cli.create.opt.force"), false).action(createCommand);
864
+ program2.command("create").description(t("cli.create.description")).argument("[targetDir]", t("cli.create.arg.targetDir")).option("-t, --template <name>", t("cli.create.opt.template")).option("-f, --force", t("cli.create.opt.force"), false).option("--ref <ref>", t("cli.create.opt.ref")).action(createCommand);
866
865
  const init = program2.command("init").description(t("cli.init.description"));
867
866
  applyUiSectionOptions(init).action(initCommand);
868
867
  program2.addCommand(createUiCommand());
869
868
  program2.addCommand(createSkillCommand());
869
+ program2.command("mockup").description(t("cli.mockup.description")).allowExcessArguments().action(mockupCommand);
870
870
  return program2;
871
871
  }
872
872
 
package/dist/lib.d.ts CHANGED
@@ -2,6 +2,8 @@ interface RunCreateArgs {
2
2
  template?: string;
3
3
  targetDir?: string;
4
4
  force?: boolean;
5
+ /** テンプレ取得元の Git ref。未指定なら `DEFAULT_TEMPLATES_REF`。 */
6
+ ref?: string;
5
7
  /**
6
8
  * 明示指定された言語(`--lang`)。`ja` / `en` のときその言語で CLI 表示・テンプレ生成を確定する。
7
9
  * 未指定(undefined / 不正値)の場合は、対話端末では最初に言語選択プロンプトを出し、
@@ -9,8 +11,7 @@ interface RunCreateArgs {
9
11
  */
10
12
  lang?: string;
11
13
  }
12
- /** `lism-cli create` / `create-lism` から共通で使える実体関数 */
13
- declare function runCreate({ template, targetDir, force, lang }: RunCreateArgs): Promise<void>;
14
+ declare function runCreate({ template, targetDir, force, lang, ref }: RunCreateArgs): Promise<void>;
14
15
 
15
16
  /**
16
17
  * CLI 表示用のメッセージ辞書(ja / en)。
@@ -21,6 +22,7 @@ declare function runCreate({ template, targetDir, force, lang }: RunCreateArgs):
21
22
  * - `init.*` … `lism-cli init` サブコマンド
22
23
  * - `ui.*` … `lism-cli ui` 配下
23
24
  * - `skill.*` … `lism-cli skill` 配下
25
+ * - `mockup.*` … `lism-cli mockup` 配下
24
26
  * - `config.*` … lism.config.* まわりのエラー・警告
25
27
  * - `common.*` … 汎用
26
28
  *
@@ -51,6 +53,10 @@ declare const messages: {
51
53
  readonly ja: "既存ディレクトリを強制上書き";
52
54
  readonly en: "Overwrite existing directory";
53
55
  };
56
+ readonly 'cli.create.opt.ref': {
57
+ readonly ja: "テンプレート取得元の Git ref(ブランチ / タグ / コミット)";
58
+ readonly en: "Git ref to fetch templates from (branch / tag / commit)";
59
+ };
54
60
  readonly 'cli.init.description': {
55
61
  readonly ja: "lism.config ファイルを新規生成する";
56
62
  readonly en: "Generate a new lism.config file";
@@ -91,6 +97,10 @@ declare const messages: {
91
97
  readonly ja: "取得元の Git ref(ブランチ / タグ / コミット)";
92
98
  readonly en: "Git ref to fetch from (branch / tag / commit)";
93
99
  };
100
+ readonly 'cli.mockup.description': {
101
+ readonly ja: "画面モックアップの案内を表示する(実体は @lism-css/mockup)";
102
+ readonly en: "Show guidance for mockups (provided by @lism-css/mockup)";
103
+ };
94
104
  readonly 'cli.skill.description': {
95
105
  readonly ja: "AI エージェント向けスキル(SKILL.md)の配置と管理";
96
106
  readonly en: "Manage SKILL.md files for AI agents";
@@ -327,6 +337,10 @@ declare const messages: {
327
337
  readonly ja: "合計: {count} コンポーネント";
328
338
  readonly en: "Total: {count} components";
329
339
  };
340
+ readonly 'mockup.guide': {
341
+ readonly ja: string;
342
+ readonly en: string;
343
+ };
330
344
  readonly 'skill.add.detected': {
331
345
  readonly ja: "検出した AI ツール: {list}";
332
346
  readonly en: "Detected AI tools: {list}";
@@ -443,11 +457,8 @@ declare const messages: {
443
457
  type MessageKey = keyof typeof messages;
444
458
 
445
459
  type Lang = 'ja' | 'en';
446
- /** 現在の言語を設定する(未知の値は無視) */
447
460
  declare function setLang(lang: string | undefined): void;
448
- /**
449
- * メッセージキーから現在の言語の文字列を取得し、必要に応じて `{name}` プレースホルダーを置換する。
450
- */
461
+ /** 現在の言語のメッセージを取得し、プレースホルダーを展開する。 */
451
462
  declare function t(key: MessageKey, vars?: Record<string, string | number>): string;
452
463
  /**
453
464
  * ロケール非依存の 2 言語オブジェクトから現在の言語の値を返す。
package/dist/lib.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  setLang,
4
4
  t,
5
5
  tOf
6
- } from "./chunk-RTEZODLP.js";
6
+ } from "./chunk-CRXMV7GV.js";
7
7
  export {
8
8
  runCreate,
9
9
  setLang,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lism-cli",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "CLI for scaffolding projects and adding UI components for Lism CSS / Lism UI.",
5
5
  "author": {
6
6
  "name": "ddryo",
@@ -39,16 +39,16 @@
39
39
  "url": "https://github.com/lism-css/lism-css/issues"
40
40
  },
41
41
  "dependencies": {
42
- "@inquirer/prompts": "^7.0.0",
43
- "commander": "^13.0.0",
44
- "giget": "^3.2.0",
45
- "jiti": "^2.6.1",
46
- "picocolors": "^1.1.0"
42
+ "@inquirer/prompts": "^7.10.1",
43
+ "commander": "^13.1.0",
44
+ "giget": "^3.3.0",
45
+ "jiti": "^2.7.0",
46
+ "picocolors": "^1.1.1"
47
47
  },
48
48
  "devDependencies": {
49
- "@types/node": "^25.5.0",
50
- "tsup": "^8.0.0",
51
- "typescript": "^5.8.3"
49
+ "@types/node": "^25.9.4",
50
+ "tsup": "^8.5.1",
51
+ "typescript": "^5.9.3"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=18.0.0"