digdesign 0.6.0 → 0.6.2

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 (2) hide show
  1. package/dist/index.js +115 -53
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2054,13 +2054,65 @@ async function impactCommand(name, options) {
2054
2054
  }
2055
2055
  }
2056
2056
 
2057
+ // src/commands/skill.ts
2058
+ import { mkdir as mkdir4, writeFile as writeFile6 } from "fs/promises";
2059
+ import path11 from "path";
2060
+ var SKILL_PATH = ".claude/skills/dig-design-system/SKILL.md";
2061
+ async function skillCommand() {
2062
+ const cwd = process.cwd();
2063
+ const registryUrl = await configExists(cwd) ? (await readConfig(cwd)).registryUrl : defaultConfig().registryUrl;
2064
+ const url = new URL("/api/skill", registryUrl);
2065
+ let response;
2066
+ try {
2067
+ response = await fetch(url);
2068
+ } catch {
2069
+ throw new DigError(`\u0627\u062A\u0635\u0627\u0644 \u0628\u0647 ${url.origin} \u0628\u0631\u0627\u06CC \u06AF\u0631\u0641\u062A\u0646\u0650 Skill \u0628\u0631\u0642\u0631\u0627\u0631 \u0646\u0634\u062F.`);
2070
+ }
2071
+ if (!response.ok) throw new DigError(`Skill \u06AF\u0631\u0641\u062A\u0647 \u0646\u0634\u062F: ${response.status}`);
2072
+ const target = path11.join(cwd, SKILL_PATH);
2073
+ await mkdir4(path11.dirname(target), { recursive: true });
2074
+ await writeFile6(target, await response.text(), "utf8");
2075
+ console.log(`\u2713 ${SKILL_PATH} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F (Skill\u0650 \u0631\u0633\u0645\u06CC\u0650 \u062F\u06CC\u06AF \u0628\u0631\u0627\u06CC Claude Code).`);
2076
+ }
2077
+
2078
+ // src/commands/tokens.ts
2079
+ import { mkdir as mkdir5, readFile as readFile8, writeFile as writeFile7 } from "fs/promises";
2080
+ import path12 from "path";
2081
+ async function tokensCommand(options) {
2082
+ const cwd = process.cwd();
2083
+ const registryUrl = await configExists(cwd) ? (await readConfig(cwd)).registryUrl : defaultConfig().registryUrl;
2084
+ const designMd = await readFile8(path12.join(cwd, DESIGN_MD_FILE), "utf8").catch(() => "");
2085
+ const brand = options.brand ?? readDesignMdSettings(designMd).brand;
2086
+ const outDir = path12.join(cwd, options.out ?? "tokens");
2087
+ await mkdir5(outDir, { recursive: true });
2088
+ for (const mode of ["light", "dark"]) {
2089
+ const url = new URL("/api/tokens", registryUrl);
2090
+ url.searchParams.set("mode", mode);
2091
+ if (brand) url.searchParams.set("brand", brand);
2092
+ let response;
2093
+ try {
2094
+ response = await fetch(url);
2095
+ } catch {
2096
+ throw new DigError(`\u0627\u062A\u0635\u0627\u0644 \u0628\u0647 ${url.origin} \u0628\u0631\u0627\u06CC \u06AF\u0631\u0641\u062A\u0646\u0650 \u062A\u0648\u06A9\u0646\u200C\u0647\u0627 \u0628\u0631\u0642\u0631\u0627\u0631 \u0646\u0634\u062F.`);
2097
+ }
2098
+ if (!response.ok) {
2099
+ const body = await response.json().catch(() => null);
2100
+ throw new DigError(`\u062A\u0648\u06A9\u0646\u200C\u0647\u0627 \u06AF\u0631\u0641\u062A\u0647 \u0646\u0634\u062F: ${body?.error ?? response.status}`);
2101
+ }
2102
+ const file = path12.join(outDir, `dig-${mode}.tokens.json`);
2103
+ await writeFile7(file, await response.text(), "utf8");
2104
+ console.log(`\u2713 ${path12.relative(cwd, file)} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F${brand ? ` (\u0628\u0631\u0646\u062F ${brand})` : ""}.`);
2105
+ }
2106
+ console.log("\n\u062F\u0631 \u0641\u06CC\u06AF\u0645\u0627 \u0647\u0631 \u0641\u0627\u06CC\u0644 \u0631\u0627 \u06CC\u06A9 mode \u0627\u0632 Variables \u0648\u0627\u0631\u062F \u06A9\u0646\u06CC\u062F (\u0631\u0648\u0634\u0646 \u0648 \u062A\u06CC\u0631\u0647).");
2107
+ }
2108
+
2057
2109
  // src/commands/init.ts
2058
- import { readFile as readFile10, writeFile as writeFile8 } from "fs/promises";
2059
- import path14 from "path";
2110
+ import { readFile as readFile11, writeFile as writeFile10 } from "fs/promises";
2111
+ import path16 from "path";
2060
2112
 
2061
2113
  // src/lib/agent-instructions.ts
2062
- import { readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
2063
- import path11 from "path";
2114
+ import { mkdir as mkdir6, readFile as readFile9, writeFile as writeFile8 } from "fs/promises";
2115
+ import path13 from "path";
2064
2116
  var AGENT_CLIENTS = [
2065
2117
  { value: "claude-code", label: "Claude Code (CLAUDE.md)" },
2066
2118
  { value: "codex", label: "Codex (AGENTS.md)" },
@@ -2075,7 +2127,7 @@ var FONTS = [
2075
2127
  ];
2076
2128
  var BLOCK_START = "<!-- dig:start";
2077
2129
  var BLOCK_END = "<!-- dig:end -->";
2078
- async function fetchInstructionsFile(registryUrl, options) {
2130
+ async function fetchSetupFiles(registryUrl, options) {
2079
2131
  const url = new URL("/api/agent-setup", registryUrl);
2080
2132
  if (options.agent) url.searchParams.set("client", options.agent);
2081
2133
  for (const key2 of ["brand", "font", "name"]) {
@@ -2089,11 +2141,10 @@ async function fetchInstructionsFile(registryUrl, options) {
2089
2141
  throw new DigError(`\u0627\u062A\u0635\u0627\u0644 \u0628\u0647 ${url.origin} \u0628\u0631\u0627\u06CC \u0633\u0627\u062E\u062A\u0646\u0650 \u0641\u0627\u06CC\u0644\u0650 \u0627\u06CC\u062C\u0646\u062A \u0628\u0631\u0642\u0631\u0627\u0631 \u0646\u0634\u062F.`);
2090
2142
  }
2091
2143
  const body = await response.json().catch(() => null);
2092
- const file = body?.files?.find((item) => /\.md$/.test(item.path) && item.path !== "DESIGN.md");
2093
- if (!response.ok || !file) {
2144
+ if (!response.ok || !body?.files?.length) {
2094
2145
  throw new DigError(`\u0641\u0627\u06CC\u0644\u0650 \u0627\u06CC\u062C\u0646\u062A \u0633\u0627\u062E\u062A\u0647 \u0646\u0634\u062F: ${body?.error ?? response.status}`);
2095
2146
  }
2096
- return file;
2147
+ return body.files;
2097
2148
  }
2098
2149
  function mergeInstructions(existing, block) {
2099
2150
  const trimmed = block.trim();
@@ -2110,19 +2161,28 @@ ${trimmed}
2110
2161
  `;
2111
2162
  }
2112
2163
  async function writeAgentInstructions(cwd, registryUrl, options) {
2113
- const file = await fetchInstructionsFile(registryUrl, options);
2114
- const target = path11.join(cwd, file.path);
2115
- const existing = await readFile8(target, "utf8").catch(() => null);
2116
- await writeFile6(target, mergeInstructions(existing, file.content), "utf8");
2164
+ const files = await fetchSetupFiles(registryUrl, options);
2165
+ const instructions = files.find((item) => /^[A-Z]+\.md$/.test(item.path) && item.path !== "DESIGN.md");
2166
+ if (!instructions) throw new DigError("\u0641\u0627\u06CC\u0644\u0650 \u0627\u06CC\u062C\u0646\u062A \u062F\u0631 \u067E\u0627\u0633\u062E\u0650 \u0633\u0631\u0648\u0631 \u0646\u0628\u0648\u062F.");
2167
+ const target = path13.join(cwd, instructions.path);
2168
+ const existing = await readFile9(target, "utf8").catch(() => null);
2169
+ await writeFile8(target, mergeInstructions(existing, instructions.content), "utf8");
2117
2170
  console.log(
2118
- existing === null ? `\u2713 ${file.path} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F (\u0627\u06CC\u062C\u0646\u062A \u0641\u0648\u0646\u062A \u0648 \u0631\u0646\u06AF \u0631\u0627 \u0627\u0632 \u0627\u06CC\u0646 \u0641\u0627\u06CC\u0644 \u0645\u06CC\u200C\u062E\u0648\u0627\u0646\u062F \u0648 \u062F\u0648\u0628\u0627\u0631\u0647 \u0646\u0645\u06CC\u200C\u067E\u0631\u0633\u062F).` : `\u2713 \u0628\u062E\u0634\u0650 \u062F\u06CC\u06AF \u062F\u0631 ${file.path} \u0628\u0647\u200C\u0631\u0648\u0632 \u0634\u062F\u061B \u0628\u0642\u06CC\u0647\u0654 \u0641\u0627\u06CC\u0644 \u062F\u0633\u062A \u0646\u062E\u0648\u0631\u062F.`
2171
+ existing === null ? `\u2713 ${instructions.path} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F (\u0627\u06CC\u062C\u0646\u062A \u0641\u0648\u0646\u062A \u0648 \u0631\u0646\u06AF \u0631\u0627 \u0627\u0632 \u0627\u06CC\u0646 \u0641\u0627\u06CC\u0644 \u0645\u06CC\u200C\u062E\u0648\u0627\u0646\u062F \u0648 \u062F\u0648\u0628\u0627\u0631\u0647 \u0646\u0645\u06CC\u200C\u067E\u0631\u0633\u062F).` : `\u2713 \u0628\u062E\u0634\u0650 \u062F\u06CC\u06AF \u062F\u0631 ${instructions.path} \u0628\u0647\u200C\u0631\u0648\u0632 \u0634\u062F\u061B \u0628\u0642\u06CC\u0647\u0654 \u0641\u0627\u06CC\u0644 \u062F\u0633\u062A \u0646\u062E\u0648\u0631\u062F.`
2119
2172
  );
2120
- return file.path;
2173
+ const skill = files.find((item) => item.path.endsWith("/SKILL.md"));
2174
+ if (skill) {
2175
+ const skillTarget = path13.join(cwd, skill.path);
2176
+ await mkdir6(path13.dirname(skillTarget), { recursive: true });
2177
+ await writeFile8(skillTarget, skill.content, "utf8");
2178
+ console.log(`\u2713 ${skill.path} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F (Skill\u0650 \u0631\u0633\u0645\u06CC\u0650 \u062F\u06CC\u06AF \u0628\u0631\u0627\u06CC \u0633\u0627\u062E\u062A\u0646\u0650 \u0635\u0641\u062D\u0647).`);
2179
+ }
2180
+ return instructions.path;
2121
2181
  }
2122
2182
 
2123
2183
  // src/commands/theme.ts
2124
- import { access as access5, mkdir as mkdir4, readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
2125
- import path13 from "path";
2184
+ import { access as access5, mkdir as mkdir7, readFile as readFile10, writeFile as writeFile9 } from "fs/promises";
2185
+ import path15 from "path";
2126
2186
 
2127
2187
  // src/lib/brand-ramp.ts
2128
2188
  var RAMP_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
@@ -2226,9 +2286,9 @@ function buildBrandRamp(hex) {
2226
2286
  }
2227
2287
 
2228
2288
  // src/lib/theme-files.ts
2229
- import path12 from "path";
2289
+ import path14 from "path";
2230
2290
  function importPath(fromFile, toFile) {
2231
- const rel = toPosixPath(path12.relative(path12.dirname(fromFile), toFile));
2291
+ const rel = toPosixPath(path14.relative(path14.dirname(fromFile), toFile));
2232
2292
  return rel.startsWith(".") ? rel : `./${rel}`;
2233
2293
  }
2234
2294
  function globalsCss(paths, extraStatements = []) {
@@ -2393,7 +2453,7 @@ function splitTheme(projectCss, digThemeCss) {
2393
2453
  var THEME_ITEM = "theme";
2394
2454
  async function readIfExists2(target) {
2395
2455
  try {
2396
- return await readFile9(target, "utf8");
2456
+ return await readFile10(target, "utf8");
2397
2457
  } catch {
2398
2458
  return null;
2399
2459
  }
@@ -2407,7 +2467,7 @@ async function exists(target) {
2407
2467
  }
2408
2468
  }
2409
2469
  function themePaths(config) {
2410
- const dir = path13.posix.dirname(toPosixPath(config.tailwind.css));
2470
+ const dir = path15.posix.dirname(toPosixPath(config.tailwind.css));
2411
2471
  return {
2412
2472
  css: config.tailwind.css,
2413
2473
  theme: config.tailwind.theme ?? `${dir}/dig-theme.css`,
@@ -2441,9 +2501,9 @@ async function recordTheme(cwd, config, themeRel, item) {
2441
2501
  await writeLock(lock, cwd);
2442
2502
  }
2443
2503
  async function writeText(cwd, rel, content) {
2444
- const target = path13.join(cwd, rel);
2445
- await mkdir4(path13.dirname(target), { recursive: true });
2446
- await writeFile7(target, content, "utf8");
2504
+ const target = path15.join(cwd, rel);
2505
+ await mkdir7(path15.dirname(target), { recursive: true });
2506
+ await writeFile9(target, content, "utf8");
2447
2507
  }
2448
2508
  async function installTheme(cwd, config, options) {
2449
2509
  const paths = themePaths(config);
@@ -2451,7 +2511,7 @@ async function installTheme(cwd, config, options) {
2451
2511
  const ramp = options.brand ? buildBrandRamp(options.brand) : void 0;
2452
2512
  await writeText(cwd, paths.theme, item.content);
2453
2513
  console.log(`\u2713 \u062A\u0645\u0650 \u062F\u06CC\u06AF \u062F\u0631 ${paths.theme} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F (\u0645\u0627\u0644\u0650 \u062F\u06CC\u06AF\u061B \u0628\u0627 \xABdig update theme\xBB \u0628\u0647\u200C\u0631\u0648\u0632 \u0645\u06CC\u200C\u0634\u0648\u062F).`);
2454
- const existingBrand = await readIfExists2(path13.join(cwd, paths.brand));
2514
+ const existingBrand = await readIfExists2(path15.join(cwd, paths.brand));
2455
2515
  if (existingBrand === null) {
2456
2516
  await writeText(cwd, paths.brand, brandCss({ ramp, hex: options.brand }));
2457
2517
  console.log(`\u2713 ${paths.brand} \u0633\u0627\u062E\u062A\u0647 \u0634\u062F (\u0645\u0627\u0644\u0650 \u067E\u0631\u0648\u0698\u0647\u061B \u062F\u06CC\u06AF \u0647\u0631\u06AF\u0632 \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC\u200C\u0627\u0634 \u0646\u0645\u06CC\u200C\u06A9\u0646\u062F).`);
@@ -2462,10 +2522,10 @@ async function installTheme(cwd, config, options) {
2462
2522
  console.log(`- ${paths.brand} \u0627\u0632 \u0642\u0628\u0644 \u0647\u0633\u062A\u061B \u062F\u0633\u062A \u0646\u062E\u0648\u0631\u062F.`);
2463
2523
  }
2464
2524
  if (ramp) reportContrast(ramp.primaryContrast);
2465
- const cssTarget = path13.join(cwd, paths.css);
2525
+ const cssTarget = path15.join(cwd, paths.css);
2466
2526
  const existingCss = await readIfExists2(cssTarget);
2467
2527
  if (!isBoilerplateCss(existingCss) && existingCss !== null) {
2468
- await writeFile7(`${cssTarget}.backup`, existingCss, "utf8");
2528
+ await writeFile9(`${cssTarget}.backup`, existingCss, "utf8");
2469
2529
  console.log(` \u0646\u0633\u062E\u0647\u0654 \u0642\u0628\u0644\u06CC\u0650 ${paths.css} \u062F\u0631 ${paths.css}.backup \u0646\u06AF\u0647 \u062F\u0627\u0634\u062A\u0647 \u0634\u062F.`);
2470
2530
  console.log(` \u0627\u06AF\u0631 \u0622\u0646 \u0641\u0627\u06CC\u0644 \u062A\u0645\u0650 \u0642\u062F\u06CC\u0645\u06CC\u0650 \u062F\u06CC\u06AF \u0628\u0648\u062F\u060C \u0628\u0647\u200C\u062C\u0627\u06CC init \u0627\u0632 \xABdig theme split\xBB \u0627\u0633\u062A\u0641\u0627\u062F\u0647 \u06A9\u0646\u06CC\u062F.`);
2471
2531
  }
@@ -2498,11 +2558,11 @@ async function themeSplitCommand(options) {
2498
2558
  return;
2499
2559
  }
2500
2560
  const paths = themePaths(config);
2501
- const current = await readIfExists2(path13.join(cwd, paths.css));
2561
+ const current = await readIfExists2(path15.join(cwd, paths.css));
2502
2562
  if (current === null || isBoilerplateCss(current)) {
2503
2563
  throw new DigError(`${paths.css} \u062A\u0645\u06CC \u0646\u062F\u0627\u0631\u062F\u061B \u0628\u0631\u0627\u06CC \u0646\u0635\u0628\u0650 \u062A\u0627\u0632\u0647 \xABdig init\xBB \u0631\u0627 \u0627\u062C\u0631\u0627 \u06A9\u0646\u06CC\u062F.`);
2504
2564
  }
2505
- if (await exists(path13.join(cwd, paths.brand))) {
2565
+ if (await exists(path15.join(cwd, paths.brand))) {
2506
2566
  throw new DigError(`${paths.brand} \u0627\u0632 \u0642\u0628\u0644 \u0648\u062C\u0648\u062F \u062F\u0627\u0631\u062F\u061B \u0628\u0631\u0627\u06CC \u062C\u0644\u0648\u06AF\u06CC\u0631\u06CC \u0627\u0632 \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC\u060C \u0627\u0648\u0644 \u062C\u0627\u0628\u0647\u200C\u062C\u0627\u06CC\u0634 \u06A9\u0646\u06CC\u062F.`);
2507
2567
  }
2508
2568
  console.log(`\u062F\u0631\u06CC\u0627\u0641\u062A\u0650 \u062A\u0645\u0650 \u062F\u06CC\u06AF \u0627\u0632 ${config.registryUrl} \u2026`);
@@ -2521,7 +2581,7 @@ ${split.changed} \u062A\u0648\u06A9\u0646\u0650 \u0639\u0648\u0636\u200C\u0634\u
2521
2581
  console.log(split.body || "(\u062E\u0627\u0644\u06CC: \u067E\u0631\u0648\u0698\u0647 \u0686\u06CC\u0632\u06CC \u062F\u0631 \u062A\u0645 \u0639\u0648\u0636 \u0646\u06A9\u0631\u062F\u0647)");
2522
2582
  return;
2523
2583
  }
2524
- await writeFile7(path13.join(cwd, `${paths.css}.backup`), current, "utf8");
2584
+ await writeFile9(path15.join(cwd, `${paths.css}.backup`), current, "utf8");
2525
2585
  await writeText(cwd, paths.theme, item.content);
2526
2586
  await writeText(cwd, paths.brand, brandCss({ body: split.body }));
2527
2587
  await writeText(cwd, paths.css, globalsCss(paths, split.extraStatements));
@@ -2545,7 +2605,7 @@ async function themeBrandCommand(hex) {
2545
2605
  }
2546
2606
  const paths = themePaths(config);
2547
2607
  const ramp = buildBrandRamp(hex);
2548
- const existing = await readIfExists2(path13.join(cwd, paths.brand)) ?? brandCss({});
2608
+ const existing = await readIfExists2(path15.join(cwd, paths.brand)) ?? brandCss({});
2549
2609
  const next = replaceBrandRamp(existing, ramp, hex);
2550
2610
  await writeText(cwd, paths.brand, next);
2551
2611
  console.log(`\u2713 \u0631\u0645\u067E\u0650 \u0628\u0631\u0646\u062F \u062F\u0631 ${paths.brand} \u0627\u0632 ${hex} \u0633\u0627\u062E\u062A\u0647 \u0634\u062F (Shade \u06F6\u06F0\u06F0 = \u0631\u0646\u06AF\u0650 \u062F\u0627\u062F\u0647\u200C\u0634\u062F\u0647).`);
@@ -2563,14 +2623,14 @@ async function themeBrandCommand(hex) {
2563
2623
  // src/commands/init.ts
2564
2624
  async function readIfExists3(target) {
2565
2625
  try {
2566
- return await readFile10(target, "utf8");
2626
+ return await readFile11(target, "utf8");
2567
2627
  } catch {
2568
2628
  return null;
2569
2629
  }
2570
2630
  }
2571
2631
  async function writeTheme(config, cwd, options) {
2572
2632
  const paths = themePaths(config);
2573
- const existing = await readIfExists3(path14.join(cwd, paths.css));
2633
+ const existing = await readIfExists3(path16.join(cwd, paths.css));
2574
2634
  if (!isBoilerplateCss(existing) && !options.yes) {
2575
2635
  console.log(`
2576
2636
  ${paths.css} \u0627\u0632 \u0642\u0628\u0644 \u0645\u062D\u062A\u0648\u0627 \u062F\u0627\u0631\u062F.`);
@@ -2595,7 +2655,7 @@ ${paths.css} \u0627\u0632 \u0642\u0628\u0644 \u0645\u062D\u062A\u0648\u0627 \u06
2595
2655
  }
2596
2656
  async function applyRtl(cwd) {
2597
2657
  for (const candidate of ["src/app/layout.tsx", "app/layout.tsx"]) {
2598
- const target = path14.join(cwd, candidate);
2658
+ const target = path16.join(cwd, candidate);
2599
2659
  const source = await readIfExists3(target);
2600
2660
  if (source === null) continue;
2601
2661
  if (/<html[^>]*\sdir=/.test(source)) {
@@ -2608,7 +2668,7 @@ async function applyRtl(cwd) {
2608
2668
  match[0],
2609
2669
  `<html${match[1]} dir="rtl">`.replace(/\s+dir="rtl">$/, ' dir="rtl">')
2610
2670
  );
2611
- await writeFile8(target, updated, "utf8");
2671
+ await writeFile10(target, updated, "utf8");
2612
2672
  console.log(`\u2713 dir="rtl" \u0628\u0647 ${candidate} \u0627\u0636\u0627\u0641\u0647 \u0634\u062F.`);
2613
2673
  return;
2614
2674
  }
@@ -2640,14 +2700,14 @@ async function initCommand(options) {
2640
2700
  rtl: await confirm("\u067E\u0631\u0648\u0698\u0647 \u0631\u0627\u0633\u062A\u200C\u0628\u0647\u200C\u0686\u067E (RTL) \u0627\u0633\u062A\u061F", base.rtl),
2641
2701
  tailwind: await (async () => {
2642
2702
  const css = await ask("\u0645\u0633\u06CC\u0631 \u0641\u0627\u06CC\u0644 CSS \u0627\u0635\u0644\u06CC \u062A\u06CC\u0644\u0648\u06CC\u0646\u062F\u061F", base.tailwind.css);
2643
- const dir = path14.posix.dirname(css.split(path14.sep).join("/"));
2703
+ const dir = path16.posix.dirname(css.split(path16.sep).join("/"));
2644
2704
  return { ...base.tailwind, css, theme: `${dir}/dig-theme.css`, brand: `${dir}/brand.css` };
2645
2705
  })()
2646
2706
  };
2647
2707
  const decisions = await askProjectDecisions(options);
2648
2708
  options = { ...options, brand: decisions.brand };
2649
2709
  await writeConfig(config, cwd);
2650
- console.log(`\u2713 ${path14.join(cwd, "dig.json")} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F.`);
2710
+ console.log(`\u2713 ${path16.join(cwd, "dig.json")} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F.`);
2651
2711
  const theme2 = await writeTheme(config, cwd, options);
2652
2712
  if (config.rtl) {
2653
2713
  await applyRtl(cwd);
@@ -2675,7 +2735,7 @@ async function initCommand(options) {
2675
2735
  import { createInterface as createInterface2 } from "readline";
2676
2736
 
2677
2737
  // src/lib/version.ts
2678
- var CLI_VERSION = "0.6.0";
2738
+ var CLI_VERSION = "0.6.2";
2679
2739
 
2680
2740
  // src/commands/mcp.ts
2681
2741
  var DEFAULT_MCP_URL = "https://docs.digdesign.ir/api/mcp";
@@ -2765,8 +2825,8 @@ async function mcpCommand(options) {
2765
2825
  }
2766
2826
 
2767
2827
  // src/lib/migration-apply.ts
2768
- import { readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
2769
- import path15 from "path";
2828
+ import { readFile as readFile12, writeFile as writeFile11 } from "fs/promises";
2829
+ import path17 from "path";
2770
2830
 
2771
2831
  // src/lib/migration-strategy.ts
2772
2832
  var TextReplaceStrategy = class {
@@ -2843,7 +2903,7 @@ function looksBinary2(buffer) {
2843
2903
  async function readTextFileSafely2(target) {
2844
2904
  let buffer;
2845
2905
  try {
2846
- buffer = await readFile11(target);
2906
+ buffer = await readFile12(target);
2847
2907
  } catch (error) {
2848
2908
  if (error.code === "ENOENT") return void 0;
2849
2909
  throw error;
@@ -2888,8 +2948,8 @@ async function planOrApplyMigrations(params) {
2888
2948
  };
2889
2949
  }
2890
2950
  const fileTargets = registryItem.files.map((file) => {
2891
- const target = path15.join(cwd, resolveTargetPath(file.path, aliases, paths));
2892
- return { relPath: toPosixPath(path15.relative(cwd, target)), target };
2951
+ const target = path17.join(cwd, resolveTargetPath(file.path, aliases, paths));
2952
+ return { relPath: toPosixPath(path17.relative(cwd, target)), target };
2893
2953
  });
2894
2954
  const currentContents = /* @__PURE__ */ new Map();
2895
2955
  for (const ft of fileTargets) {
@@ -2955,12 +3015,12 @@ async function planOrApplyMigrations(params) {
2955
3015
  const written = [];
2956
3016
  try {
2957
3017
  for (const item of pending) {
2958
- await writeFile9(item.target, item.newContent, "utf8");
3018
+ await writeFile11(item.target, item.newContent, "utf8");
2959
3019
  written.push(item);
2960
3020
  }
2961
3021
  } catch (error) {
2962
3022
  for (const item of written) {
2963
- await writeFile9(item.target, item.originalContent, "utf8");
3023
+ await writeFile11(item.target, item.originalContent, "utf8");
2964
3024
  }
2965
3025
  return {
2966
3026
  name,
@@ -3573,7 +3633,7 @@ ${entry.migrationHint}`);
3573
3633
 
3574
3634
  // src/lib/missing-dependencies.ts
3575
3635
  import { access as access6 } from "fs/promises";
3576
- import path16 from "path";
3636
+ import path18 from "path";
3577
3637
  async function exists2(target) {
3578
3638
  try {
3579
3639
  await access6(target);
@@ -3594,7 +3654,7 @@ async function findMissingDependencies(params) {
3594
3654
  for (const item of tree.values()) {
3595
3655
  if (requested.has(item.name) || lock.components[item.name]) continue;
3596
3656
  for (const file of item.files) {
3597
- const target = path16.join(
3657
+ const target = path18.join(
3598
3658
  cwd,
3599
3659
  resolveTargetPath(file.path, config.aliases, targetPathOptions(config))
3600
3660
  );
@@ -3608,8 +3668,8 @@ async function findMissingDependencies(params) {
3608
3668
  }
3609
3669
 
3610
3670
  // src/lib/update.ts
3611
- import { mkdir as mkdir5, readFile as readFile12, rm as rm2, writeFile as writeFile10 } from "fs/promises";
3612
- import path17 from "path";
3671
+ import { mkdir as mkdir8, readFile as readFile13, rm as rm2, writeFile as writeFile12 } from "fs/promises";
3672
+ import path19 from "path";
3613
3673
  function safeFileIndexes(drift) {
3614
3674
  const indexes = [];
3615
3675
  drift.files.forEach((file, index) => {
@@ -3629,7 +3689,7 @@ async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun, paths)
3629
3689
  for (const index of safeIndexes) {
3630
3690
  const file = drift.files[index];
3631
3691
  const registryFile = registryItem.files[index];
3632
- const target = path17.join(cwd, resolveTargetPath(registryFile.path, aliases, paths));
3692
+ const target = path19.join(cwd, resolveTargetPath(registryFile.path, aliases, paths));
3633
3693
  const isNewFile = file.status === "new_upstream";
3634
3694
  pending.push({
3635
3695
  index,
@@ -3637,14 +3697,14 @@ async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun, paths)
3637
3697
  newContent: registryFile.content,
3638
3698
  newHash: registryFile.hash ?? hashContent(registryFile.content),
3639
3699
  isNewFile,
3640
- originalContent: isNewFile ? void 0 : await readFile12(target, "utf8")
3700
+ originalContent: isNewFile ? void 0 : await readFile13(target, "utf8")
3641
3701
  });
3642
3702
  }
3643
3703
  const written = [];
3644
3704
  try {
3645
3705
  for (const item of pending) {
3646
- if (item.isNewFile) await mkdir5(path17.dirname(item.target), { recursive: true });
3647
- await writeFile10(item.target, item.newContent, "utf8");
3706
+ if (item.isNewFile) await mkdir8(path19.dirname(item.target), { recursive: true });
3707
+ await writeFile12(item.target, item.newContent, "utf8");
3648
3708
  written.push(item);
3649
3709
  }
3650
3710
  } catch (error) {
@@ -3652,7 +3712,7 @@ async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun, paths)
3652
3712
  if (item.isNewFile) {
3653
3713
  await rm2(item.target, { force: true });
3654
3714
  } else {
3655
- await writeFile10(item.target, item.originalContent, "utf8");
3715
+ await writeFile12(item.target, item.originalContent, "utf8");
3656
3716
  }
3657
3717
  }
3658
3718
  return { actions, writtenHashes: {}, rollbackError: error.message };
@@ -3981,6 +4041,8 @@ program.name("dig").description("CLI \u0631\u0633\u0645\u06CC \u062F\u06CC\u0632
3981
4041
  program.command("init").description(
3982
4042
  '\u0631\u0627\u0647\u200C\u0627\u0646\u062F\u0627\u0632\u06CC \u062F\u06CC\u06AF \u062F\u0631 \u067E\u0631\u0648\u0698\u0647: dig.json\u060C \u062A\u0645 \u0648 \u062A\u0648\u06A9\u0646\u200C\u0647\u0627\u060C dir="rtl"\u060C DESIGN.md \u0648 \u0641\u0627\u06CC\u0644\u0650 \u062F\u0633\u062A\u0648\u0631\u0650 \u06A9\u0627\u0631\u06CC\u0650 \u0627\u06CC\u062C\u0646\u062A'
3983
4043
  ).option("--yes", "\u067E\u0627\u0633\u062E \u067E\u06CC\u0634\u200C\u0641\u0631\u0636 \u0628\u0647 \u0647\u0645\u0647\u0654 \u0633\u0648\u0627\u0644\u0627\u062A", false).option("--brand <hex>", "\u0633\u0627\u062E\u062A\u0646\u0650 \u0631\u0645\u067E\u0650 \u0628\u0631\u0646\u062F \u0627\u0632 \u06CC\u06A9 \u0631\u0646\u06AF (\u0631\u0648\u06CC Shade \u06F6\u06F0\u06F0 \u0645\u06CC\u200C\u0646\u0634\u06CC\u0646\u062F)\u060C \u0645\u062B\u0644 #2C4C5B").option("--font <font>", "\u0641\u0648\u0646\u062A: iransans\u060C yekan \u06CC\u0627 vazirmatn").option("--agent <agent>", "\u0627\u06CC\u062C\u0646\u062A: claude-code\u060C codex\u060C cursor\u060C vscode \u06CC\u0627 gemini (\u0646\u0627\u0645\u0650 \u0641\u0627\u06CC\u0644\u0650 \u062F\u0633\u062A\u0648\u0631\u0650 \u06A9\u0627\u0631\u06CC \u0631\u0627 \u062A\u0639\u06CC\u06CC\u0646 \u0645\u06CC\u200C\u06A9\u0646\u062F)").action(initCommand);
4044
+ program.command("tokens").description("\u062A\u0648\u06A9\u0646\u200C\u0647\u0627\u06CC \u062F\u06CC\u06AF \u062F\u0631 \u0642\u0627\u0644\u0628\u0650 \u0627\u0633\u062A\u0627\u0646\u062F\u0627\u0631\u062F\u0650 DTCG \u0628\u0631\u0627\u06CC \u0641\u06CC\u06AF\u0645\u0627 \u0648 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06CC \u0637\u0631\u0627\u062D\u06CC\u060C \u06CC\u06A9 \u0641\u0627\u06CC\u0644 \u0628\u0631\u0627\u06CC \u0647\u0631 \u062D\u0627\u0644\u062A").option("--brand <hex>", "\u0631\u0646\u06AF \u0628\u0631\u0646\u062F\u061B \u067E\u06CC\u0634\u200C\u0641\u0631\u0636 \u0627\u0632 DESIGN.md\u0650 \u067E\u0631\u0648\u0698\u0647").option("--out <dir>", "\u067E\u0648\u0634\u0647\u0654 \u062E\u0631\u0648\u062C\u06CC (\u067E\u06CC\u0634\u200C\u0641\u0631\u0636 tokens)").action(tokensCommand);
4045
+ program.command("skill").description("\u06AF\u0630\u0627\u0634\u062A\u0646 \u06CC\u0627 \u0628\u0647\u200C\u0631\u0648\u0632\u06A9\u0631\u062F\u0646\u0650 Skill\u0650 \u0631\u0633\u0645\u06CC\u0650 \u062F\u06CC\u06AF \u0628\u0631\u0627\u06CC Claude Code \u062F\u0631 .claude/skills").action(skillCommand);
3984
4046
  program.command("design-md").description("\u0633\u0627\u062E\u062A\u0646\u0650 DESIGN.md \u062F\u0631 \u0631\u06CC\u0634\u0647\u0654 \u067E\u0631\u0648\u0698\u0647: \u062A\u0648\u06A9\u0646\u200C\u0647\u0627 \u0648 \u0642\u0627\u0639\u062F\u0647\u200C\u0647\u0627\u06CC \u062F\u06CC\u06AF \u0628\u0631\u0627\u06CC \u0627\u06CC\u062C\u0646\u062A\u200C\u0647\u0627\u06CC \u06A9\u062F\u0646\u0648\u06CC\u0633").option("--brand <hex>", "\u0631\u0646\u06AF \u0628\u0631\u0646\u062F \u062A\u0627 \u0631\u0646\u06AF\u200C\u0647\u0627\u06CC \u0648\u0627\u0642\u0639\u06CC\u0650 \u0628\u0631\u0646\u062F \u062F\u0631 \u0641\u0627\u06CC\u0644 \u0628\u06CC\u0627\u06CC\u062F\u060C \u0645\u062B\u0644 #2C4C5B").option("--secondary <hex>", "\u0631\u0646\u06AF \u062F\u0648\u0645\u0650 \u0628\u0631\u0646\u062F").option("--name <name>", "\u0646\u0627\u0645 \u0645\u062D\u0635\u0648\u0644").option("--font <font>", "\u0641\u0648\u0646\u062A: iransans\u060C yekan \u06CC\u0627 vazirmatn").option("--radius <radius>", "\u0634\u0639\u0627\u0639: none\u060C sm\u060C md\u060C lg\u060C xl \u06CC\u0627 full").option("--force", "\u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC\u0650 DESIGN.md\u0650 \u062F\u0633\u062A\u200C\u0646\u0648\u0634\u062A\u0647", false).action(designMdCommand);
3985
4047
  var theme = program.command("theme").description("\u062A\u0645 \u0648 \u0628\u0631\u0646\u062F: \u062C\u062F\u0627 \u06A9\u0631\u062F\u0646\u0650 \u062A\u0645\u0650 \u062F\u06CC\u06AF \u0627\u0632 \u0628\u0631\u0646\u062F\u0650 \u067E\u0631\u0648\u0698\u0647");
3986
4048
  theme.command("split").description("\u067E\u0631\u0648\u0698\u0647\u0654 \u0642\u062F\u06CC\u0645\u06CC \u0631\u0627 \u0628\u0647 \u0633\u0627\u062E\u062A\u0627\u0631\u0650 \u062F\u0648\u0641\u0627\u06CC\u0644\u06CC \u0645\u06CC\u200C\u0628\u0631\u062F (dig-theme.css \u0645\u0627\u0644\u0650 \u062F\u06CC\u06AF\u060C brand.css \u0645\u0627\u0644\u0650 \u067E\u0631\u0648\u0698\u0647)").option("--dry-run", "\u0641\u0642\u0637 \u0646\u0634\u0627\u0646 \u0628\u062F\u0647 \u0686\u0647 \u0686\u06CC\u0632\u06CC \u0628\u0647 brand.css \u0645\u06CC\u200C\u0631\u0648\u062F\u060C \u0686\u06CC\u0632\u06CC \u0646\u0646\u0648\u06CC\u0633", false).action(themeSplitCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "digdesign",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "CLI رسمی برای نصب کامپوننت‌های دیزاین سیستم دیگ",
5
5
  "type": "module",
6
6
  "license": "MIT",