cmx-sdk 0.2.7 → 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 (36) hide show
  1. package/dist/{chunk-S3TFTN6H.js → chunk-EZMBZWH7.js} +57 -0
  2. package/dist/cli.js +82 -34
  3. package/dist/index.d.ts +2 -1
  4. package/dist/index.js +79 -31
  5. package/dist/index.js.map +1 -1
  6. package/dist/{interactive-menu-QKE6FMPN.js → interactive-menu-FYVOQSTL.js} +1 -1
  7. package/dist/{update-sdk-ZDFOSMN4.js → update-sdk-KJZ6VB4M.js} +1 -1
  8. package/package.json +2 -1
  9. package/templates/AGENTS.md +173 -0
  10. package/templates/CLAUDE.md +28 -0
  11. package/templates/claude/commands/check.md +64 -0
  12. package/templates/claude/commands/next-action.md +66 -0
  13. package/templates/claude/skills/cmx-cache/SKILL.md +50 -0
  14. package/templates/claude/skills/cmx-cache/references/cache-patterns.md +153 -0
  15. package/templates/claude/skills/cmx-component/SKILL.md +108 -0
  16. package/templates/claude/skills/cmx-component/references/component-schema.md +123 -0
  17. package/templates/claude/skills/cmx-content/SKILL.md +158 -0
  18. package/templates/claude/skills/cmx-content/references/migration-patterns.md +120 -0
  19. package/templates/claude/skills/cmx-content/references/seed-patterns.md +146 -0
  20. package/templates/claude/skills/cmx-dev/SKILL.md +266 -0
  21. package/templates/claude/skills/cmx-dev/references/api-patterns.md +220 -0
  22. package/templates/claude/skills/cmx-dev/references/cli-reference.md +54 -0
  23. package/templates/claude/skills/cmx-form/SKILL.md +103 -0
  24. package/templates/claude/skills/cmx-form/references/form-template.md +152 -0
  25. package/templates/claude/skills/cmx-migrate/SKILL.md +501 -0
  26. package/templates/claude/skills/cmx-migrate/references/analysis-guide.md +127 -0
  27. package/templates/claude/skills/cmx-migrate/references/html-to-mdx.md +99 -0
  28. package/templates/claude/skills/cmx-migrate/references/intermediate-format.md +196 -0
  29. package/templates/claude/skills/cmx-migrate/references/tool-setup.md +150 -0
  30. package/templates/claude/skills/cmx-schema/SKILL.md +159 -0
  31. package/templates/claude/skills/cmx-schema/references/field-types.md +164 -0
  32. package/templates/claude/skills/cmx-schema/references/migration-scenarios.md +44 -0
  33. package/templates/claude/skills/cmx-seo/SKILL.md +54 -0
  34. package/templates/claude/skills/cmx-seo/references/seo-patterns.md +216 -0
  35. package/templates/claude/skills/cmx-style/SKILL.md +48 -0
  36. package/templates/claude/skills/cmx-style/references/style-patterns.md +114 -0
@@ -9,6 +9,12 @@ import {
9
9
 
10
10
  // src/commands/update-sdk.ts
11
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, "..", "..");
12
18
  function resolveRequestedVersion(version) {
13
19
  if (version === void 0) return "latest";
14
20
  const normalized = version.trim();
@@ -17,6 +23,52 @@ function resolveRequestedVersion(version) {
17
23
  }
18
24
  return normalized;
19
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
+ }
20
72
  async function updateSdk(options = {}) {
21
73
  console.log("\n cmx-sdk \u306E\u4F9D\u5B58\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u66F4\u65B0\u3057\u307E\u3059...\n");
22
74
  const projectRoot = findProjectRoot();
@@ -50,6 +102,11 @@ async function updateSdk(options = {}) {
50
102
  const updatedVersion = readSdkVersion(projectRoot);
51
103
  console.log("\n \u2705 cmx-sdk \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F\uFF01");
52
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");
53
110
  console.log("\n \u6B21\u306E\u30B9\u30C6\u30C3\u30D7:");
54
111
  console.log(" 1. \u578B\u751F\u6210\u3092\u518D\u5B9F\u884C");
55
112
  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-S3TFTN6H.js";
10
+ } from "./chunk-EZMBZWH7.js";
11
11
  import "./chunk-NZQ6SBFS.js";
12
12
  import "./chunk-EDXXR5BE.js";
13
13
  import "./chunk-IIQLQIDP.js";
@@ -3369,8 +3369,14 @@ var FORBIDDEN_PATTERNS = [
3369
3369
  { pattern: /src\s*=\s*["']?\s*data:/i, message: "data: URL\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093" }
3370
3370
  ];
3371
3371
  function stripCodeBlocksForPatternCheck(mdx) {
3372
- let result = mdx.replace(/<CodeBlock[^>]*>([^]*?)<\/CodeBlock>/g, "<CodeBlock>__CODE_PLACEHOLDER__</CodeBlock>");
3373
- result = result.replace(/```[\s\S]*?```/g, "```__CODE_PLACEHOLDER__```");
3372
+ let result = mdx.replace(/<CodeBlock[^>]*>([^]*?)<\/CodeBlock>/g, (_match, content) => {
3373
+ const newlineCount = (content.match(/\n/g) || []).length;
3374
+ return "<CodeBlock>__CODE_PLACEHOLDER__" + "\n".repeat(newlineCount) + "</CodeBlock>";
3375
+ });
3376
+ result = result.replace(/```[\s\S]*?```/g, (match) => {
3377
+ const newlineCount = (match.match(/\n/g) || []).length;
3378
+ return "```__CODE_PLACEHOLDER__" + "\n".repeat(Math.max(0, newlineCount - 1)) + "```";
3379
+ });
3374
3380
  return result;
3375
3381
  }
3376
3382
  function escapeCodeBlocksForCompile(mdx) {
@@ -3386,8 +3392,6 @@ function escapeCodeBlocksForCompile(mdx) {
3386
3392
  }
3387
3393
  function extractComponents(mdx) {
3388
3394
  const components = [];
3389
- const selfClosingPattern = /<([A-Z][a-zA-Z0-9]*)\s*([^>]*?)\/>/g;
3390
- const withChildrenPattern = /<([A-Z][a-zA-Z0-9]*)\s*([^>]*)>([^]*?)<\/\1>/g;
3391
3395
  const lines = mdx.split("\n");
3392
3396
  const lineOffsets = [];
3393
3397
  let offset = 0;
@@ -3396,37 +3400,81 @@ function extractComponents(mdx) {
3396
3400
  offset += line.length + 1;
3397
3401
  }
3398
3402
  function getLineNumber(index) {
3399
- for (let i = lineOffsets.length - 1; i >= 0; i--) {
3400
- if (lineOffsets[i] <= index) {
3401
- return i + 1;
3403
+ let lo = 0, hi = lineOffsets.length - 1;
3404
+ while (lo < hi) {
3405
+ const mid = Math.floor((lo + hi + 1) / 2);
3406
+ if (lineOffsets[mid] <= index) {
3407
+ lo = mid;
3408
+ } else {
3409
+ hi = mid - 1;
3402
3410
  }
3403
3411
  }
3404
- return 1;
3405
- }
3406
- let match;
3407
- while ((match = selfClosingPattern.exec(mdx)) !== null) {
3408
- const name = match[1];
3409
- const propsString = match[2];
3410
- const props = parseProps(propsString);
3411
- components.push({
3412
- name,
3413
- props,
3414
- line: getLineNumber(match.index)
3415
- });
3412
+ return lo + 1;
3416
3413
  }
3417
- while ((match = withChildrenPattern.exec(mdx)) !== null) {
3418
- const name = match[1];
3419
- const propsString = match[2];
3420
- const children = match[3].trim();
3421
- const props = parseProps(propsString);
3422
- if (children) {
3423
- props.children = children;
3424
- }
3425
- components.push({
3426
- name,
3427
- props,
3428
- line: getLineNumber(match.index)
3429
- });
3414
+ const stack = [];
3415
+ let i = 0;
3416
+ while (i < mdx.length) {
3417
+ if (mdx[i] !== "<") {
3418
+ i++;
3419
+ continue;
3420
+ }
3421
+ const tagStart = i;
3422
+ i++;
3423
+ if (mdx[i] === "/") {
3424
+ i++;
3425
+ const closeMatch = mdx.slice(i).match(/^([A-Z][a-zA-Z0-9]*)\s*>/);
3426
+ if (closeMatch) {
3427
+ const closingName = closeMatch[1];
3428
+ i += closeMatch[0].length;
3429
+ for (let s = stack.length - 1; s >= 0; s--) {
3430
+ if (stack[s].name === closingName) {
3431
+ const opening = stack[s];
3432
+ const children = mdx.slice(opening.contentStart, tagStart).trim();
3433
+ const props = parseProps(opening.propsString);
3434
+ if (children) {
3435
+ props.children = children;
3436
+ }
3437
+ components.push({
3438
+ name: opening.name,
3439
+ props,
3440
+ line: opening.line
3441
+ });
3442
+ stack.splice(s, 1);
3443
+ break;
3444
+ }
3445
+ }
3446
+ }
3447
+ continue;
3448
+ }
3449
+ if (mdx[i] === "!" && mdx[i + 1] === "-" && mdx[i + 2] === "-") {
3450
+ const commentEnd = mdx.indexOf("-->", i + 3);
3451
+ i = commentEnd !== -1 ? commentEnd + 3 : mdx.length;
3452
+ continue;
3453
+ }
3454
+ const tagMatch = mdx.slice(i).match(/^([A-Z][a-zA-Z0-9]*)([\s\S]*?)(\/)?>/);
3455
+ if (!tagMatch) {
3456
+ continue;
3457
+ }
3458
+ const name = tagMatch[1];
3459
+ const attrsPart = tagMatch[2].trim();
3460
+ const isSelfClosing = tagMatch[3] === "/";
3461
+ i += tagMatch[0].length;
3462
+ if (isSelfClosing) {
3463
+ components.push({
3464
+ name,
3465
+ props: parseProps(attrsPart),
3466
+ line: getLineNumber(tagStart)
3467
+ });
3468
+ } else {
3469
+ stack.push({
3470
+ name,
3471
+ propsString: attrsPart,
3472
+ tagStart,
3473
+ contentStart: tagStart + 1 + tagMatch[0].length,
3474
+ // after '>'
3475
+ line: getLineNumber(tagStart)
3476
+ });
3477
+ }
3430
3478
  }
3431
3479
  return components;
3432
3480
  }
@@ -3774,7 +3822,7 @@ function requireApiCredentials() {
3774
3822
  return { apiUrl, apiKey };
3775
3823
  }
3776
3824
  program.action(async () => {
3777
- const { interactiveMenu } = await import("./interactive-menu-QKE6FMPN.js");
3825
+ const { interactiveMenu } = await import("./interactive-menu-FYVOQSTL.js");
3778
3826
  await interactiveMenu();
3779
3827
  });
3780
3828
  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/index.d.ts CHANGED
@@ -2391,7 +2391,8 @@ declare const componentSchemas: {
2391
2391
  }, z.core.$strip>;
2392
2392
  };
2393
2393
  type ComponentName = keyof typeof componentSchemas;
2394
- type ComponentSource = "standard" | "custom";
2394
+ declare const COMPONENT_SOURCES: readonly ["standard", "custom"];
2395
+ type ComponentSource = (typeof COMPONENT_SOURCES)[number];
2395
2396
  type ComponentKind = "presentational" | "data-bound";
2396
2397
  interface ComponentBinding {
2397
2398
  prop: string;
package/dist/index.js CHANGED
@@ -837,8 +837,14 @@ var FORBIDDEN_PATTERNS = [
837
837
  { pattern: /src\s*=\s*["']?\s*data:/i, message: "data: URL\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093" }
838
838
  ];
839
839
  function stripCodeBlocksForPatternCheck(mdx) {
840
- let result = mdx.replace(/<CodeBlock[^>]*>([^]*?)<\/CodeBlock>/g, "<CodeBlock>__CODE_PLACEHOLDER__</CodeBlock>");
841
- result = result.replace(/```[\s\S]*?```/g, "```__CODE_PLACEHOLDER__```");
840
+ let result = mdx.replace(/<CodeBlock[^>]*>([^]*?)<\/CodeBlock>/g, (_match, content) => {
841
+ const newlineCount = (content.match(/\n/g) || []).length;
842
+ return "<CodeBlock>__CODE_PLACEHOLDER__" + "\n".repeat(newlineCount) + "</CodeBlock>";
843
+ });
844
+ result = result.replace(/```[\s\S]*?```/g, (match) => {
845
+ const newlineCount = (match.match(/\n/g) || []).length;
846
+ return "```__CODE_PLACEHOLDER__" + "\n".repeat(Math.max(0, newlineCount - 1)) + "```";
847
+ });
842
848
  return result;
843
849
  }
844
850
  function escapeCodeBlocksForCompile(mdx) {
@@ -854,8 +860,6 @@ function escapeCodeBlocksForCompile(mdx) {
854
860
  }
855
861
  function extractComponents(mdx) {
856
862
  const components = [];
857
- const selfClosingPattern = /<([A-Z][a-zA-Z0-9]*)\s*([^>]*?)\/>/g;
858
- const withChildrenPattern = /<([A-Z][a-zA-Z0-9]*)\s*([^>]*)>([^]*?)<\/\1>/g;
859
863
  const lines = mdx.split("\n");
860
864
  const lineOffsets = [];
861
865
  let offset = 0;
@@ -864,37 +868,81 @@ function extractComponents(mdx) {
864
868
  offset += line.length + 1;
865
869
  }
866
870
  function getLineNumber(index) {
867
- for (let i = lineOffsets.length - 1; i >= 0; i--) {
868
- if (lineOffsets[i] <= index) {
869
- return i + 1;
871
+ let lo = 0, hi = lineOffsets.length - 1;
872
+ while (lo < hi) {
873
+ const mid = Math.floor((lo + hi + 1) / 2);
874
+ if (lineOffsets[mid] <= index) {
875
+ lo = mid;
876
+ } else {
877
+ hi = mid - 1;
870
878
  }
871
879
  }
872
- return 1;
880
+ return lo + 1;
873
881
  }
874
- let match;
875
- while ((match = selfClosingPattern.exec(mdx)) !== null) {
876
- const name = match[1];
877
- const propsString = match[2];
878
- const props = parseProps(propsString);
879
- components.push({
880
- name,
881
- props,
882
- line: getLineNumber(match.index)
883
- });
884
- }
885
- while ((match = withChildrenPattern.exec(mdx)) !== null) {
886
- const name = match[1];
887
- const propsString = match[2];
888
- const children = match[3].trim();
889
- const props = parseProps(propsString);
890
- if (children) {
891
- props.children = children;
882
+ const stack = [];
883
+ let i = 0;
884
+ while (i < mdx.length) {
885
+ if (mdx[i] !== "<") {
886
+ i++;
887
+ continue;
888
+ }
889
+ const tagStart = i;
890
+ i++;
891
+ if (mdx[i] === "/") {
892
+ i++;
893
+ const closeMatch = mdx.slice(i).match(/^([A-Z][a-zA-Z0-9]*)\s*>/);
894
+ if (closeMatch) {
895
+ const closingName = closeMatch[1];
896
+ i += closeMatch[0].length;
897
+ for (let s = stack.length - 1; s >= 0; s--) {
898
+ if (stack[s].name === closingName) {
899
+ const opening = stack[s];
900
+ const children = mdx.slice(opening.contentStart, tagStart).trim();
901
+ const props = parseProps(opening.propsString);
902
+ if (children) {
903
+ props.children = children;
904
+ }
905
+ components.push({
906
+ name: opening.name,
907
+ props,
908
+ line: opening.line
909
+ });
910
+ stack.splice(s, 1);
911
+ break;
912
+ }
913
+ }
914
+ }
915
+ continue;
916
+ }
917
+ if (mdx[i] === "!" && mdx[i + 1] === "-" && mdx[i + 2] === "-") {
918
+ const commentEnd = mdx.indexOf("-->", i + 3);
919
+ i = commentEnd !== -1 ? commentEnd + 3 : mdx.length;
920
+ continue;
921
+ }
922
+ const tagMatch = mdx.slice(i).match(/^([A-Z][a-zA-Z0-9]*)([\s\S]*?)(\/)?>/);
923
+ if (!tagMatch) {
924
+ continue;
925
+ }
926
+ const name = tagMatch[1];
927
+ const attrsPart = tagMatch[2].trim();
928
+ const isSelfClosing = tagMatch[3] === "/";
929
+ i += tagMatch[0].length;
930
+ if (isSelfClosing) {
931
+ components.push({
932
+ name,
933
+ props: parseProps(attrsPart),
934
+ line: getLineNumber(tagStart)
935
+ });
936
+ } else {
937
+ stack.push({
938
+ name,
939
+ propsString: attrsPart,
940
+ tagStart,
941
+ contentStart: tagStart + 1 + tagMatch[0].length,
942
+ // after '>'
943
+ line: getLineNumber(tagStart)
944
+ });
892
945
  }
893
- components.push({
894
- name,
895
- props,
896
- line: getLineNumber(match.index)
897
- });
898
946
  }
899
947
  return components;
900
948
  }