@collectui/bdui 0.1.8 → 0.1.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/package.json +1 -1
- package/src/add.js +2 -1
- package/src/init.js +85 -7
- package/src/list.js +4 -2
- package/src/mcp.js +5 -0
package/package.json
CHANGED
package/src/add.js
CHANGED
|
@@ -145,7 +145,8 @@ export async function cmdAdd(names, flags) {
|
|
|
145
145
|
)
|
|
146
146
|
);
|
|
147
147
|
}
|
|
148
|
-
|
|
148
|
+
// Next 项目里 next/link 是一等公民,提示反而是噪音(盲测 #10)
|
|
149
|
+
if (nextImports.size && !project.deps?.next) {
|
|
149
150
|
console.log(
|
|
150
151
|
c.yellow(
|
|
151
152
|
`\nNote: ${[...nextImports].sort().join(", ")} imported by installed files — these only compile in a Next.js project.`
|
package/src/init.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// `bdui init` — 对齐 boardui init:装 foundations(cx/theme/typography/globals)
|
|
2
2
|
// + agent 规则(AGENTS.md + .cursor/rules),内容全部来自 registry(与官方同源)
|
|
3
3
|
|
|
4
|
-
import { existsSync } from "fs";
|
|
4
|
+
import { appendFileSync, existsSync, readFileSync, writeFileSync } from "fs";
|
|
5
5
|
import ora from "ora";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { installPackages, pkgBaseName } from "./add.js";
|
|
@@ -29,9 +29,25 @@ function frameworkSetup(project, cwd) {
|
|
|
29
29
|
|
|
30
30
|
if (!has("tailwindcss")) pkgs.push("tailwindcss");
|
|
31
31
|
if (project.deps?.next) {
|
|
32
|
-
// Next.js:官方模板自带 @/ alias 与 @types/node;仅补缺失的 tailwind
|
|
32
|
+
// Next.js:官方模板自带 @/ alias 与 @types/node;仅补缺失的 tailwind 管道。
|
|
33
|
+
// postcss 配置是硬前提:模板没带 Tailwind 时 postcss.config 不存在,
|
|
34
|
+
// @tailwindcss/postcss 装了也不接管,组件样式静默失效(next build 只给
|
|
35
|
+
// "Unknown at rule: @apply" 警告仍报成功)——缺配置就补 v4 标准形态
|
|
33
36
|
if (!has("@tailwindcss/postcss")) pkgs.push("@tailwindcss/postcss");
|
|
34
|
-
|
|
37
|
+
const hasPostcssCfg = [
|
|
38
|
+
"postcss.config.mjs",
|
|
39
|
+
"postcss.config.js",
|
|
40
|
+
"postcss.config.cjs",
|
|
41
|
+
"postcss.config.ts",
|
|
42
|
+
].some((f) => existsSync(path.join(cwd, f)));
|
|
43
|
+
const writes = [];
|
|
44
|
+
if (!hasPostcssCfg)
|
|
45
|
+
writes.push({
|
|
46
|
+
file: "postcss.config.mjs",
|
|
47
|
+
content:
|
|
48
|
+
'const config = {\n plugins: { "@tailwindcss/postcss": {} },\n};\n\nexport default config;\n',
|
|
49
|
+
});
|
|
50
|
+
return { pkgs, notes, writes };
|
|
35
51
|
}
|
|
36
52
|
const viteConfig = [
|
|
37
53
|
"vite.config.ts",
|
|
@@ -59,7 +75,7 @@ function frameworkSetup(project, cwd) {
|
|
|
59
75
|
].join("\n")
|
|
60
76
|
);
|
|
61
77
|
}
|
|
62
|
-
return { pkgs, notes };
|
|
78
|
+
return { pkgs, notes, writes: [] };
|
|
63
79
|
}
|
|
64
80
|
|
|
65
81
|
export async function cmdInit(flags) {
|
|
@@ -68,8 +84,10 @@ export async function cmdInit(flags) {
|
|
|
68
84
|
if (!project.pkg)
|
|
69
85
|
throw new Error("No package.json found — run inside your app project.");
|
|
70
86
|
|
|
87
|
+
// alias 不在此行展示:tsconfig 的 @/ 别名与实际落位(components/base/<group>)
|
|
88
|
+
// 口径不同,曾让客户误读(2026-10-26 盲测 #6);落位在 ✓ 行明示
|
|
71
89
|
console.log(
|
|
72
|
-
`${c.cyan("init")} detected ${project.packageManager}, src=${project.usesSrcDir}
|
|
90
|
+
`${c.cyan("init")} detected ${project.packageManager}, src=${project.usesSrcDir}`
|
|
73
91
|
);
|
|
74
92
|
|
|
75
93
|
// npm 依赖:foundation 用到的 + 可选 pro 依赖(官方 --pro 同款集)+ 框架适配
|
|
@@ -98,6 +116,60 @@ export async function cmdInit(flags) {
|
|
|
98
116
|
wrote += await writeItemFiles(item, outRoot, flags);
|
|
99
117
|
}
|
|
100
118
|
|
|
119
|
+
// 框架管道配置(postcss.config.mjs 等):样式静默失效的根因修复(盲测 #1)
|
|
120
|
+
for (const w of setup.writes ?? []) {
|
|
121
|
+
const target = path.join(cwd, w.file);
|
|
122
|
+
if (existsSync(target)) continue;
|
|
123
|
+
writeFileSync(target, w.content);
|
|
124
|
+
console.log(
|
|
125
|
+
` ${c.green("add")} ${w.file} (Tailwind v4 PostCSS pipeline)`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// .mcp.json 常嵌 license key(MCP 官方形态)——git 仓库防一次 commit 泄漏(盲测 #3)
|
|
130
|
+
const gitignore = path.join(cwd, ".gitignore");
|
|
131
|
+
if (existsSync(path.join(cwd, ".git")) || existsSync(gitignore)) {
|
|
132
|
+
const cur = existsSync(gitignore) ? readFileSync(gitignore, "utf8") : "";
|
|
133
|
+
if (!/^\s*\.mcp\.json\s*$/m.test(cur)) {
|
|
134
|
+
appendFileSync(
|
|
135
|
+
gitignore,
|
|
136
|
+
`${cur && !cur.endsWith("\n") ? "\n" : ""}\n# BoardUI MCP config (contains your license key)\n.mcp.json\n`
|
|
137
|
+
);
|
|
138
|
+
console.log(
|
|
139
|
+
` ${c.green("add")} .gitignore += .mcp.json (license key leak guard)`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 样式入口自动接线:根布局存在且未引入时补 import,免手动 Note(盲测 #7)
|
|
145
|
+
const layoutFile = [
|
|
146
|
+
"app/layout.tsx",
|
|
147
|
+
"app/layout.ts",
|
|
148
|
+
"app/layout.jsx",
|
|
149
|
+
"app/layout.js",
|
|
150
|
+
]
|
|
151
|
+
.map((f) => path.join(project.sourceRoot, f))
|
|
152
|
+
.find((p) => existsSync(p));
|
|
153
|
+
let stylesWired = false;
|
|
154
|
+
if (layoutFile) {
|
|
155
|
+
const src = readFileSync(layoutFile, "utf8");
|
|
156
|
+
if (src.includes("@/styles/globals.css")) {
|
|
157
|
+
stylesWired = true;
|
|
158
|
+
} else {
|
|
159
|
+
const lines = src.split("\n");
|
|
160
|
+
// 插到最后一个顶层 import 之后;没有 import 则插到文件头
|
|
161
|
+
let at = 0;
|
|
162
|
+
for (let i = 0; i < lines.length; i++)
|
|
163
|
+
if (/^import[\s{"']/.test(lines[i])) at = i + 1;
|
|
164
|
+
lines.splice(at, 0, 'import "@/styles/globals.css";');
|
|
165
|
+
writeFileSync(layoutFile, lines.join("\n"));
|
|
166
|
+
stylesWired = true;
|
|
167
|
+
console.log(
|
|
168
|
+
` ${c.green("add")} ${path.relative(cwd, layoutFile)}: import "@/styles/globals.css"`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
101
173
|
// agent 规则(AGENTS.md + .cursor/rules/boardui.mdc)
|
|
102
174
|
const ruleLines = await applyAgentRules(cwd);
|
|
103
175
|
|
|
@@ -118,11 +190,17 @@ export async function cmdInit(flags) {
|
|
|
118
190
|
throw e;
|
|
119
191
|
}
|
|
120
192
|
}
|
|
121
|
-
console.log(
|
|
193
|
+
console.log(
|
|
194
|
+
c.green(
|
|
195
|
+
`\n✓ ${wrote} foundation file(s) written to ${path.relative(cwd, outRoot) || "."}.`
|
|
196
|
+
)
|
|
197
|
+
);
|
|
122
198
|
for (const note of setup.notes) console.log(c.yellow(`\n${note}\n`));
|
|
123
199
|
for (const line of ruleLines) console.log(line);
|
|
124
200
|
console.log(
|
|
125
|
-
|
|
201
|
+
stylesWired
|
|
202
|
+
? ` ${c.dim('Note: BoardUI styles wired into your root layout (import "@/styles/globals.css").')}`
|
|
203
|
+
: ` ${c.dim('Note: import the styles in your root layout or global css: import "@/styles/globals.css";')}`
|
|
126
204
|
);
|
|
127
205
|
console.log(
|
|
128
206
|
c.green(
|
package/src/list.js
CHANGED
|
@@ -17,9 +17,11 @@ export async function cmdList() {
|
|
|
17
17
|
};
|
|
18
18
|
for (const [key, group] of groups) {
|
|
19
19
|
console.log(c.bold(labels[key] ?? key));
|
|
20
|
-
|
|
20
|
+
// Pro 标记:混排时无从分辨 Pro/免费(盲测 #5),对齐 MCP list 的 (pro) 口径
|
|
21
|
+
const label = (i) => (i.pro ? `${i.name} (pro)` : i.name);
|
|
22
|
+
const width = Math.max(...group.map((i) => label(i).length)) + 2;
|
|
21
23
|
for (const item of group) {
|
|
22
|
-
const name = item.
|
|
24
|
+
const name = label(item).padEnd(width);
|
|
23
25
|
console.log(` ${name}${item.description ?? ""}`);
|
|
24
26
|
}
|
|
25
27
|
console.log();
|
package/src/mcp.js
CHANGED
|
@@ -343,6 +343,11 @@ async function call(name, args, serverKey) {
|
|
|
343
343
|
|
|
344
344
|
export async function cmdMcp(options = {}) {
|
|
345
345
|
const serverKey = options.key ?? undefined; // `bdui mcp --key <key>`:整会话兜底,见 loadItem 注释
|
|
346
|
+
// stderr 提示(stdio 协议,stdout 必须干净):key 常嵌 .mcp.json,防 commit 泄漏(盲测 #3)
|
|
347
|
+
if (serverKey)
|
|
348
|
+
console.error(
|
|
349
|
+
"[bdui] tip: if this key is embedded in .mcp.json, keep that file out of git (add it to .gitignore)."
|
|
350
|
+
);
|
|
346
351
|
const rl = createInterface({ input: process.stdin });
|
|
347
352
|
const write = (obj) => process.stdout.write(JSON.stringify(obj) + "\n");
|
|
348
353
|
|