cmx-sdk 0.2.6 → 0.2.8

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 (48) hide show
  1. package/README.md +16 -0
  2. package/dist/add-studio-YUDYE2OH.js +72 -0
  3. package/dist/{chunk-XPP5MZKG.js → chunk-7TDMLYBI.js} +17 -45
  4. package/dist/chunk-EDXXR5BE.js +80 -0
  5. package/dist/chunk-EZMBZWH7.js +121 -0
  6. package/dist/chunk-FPQYL5GE.js +128 -0
  7. package/dist/chunk-NZQ6SBFS.js +35 -0
  8. package/dist/cli.js +1152 -619
  9. package/dist/index.d.ts +253 -385
  10. package/dist/index.js +154 -25
  11. package/dist/index.js.map +1 -1
  12. package/dist/{init-NDNG5Q5T.js → init-FLRQXJX4.js} +23 -51
  13. package/dist/interactive-menu-FYVOQSTL.js +80 -0
  14. package/dist/studio-HAS6DYLO.js +8 -0
  15. package/dist/update-sdk-KJZ6VB4M.js +10 -0
  16. package/dist/update-studio-TWCYSYIS.js +14 -0
  17. package/package.json +18 -10
  18. package/templates/AGENTS.md +173 -0
  19. package/templates/CLAUDE.md +28 -0
  20. package/templates/claude/commands/check.md +64 -0
  21. package/templates/claude/commands/next-action.md +66 -0
  22. package/templates/claude/skills/cmx-cache/SKILL.md +50 -0
  23. package/templates/claude/skills/cmx-cache/references/cache-patterns.md +153 -0
  24. package/templates/claude/skills/cmx-component/SKILL.md +108 -0
  25. package/templates/claude/skills/cmx-component/references/component-schema.md +123 -0
  26. package/templates/claude/skills/cmx-content/SKILL.md +158 -0
  27. package/templates/claude/skills/cmx-content/references/migration-patterns.md +120 -0
  28. package/templates/claude/skills/cmx-content/references/seed-patterns.md +146 -0
  29. package/templates/claude/skills/cmx-dev/SKILL.md +266 -0
  30. package/templates/claude/skills/cmx-dev/references/api-patterns.md +220 -0
  31. package/templates/claude/skills/cmx-dev/references/cli-reference.md +54 -0
  32. package/templates/claude/skills/cmx-form/SKILL.md +103 -0
  33. package/templates/claude/skills/cmx-form/references/form-template.md +152 -0
  34. package/templates/claude/skills/cmx-migrate/SKILL.md +501 -0
  35. package/templates/claude/skills/cmx-migrate/references/analysis-guide.md +127 -0
  36. package/templates/claude/skills/cmx-migrate/references/html-to-mdx.md +99 -0
  37. package/templates/claude/skills/cmx-migrate/references/intermediate-format.md +196 -0
  38. package/templates/claude/skills/cmx-migrate/references/tool-setup.md +150 -0
  39. package/templates/claude/skills/cmx-schema/SKILL.md +159 -0
  40. package/templates/claude/skills/cmx-schema/references/field-types.md +164 -0
  41. package/templates/claude/skills/cmx-schema/references/migration-scenarios.md +44 -0
  42. package/templates/claude/skills/cmx-seo/SKILL.md +54 -0
  43. package/templates/claude/skills/cmx-seo/references/seo-patterns.md +216 -0
  44. package/templates/claude/skills/cmx-style/SKILL.md +48 -0
  45. package/templates/claude/skills/cmx-style/references/style-patterns.md +114 -0
  46. package/dist/add-studio-J7M7KOWM.js +0 -125
  47. package/dist/interactive-menu-RPPCBCOU.js +0 -66
  48. package/dist/studio-3YGVKWS4.js +0 -7
package/README.md CHANGED
@@ -223,6 +223,22 @@ npx cmx-sdk mdx validate --file src/content/post.mdx
223
223
  npx cmx-sdk mdx doctor
224
224
  ```
225
225
 
226
+ ### Starter Kit Maintenance
227
+
228
+ ```bash
229
+ # Replace .cmx/studio with the latest distributed Studio app
230
+ npx cmx-sdk update-studio
231
+
232
+ # Skip confirmation prompt when replacing Studio
233
+ npx cmx-sdk update-studio --force
234
+
235
+ # Update cmx-sdk dependency in your starter kit root
236
+ npx cmx-sdk update-sdk
237
+
238
+ # Pin to a specific version or tag
239
+ npx cmx-sdk update-sdk --version 0.2.6
240
+ ```
241
+
226
242
  ### Requirements
227
243
 
228
244
  Set `CMX_API_URL` and `CMX_API_KEY` in your `.env` or `.env.local`:
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ downloadStudioFiles
4
+ } from "./chunk-NZQ6SBFS.js";
5
+ import {
6
+ commandToString,
7
+ detectPackageManager,
8
+ findProjectRoot,
9
+ getInstallCommand,
10
+ getStudioStandaloneDevCommand
11
+ } from "./chunk-EDXXR5BE.js";
12
+ import "./chunk-IIQLQIDP.js";
13
+
14
+ // src/commands/add-studio.ts
15
+ import { existsSync } from "fs";
16
+ import { join } from "path";
17
+ import { execSync } from "child_process";
18
+ import { config } from "dotenv";
19
+ async function addStudio() {
20
+ console.log("\n CMX Studio \u3092\u8FFD\u52A0\u4E2D...\n");
21
+ const projectRoot = findProjectRoot();
22
+ if (!projectRoot) {
23
+ console.error(" \u274C CMX \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
24
+ console.error(" package.json \u306B cmx-sdk \u4F9D\u5B58\u304C\u3042\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\n");
25
+ process.exit(1);
26
+ }
27
+ const studioDir = join(projectRoot, ".cmx", "studio");
28
+ if (existsSync(studioDir)) {
29
+ console.error(" \u274C .cmx/studio/ \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059");
30
+ console.error(" \u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3059\u308B\u5834\u5408\u306F\u5148\u306B\u524A\u9664\u3057\u3066\u304F\u3060\u3055\u3044\n");
31
+ process.exit(1);
32
+ }
33
+ config({ path: join(projectRoot, ".env") });
34
+ const apiUrl = process.env.CMX_API_URL;
35
+ const apiKey = process.env.CMX_API_KEY;
36
+ if (!apiUrl || !apiKey) {
37
+ console.error(" \u274C CMX_API_URL \u3068 CMX_API_KEY \u304C\u5FC5\u8981\u3067\u3059");
38
+ console.error(" .env \u306B\u8A8D\u8A3C\u60C5\u5831\u3092\u8A2D\u5B9A\u3057\u3066\u304B\u3089\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\n");
39
+ process.exit(1);
40
+ }
41
+ console.log(" \u23F3 Studio \u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u4E2D...");
42
+ try {
43
+ await downloadStudioFiles(studioDir, { apiUrl, apiKey });
44
+ console.log(" \u2713 Studio \u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3057\u307E\u3057\u305F");
45
+ } catch (error) {
46
+ console.error("\n \u274C Studio \u306E\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
47
+ console.error(` ${error instanceof Error ? error.message : "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC"}
48
+ `);
49
+ process.exit(1);
50
+ }
51
+ console.log("\n \u{1F4E6} Studio \u306E\u4F9D\u5B58\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u4E2D...");
52
+ const pm = detectPackageManager(projectRoot);
53
+ const installCmd = getInstallCommand(pm);
54
+ try {
55
+ execSync(commandToString(installCmd), { cwd: studioDir, stdio: "inherit" });
56
+ } catch {
57
+ console.error("\n \u26A0\uFE0F \u4F9D\u5B58\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
58
+ console.error(` cd .cmx/studio && ${commandToString(installCmd)} \u3067\u624B\u52D5\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u3066\u304F\u3060\u3055\u3044
59
+ `);
60
+ }
61
+ console.log("\n \u2705 CMX Studio \u3092\u8FFD\u52A0\u3057\u307E\u3057\u305F\uFF01\n");
62
+ console.log(" \u6B21\u306E\u30B9\u30C6\u30C3\u30D7:");
63
+ console.log(" 1. \u30B5\u30A4\u30C8 + Studio \u3092\u8D77\u52D5");
64
+ console.log(" npx cmx-sdk studio");
65
+ console.log(" 2. Studio \u306E\u307F\u8D77\u52D5");
66
+ console.log(` ${getStudioStandaloneDevCommand(pm)}
67
+ `);
68
+ process.exit(0);
69
+ }
70
+ export {
71
+ addStudio
72
+ };
@@ -1,47 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ detectPackageManager,
4
+ findProjectRoot,
5
+ getRunDevCommand,
6
+ toPlatformCommand
7
+ } from "./chunk-EDXXR5BE.js";
2
8
 
3
9
  // src/commands/studio.ts
4
- import { existsSync, readFileSync } from "fs";
10
+ import { existsSync } from "fs";
5
11
  import { spawn } from "child_process";
6
- import { join, resolve } from "path";
7
- function findProjectRoot() {
8
- let dir = resolve(process.cwd());
9
- const root = resolve("/");
10
- while (dir !== root) {
11
- const pkgPath = join(dir, "package.json");
12
- if (existsSync(pkgPath)) {
13
- try {
14
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
15
- if (pkg.dependencies?.["cmx-sdk"] || pkg.devDependencies?.["cmx-sdk"]) {
16
- return dir;
17
- }
18
- } catch {
19
- }
20
- }
21
- dir = resolve(dir, "..");
22
- }
23
- return null;
24
- }
25
- function detectPackageManager(dir) {
26
- if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm";
27
- if (existsSync(join(dir, "yarn.lock"))) return "yarn";
28
- return "npm";
29
- }
30
- function getRunCommand(pm) {
31
- if (pm === "pnpm") return { command: "pnpm", args: ["dev"] };
32
- if (pm === "yarn") return { command: "yarn", args: ["dev"] };
33
- return { command: "npm", args: ["run", "dev"] };
34
- }
35
- function toPlatformCommand(command) {
36
- if (process.platform === "win32") {
37
- if (command === "npm") return "npm.cmd";
38
- if (command === "pnpm") return "pnpm.cmd";
39
- if (command === "yarn") return "yarn.cmd";
40
- }
41
- return command;
42
- }
12
+ import { join } from "path";
43
13
  async function studio() {
44
- console.log("\n CMX Studio \u8D77\u52D5\u4E2D...\n");
14
+ console.log("\n CMX Studio \u3092\u8D77\u52D5\u3057\u307E\u3059...\n");
45
15
  const projectRoot = findProjectRoot();
46
16
  if (!projectRoot) {
47
17
  console.error(" \u274C CMX \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
@@ -56,8 +26,8 @@ async function studio() {
56
26
  }
57
27
  const rootPm = detectPackageManager(projectRoot);
58
28
  const studioPm = detectPackageManager(studioDir);
59
- const rootRun = getRunCommand(rootPm);
60
- const studioRun = getRunCommand(studioPm);
29
+ const rootRun = getRunDevCommand(rootPm);
30
+ const studioRun = getRunDevCommand(studioPm);
61
31
  const children = [];
62
32
  let shuttingDown = false;
63
33
  const shutdown = (exitCode) => {
@@ -74,6 +44,7 @@ async function studio() {
74
44
  }, 300).unref();
75
45
  };
76
46
  const spawnDev = (label, cwd, run) => {
47
+ const displayLabel = label === "site" ? "\u30B5\u30A4\u30C8" : "Studio";
77
48
  const command = toPlatformCommand(run.command);
78
49
  const child = spawn(command, run.args, {
79
50
  cwd,
@@ -82,7 +53,7 @@ async function studio() {
82
53
  });
83
54
  child.on("error", (error) => {
84
55
  console.error(`
85
- \u274C ${label} \u306E\u8D77\u52D5\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${error.message}
56
+ \u274C ${displayLabel} \u306E\u8D77\u52D5\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${error.message}
86
57
  `);
87
58
  shutdown(1);
88
59
  });
@@ -90,14 +61,15 @@ async function studio() {
90
61
  if (shuttingDown) return;
91
62
  const detail = signal ? `signal ${signal}` : `code ${code ?? 1}`;
92
63
  console.error(`
93
- \u26A0\uFE0F ${label} \u30D7\u30ED\u30BB\u30B9\u304C\u7D42\u4E86\u3057\u307E\u3057\u305F (${detail})
64
+ \u26A0\uFE0F ${displayLabel} \u30D7\u30ED\u30BB\u30B9\u304C\u7D42\u4E86\u3057\u307E\u3057\u305F (${detail})
94
65
  `);
95
66
  shutdown(code ?? 1);
96
67
  });
97
68
  children.push(child);
98
69
  };
99
- console.log(" - site : http://localhost:4000");
100
- console.log(" - studio : http://localhost:4001\n");
70
+ console.log(" \u8D77\u52D5URL:");
71
+ console.log(" \u30B5\u30A4\u30C8 : http://localhost:4000");
72
+ console.log(" Studio : http://localhost:4001\n");
101
73
  spawnDev("site", projectRoot, rootRun);
102
74
  spawnDev("studio", studioDir, studioRun);
103
75
  process.on("SIGINT", () => shutdown(0));
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/project-context.ts
4
+ import { existsSync, readFileSync } from "fs";
5
+ import { join, resolve } from "path";
6
+ function findProjectRoot(startDir = process.cwd()) {
7
+ let dir = resolve(startDir);
8
+ const root = resolve("/");
9
+ while (dir !== root) {
10
+ const pkgPath = join(dir, "package.json");
11
+ if (existsSync(pkgPath)) {
12
+ try {
13
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
14
+ if (pkg.dependencies?.["cmx-sdk"] || pkg.devDependencies?.["cmx-sdk"]) {
15
+ return dir;
16
+ }
17
+ } catch {
18
+ }
19
+ }
20
+ dir = resolve(dir, "..");
21
+ }
22
+ return null;
23
+ }
24
+ function detectPackageManager(dir) {
25
+ if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm";
26
+ if (existsSync(join(dir, "yarn.lock"))) return "yarn";
27
+ return "npm";
28
+ }
29
+ function toPlatformCommand(command) {
30
+ if (process.platform === "win32") {
31
+ if (command === "npm") return "npm.cmd";
32
+ if (command === "pnpm") return "pnpm.cmd";
33
+ if (command === "yarn") return "yarn.cmd";
34
+ }
35
+ return command;
36
+ }
37
+ function getInstallCommand(pm) {
38
+ if (pm === "yarn") return { command: "yarn", args: [] };
39
+ return { command: pm, args: ["install"] };
40
+ }
41
+ function getRunDevCommand(pm) {
42
+ if (pm === "pnpm") return { command: "pnpm", args: ["dev"] };
43
+ if (pm === "yarn") return { command: "yarn", args: ["dev"] };
44
+ return { command: "npm", args: ["run", "dev"] };
45
+ }
46
+ function getAddDependencyCommand(pm, packageSpec) {
47
+ if (pm === "pnpm") return { command: "pnpm", args: ["add", packageSpec] };
48
+ if (pm === "yarn") return { command: "yarn", args: ["add", packageSpec] };
49
+ return { command: "npm", args: ["install", packageSpec] };
50
+ }
51
+ function commandToString(command) {
52
+ return [command.command, ...command.args].join(" ");
53
+ }
54
+ function getStudioStandaloneDevCommand(pm) {
55
+ if (pm === "pnpm") return "pnpm --dir .cmx/studio dev";
56
+ if (pm === "yarn") return "yarn --cwd .cmx/studio dev";
57
+ return "npm --prefix .cmx/studio run dev";
58
+ }
59
+ function readSdkVersion(projectRoot) {
60
+ const pkgPath = join(projectRoot, "package.json");
61
+ if (!existsSync(pkgPath)) return null;
62
+ try {
63
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
64
+ return pkg.dependencies?.["cmx-sdk"] ?? pkg.devDependencies?.["cmx-sdk"] ?? null;
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+
70
+ export {
71
+ findProjectRoot,
72
+ detectPackageManager,
73
+ toPlatformCommand,
74
+ getInstallCommand,
75
+ getRunDevCommand,
76
+ getAddDependencyCommand,
77
+ commandToString,
78
+ getStudioStandaloneDevCommand,
79
+ readSdkVersion
80
+ };
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ commandToString,
4
+ detectPackageManager,
5
+ findProjectRoot,
6
+ getAddDependencyCommand,
7
+ readSdkVersion
8
+ } from "./chunk-EDXXR5BE.js";
9
+
10
+ // src/commands/update-sdk.ts
11
+ import { execSync } from "child_process";
12
+ import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
13
+ 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, "..", "..");
18
+ function resolveRequestedVersion(version) {
19
+ if (version === void 0) return "latest";
20
+ const normalized = version.trim();
21
+ if (normalized.length === 0) {
22
+ throw new Error("--version \u306B\u7A7A\u6587\u5B57\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093");
23
+ }
24
+ return normalized;
25
+ }
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");
41
+ }
42
+ function syncManagedFile(projectRoot, relativePath) {
43
+ const templatePath = join(SDK_ROOT, "templates", relativePath);
44
+ if (!existsSync(templatePath)) return;
45
+ const destPath = join(projectRoot, relativePath);
46
+ const templateContent = readFileSync(templatePath, "utf-8");
47
+ if (!existsSync(destPath)) {
48
+ mkdirSync(dirname(destPath), { recursive: true });
49
+ writeFileSync(destPath, templateContent);
50
+ console.log(` \u2705 ${relativePath} \u3092\u4F5C\u6210\u3057\u307E\u3057\u305F`);
51
+ return;
52
+ }
53
+ const blockRegex = /<!-- cmx-sdk:start id="([^"]+)" -->([\s\S]*?)<!-- cmx-sdk:end -->/g;
54
+ let userContent = readFileSync(destPath, "utf-8");
55
+ let updatedBlocks = 0;
56
+ let match;
57
+ while ((match = blockRegex.exec(templateContent)) !== null) {
58
+ const [fullBlock, id] = match;
59
+ const userBlockRegex = new RegExp(
60
+ `<!-- cmx-sdk:start id="${id}" -->[\\s\\S]*?<!-- cmx-sdk:end -->`
61
+ );
62
+ if (userBlockRegex.test(userContent)) {
63
+ userContent = userContent.replace(userBlockRegex, fullBlock);
64
+ updatedBlocks++;
65
+ }
66
+ }
67
+ if (updatedBlocks > 0) {
68
+ writeFileSync(destPath, userContent);
69
+ console.log(` \u2705 ${relativePath} \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F\uFF08${updatedBlocks} \u30D6\u30ED\u30C3\u30AF\uFF09`);
70
+ }
71
+ }
72
+ async function updateSdk(options = {}) {
73
+ console.log("\n cmx-sdk \u306E\u4F9D\u5B58\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u66F4\u65B0\u3057\u307E\u3059...\n");
74
+ const projectRoot = findProjectRoot();
75
+ if (!projectRoot) {
76
+ console.error(" \u274C CMX \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
77
+ console.error(" package.json \u306B cmx-sdk \u4F9D\u5B58\u304C\u3042\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\n");
78
+ process.exit(1);
79
+ }
80
+ let version;
81
+ try {
82
+ version = resolveRequestedVersion(options.version);
83
+ } catch (error) {
84
+ console.error(` \u274C ${error instanceof Error ? error.message : "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC"}
85
+ `);
86
+ process.exit(1);
87
+ }
88
+ const currentVersion = readSdkVersion(projectRoot);
89
+ const pm = detectPackageManager(projectRoot);
90
+ const dependencySpec = `cmx-sdk@${version}`;
91
+ const addCommand = getAddDependencyCommand(pm, dependencySpec);
92
+ console.log(` \u73FE\u5728\u306E\u30D0\u30FC\u30B8\u30E7\u30F3: ${currentVersion ?? "\u4E0D\u660E"}`);
93
+ console.log(` \u23F3 \u5B9F\u884C\u30B3\u30DE\u30F3\u30C9: ${commandToString(addCommand)}`);
94
+ try {
95
+ execSync(commandToString(addCommand), { cwd: projectRoot, stdio: "inherit" });
96
+ } catch {
97
+ console.error("\n \u274C cmx-sdk \u306E\u66F4\u65B0\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
98
+ console.error(` \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30EB\u30FC\u30C8\u3067 ${commandToString(addCommand)} \u3092\u624B\u52D5\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044
99
+ `);
100
+ process.exit(1);
101
+ }
102
+ const updatedVersion = readSdkVersion(projectRoot);
103
+ console.log("\n \u2705 cmx-sdk \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F\uFF01");
104
+ console.log(` \u66F4\u65B0\u5F8C\u30D0\u30FC\u30B8\u30E7\u30F3: ${updatedVersion ?? "\u4E0D\u660E"}`);
105
+ 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");
110
+ console.log("\n \u6B21\u306E\u30B9\u30C6\u30C3\u30D7:");
111
+ console.log(" 1. \u578B\u751F\u6210\u3092\u518D\u5B9F\u884C");
112
+ console.log(" npx cmx-sdk codegen types");
113
+ console.log(" 2. \u6574\u5408\u6027\u30C1\u30A7\u30C3\u30AF");
114
+ console.log(" npx cmx-sdk codegen check\n");
115
+ process.exit(0);
116
+ }
117
+
118
+ export {
119
+ resolveRequestedVersion,
120
+ updateSdk
121
+ };
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ downloadStudioFiles
4
+ } from "./chunk-NZQ6SBFS.js";
5
+ import {
6
+ commandToString,
7
+ detectPackageManager,
8
+ findProjectRoot,
9
+ getInstallCommand,
10
+ getStudioStandaloneDevCommand
11
+ } from "./chunk-EDXXR5BE.js";
12
+
13
+ // src/commands/update-studio.ts
14
+ import { confirm } from "@inquirer/prompts";
15
+ import { execSync } from "child_process";
16
+ import { config } from "dotenv";
17
+ import { existsSync, mkdirSync, renameSync, rmSync } from "fs";
18
+ import { join } from "path";
19
+ function formatBackupTimestamp(date = /* @__PURE__ */ new Date()) {
20
+ const yyyy = String(date.getFullYear());
21
+ const mm = String(date.getMonth() + 1).padStart(2, "0");
22
+ const dd = String(date.getDate()).padStart(2, "0");
23
+ const hh = String(date.getHours()).padStart(2, "0");
24
+ const mi = String(date.getMinutes()).padStart(2, "0");
25
+ const ss = String(date.getSeconds()).padStart(2, "0");
26
+ return `${yyyy}${mm}${dd}-${hh}${mi}${ss}`;
27
+ }
28
+ function restoreStudioFromBackup(studioDir, backupDir) {
29
+ if (existsSync(studioDir)) {
30
+ rmSync(studioDir, { recursive: true, force: true });
31
+ }
32
+ renameSync(backupDir, studioDir);
33
+ }
34
+ async function updateStudio(options = {}) {
35
+ console.log("\n CMX Studio \u3092\u66F4\u65B0\u3057\u307E\u3059...\n");
36
+ const projectRoot = findProjectRoot();
37
+ if (!projectRoot) {
38
+ console.error(" \u274C CMX \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
39
+ console.error(" package.json \u306B cmx-sdk \u4F9D\u5B58\u304C\u3042\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\n");
40
+ process.exit(1);
41
+ }
42
+ const studioDir = join(projectRoot, ".cmx", "studio");
43
+ if (!existsSync(join(studioDir, "package.json"))) {
44
+ console.error(" \u274C .cmx/studio \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
45
+ console.error(" \u5148\u306B npx cmx-sdk add-studio \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\n");
46
+ process.exit(1);
47
+ }
48
+ if (!options.force) {
49
+ const accepted = await confirm({
50
+ message: "\u65E2\u5B58\u306E .cmx/studio \u3092\u6700\u65B0\u69CB\u6210\u3067\u7F6E\u63DB\u3057\u307E\u3059\u3002\u7D9A\u884C\u3057\u307E\u3059\u304B\uFF1F",
51
+ default: true
52
+ });
53
+ if (!accepted) {
54
+ console.log("\n \u66F4\u65B0\u3092\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u307E\u3057\u305F\u3002\n");
55
+ process.exit(0);
56
+ }
57
+ }
58
+ config({ path: join(projectRoot, ".env") });
59
+ const apiUrl = process.env.CMX_API_URL;
60
+ const apiKey = process.env.CMX_API_KEY;
61
+ if (!apiUrl || !apiKey) {
62
+ console.error(" \u274C CMX_API_URL \u3068 CMX_API_KEY \u304C\u5FC5\u8981\u3067\u3059");
63
+ console.error(" .env \u306B\u8A8D\u8A3C\u60C5\u5831\u3092\u8A2D\u5B9A\u3057\u3066\u304B\u3089\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\n");
64
+ process.exit(1);
65
+ }
66
+ const timestamp = formatBackupTimestamp();
67
+ const cmxDir = join(projectRoot, ".cmx");
68
+ const backupDir = join(cmxDir, `studio.backup-${timestamp}`);
69
+ const nextStudioDir = join(cmxDir, `.studio-update-${timestamp}`);
70
+ mkdirSync(cmxDir, { recursive: true });
71
+ let movedToBackup = false;
72
+ console.log(" \u23F3 Studio \u3092\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3057\u3066\u7F6E\u63DB\u4E2D...");
73
+ try {
74
+ renameSync(studioDir, backupDir);
75
+ movedToBackup = true;
76
+ await downloadStudioFiles(nextStudioDir, { apiUrl, apiKey });
77
+ renameSync(nextStudioDir, studioDir);
78
+ } catch (error) {
79
+ rmSync(nextStudioDir, { recursive: true, force: true });
80
+ console.error("\n \u274C Studio \u306E\u66F4\u65B0\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
81
+ console.error(` ${error instanceof Error ? error.message : "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC"}`);
82
+ if (movedToBackup && existsSync(backupDir)) {
83
+ try {
84
+ restoreStudioFromBackup(studioDir, backupDir);
85
+ console.error(" \u21A9 \u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u304B\u3089\u5FA9\u65E7\u3057\u307E\u3057\u305F\n");
86
+ } catch (restoreError) {
87
+ console.error(` \u26A0\uFE0F \u81EA\u52D5\u5FA9\u65E7\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${restoreError instanceof Error ? restoreError.message : "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC"}`);
88
+ console.error(` \u624B\u52D5\u3067 ${backupDir} \u3092 ${studioDir} \u306B\u623B\u3057\u3066\u304F\u3060\u3055\u3044
89
+ `);
90
+ }
91
+ }
92
+ process.exit(1);
93
+ }
94
+ const pm = detectPackageManager(projectRoot);
95
+ const installCommand = getInstallCommand(pm);
96
+ let installSucceeded = false;
97
+ console.log("\n \u{1F4E6} Studio \u306E\u4F9D\u5B58\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u4E2D...");
98
+ try {
99
+ execSync(commandToString(installCommand), { cwd: studioDir, stdio: "inherit" });
100
+ installSucceeded = true;
101
+ } catch {
102
+ console.error("\n \u26A0\uFE0F \u4F9D\u5B58\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
103
+ console.error(` cd .cmx/studio && ${commandToString(installCommand)} \u3092\u624B\u52D5\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044`);
104
+ console.error(` \u5FC5\u8981\u306A\u3089\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3092\u5FA9\u5143: ${backupDir}
105
+ `);
106
+ }
107
+ if (installSucceeded) {
108
+ rmSync(backupDir, { recursive: true, force: true });
109
+ }
110
+ console.log("\n \u2705 CMX Studio \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F\uFF01\n");
111
+ console.log(" \u6B21\u306E\u30B9\u30C6\u30C3\u30D7:");
112
+ console.log(" 1. \u30B5\u30A4\u30C8 + Studio \u3092\u8D77\u52D5");
113
+ console.log(" npx cmx-sdk studio");
114
+ console.log(" 2. Studio \u306E\u307F\u8D77\u52D5");
115
+ console.log(` ${getStudioStandaloneDevCommand(pm)}`);
116
+ if (!installSucceeded) {
117
+ console.log(" 3. \u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3092\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059");
118
+ console.log(` ${backupDir}`);
119
+ }
120
+ console.log("");
121
+ process.exit(0);
122
+ }
123
+
124
+ export {
125
+ formatBackupTimestamp,
126
+ restoreStudioFromBackup,
127
+ updateStudio
128
+ };
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ cleanupTempFile,
4
+ downloadTarball
5
+ } from "./chunk-IIQLQIDP.js";
6
+
7
+ // src/commands/studio-distribution.ts
8
+ import { mkdirSync } from "fs";
9
+ import { dirname, join } from "path";
10
+ import { extract } from "tar";
11
+ function isStudioEntry(path) {
12
+ const parts = path.split("/");
13
+ return parts.length >= 3 && parts[1] === ".cmx" && parts[2] === "studio";
14
+ }
15
+ async function downloadStudioFiles(studioDir, options) {
16
+ const parentDir = dirname(studioDir);
17
+ const tmpFile = join(parentDir, `.tmp-studio-tarball-${Date.now()}.tar.gz`);
18
+ const normalizedApiUrl = options.apiUrl.replace(/\/$/, "");
19
+ const downloadUrl = `${normalizedApiUrl}/api/v1/sdk/download/studio`;
20
+ const headers = { Authorization: `Bearer ${options.apiKey}` };
21
+ mkdirSync(parentDir, { recursive: true });
22
+ await downloadTarball(downloadUrl, tmpFile, { headers });
23
+ mkdirSync(studioDir, { recursive: true });
24
+ await extract({
25
+ file: tmpFile,
26
+ cwd: studioDir,
27
+ strip: 2,
28
+ filter: isStudioEntry
29
+ });
30
+ cleanupTempFile(tmpFile);
31
+ }
32
+
33
+ export {
34
+ downloadStudioFiles
35
+ };