@askewly/design 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { verifyDir } from "./verify.js";
10
10
  import { loadKnowledge, loadRecipes, loadTerms, loadTokens, loadTokensCss, searchKnowledge, searchTerms, tokensForTier, } from "./load.js";
11
11
  import { recall, RECALL_AXES } from "./data.js";
12
12
  import { assetUrl, buildPrompt, loadAssets, searchAssets, suggestAssets } from "./assets.js";
13
- import { getSite, listSites, SiteError } from "./site.js";
13
+ import { getSite, listSites, siteNextStep, SiteError } from "./site.js";
14
14
  const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
15
15
  const program = new Command();
16
16
  program
@@ -154,6 +154,14 @@ program
154
154
  try {
155
155
  const result = addRecipe(recipe, path.resolve(options.out), Boolean(options.force), path.resolve(options.tokens));
156
156
  console.log(`wrote ${result.file}`);
157
+ for (const lib of result.libs) {
158
+ if (lib.status === "written")
159
+ console.log(`wrote ${lib.file}`);
160
+ else if (lib.status === "unchanged")
161
+ console.log(`unchanged ${lib.file} (already identical)`);
162
+ else
163
+ console.log(`⚠ kept ${lib.file} - differs from the bundled lib; not overwritten. Diff it by hand if the component misbehaves.`);
164
+ }
157
165
  if (result.missingTokens.length > 0) {
158
166
  console.log(`\n⚠ tokens not found in ${options.tokens} — run \`askewly-design init\` first. Required:`);
159
167
  for (const token of result.missingTokens)
@@ -443,8 +451,8 @@ siteCmd
443
451
  try {
444
452
  const target = dir ?? slug;
445
453
  const n = await getSite(slug, target);
446
- console.log(`${n} files -> ${target}
447
- read ${path.join(target, "ASKEWLY-BUNDLE.md")} for what was left out and how to run it`);
454
+ console.log(`${n} files -> ${target}
455
+ ${siteNextStep(target)}`);
448
456
  }
449
457
  catch (error) {
450
458
  if (error instanceof SiteError)
package/dist/inject.js CHANGED
@@ -71,12 +71,16 @@ export function extractSectionNotes(recipe, title) {
71
71
  .filter((line) => line.trim().startsWith("- "))
72
72
  .map((line) => line.trim().slice(2));
73
73
  }
74
+ /** kickstart 의 srcRoot 규칙과 같다: 프로젝트에 src/ 가 있으면 그 안, 없으면 프로젝트 루트. */
75
+ export function defaultSrcRoot(projectDir) {
76
+ return existsSync(path.join(projectDir, "src")) ? path.join(projectDir, "src") : projectDir;
77
+ }
74
78
  /**
75
79
  * Writes the recipe's Code excerpt to <outDir>/<id>.tsx and reports which
76
80
  * tokens_used entries are not covered by an existing tokens.css in outDir's
77
81
  * project root (heuristic: tokens.css next to outDir or in cwd).
78
82
  */
79
- export function addRecipe(recipe, outDir, force, tokensCssPath) {
83
+ export function addRecipe(recipe, outDir, force, tokensCssPath, srcRoot = defaultSrcRoot(process.cwd())) {
80
84
  const snippet = extractCodeSnippet(recipe);
81
85
  const file = path.join(outDir, `${recipe.id}.tsx`);
82
86
  if (existsSync(file) && !force) {
@@ -84,6 +88,20 @@ export function addRecipe(recipe, outDir, force, tokensCssPath) {
84
88
  }
85
89
  mkdirSync(outDir, { recursive: true });
86
90
  writeFileSync(file, snippet);
91
+ // 컴포넌트가 import 하는 로컬 lib(`@/lib/...`)도 함께 쓴다. 같은 내용이면 건너뛰고,
92
+ // 다르면 덮어쓰지 않고 알린다(사용자가 고친 lib 를 조용히 날리지 않는다).
93
+ const libs = [];
94
+ for (const lib of recipe.lib_files ?? []) {
95
+ const dest = path.join(srcRoot, lib.target);
96
+ if (existsSync(dest)) {
97
+ const same = readFileSync(dest, "utf8").replace(/\r\n/g, "\n") === lib.content;
98
+ libs.push({ file: dest, status: same ? "unchanged" : "conflict" });
99
+ continue;
100
+ }
101
+ mkdirSync(path.dirname(dest), { recursive: true });
102
+ writeFileSync(dest, lib.content);
103
+ libs.push({ file: dest, status: "written" });
104
+ }
87
105
  let missingTokens = [];
88
106
  const tokensUsed = recipe.tokens_used ?? [];
89
107
  if (tokensUsed.length > 0) {
@@ -101,6 +119,7 @@ export function addRecipe(recipe, outDir, force, tokensCssPath) {
101
119
  }
102
120
  return {
103
121
  file,
122
+ libs,
104
123
  missingTokens,
105
124
  checks: extractSectionNotes(recipe, "Checks"),
106
125
  antiPatterns: extractSectionNotes(recipe, "Anti-patterns"),
package/dist/site.js CHANGED
@@ -79,6 +79,12 @@ export function readZip(buf) {
79
79
  }
80
80
  return out;
81
81
  }
82
+ export function siteNextStep(dir) {
83
+ if (existsSync(path.join(dir, "content.json"))) {
84
+ return "edit content.json with your text and media paths, then run the page; read blueprint.md for how it is built";
85
+ }
86
+ return `read ${path.join(dir, "ASKEWLY-BUNDLE.md")} for what was left out and how to run it`;
87
+ }
82
88
  export async function listSites(base = bundleBaseUrl()) {
83
89
  return fetchSiteIndex(base);
84
90
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askewly/design",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Query, inject, and verify the Askewly Design system (tokens, UI vocabulary, recipes) from your terminal or coding agent.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://ui.askewly.com",