@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@collectui/bdui",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Add BoardUI components to your project.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/add.js CHANGED
@@ -145,7 +145,8 @@ export async function cmdAdd(names, flags) {
145
145
  )
146
146
  );
147
147
  }
148
- if (nextImports.size) {
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
- return { pkgs, notes };
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}, alias=${project.alias}`
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(c.green(`\n✓ ${wrote} foundation file(s) written.`));
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
- ` ${c.dim('Note: import the styles in your root layout or global css: import "@/styles/globals.css";')}`
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
- const width = Math.max(...group.map((i) => i.name.length)) + 2;
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.name.padEnd(width);
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