cmx-sdk 0.2.9 → 0.2.11

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.
Files changed (43) hide show
  1. package/README.md +37 -1
  2. package/dist/add-studio-YUDYE2OH.js +0 -0
  3. package/dist/chunk-7TDMLYBI.js +0 -0
  4. package/dist/chunk-EDXXR5BE.js +0 -0
  5. package/dist/chunk-FPQYL5GE.js +0 -0
  6. package/dist/chunk-IIQLQIDP.js +0 -0
  7. package/dist/chunk-NZQ6SBFS.js +0 -0
  8. package/dist/{chunk-EZMBZWH7.js → chunk-Y3S3K6M3.js} +73 -28
  9. package/dist/cli.js +215 -3
  10. package/dist/init-FLRQXJX4.js +0 -0
  11. package/dist/{interactive-menu-FYVOQSTL.js → interactive-menu-PYMJB5LY.js} +4 -1
  12. package/dist/studio-HAS6DYLO.js +0 -0
  13. package/dist/{update-sdk-KJZ6VB4M.js → update-sdk-ZXMWQF3I.js} +2 -1
  14. package/dist/update-studio-TWCYSYIS.js +0 -0
  15. package/package.json +14 -16
  16. package/templates/AGENTS.md +0 -173
  17. package/templates/CLAUDE.md +0 -28
  18. package/templates/claude/commands/check.md +0 -64
  19. package/templates/claude/commands/next-action.md +0 -66
  20. package/templates/claude/skills/cmx-cache/SKILL.md +0 -50
  21. package/templates/claude/skills/cmx-cache/references/cache-patterns.md +0 -153
  22. package/templates/claude/skills/cmx-component/SKILL.md +0 -108
  23. package/templates/claude/skills/cmx-component/references/component-schema.md +0 -123
  24. package/templates/claude/skills/cmx-content/SKILL.md +0 -158
  25. package/templates/claude/skills/cmx-content/references/migration-patterns.md +0 -120
  26. package/templates/claude/skills/cmx-content/references/seed-patterns.md +0 -146
  27. package/templates/claude/skills/cmx-dev/SKILL.md +0 -266
  28. package/templates/claude/skills/cmx-dev/references/api-patterns.md +0 -220
  29. package/templates/claude/skills/cmx-dev/references/cli-reference.md +0 -54
  30. package/templates/claude/skills/cmx-form/SKILL.md +0 -103
  31. package/templates/claude/skills/cmx-form/references/form-template.md +0 -152
  32. package/templates/claude/skills/cmx-migrate/SKILL.md +0 -501
  33. package/templates/claude/skills/cmx-migrate/references/analysis-guide.md +0 -127
  34. package/templates/claude/skills/cmx-migrate/references/html-to-mdx.md +0 -99
  35. package/templates/claude/skills/cmx-migrate/references/intermediate-format.md +0 -196
  36. package/templates/claude/skills/cmx-migrate/references/tool-setup.md +0 -150
  37. package/templates/claude/skills/cmx-schema/SKILL.md +0 -159
  38. package/templates/claude/skills/cmx-schema/references/field-types.md +0 -164
  39. package/templates/claude/skills/cmx-schema/references/migration-scenarios.md +0 -44
  40. package/templates/claude/skills/cmx-seo/SKILL.md +0 -54
  41. package/templates/claude/skills/cmx-seo/references/seo-patterns.md +0 -216
  42. package/templates/claude/skills/cmx-style/SKILL.md +0 -48
  43. package/templates/claude/skills/cmx-style/references/style-patterns.md +0 -114
package/README.md CHANGED
@@ -223,6 +223,42 @@ npx cmx-sdk mdx validate --file src/content/post.mdx
223
223
  npx cmx-sdk mdx doctor
224
224
  ```
225
225
 
226
+ ### Asset Upload (CLI)
227
+
228
+ ```bash
229
+ # Basic upload
230
+ npx cmx-sdk upload-asset --file ./public/images/logo.png
231
+
232
+ # With metadata
233
+ npx cmx-sdk upload-asset \
234
+ --file ./public/images/hero.webp \
235
+ --alt "トップページヒーロー画像" \
236
+ --description "2026 Spring campaign" \
237
+ --group landing-page \
238
+ --tags lp,hero,spring
239
+
240
+ # List assets
241
+ npx cmx-sdk list-assets --group landing-page --tags lp,hero --query "hero"
242
+
243
+ # Update asset metadata
244
+ npx cmx-sdk update-asset \
245
+ --id 123e4567-e89b-12d3-a456-426614174000 \
246
+ --alt "更新後の代替テキスト" \
247
+ --description "更新後の説明" \
248
+ --group landing-page \
249
+ --tags lp,hero,updated
250
+
251
+ # Clear group/tags
252
+ npx cmx-sdk update-asset \
253
+ --id 123e4567-e89b-12d3-a456-426614174000 \
254
+ --clear-group \
255
+ --clear-tags
256
+ ```
257
+
258
+ `upload-asset` / `list-assets` / `update-asset` は MCP Assets API (`/api/mcp/assets*`) を使用します。
259
+ - `list-assets`: `assets:read`
260
+ - `upload-asset`, `update-asset`: `assets:write`
261
+
226
262
  ### Starter Kit Maintenance
227
263
 
228
264
  ```bash
@@ -236,7 +272,7 @@ npx cmx-sdk update-studio --force
236
272
  npx cmx-sdk update-sdk
237
273
 
238
274
  # Pin to a specific version or tag
239
- npx cmx-sdk update-sdk --version 0.2.6
275
+ npx cmx-sdk update-sdk --version 0.2.11
240
276
  ```
241
277
 
242
278
  ### Requirements
File without changes
File without changes
File without changes
File without changes
File without changes
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 { fileURLToPath } from "url";
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 syncClaudeCommands(projectRoot) {
27
- const templatesDir = join(SDK_ROOT, "templates", "claude", "commands");
28
- if (!existsSync(templatesDir)) return;
29
- const destDir = join(projectRoot, ".claude", "commands");
30
- mkdirSync(destDir, { recursive: true });
31
- cpSync(templatesDir, destDir, { recursive: true, force: true });
32
- console.log(" \u2705 .claude/commands \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F");
33
- }
34
- function syncClaudeSkills(projectRoot) {
35
- const templatesDir = join(SDK_ROOT, "templates", "claude", "skills");
36
- if (!existsSync(templatesDir)) return;
37
- const destDir = join(projectRoot, ".claude", "skills");
38
- mkdirSync(destDir, { recursive: true });
39
- cpSync(templatesDir, destDir, { recursive: true, force: true });
40
- console.log(" \u2705 .claude/skills \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F");
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 syncManagedFile(projectRoot, relativePath) {
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
- syncClaudeCommands(projectRoot);
107
- syncClaudeSkills(projectRoot);
108
- syncManagedFile(projectRoot, "AGENTS.md");
109
- syncManagedFile(projectRoot, "CLAUDE.md");
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-EZMBZWH7.js";
10
+ } from "./chunk-Y3S3K6M3.js";
11
11
  import "./chunk-NZQ6SBFS.js";
12
12
  import "./chunk-EDXXR5BE.js";
13
13
  import "./chunk-IIQLQIDP.js";
@@ -4189,11 +4189,220 @@ async function getDataEntryDeletionImpact(options) {
4189
4189
  }
4190
4190
  }
4191
4191
 
4192
+ // src/commands/upload-asset.ts
4193
+ import { readFile } from "fs/promises";
4194
+ import { basename as basename2, extname as extname4 } from "path";
4195
+ var MIME_BY_EXTENSION = {
4196
+ ".jpg": "image/jpeg",
4197
+ ".jpeg": "image/jpeg",
4198
+ ".png": "image/png",
4199
+ ".gif": "image/gif",
4200
+ ".webp": "image/webp",
4201
+ ".svg": "image/svg+xml"
4202
+ };
4203
+ function resolveMimeType(filePath, mimeOption) {
4204
+ const explicitMime = mimeOption?.trim();
4205
+ if (explicitMime) return explicitMime;
4206
+ const ext = extname4(filePath).toLowerCase();
4207
+ const inferred = MIME_BY_EXTENSION[ext];
4208
+ if (inferred) return inferred;
4209
+ throw new Error(
4210
+ `MIME type \u3092\u5224\u5B9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: ${filePath}\u3002--mime \u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: image/png\uFF09`
4211
+ );
4212
+ }
4213
+ function parseJsonSafely(raw) {
4214
+ if (!raw) return {};
4215
+ try {
4216
+ return JSON.parse(raw);
4217
+ } catch {
4218
+ return null;
4219
+ }
4220
+ }
4221
+ async function uploadAsset(options) {
4222
+ ensureApiCredentials();
4223
+ if (!options.file) {
4224
+ console.error("\u30A8\u30E9\u30FC: --file \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044");
4225
+ process.exit(1);
4226
+ }
4227
+ const apiUrl = process.env.CMX_API_URL.replace(/\/$/, "");
4228
+ const apiKey = process.env.CMX_API_KEY;
4229
+ try {
4230
+ const fileBuffer = await readFile(options.file);
4231
+ const mimeType = resolveMimeType(options.file, options.mime);
4232
+ const formData = new FormData();
4233
+ formData.append("file", new Blob([fileBuffer], { type: mimeType }), basename2(options.file));
4234
+ if (options.alt) formData.append("alt", options.alt);
4235
+ if (options.description) formData.append("description", options.description);
4236
+ if (options.group) formData.append("group", options.group);
4237
+ if (options.tags) formData.append("tags", options.tags);
4238
+ console.log(`\u30A2\u30BB\u30C3\u30C8\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u3066\u3044\u307E\u3059: ${options.file}...`);
4239
+ const response = await fetch(`${apiUrl}/api/mcp/assets`, {
4240
+ method: "POST",
4241
+ headers: {
4242
+ Authorization: `Bearer ${apiKey}`
4243
+ },
4244
+ body: formData
4245
+ });
4246
+ const rawBody = await response.text();
4247
+ if (!response.ok) {
4248
+ throw new Error(`API \u30A8\u30E9\u30FC (${response.status}): ${formatApiErrorMessage(rawBody)}`);
4249
+ }
4250
+ const parsed = parseJsonSafely(rawBody);
4251
+ if (!parsed || typeof parsed !== "object") {
4252
+ throw new Error("API \u5FDC\u7B54\u306E JSON \u89E3\u6790\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
4253
+ }
4254
+ const payload = parsed;
4255
+ console.log("\u30A2\u30BB\u30C3\u30C8\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u307E\u3057\u305F:");
4256
+ console.log(JSON.stringify(parsed, null, 2));
4257
+ if (payload.asset?.id) console.log(`
4258
+ \u30A2\u30BB\u30C3\u30C8 ID: ${payload.asset.id}`);
4259
+ if (payload.asset?.url) console.log(`\u30A2\u30BB\u30C3\u30C8 URL: ${payload.asset.url}`);
4260
+ } catch (error) {
4261
+ console.error("\u2717 \u30A2\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F:");
4262
+ console.error(error instanceof Error ? error.message : String(error));
4263
+ process.exit(1);
4264
+ }
4265
+ }
4266
+
4267
+ // src/commands/list-assets.ts
4268
+ function parseIntegerOption(label, value) {
4269
+ if (value === void 0) return void 0;
4270
+ const parsed = Number.parseInt(value, 10);
4271
+ if (!Number.isInteger(parsed) || parsed < 0) {
4272
+ throw new Error(`--${label} \u306F 0 \u4EE5\u4E0A\u306E\u6574\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`);
4273
+ }
4274
+ return parsed;
4275
+ }
4276
+ function parseJsonSafely2(raw) {
4277
+ if (!raw) return {};
4278
+ try {
4279
+ return JSON.parse(raw);
4280
+ } catch {
4281
+ return null;
4282
+ }
4283
+ }
4284
+ async function listAssets(options) {
4285
+ ensureApiCredentials();
4286
+ const apiUrl = process.env.CMX_API_URL.replace(/\/$/, "");
4287
+ const apiKey = process.env.CMX_API_KEY;
4288
+ try {
4289
+ const limit = parseIntegerOption("limit", options.limit);
4290
+ const offset = parseIntegerOption("offset", options.offset);
4291
+ const searchParams = new URLSearchParams();
4292
+ if (options.group) searchParams.set("group", options.group);
4293
+ if (options.tags) searchParams.set("tags", options.tags);
4294
+ if (options.query) searchParams.set("q", options.query);
4295
+ if (options.mime) searchParams.set("mime", options.mime);
4296
+ if (limit !== void 0) searchParams.set("limit", String(limit));
4297
+ if (offset !== void 0) searchParams.set("offset", String(offset));
4298
+ const queryString = searchParams.toString();
4299
+ const url = `${apiUrl}/api/mcp/assets/search${queryString ? `?${queryString}` : ""}`;
4300
+ console.log("\u30A2\u30BB\u30C3\u30C8\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u3066\u3044\u307E\u3059...");
4301
+ const response = await fetch(url, {
4302
+ method: "GET",
4303
+ headers: {
4304
+ Authorization: `Bearer ${apiKey}`
4305
+ }
4306
+ });
4307
+ const rawBody = await response.text();
4308
+ if (!response.ok) {
4309
+ throw new Error(`API \u30A8\u30E9\u30FC (${response.status}): ${formatApiErrorMessage(rawBody)}`);
4310
+ }
4311
+ const parsed = parseJsonSafely2(rawBody);
4312
+ if (!parsed || typeof parsed !== "object") {
4313
+ throw new Error("API \u5FDC\u7B54\u306E JSON \u89E3\u6790\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
4314
+ }
4315
+ const payload = parsed;
4316
+ const count = Array.isArray(payload.assets) ? payload.assets.length : 0;
4317
+ console.log(`${count} \u4EF6\u306E\u30A2\u30BB\u30C3\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F:`);
4318
+ console.log(JSON.stringify(parsed, null, 2));
4319
+ } catch (error) {
4320
+ console.error("\u2717 \u30A2\u30BB\u30C3\u30C8\u4E00\u89A7\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F:");
4321
+ console.error(error instanceof Error ? error.message : String(error));
4322
+ process.exit(1);
4323
+ }
4324
+ }
4325
+
4326
+ // src/commands/update-asset.ts
4327
+ function parseJsonSafely3(raw) {
4328
+ if (!raw) return {};
4329
+ try {
4330
+ return JSON.parse(raw);
4331
+ } catch {
4332
+ return null;
4333
+ }
4334
+ }
4335
+ function parseTagNames(tags) {
4336
+ if (!tags) return [];
4337
+ return tags.split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0);
4338
+ }
4339
+ async function updateAsset(options) {
4340
+ ensureApiCredentials();
4341
+ if (!options.id) {
4342
+ console.error("\u30A8\u30E9\u30FC: --id \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044");
4343
+ process.exit(1);
4344
+ }
4345
+ if (options.group !== void 0 && options.clearGroup) {
4346
+ console.error("\u30A8\u30E9\u30FC: --group \u3068 --clear-group \u306F\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093");
4347
+ process.exit(1);
4348
+ }
4349
+ if (options.tags !== void 0 && options.clearTags) {
4350
+ console.error("\u30A8\u30E9\u30FC: --tags \u3068 --clear-tags \u306F\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093");
4351
+ process.exit(1);
4352
+ }
4353
+ const requestBody = {
4354
+ assetId: options.id
4355
+ };
4356
+ if (options.alt !== void 0) requestBody.alt = options.alt;
4357
+ if (options.description !== void 0) requestBody.description = options.description;
4358
+ if (options.clearGroup) {
4359
+ requestBody.groupSlug = null;
4360
+ } else if (options.group !== void 0) {
4361
+ requestBody.groupSlug = options.group;
4362
+ }
4363
+ if (options.clearTags) {
4364
+ requestBody.tagNames = [];
4365
+ } else if (options.tags !== void 0) {
4366
+ requestBody.tagNames = parseTagNames(options.tags);
4367
+ }
4368
+ if (Object.keys(requestBody).length === 1) {
4369
+ console.error("\u30A8\u30E9\u30FC: \u66F4\u65B0\u3059\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u5C11\u306A\u304F\u3068\u30821\u3064\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044");
4370
+ process.exit(1);
4371
+ }
4372
+ const apiUrl = process.env.CMX_API_URL.replace(/\/$/, "");
4373
+ const apiKey = process.env.CMX_API_KEY;
4374
+ try {
4375
+ console.log(`\u30A2\u30BB\u30C3\u30C8\u3092\u66F4\u65B0\u3057\u3066\u3044\u307E\u3059: ${options.id}...`);
4376
+ const response = await fetch(`${apiUrl}/api/mcp/assets`, {
4377
+ method: "PATCH",
4378
+ headers: {
4379
+ Authorization: `Bearer ${apiKey}`,
4380
+ "Content-Type": "application/json"
4381
+ },
4382
+ body: JSON.stringify(requestBody)
4383
+ });
4384
+ const rawBody = await response.text();
4385
+ if (!response.ok) {
4386
+ throw new Error(`API \u30A8\u30E9\u30FC (${response.status}): ${formatApiErrorMessage(rawBody)}`);
4387
+ }
4388
+ const parsed = parseJsonSafely3(rawBody);
4389
+ if (!parsed || typeof parsed !== "object") {
4390
+ throw new Error("API \u5FDC\u7B54\u306E JSON \u89E3\u6790\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
4391
+ }
4392
+ console.log("\u30A2\u30BB\u30C3\u30C8\u3092\u66F4\u65B0\u3057\u307E\u3057\u305F:");
4393
+ console.log(JSON.stringify(parsed, null, 2));
4394
+ } catch (error) {
4395
+ console.error("\u2717 \u30A2\u30BB\u30C3\u30C8\u66F4\u65B0\u306B\u5931\u6557\u3057\u307E\u3057\u305F:");
4396
+ console.error(error instanceof Error ? error.message : String(error));
4397
+ process.exit(1);
4398
+ }
4399
+ }
4400
+
4192
4401
  // src/cli.ts
4193
4402
  config();
4194
4403
  installSdkFetchInterceptor();
4195
4404
  var program = new Command();
4196
- program.name("cmx-sdk").description("CMX \u30B9\u30AD\u30FC\u30DE\u3068\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u64CD\u4F5C\u3059\u308B CLI \u30C4\u30FC\u30EB").version("0.2.6").allowExcessArguments(false);
4405
+ program.name("cmx-sdk").description("CMX \u30B9\u30AD\u30FC\u30DE\u3068\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u64CD\u4F5C\u3059\u308B CLI \u30C4\u30FC\u30EB").version("0.2.11").allowExcessArguments(false);
4197
4406
  function requireApiCredentials() {
4198
4407
  const apiUrl = process.env.CMX_API_URL;
4199
4408
  const apiKey = process.env.CMX_API_KEY;
@@ -4204,7 +4413,7 @@ function requireApiCredentials() {
4204
4413
  return { apiUrl, apiKey };
4205
4414
  }
4206
4415
  program.action(async () => {
4207
- const { interactiveMenu } = await import("./interactive-menu-FYVOQSTL.js");
4416
+ const { interactiveMenu } = await import("./interactive-menu-PYMJB5LY.js");
4208
4417
  await interactiveMenu();
4209
4418
  });
4210
4419
  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) => {
@@ -4313,6 +4522,9 @@ program.command("remove-collection-data-type").description("\u30B3\u30EC\u30AF\u
4313
4522
  program.command("link-collection-data-type").description("\u65E2\u5B58\u306E\u30B0\u30ED\u30FC\u30D0\u30EB\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u3092\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3078\u7D10\u3065\u3051").requiredOption("--collection <slug>", "\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u306E\u30B9\u30E9\u30C3\u30B0").requiredOption("--data-type <slug>", "\u7D10\u3065\u3051\u308B\u30B0\u30ED\u30FC\u30D0\u30EB\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u306E\u30B9\u30E9\u30C3\u30B0").requiredOption("--field-slug <slug>", "\u53C2\u7167\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u30B9\u30E9\u30C3\u30B0").requiredOption("--label <label>", "\u53C2\u7167\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u8868\u793A\u540D").option("--reference-type <type>", "\u53C2\u7167\u30BF\u30A4\u30D7\uFF08single \u307E\u305F\u306F multiple\u3001\u65E2\u5B9A: single\uFF09", "single").action(linkCollectionDataType);
4314
4523
  program.command("list-collection-presets").description("\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u5411\u3051\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u30D7\u30EA\u30BB\u30C3\u30C8\u4E00\u89A7\u3092\u8868\u793A").option("--type <type>", "\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u7A2E\u5225 (post, news, doc, page)").action(listCollectionPresets);
4315
4524
  program.command("create-data-entry").description("\u30C7\u30FC\u30BF\u30A8\u30F3\u30C8\u30EA\u30FC\u3092\u4F5C\u6210").requiredOption("--type-slug <slug>", "\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u306E\u30B9\u30E9\u30C3\u30B0").option("--json <json>", "\u30A8\u30F3\u30C8\u30EA\u30FC\u5185\u5BB9\u306E JSON \u6587\u5B57\u5217").option("--file <file>", "\u30A8\u30F3\u30C8\u30EA\u30FC\u5185\u5BB9 JSON \u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9").action(createDataEntry);
4525
+ program.command("upload-asset").description("\u30A2\u30BB\u30C3\u30C8\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\uFF08MCP Assets API\uFF09").requiredOption("--file <path>", "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u30D1\u30B9").option("--alt <text>", "\u4EE3\u66FF\u30C6\u30AD\u30B9\u30C8").option("--description <text>", "\u8AAC\u660E").option("--group <slug>", "\u30A2\u30BB\u30C3\u30C8\u30B0\u30EB\u30FC\u30D7\u306E\u30B9\u30E9\u30C3\u30B0").option("--tags <tags>", "\u30BF\u30B0\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09").option("--mime <type>", "MIME type\uFF08\u672A\u6307\u5B9A\u6642\u306F\u62E1\u5F35\u5B50\u304B\u3089\u63A8\u5B9A\uFF09").action(uploadAsset);
4526
+ program.command("list-assets").description("\u30A2\u30BB\u30C3\u30C8\u3092\u691C\u7D22\u30FB\u4E00\u89A7\u8868\u793A\uFF08MCP Assets API\uFF09").option("--group <slug>", "\u30B0\u30EB\u30FC\u30D7\u30B9\u30E9\u30C3\u30B0\u3067\u7D5E\u308A\u8FBC\u307F").option("--tags <tags>", "\u30BF\u30B0\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09\u3067\u7D5E\u308A\u8FBC\u307F").option("--query <text>", "\u691C\u7D22\u30AF\u30A8\u30EA\uFF08alt/description \u3092\u691C\u7D22\uFF09").option("--mime <type>", "MIME type\uFF08\u4F8B: image, video, image/png\uFF09").option("--limit <number>", "\u53D6\u5F97\u4EF6\u6570\uFF08\u6700\u592750\uFF09").option("--offset <number>", "\u30AA\u30D5\u30BB\u30C3\u30C8").action(listAssets);
4527
+ program.command("update-asset").description("\u30A2\u30BB\u30C3\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u66F4\u65B0\uFF08MCP Assets API\uFF09").requiredOption("--id <id>", "\u30A2\u30BB\u30C3\u30C8 ID").option("--alt <text>", "\u4EE3\u66FF\u30C6\u30AD\u30B9\u30C8\uFF08\u7A7A\u6587\u5B57\u3067\u30AF\u30EA\u30A2\uFF09").option("--description <text>", "\u8AAC\u660E\uFF08\u7A7A\u6587\u5B57\u3067\u30AF\u30EA\u30A2\uFF09").option("--group <slug>", "\u30B0\u30EB\u30FC\u30D7\u30B9\u30E9\u30C3\u30B0").option("--clear-group", "\u30B0\u30EB\u30FC\u30D7\u3092\u89E3\u9664").option("--tags <tags>", "\u30BF\u30B0\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09").option("--clear-tags", "\u30BF\u30B0\u3092\u5168\u524A\u9664").action(updateAsset);
4316
4528
  program.command("list-data-entries").description("\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u3054\u3068\u306E\u30C7\u30FC\u30BF\u30A8\u30F3\u30C8\u30EA\u30FC\u4E00\u89A7\u3092\u8868\u793A").requiredOption("--type-slug <slug>", "\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u306E\u30B9\u30E9\u30C3\u30B0").option("--sort-by <field>", "\u4E26\u3073\u66FF\u3048\u5BFE\u8C61\u30D5\u30A3\u30FC\u30EB\u30C9").option("--sort-order <order>", "\u4E26\u3073\u9806 (asc \u307E\u305F\u306F desc)").option("--limit <number>", "\u53D6\u5F97\u4EF6\u6570\u306E\u4E0A\u9650").option("--offset <number>", "\u30B9\u30AD\u30C3\u30D7\u4EF6\u6570").option("--status <status>", "\u30B9\u30C6\u30FC\u30BF\u30B9\u3067\u7D5E\u308A\u8FBC\u307F\uFF08draft \u307E\u305F\u306F published\uFF09").action(listDataEntries);
4317
4529
  program.command("get-data-entry").description("\u5358\u4E00\u306E\u30C7\u30FC\u30BF\u30A8\u30F3\u30C8\u30EA\u30FC\u3092\u53D6\u5F97").requiredOption("--type-slug <slug>", "\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u306E\u30B9\u30E9\u30C3\u30B0").requiredOption("--id <id>", "\u30C7\u30FC\u30BF\u30A8\u30F3\u30C8\u30EA\u30FC ID").action(getDataEntry);
4318
4530
  program.command("update-data-entry").description("\u30C7\u30FC\u30BF\u30A8\u30F3\u30C8\u30EA\u30FC\u3092\u66F4\u65B0").requiredOption("--type-slug <slug>", "\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u306E\u30B9\u30E9\u30C3\u30B0").requiredOption("--id <id>", "\u30C7\u30FC\u30BF\u30A8\u30F3\u30C8\u30EA\u30FC ID").option("--json <json>", "\u66F4\u65B0\u5185\u5BB9\u306E JSON \u6587\u5B57\u5217").option("--file <file>", "\u66F4\u65B0\u5185\u5BB9 JSON \u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9").action(updateDataEntry);
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-KJZ6VB4M.js");
34
+ const { updateSdk } = await import("./update-sdk-ZXMWQF3I.js");
35
35
  return updateSdk({});
36
36
  }
37
37
  case "studio": {
@@ -63,6 +63,9 @@ async function interactiveMenu() {
63
63
  npx cmx-sdk codegen all \u578B\u751F\u6210 + \u30DA\u30FC\u30B8\u751F\u6210 + \u6574\u5408\u30C1\u30A7\u30C3\u30AF
64
64
  npx cmx-sdk mdx validate MDX \u672C\u6587\u3092\u691C\u8A3C
65
65
  npx cmx-sdk mdx doctor MDX \u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u5B9A\u7FA9\u3092\u691C\u8A3C
66
+ npx cmx-sdk upload-asset --file \u30A2\u30BB\u30C3\u30C8\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9
67
+ npx cmx-sdk list-assets \u30A2\u30BB\u30C3\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
68
+ npx cmx-sdk update-asset --id \u30A2\u30BB\u30C3\u30C8\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u66F4\u65B0
66
69
  npx cmx-sdk --help \u5168\u30B3\u30DE\u30F3\u30C9\u3092\u8868\u793A
67
70
 
68
71
  \u8D77\u52D5\u4F8B:
File without changes
@@ -2,8 +2,9 @@
2
2
  import {
3
3
  resolveRequestedVersion,
4
4
  updateSdk
5
- } from "./chunk-EZMBZWH7.js";
5
+ } from "./chunk-Y3S3K6M3.js";
6
6
  import "./chunk-EDXXR5BE.js";
7
+ import "./chunk-IIQLQIDP.js";
7
8
  export {
8
9
  resolveRequestedVersion,
9
10
  updateSdk
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cmx-sdk",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
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
+ }