@axis-ds/mcp 1.4.8 → 1.4.9
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/README.md +1 -1
- package/dist/index.js +30 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ Claude Desktop 또는 기타 MCP 호환 클라이언트에서 설정:
|
|
|
41
41
|
- 이름은 레지스트리 이름 그대로입니다. Agentic UI 는 `agentic-` 접두를 붙입니다(예: `agentic-run-progress`). 의존 항목(`utils` · `agentic-a11y-labels`)은 함께 설치됩니다.
|
|
42
42
|
- `targetDir` 는 이미 있는 프로젝트 루트입니다(상대 경로는 서버의 현재 디렉터리 기준). `axis.config.json` 이 있으면 그 `componentsDir` · `agenticDir` 에, 없으면 `components/ui` · `components/agentic` 에 설치하고 그 사실을 알립니다. 프로젝트 밖으로 나가는 경로는 아무것도 쓰지 않고 실패합니다.
|
|
43
43
|
- 내용이 다른 기존 파일은 덮어쓰지 않고 건너뛰며 응답 첫머리에 건너뛴 수를 적습니다. `overwrite: true` 일 때만 덮어씁니다.
|
|
44
|
-
- 의존성은 설치하지 않고 lockfile 에 맞는 명령(`pnpm add` · `npm install` · `yarn add`)만 안내합니다. lockfile 이 없으면 `package.json` 의 `packageManager` 를 봅니다(1.4.2 부터). `axis.apply_template` 의 「필요한 의존성」 · `axis.list_brands` · `axis.get_brand` 의 설치 안내도 1.4.2 부터 같은 방식으로 `targetDir` 의 매니저를 따릅니다(1.4.1 까지는 `pnpm` 고정).
|
|
44
|
+
- 의존성은 설치하지 않고 lockfile 에 맞는 명령(`pnpm add` · `npm install` · `yarn add`)만 안내합니다. 워크스페이스 루트 `package.json` 에 선언된 의존성은 안내하지 않고, 1.4.8 다음 patch 부터(WI-0095) Yarn Plug'n'Play 에서는 루트에만 선언한 의존성도 앱이 해석하지 못하므로 안내 명령에 넣습니다(CLI `axis add` 와 같음). lockfile 이 없으면 `package.json` 의 `packageManager` 를 봅니다(1.4.2 부터). `axis.apply_template` 의 「필요한 의존성」 · `axis.list_brands` · `axis.get_brand` 의 설치 안내도 1.4.2 부터 같은 방식으로 `targetDir` 의 매니저를 따릅니다(1.4.1 까지는 `pnpm` 고정).
|
|
45
45
|
- `axis.apply_template` 은 `targetDir` 에 이미 있는 `package.json` · `axis.config.json`(템플릿 루트의 것)을 덮어쓰지 않고 CLI `axis template apply` 와 같은 규칙으로 합칩니다(WI-0088). `packageManager` 등 사용자 필드가 남고, 결과의 파일 목록에 「합치기」로 표시합니다. 파일을 쓰는 도중 실패하면 건드린 파일을 되돌리고 오류로 응답합니다. 템플릿 경로가 `targetDir` 밖(절대 경로 · `..` · 밖을 가리키는 심볼릭 링크 경유)이면 `axis.apply_template` · `axis.diff_template` 은 아무 파일도 쓰거나 읽지 않고 오류로 응답합니다.
|
|
46
46
|
|
|
47
47
|
## 토큰 도구
|
package/dist/index.js
CHANGED
|
@@ -1476,9 +1476,6 @@ import { basename, dirname as dirname2, extname, isAbsolute, join as join2, rela
|
|
|
1476
1476
|
function declaredRange(baseDir, pkg, name) {
|
|
1477
1477
|
return declaredDependency(baseDir, pkg, name)?.range;
|
|
1478
1478
|
}
|
|
1479
|
-
function declaredRangeForCheck(baseDir, pkg, name) {
|
|
1480
|
-
return declaredDependency(baseDir, pkg, name, void 0, { appOnlyInPnp: true })?.range;
|
|
1481
|
-
}
|
|
1482
1479
|
function isPlainObject2(value) {
|
|
1483
1480
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1484
1481
|
}
|
|
@@ -2744,6 +2741,33 @@ function componentsUseAnimation(baseDir, componentsDir) {
|
|
|
2744
2741
|
}
|
|
2745
2742
|
return false;
|
|
2746
2743
|
}
|
|
2744
|
+
function animationPluginProblem(baseDir, pkg, name, pnp) {
|
|
2745
|
+
const declared = declaredDependency(baseDir, pkg, name, void 0, { appOnlyInPnp: true });
|
|
2746
|
+
if (declared === void 0) {
|
|
2747
|
+
return pnpRootOnlyDependency(baseDir, pkg, name) !== void 0 ? { name, kind: "pnpRootOnly", why: `${name} \uAC00 ${PNP_ROOT_ONLY_NOTE}` } : { name, kind: "undeclared", why: `${name} \uC120\uC5B8 \uC5C6\uC74C` };
|
|
2748
|
+
}
|
|
2749
|
+
if (!pnp && findInstalledPackage(baseDir, name) === void 0) {
|
|
2750
|
+
return { name, kind: "notInstalled", why: `${name} \uBBF8\uC124\uCE58(\uC120\uC5B8\uB9CC \uC788\uC74C)`, root: declared.source === "root" };
|
|
2751
|
+
}
|
|
2752
|
+
return void 0;
|
|
2753
|
+
}
|
|
2754
|
+
function inspectTailwind4Animation(baseDirInput, pkgInput) {
|
|
2755
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
2756
|
+
const pkg = pkgInput ?? readPackageJson(baseDir);
|
|
2757
|
+
const pnp = isPnpProject(baseDir);
|
|
2758
|
+
const selection = selectCheckGlobalCss(baseDir);
|
|
2759
|
+
const note = globalCssSelectionNote(selection);
|
|
2760
|
+
const expanded = selection.path !== void 0 && selection.rel !== void 0 ? expandGlobalCss(baseDir, selection.path, selection.rel, outsideCssDir(selection)) : void 0;
|
|
2761
|
+
const css = expanded !== void 0 ? stripCssComments(expanded.evidence) : "";
|
|
2762
|
+
const twAnimate = new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`);
|
|
2763
|
+
const animatePlugin = new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`);
|
|
2764
|
+
const lines = [];
|
|
2765
|
+
if (twAnimate.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND4);
|
|
2766
|
+
if (animatePlugin.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND3);
|
|
2767
|
+
const via = expanded !== void 0 ? cssImportViaNote(viaFiles([evidenceOrigin(expanded, (f) => twAnimate.test(f)), evidenceOrigin(expanded, (f) => animatePlugin.test(f))])) : "";
|
|
2768
|
+
const problems = lines.map((name) => animationPluginProblem(baseDir, pkg, name, pnp)).filter((p) => p !== void 0);
|
|
2769
|
+
return { selection, file: selection.rel, note, via, lines, problems };
|
|
2770
|
+
}
|
|
2747
2771
|
function checkAnimationPlugin(baseDirInput) {
|
|
2748
2772
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
2749
2773
|
const pkg = readPackageJson(baseDir);
|
|
@@ -2754,25 +2778,8 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
2754
2778
|
const by = declared ? "@axis-ds/ui-react \uC120\uC5B8" : "componentsDir \uC758 animate-in \uB958 \uD074\uB798\uC2A4";
|
|
2755
2779
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
2756
2780
|
const pnp = isPnpProject(baseDir);
|
|
2757
|
-
const pluginProblem = (name) => {
|
|
2758
|
-
if (declaredRangeForCheck(baseDir, pkg, name) === void 0) {
|
|
2759
|
-
return pnpRootOnlyDependency(baseDir, pkg, name) !== void 0 ? `${name} \uAC00 ${PNP_ROOT_ONLY_NOTE}` : `${name} \uC120\uC5B8 \uC5C6\uC74C`;
|
|
2760
|
-
}
|
|
2761
|
-
if (!pnp && findInstalledPackage(baseDir, name) === void 0) return `${name} \uBBF8\uC124\uCE58(\uC120\uC5B8\uB9CC \uC788\uC74C)`;
|
|
2762
|
-
return void 0;
|
|
2763
|
-
};
|
|
2764
2781
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
2765
|
-
const
|
|
2766
|
-
const note = globalCssSelectionNote(selection);
|
|
2767
|
-
const file = selection.rel;
|
|
2768
|
-
const expanded = selection.path !== void 0 && selection.rel !== void 0 ? expandGlobalCss(baseDir, selection.path, selection.rel, outsideCssDir(selection)) : void 0;
|
|
2769
|
-
const css = expanded !== void 0 ? stripCssComments(expanded.evidence) : "";
|
|
2770
|
-
const twAnimate = new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`);
|
|
2771
|
-
const animatePlugin = new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`);
|
|
2772
|
-
const lines = [];
|
|
2773
|
-
if (twAnimate.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND4);
|
|
2774
|
-
if (animatePlugin.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND3);
|
|
2775
|
-
const via = expanded !== void 0 ? cssImportViaNote(viaFiles([evidenceOrigin(expanded, (f) => twAnimate.test(f)), evidenceOrigin(expanded, (f) => animatePlugin.test(f))])) : "";
|
|
2782
|
+
const { file, note, via, lines, problems } = inspectTailwind4Animation(baseDir, pkg);
|
|
2776
2783
|
if (lines.length === 0) {
|
|
2777
2784
|
return {
|
|
2778
2785
|
name: "animation",
|
|
@@ -2780,7 +2787,6 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
2780
2787
|
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND4} \uC124\uCE58 \uB4A4 @import "${ANIMATION_PLUGIN_TAILWIND4}";${note}`
|
|
2781
2788
|
};
|
|
2782
2789
|
}
|
|
2783
|
-
const problems = lines.map((name) => ({ name, why: pluginProblem(name) })).filter((x) => x.why !== void 0);
|
|
2784
2790
|
if (problems.length === 0) return { name: "animation", severity: "pass", message: `${file}\uC5D0 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4${via}${note}` };
|
|
2785
2791
|
return {
|
|
2786
2792
|
name: "animation",
|
|
@@ -2791,7 +2797,7 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
2791
2797
|
const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync3(join2(baseDir, f)));
|
|
2792
2798
|
const source = configFile !== void 0 ? stripJsComments(readFileSync4(join2(baseDir, configFile), "utf8")) : "";
|
|
2793
2799
|
const plugins = configFile !== void 0 ? readAnimationPluginUse(source) : "absent";
|
|
2794
|
-
const pluginReason =
|
|
2800
|
+
const pluginReason = animationPluginProblem(baseDir, pkg, ANIMATION_PLUGIN_TAILWIND3, pnp)?.why;
|
|
2795
2801
|
if (plugins === "found" && pluginReason === void 0) {
|
|
2796
2802
|
return { name: "animation", severity: "pass", message: `${configFile}\uC758 plugins \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
2797
2803
|
}
|
|
@@ -3305,7 +3311,7 @@ function missingDependencies(root, items) {
|
|
|
3305
3311
|
for (const item of items) {
|
|
3306
3312
|
for (const dep of item.dependencies) {
|
|
3307
3313
|
const name = dependencyName(dep);
|
|
3308
|
-
if (declaredDependency(root, pkg, name, rootPkg) !== void 0) continue;
|
|
3314
|
+
if (declaredDependency(root, pkg, name, rootPkg, { appOnlyInPnp: true }) !== void 0) continue;
|
|
3309
3315
|
if (name in specs) continue;
|
|
3310
3316
|
const explicit = dep.length > name.length ? dep.slice(name.length + 1) : void 0;
|
|
3311
3317
|
specs[name] = explicit ?? ranges[name];
|