cmx-sdk 0.2.9 → 0.2.10
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/dist/add-studio-YUDYE2OH.js +0 -0
- package/dist/chunk-7TDMLYBI.js +0 -0
- package/dist/chunk-EDXXR5BE.js +0 -0
- package/dist/chunk-FPQYL5GE.js +0 -0
- package/dist/chunk-IIQLQIDP.js +0 -0
- package/dist/chunk-NZQ6SBFS.js +0 -0
- package/dist/{chunk-EZMBZWH7.js → chunk-Y3S3K6M3.js} +73 -28
- package/dist/cli.js +2 -2
- package/dist/init-FLRQXJX4.js +0 -0
- package/dist/{interactive-menu-FYVOQSTL.js → interactive-menu-5PRQIESI.js} +1 -1
- package/dist/studio-HAS6DYLO.js +0 -0
- package/dist/{update-sdk-KJZ6VB4M.js → update-sdk-ZXMWQF3I.js} +2 -1
- package/dist/update-studio-TWCYSYIS.js +0 -0
- package/package.json +14 -16
- package/templates/AGENTS.md +0 -173
- package/templates/CLAUDE.md +0 -28
- package/templates/claude/commands/check.md +0 -64
- package/templates/claude/commands/next-action.md +0 -66
- package/templates/claude/skills/cmx-cache/SKILL.md +0 -50
- package/templates/claude/skills/cmx-cache/references/cache-patterns.md +0 -153
- package/templates/claude/skills/cmx-component/SKILL.md +0 -108
- package/templates/claude/skills/cmx-component/references/component-schema.md +0 -123
- package/templates/claude/skills/cmx-content/SKILL.md +0 -158
- package/templates/claude/skills/cmx-content/references/migration-patterns.md +0 -120
- package/templates/claude/skills/cmx-content/references/seed-patterns.md +0 -146
- package/templates/claude/skills/cmx-dev/SKILL.md +0 -266
- package/templates/claude/skills/cmx-dev/references/api-patterns.md +0 -220
- package/templates/claude/skills/cmx-dev/references/cli-reference.md +0 -54
- package/templates/claude/skills/cmx-form/SKILL.md +0 -103
- package/templates/claude/skills/cmx-form/references/form-template.md +0 -152
- package/templates/claude/skills/cmx-migrate/SKILL.md +0 -501
- package/templates/claude/skills/cmx-migrate/references/analysis-guide.md +0 -127
- package/templates/claude/skills/cmx-migrate/references/html-to-mdx.md +0 -99
- package/templates/claude/skills/cmx-migrate/references/intermediate-format.md +0 -196
- package/templates/claude/skills/cmx-migrate/references/tool-setup.md +0 -150
- package/templates/claude/skills/cmx-schema/SKILL.md +0 -159
- package/templates/claude/skills/cmx-schema/references/field-types.md +0 -164
- package/templates/claude/skills/cmx-schema/references/migration-scenarios.md +0 -44
- package/templates/claude/skills/cmx-seo/SKILL.md +0 -54
- package/templates/claude/skills/cmx-seo/references/seo-patterns.md +0 -216
- package/templates/claude/skills/cmx-style/SKILL.md +0 -48
- package/templates/claude/skills/cmx-style/references/style-patterns.md +0 -114
|
File without changes
|
package/dist/chunk-7TDMLYBI.js
CHANGED
|
File without changes
|
package/dist/chunk-EDXXR5BE.js
CHANGED
|
File without changes
|
package/dist/chunk-FPQYL5GE.js
CHANGED
|
File without changes
|
package/dist/chunk-IIQLQIDP.js
CHANGED
|
File without changes
|
package/dist/chunk-NZQ6SBFS.js
CHANGED
|
File without changes
|
|
@@ -6,15 +6,17 @@ import {
|
|
|
6
6
|
getAddDependencyCommand,
|
|
7
7
|
readSdkVersion
|
|
8
8
|
} from "./chunk-EDXXR5BE.js";
|
|
9
|
+
import {
|
|
10
|
+
cleanupTempFile,
|
|
11
|
+
downloadTarball
|
|
12
|
+
} from "./chunk-IIQLQIDP.js";
|
|
9
13
|
|
|
10
14
|
// src/commands/update-sdk.ts
|
|
11
15
|
import { execSync } from "child_process";
|
|
12
|
-
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
16
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
17
|
+
import { tmpdir } from "os";
|
|
13
18
|
import { dirname, join } from "path";
|
|
14
|
-
import {
|
|
15
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
16
|
-
var __dirname = dirname(__filename);
|
|
17
|
-
var SDK_ROOT = join(__dirname, "..", "..");
|
|
19
|
+
import { extract } from "tar";
|
|
18
20
|
function resolveRequestedVersion(version) {
|
|
19
21
|
if (version === void 0) return "latest";
|
|
20
22
|
const normalized = version.trim();
|
|
@@ -23,27 +25,25 @@ function resolveRequestedVersion(version) {
|
|
|
23
25
|
}
|
|
24
26
|
return normalized;
|
|
25
27
|
}
|
|
26
|
-
function
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
28
|
+
function readProjectCmxConfig(projectRoot) {
|
|
29
|
+
const envFiles = [".env.local", ".env"];
|
|
30
|
+
for (const envFile of envFiles) {
|
|
31
|
+
const envPath = join(projectRoot, envFile);
|
|
32
|
+
if (!existsSync(envPath)) continue;
|
|
33
|
+
try {
|
|
34
|
+
const content = readFileSync(envPath, "utf-8");
|
|
35
|
+
const apiUrl = content.match(/^CMX_API_URL=(.+)$/m)?.[1]?.trim();
|
|
36
|
+
const apiKey = content.match(/^CMX_API_KEY=(.+)$/m)?.[1]?.trim();
|
|
37
|
+
if (apiUrl && apiKey) {
|
|
38
|
+
return { apiUrl, apiKey };
|
|
39
|
+
}
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
41
44
|
}
|
|
42
|
-
function
|
|
43
|
-
const templatePath = join(SDK_ROOT, "templates", relativePath);
|
|
44
|
-
if (!existsSync(templatePath)) return;
|
|
45
|
+
function syncManagedFileFromContent(projectRoot, relativePath, templateContent) {
|
|
45
46
|
const destPath = join(projectRoot, relativePath);
|
|
46
|
-
const templateContent = readFileSync(templatePath, "utf-8");
|
|
47
47
|
if (!existsSync(destPath)) {
|
|
48
48
|
mkdirSync(dirname(destPath), { recursive: true });
|
|
49
49
|
writeFileSync(destPath, templateContent);
|
|
@@ -69,6 +69,40 @@ function syncManagedFile(projectRoot, relativePath) {
|
|
|
69
69
|
console.log(` \u2705 ${relativePath} \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F\uFF08${updatedBlocks} \u30D6\u30ED\u30C3\u30AF\uFF09`);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
+
async function syncFromApi(projectRoot, apiUrl, apiKey) {
|
|
73
|
+
const tmpFile = join(tmpdir(), `.tmp-starter-kit-${Date.now()}.tar.gz`);
|
|
74
|
+
const tmpExtractDir = join(tmpdir(), `.tmp-starter-kit-extract-${Date.now()}`);
|
|
75
|
+
try {
|
|
76
|
+
await downloadTarball(`${apiUrl}/api/v1/sdk/download/starter-kit`, tmpFile, {
|
|
77
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
78
|
+
});
|
|
79
|
+
mkdirSync(tmpExtractDir, { recursive: true });
|
|
80
|
+
await extract({
|
|
81
|
+
file: tmpFile,
|
|
82
|
+
cwd: tmpExtractDir,
|
|
83
|
+
strip: 1,
|
|
84
|
+
filter: (entryPath) => entryPath.includes("/.claude/") || entryPath.endsWith("/AGENTS.md") || entryPath.endsWith("/CLAUDE.md")
|
|
85
|
+
});
|
|
86
|
+
const extractedClaude = join(tmpExtractDir, ".claude");
|
|
87
|
+
if (existsSync(extractedClaude)) {
|
|
88
|
+
mkdirSync(join(projectRoot, ".claude"), { recursive: true });
|
|
89
|
+
cpSync(extractedClaude, join(projectRoot, ".claude"), { recursive: true, force: true });
|
|
90
|
+
console.log(" \u2705 .claude/ \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F");
|
|
91
|
+
}
|
|
92
|
+
for (const filename of ["AGENTS.md", "CLAUDE.md"]) {
|
|
93
|
+
const extractedFile = join(tmpExtractDir, filename);
|
|
94
|
+
if (existsSync(extractedFile)) {
|
|
95
|
+
syncManagedFileFromContent(projectRoot, filename, readFileSync(extractedFile, "utf-8"));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} finally {
|
|
99
|
+
cleanupTempFile(tmpFile);
|
|
100
|
+
try {
|
|
101
|
+
rmSync(tmpExtractDir, { recursive: true, force: true });
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
72
106
|
async function updateSdk(options = {}) {
|
|
73
107
|
console.log("\n cmx-sdk \u306E\u4F9D\u5B58\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u66F4\u65B0\u3057\u307E\u3059...\n");
|
|
74
108
|
const projectRoot = findProjectRoot();
|
|
@@ -103,10 +137,21 @@ async function updateSdk(options = {}) {
|
|
|
103
137
|
console.log("\n \u2705 cmx-sdk \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F\uFF01");
|
|
104
138
|
console.log(` \u66F4\u65B0\u5F8C\u30D0\u30FC\u30B8\u30E7\u30F3: ${updatedVersion ?? "\u4E0D\u660E"}`);
|
|
105
139
|
console.log("\n \u23F3 Claude Code \u30D5\u30A1\u30A4\u30EB\u3092\u66F4\u65B0\u4E2D...");
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
140
|
+
const cmxConfig = readProjectCmxConfig(projectRoot);
|
|
141
|
+
if (!cmxConfig) {
|
|
142
|
+
console.warn(" \u26A0\uFE0F CMX_API_URL / CMX_API_KEY \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
|
|
143
|
+
console.warn(" .env.local \u306B\u8A2D\u5B9A\u3059\u308B\u3068 .claude/ / AGENTS.md / CLAUDE.md \u3082\u81EA\u52D5\u66F4\u65B0\u3055\u308C\u307E\u3059\n");
|
|
144
|
+
} else {
|
|
145
|
+
try {
|
|
146
|
+
console.log(" \u23F3 \u30B9\u30BF\u30FC\u30BF\u30FC\u30AD\u30C3\u30C8\u304B\u3089\u6700\u65B0\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u5F97\u4E2D...");
|
|
147
|
+
await syncFromApi(projectRoot, cmxConfig.apiUrl, cmxConfig.apiKey);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error(
|
|
150
|
+
` \u274C Claude Code \u30D5\u30A1\u30A4\u30EB\u306E\u66F4\u65B0\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${error instanceof Error ? error.message : "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC"}
|
|
151
|
+
`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
110
155
|
console.log("\n \u6B21\u306E\u30B9\u30C6\u30C3\u30D7:");
|
|
111
156
|
console.log(" 1. \u578B\u751F\u6210\u3092\u518D\u5B9F\u884C");
|
|
112
157
|
console.log(" npx cmx-sdk codegen types");
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-FPQYL5GE.js";
|
|
8
8
|
import {
|
|
9
9
|
updateSdk
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Y3S3K6M3.js";
|
|
11
11
|
import "./chunk-NZQ6SBFS.js";
|
|
12
12
|
import "./chunk-EDXXR5BE.js";
|
|
13
13
|
import "./chunk-IIQLQIDP.js";
|
|
@@ -4204,7 +4204,7 @@ function requireApiCredentials() {
|
|
|
4204
4204
|
return { apiUrl, apiKey };
|
|
4205
4205
|
}
|
|
4206
4206
|
program.action(async () => {
|
|
4207
|
-
const { interactiveMenu } = await import("./interactive-menu-
|
|
4207
|
+
const { interactiveMenu } = await import("./interactive-menu-5PRQIESI.js");
|
|
4208
4208
|
await interactiveMenu();
|
|
4209
4209
|
});
|
|
4210
4210
|
program.command("init [project-name]").description("\u65B0\u3057\u3044 CMX \u30B5\u30A4\u30C8\u3092\u4F5C\u6210").option("--no-studio", "CMX Studio \u3092\u30B9\u30AD\u30C3\u30D7").option("--pm <manager>", "\u30D1\u30C3\u30B1\u30FC\u30B8\u30DE\u30CD\u30FC\u30B8\u30E3\u30FC (npm, pnpm, yarn)").option("--key <key>", "CMX API \u30AD\u30FC\uFF08\u5FC5\u9808\u3002\u672A\u6307\u5B9A\u6642\u306F\u30D7\u30ED\u30F3\u30D7\u30C8\u8868\u793A\uFF09").option("--api-url <url>", "CMX API \u30B5\u30FC\u30D0\u30FC\u306E URL").action(async (projectName, options) => {
|
package/dist/init-FLRQXJX4.js
CHANGED
|
File without changes
|
|
@@ -31,7 +31,7 @@ async function interactiveMenu() {
|
|
|
31
31
|
return updateStudio({});
|
|
32
32
|
}
|
|
33
33
|
case "update-sdk": {
|
|
34
|
-
const { updateSdk } = await import("./update-sdk-
|
|
34
|
+
const { updateSdk } = await import("./update-sdk-ZXMWQF3I.js");
|
|
35
35
|
return updateSdk({});
|
|
36
36
|
}
|
|
37
37
|
case "studio": {
|
package/dist/studio-HAS6DYLO.js
CHANGED
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cmx-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "CMX SDK - Official SDK for building content-driven websites with CMX",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
],
|
|
27
27
|
"files": [
|
|
28
28
|
"dist",
|
|
29
|
-
"templates",
|
|
30
29
|
"README.md"
|
|
31
30
|
],
|
|
32
31
|
"exports": {
|
|
@@ -35,19 +34,6 @@
|
|
|
35
34
|
"import": "./dist/index.js"
|
|
36
35
|
}
|
|
37
36
|
},
|
|
38
|
-
"scripts": {
|
|
39
|
-
"prebuild": "node scripts/copy-api-client.js",
|
|
40
|
-
"sync:starter-kit-docs": "pnpm --filter @cmx/api-server generate:openapi && node scripts/sync-starter-kit-docs.mjs --write",
|
|
41
|
-
"sync:starter-kit-docs:check": "pnpm --filter @cmx/api-server generate:openapi && node scripts/sync-starter-kit-docs.mjs --check",
|
|
42
|
-
"check:sdk-command-api-usage": "node scripts/check-sdk-command-api-usage.mjs",
|
|
43
|
-
"check:generated-sync": "node scripts/check-generated-sync.mjs",
|
|
44
|
-
"test:contracts": "tsx scripts/check-cli-contracts.ts",
|
|
45
|
-
"verify:release": "pnpm run check:sdk-command-api-usage && pnpm run check:generated-sync && pnpm run test:contracts",
|
|
46
|
-
"build": "tsup",
|
|
47
|
-
"dev": "tsup --watch",
|
|
48
|
-
"typecheck": "tsc --noEmit",
|
|
49
|
-
"prepublishOnly": "pnpm run verify:release && pnpm run sync:starter-kit-docs:check && pnpm run build"
|
|
50
|
-
},
|
|
51
37
|
"dependencies": {
|
|
52
38
|
"@inquirer/prompts": "^8.2.1",
|
|
53
39
|
"@mdx-js/mdx": "^3.1.1",
|
|
@@ -70,5 +56,17 @@
|
|
|
70
56
|
"tsup": "^8.5.1",
|
|
71
57
|
"tsx": "^4.21.0",
|
|
72
58
|
"typescript": "^5.9.3"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"prebuild": "node scripts/copy-api-client.js",
|
|
62
|
+
"sync:starter-kit-docs": "pnpm --filter @cmx/api-server generate:openapi && node scripts/sync-starter-kit-docs.mjs --write",
|
|
63
|
+
"sync:starter-kit-docs:check": "pnpm --filter @cmx/api-server generate:openapi && node scripts/sync-starter-kit-docs.mjs --check",
|
|
64
|
+
"check:sdk-command-api-usage": "node scripts/check-sdk-command-api-usage.mjs",
|
|
65
|
+
"check:generated-sync": "node scripts/check-generated-sync.mjs",
|
|
66
|
+
"test:contracts": "tsx scripts/check-cli-contracts.ts",
|
|
67
|
+
"verify:release": "pnpm run check:sdk-command-api-usage && pnpm run check:generated-sync && pnpm run test:contracts",
|
|
68
|
+
"build": "tsup",
|
|
69
|
+
"dev": "tsup --watch",
|
|
70
|
+
"typecheck": "tsc --noEmit"
|
|
73
71
|
}
|
|
74
|
-
}
|
|
72
|
+
}
|
package/templates/AGENTS.md
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
# CMX Starter Kit — AI Agent Instructions
|
|
2
|
-
|
|
3
|
-
このファイルはAIコーディングエージェント(Claude Code, Cursor, GitHub Copilot, Google Jules 等)向けの共通指示書です。
|
|
4
|
-
|
|
5
|
-
> **注意:** `<!-- cmx-sdk:start -->` ~ `<!-- cmx-sdk:end -->` の範囲は `npx cmx-sdk update-sdk` で自動更新されます。
|
|
6
|
-
> その範囲外はカスタマイズ可能です。
|
|
7
|
-
|
|
8
|
-
## サイト設定
|
|
9
|
-
|
|
10
|
-
サイト固有の設定は以下を参照:
|
|
11
|
-
|
|
12
|
-
→ cmx/site-config.md — 開発方針(種別・トーン・デザイン方針・禁止事項)
|
|
13
|
-
→ cmx-workflow/style-guide.md — 執筆ルール(文体・用語・記事構成、別配布)
|
|
14
|
-
|
|
15
|
-
すべてのコード変更・提案は site-config.md の方針と矛盾しないことを確認すること。
|
|
16
|
-
コンテンツ生成時は style-guide.md のトーン・フォーマットに従うこと。
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
<!-- cmx-sdk:start id="architecture" -->
|
|
21
|
-
## アーキテクチャ
|
|
22
|
-
|
|
23
|
-
CMX Starter Kit はヘッドレスCMSのフロントエンドテンプレートです。
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
CMX Admin(サービス側) Starter Kit(このリポジトリ)
|
|
27
|
-
┌─────────────────────┐ ┌──────────────────────────┐
|
|
28
|
-
│ コレクション / データタイプ │ Public │ Next.js 16 (App Router) │
|
|
29
|
-
│ 投稿 / アセット / フォーム │ API │ cmx-sdk でデータ取得 │
|
|
30
|
-
│ │◄─────────│ Cloudflare Workers デプロイ │
|
|
31
|
-
│ APIキー ─────────────────────────│ .env の CMX_API_KEY で認証 │
|
|
32
|
-
└─────────────────────┘ └──────────────────────────┘
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### 厳守ルール
|
|
36
|
-
|
|
37
|
-
- **すべてのデータ取得は `cmx-sdk` 経由。** DB直接アクセスは存在しない
|
|
38
|
-
- **サーバーコンポーネントがデフォルト。** クライアントコンポーネントは必要最小限に
|
|
39
|
-
- **CMXデータを取得するページには `export const dynamic = "force-dynamic"` を必ず付ける**
|
|
40
|
-
- **MDXレンダリングは `src/lib/mdx/render.tsx` の `renderMdx` を使う。** 独自のMDX処理を書かない
|
|
41
|
-
- **カスタムコンポーネントは `src/components/custom/index.ts` から export する。** export すれば MDX 内で自動的に使用可能になる
|
|
42
|
-
- **`cmx/generated/` 配下のファイルは手動編集禁止。** `npx cmx-sdk codegen types` で再生成する
|
|
43
|
-
|
|
44
|
-
### 独自実装の禁止
|
|
45
|
-
|
|
46
|
-
- **独自の API クライアントや fetch ラッパーを作成しない。** `cmx-sdk` と `@/lib/` 配下の既存関数のみ使用する
|
|
47
|
-
- **`cmx-sdk` にない機能が必要な場合、独自実装せずユーザーに相談する**
|
|
48
|
-
|
|
49
|
-
### エラー時の行動規範
|
|
50
|
-
|
|
51
|
-
1. **1回リトライ**する
|
|
52
|
-
2. リトライでも解決しない場合、**代替手段を勝手に実装せず、ユーザーに報告して確認を取る**
|
|
53
|
-
<!-- cmx-sdk:end -->
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
<!-- cmx-sdk:start id="env-vars" -->
|
|
58
|
-
## 環境変数
|
|
59
|
-
|
|
60
|
-
| 変数名 | 必須 | 説明 |
|
|
61
|
-
|--------|------|------|
|
|
62
|
-
| `CMX_API_KEY` | 必須 | CMX Admin で発行した API キー |
|
|
63
|
-
| `CMX_API_URL` | 必須 | CMX Admin インスタンスの URL |
|
|
64
|
-
| `CMX_WORKSPACE_ID` | 任意 | ワークスペースID(APIキーから自動判定) |
|
|
65
|
-
| `NEXT_PUBLIC_SITE_URL` | 必須 | 公開サイトの URL |
|
|
66
|
-
| `REVALIDATE_API_KEY` | 任意 | リバリデーション用の秘密鍵 |
|
|
67
|
-
<!-- cmx-sdk:end -->
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
<!-- cmx-sdk:start id="commands" -->
|
|
72
|
-
## コマンド
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
pnpm dev # 開発サーバー起動(Turbopack, port 4000)
|
|
76
|
-
pnpm build # Next.js ビルド
|
|
77
|
-
pnpm build:cf # Cloudflare Workers 向けビルド
|
|
78
|
-
pnpm deploy # Cloudflare Workers デプロイ
|
|
79
|
-
pnpm typecheck # TypeScript 型チェック
|
|
80
|
-
pnpm lint # ESLint
|
|
81
|
-
npx cmx-sdk sync-components # カスタムコンポーネントを Admin に同期
|
|
82
|
-
npx cmx-sdk components scaffold --name FeatureCard # コンポーネント雛形を生成
|
|
83
|
-
npx cmx-sdk codegen types # スキーマから型付きコードを自動生成
|
|
84
|
-
npx cmx-sdk codegen pages --template layered # ページ雛形(resolver/meta/view分離)を生成
|
|
85
|
-
npx cmx-sdk codegen check # 生成コードと import/tsconfig の整合を検証
|
|
86
|
-
npx cmx-sdk codegen all # types → pages → check を一括実行
|
|
87
|
-
npx cmx-sdk mdx validate # MDX本文の構文/禁止構文/props を検証
|
|
88
|
-
npx cmx-sdk mdx doctor # MDX定義JSONと実装/exportの整合を検証
|
|
89
|
-
npx cmx-sdk create-collection --json '...' # コレクションを API 経由で作成
|
|
90
|
-
npx cmx-sdk create-data-type --json '...' # データタイプを API 経由で作成
|
|
91
|
-
npx cmx-sdk create-data-entry --type-slug {slug} --json '...' # データエントリを作成
|
|
92
|
-
npx cmx-sdk list-collection-data-types --collection {slug} # コレクションの付属データタイプ一覧
|
|
93
|
-
npx cmx-sdk list-collection-presets --type {type} # プリセット一覧(おすすめ/その他)
|
|
94
|
-
npx cmx-sdk update-sdk # SDK・コマンド・スキルを最新版に更新
|
|
95
|
-
```
|
|
96
|
-
<!-- cmx-sdk:end -->
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
<!-- cmx-sdk:start id="setup-flow" -->
|
|
101
|
-
## 開発フロー
|
|
102
|
-
|
|
103
|
-
### 初期構築
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
1. サイトコンフィグ作成 cmx/site-config.md を作成
|
|
107
|
-
2. 環境セットアップ .env.local 設定 → pnpm install → pnpm dev
|
|
108
|
-
3. スキーマ設計 コレクション・データタイプの JSON 定義を作成
|
|
109
|
-
→ create-collection / create-data-type コマンドで登録
|
|
110
|
-
4. テストデータ投入 Admin 側でコンテンツを作成し「公開」にする
|
|
111
|
-
5. コード生成 npx cmx-sdk codegen types で型付き関数を生成
|
|
112
|
-
6. 雛形生成(任意) npx cmx-sdk codegen pages --template layered
|
|
113
|
-
7. ページ実装 一覧ページ・詳細ページ・静的ページを作成
|
|
114
|
-
8. コンポーネント作成 MDX 用カスタムコンポーネントを定義・実装・同期
|
|
115
|
-
9. デプロイ pnpm build:cf && pnpm deploy
|
|
116
|
-
```
|
|
117
|
-
<!-- cmx-sdk:end -->
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
<!-- cmx-sdk:start id="api-patterns" -->
|
|
122
|
-
## API パターン
|
|
123
|
-
|
|
124
|
-
### データ取得
|
|
125
|
-
|
|
126
|
-
```tsx
|
|
127
|
-
// cmx-sdk 直接(汎用)
|
|
128
|
-
import { getCollectionContents, getCollectionContentDetail, getDataEntries, getDataEntry } from "cmx-sdk"
|
|
129
|
-
|
|
130
|
-
// re-export 経由(推奨)
|
|
131
|
-
import { getCollectionContents, getCollectionContentDetail, getDataEntries } from "@/lib/api/admin-client"
|
|
132
|
-
|
|
133
|
-
// エラー時 throw するラッパー(ページで使用)
|
|
134
|
-
import { requireFetchContents, requireFetchContent, requireDataEntries } from "@/lib/utils/data-fetching"
|
|
135
|
-
|
|
136
|
-
// 型付き自動生成関数(npx cmx-sdk codegen types 後)
|
|
137
|
-
import { getBlogContents, getBlogContentDetail } from "@cmx/generated"
|
|
138
|
-
import { getStaff, getStaffById } from "@cmx/generated"
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### ページテンプレート: コレクション一覧
|
|
142
|
-
|
|
143
|
-
```tsx
|
|
144
|
-
// src/app/{collection}/page.tsx
|
|
145
|
-
import { COLLECTION_SLUGS } from "@/lib/constants/collections"
|
|
146
|
-
import { requireFetchContents } from "@/lib/utils/data-fetching"
|
|
147
|
-
|
|
148
|
-
export const dynamic = "force-dynamic"
|
|
149
|
-
|
|
150
|
-
export default async function ListPage() {
|
|
151
|
-
const { collection, contents } = await requireFetchContents(COLLECTION_SLUGS.xxx)
|
|
152
|
-
return (/* 一覧 UI */)
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### ページテンプレート: コレクション詳細
|
|
157
|
-
|
|
158
|
-
```tsx
|
|
159
|
-
// src/app/{collection}/[slug]/page.tsx
|
|
160
|
-
import { COLLECTION_SLUGS } from "@/lib/constants/collections"
|
|
161
|
-
import { requireFetchContent } from "@/lib/utils/data-fetching"
|
|
162
|
-
import { renderMdx } from "@/lib/mdx/render"
|
|
163
|
-
|
|
164
|
-
export const dynamic = "force-dynamic"
|
|
165
|
-
|
|
166
|
-
export default async function DetailPage({ params }: { params: Promise<{ slug: string }> }) {
|
|
167
|
-
const { slug } = await params
|
|
168
|
-
const { content, references } = await requireFetchContent(COLLECTION_SLUGS.xxx, slug)
|
|
169
|
-
const { content: rendered } = await renderMdx(content.mdx, references)
|
|
170
|
-
return <article className="prose prose-lg max-w-none">{rendered}</article>
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
<!-- cmx-sdk:end -->
|
package/templates/CLAUDE.md
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Claude Code 設定
|
|
2
|
-
|
|
3
|
-
> **注意:** `<!-- cmx-sdk:start -->` ~ `<!-- cmx-sdk:end -->` の範囲は `npx cmx-sdk update-sdk` で自動更新されます。
|
|
4
|
-
> その範囲外はカスタマイズ可能です。
|
|
5
|
-
|
|
6
|
-
<!-- cmx-sdk:start id="project-rules" -->
|
|
7
|
-
## プロジェクトルール
|
|
8
|
-
|
|
9
|
-
CMX Starter Kit のルール・アーキテクチャ・API パターンは `AGENTS.md` を参照。
|
|
10
|
-
|
|
11
|
-
### コミット前
|
|
12
|
-
|
|
13
|
-
変更を加えたらコミット前に必ずチェックを実行:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
pnpm typecheck # TypeScript 型チェック
|
|
17
|
-
pnpm build # ビルド確認
|
|
18
|
-
npx cmx-sdk codegen check # 生成コード整合チェック
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
または Studio の「チェック」ボタンを使用。
|
|
22
|
-
<!-- cmx-sdk:end -->
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## プロジェクト固有の設定
|
|
27
|
-
|
|
28
|
-
<!-- ここにプロジェクト固有のルールやメモを追記してください -->
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Check
|
|
3
|
-
description: ビルド・型・整合性を一括チェック
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
allowed-tools: Bash
|
|
6
|
-
continuation-mode: auto
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Check(ビルド・整合性チェック)
|
|
10
|
-
|
|
11
|
-
## 実行内容
|
|
12
|
-
|
|
13
|
-
以下をこの順番で実行する。エラーがあれば即座に報告して止まる。
|
|
14
|
-
|
|
15
|
-
### 1. TypeScript 型チェック
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
pnpm typecheck
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### 2. ビルド確認
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
pnpm build
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### 3. 生成コードと import/tsconfig の整合チェック
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npx cmx-sdk codegen check
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## 出力フォーマット
|
|
34
|
-
|
|
35
|
-
成功時:
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
## チェック結果
|
|
39
|
-
|
|
40
|
-
- [x] TypeScript: 型エラーなし
|
|
41
|
-
- [x] ビルド: 成功
|
|
42
|
-
- [x] 整合性: 問題なし
|
|
43
|
-
|
|
44
|
-
✅ すべてのチェックが通りました。
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
エラー時:
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
## チェック結果
|
|
51
|
-
|
|
52
|
-
- [x] TypeScript: 型エラーなし
|
|
53
|
-
- [ ] ビルド: ❌ エラー {n} 件
|
|
54
|
-
- [ ] 整合性: スキップ(ビルドエラーのため)
|
|
55
|
-
|
|
56
|
-
修正すべき箇所:
|
|
57
|
-
1. {ファイル名}:{行番号} - {エラー内容}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## ルール
|
|
61
|
-
|
|
62
|
-
- エラーが出たステップで止め、以降のステップはスキップする
|
|
63
|
-
- エラー内容は要約せず、そのまま出力する
|
|
64
|
-
- 修正案がある場合は箇条書きで提示する
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Next Action
|
|
3
|
-
description: 迷ったときに現在地を確認し、次にやるべきことを案内
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
allowed-tools: Bash, Read, Glob, Grep
|
|
6
|
-
continuation-mode: auto
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Next Action
|
|
10
|
-
|
|
11
|
-
## チェック項目
|
|
12
|
-
|
|
13
|
-
### 環境
|
|
14
|
-
|
|
15
|
-
- `.env.local` が存在するか
|
|
16
|
-
- `CMX_API_KEY` が設定されているか
|
|
17
|
-
|
|
18
|
-
### サイトコンフィグ
|
|
19
|
-
|
|
20
|
-
- `cmx/site-config.md` が記入済みか(「未設定」が残っていないか)
|
|
21
|
-
|
|
22
|
-
### スキーマ
|
|
23
|
-
|
|
24
|
-
- `src/lib/constants/collections.ts` の登録スラッグ一覧
|
|
25
|
-
- `cmx/generated/` の生成済みファイル一覧
|
|
26
|
-
- 両者の不一致がないか
|
|
27
|
-
|
|
28
|
-
### ページ
|
|
29
|
-
|
|
30
|
-
- `src/app/` 配下のページ一覧
|
|
31
|
-
- 登録済みコレクションに対応するページが全て存在するか
|
|
32
|
-
- データタイプに対応するページが存在するか
|
|
33
|
-
|
|
34
|
-
### コンポーネント
|
|
35
|
-
|
|
36
|
-
- `cmx/components/` の JSON 定義一覧
|
|
37
|
-
- `src/components/custom/index.ts` のエクスポート一覧
|
|
38
|
-
- 定義と実装の不一致がないか
|
|
39
|
-
|
|
40
|
-
## 判定ルール
|
|
41
|
-
|
|
42
|
-
- 未完了(✗ または △)の項目が1つでもある場合は、未完了優先で次アクションを案内する
|
|
43
|
-
- すべて完了(✓)の場合は、保守・改善フェーズ向けの追加提案を出す
|
|
44
|
-
|
|
45
|
-
## 出力フォーマット
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
## Next Action(現在地)
|
|
49
|
-
|
|
50
|
-
- [x] 環境: 設定済み
|
|
51
|
-
- [ ] サイトコンフィグ: 一部未設定(未設定: {項目名...})
|
|
52
|
-
- [x] スキーマ: 整合済み(コレクション {n} / データタイプ {n})
|
|
53
|
-
- [ ] ページ: 未実装 {n} 件({slug...})
|
|
54
|
-
- [x] コンポーネント: 整合済み(定義 {n} / 実装 {n})
|
|
55
|
-
|
|
56
|
-
### Next Action(最優先)
|
|
57
|
-
- {1件だけ。具体的なコマンド付きで提示}
|
|
58
|
-
例: `/setup/05_pages` で未実装ページを作成する
|
|
59
|
-
|
|
60
|
-
### 追加提案
|
|
61
|
-
- 未完了がある場合:
|
|
62
|
-
- 未完了項目に直結する提案を最大2件
|
|
63
|
-
- すべて完了している場合:
|
|
64
|
-
- 保守・改善に進む提案を最大2件
|
|
65
|
-
- 例: `/maintain/component`, `/maintain/style`, `/deploy`
|
|
66
|
-
```
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: cmx-cache
|
|
3
|
-
description: |
|
|
4
|
-
CMX Starter Kit のキャッシュ戦略スキル。force-dynamic → ISR 切り替え、sdkFetchWithTags、CACHE_TAGS、リバリデーション設定、Cloudflare R2 キャッシュ。
|
|
5
|
-
トリガー: 「キャッシュを設定」「ISRに切り替え」「リバリデーションを設定」
|
|
6
|
-
「force-dynamicを外す」「キャッシュタグを設定」「パフォーマンス改善」
|
|
7
|
-
「ページの表示速度を上げたい」「キャッシュ戦略」「R2キャッシュ」
|
|
8
|
-
「revalidateを設定」「オンデマンド再検証」など。
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# CMX キャッシュ戦略
|
|
12
|
-
|
|
13
|
-
## 現状の構成
|
|
14
|
-
|
|
15
|
-
スターターキットの初期状態は全ページ `export const dynamic = "force-dynamic"`(毎リクエスト SSR)。ISR 基盤(R2 バケット、リバリデーション API)は構築済み。
|
|
16
|
-
|
|
17
|
-
## ISR 移行の判断基準
|
|
18
|
-
|
|
19
|
-
| 条件 | 推奨 |
|
|
20
|
-
|------|------|
|
|
21
|
-
| コンテンツ更新頻度が低い | ISR(revalidate: 3600 等) |
|
|
22
|
-
| リアルタイム性が必要 | force-dynamic のまま |
|
|
23
|
-
| プレビューページ | 常に force-dynamic |
|
|
24
|
-
| 静的ページ(about 等) | ISR(revalidate: 86400)または静的生成 |
|
|
25
|
-
|
|
26
|
-
## 移行手順
|
|
27
|
-
|
|
28
|
-
詳細は [references/cache-patterns.md](references/cache-patterns.md) を参照。
|
|
29
|
-
|
|
30
|
-
### 1. ページの revalidate 設定
|
|
31
|
-
|
|
32
|
-
`export const dynamic = "force-dynamic"` を削除し `export const revalidate = 秒数` に変更。
|
|
33
|
-
|
|
34
|
-
### 2. タグ付き fetch に切り替え
|
|
35
|
-
|
|
36
|
-
`sdkFetchWithTags` を使い、CACHE_TAGS でタグを付与。
|
|
37
|
-
|
|
38
|
-
### 3. リバリデーション API の確認
|
|
39
|
-
|
|
40
|
-
`/api/revalidate` エンドポイントが動作することを確認。`REVALIDATE_API_KEY` 環境変数が必要。
|
|
41
|
-
|
|
42
|
-
### 4. Cloudflare R2 の確認
|
|
43
|
-
|
|
44
|
-
`wrangler.jsonc` で R2 バケットバインディング `NEXT_INC_CACHE_R2_BUCKET` が設定済みか確認。
|
|
45
|
-
|
|
46
|
-
## 変更後
|
|
47
|
-
|
|
48
|
-
1. デプロイ後にページの `Cache-Control` ヘッダーを確認
|
|
49
|
-
2. コンテンツ更新後にリバリデーションが動作することを確認
|
|
50
|
-
3. プレビューページが常に最新データを返すことを確認
|