create-linkdesk-plugin 0.1.8 → 0.1.10

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": "create-linkdesk-plugin",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "LinkDesk 插件脚手架——`npm create linkdesk-plugin@latest my-cool-plugin` 一行生成你的第一个插件项目(对标 yo code)。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,6 +11,8 @@
11
11
  // ── 插件身份 ──
12
12
  // 🔴 插件 ID:**显式声明**。它是安装目录名 / 卸载墓碑 / 更新对账的唯一键,**发布后永不可变**。
13
13
  // 它与插件所在的目录名**无关**(目录可以随便改)——所以别拿目录名当它的替身。
14
+ // ⚠️ 且**不得以 `ldk-` 开头**:`ldk-` 是宿主与共享组件的命名空间,而你在 index.css 里的
15
+ // 类名前缀正是由它派生(`<pluginId>-你的类名`)——以 `ldk-` 开头 = 把自己的名字落进宿主空间。
14
16
  "pluginId": "{{pluginName}}",
15
17
  "name": "{{displayName}}", // 显示名——标签页 / 插件详情等 UI 出现处
16
18
  "version": "0.1.0", // 语义化版本 x.y.z——市场更新比较靠它;+1 时务必同笔补 CHANGELOG.md 的新段
@@ -127,29 +127,38 @@ if (report) process.stdout.write(renderPluginLintReport(report) + "\n");
127
127
  * 但必须响亮打印——静默放过才是真问题。
128
128
  */
129
129
  const RULE_NOT_FOUND_RE = /^Definition for rule '.*' was not found/;
130
- /** 按腿取偏离数(label 与 lint.ts 的 legs 一致) */
131
- const legCount = (label) => report?.legs.find((l) => l.label === label)?.violations.length ?? 0;
132
130
 
133
131
  const allRows = report?.eslintRows ?? [];
134
132
  const ruleNotFound = allRows.filter((r) => RULE_NOT_FOUND_RE.test(r.message));
135
133
  const strictEslintRows = allRows.filter((r) => !RULE_NOT_FOUND_RE.test(r.message));
136
- /** 判红的三样:真 eslint 偏离 + css 硬编码腿(硬约束 1 的 .css 半边,eslint 到不了 .css)+ 见下 ②③④⑤ */
137
- const cssLegViolations = legCount("check-css-hardcode");
138
- const strictLintViolations = strictEslintRows.length + cssLegViolations;
139
- /** 只报告不拦的两条腿:字号度量与 4px 节奏——属「审美校准」,存量偏离多且修它们要动插件源码 */
140
- const advisoryLintViolations = legCount("check-font-scale") + legCount("check-spacing-grid");
134
+ /**
135
+ * 判红的两样:真 eslint 偏离 + check 腿偏离(见下 ②③④⑤)。
136
+ * 🔴 **严格腿 = 除「报表档」外的全部腿**(fail-closed):SDK 新增一条腿(如 check-css-namespace)
137
+ * 自动进严格档——想放宽必须把腿名写进 ADVISORY_LEGS 并说明理由,不许默默不查。
138
+ */
139
+ const ADVISORY_LEGS = new Set(["check-font-scale", "check-spacing-grid"]);
140
+ const reportLegs = report?.legs ?? [];
141
+ const strictLegs = reportLegs.filter((l) => !ADVISORY_LEGS.has(l.label));
142
+ const strictLegViolations = strictLegs.reduce((sum, l) => sum + l.violations.length, 0);
143
+ const strictLintViolations = strictEslintRows.length + strictLegViolations;
144
+ /** 报表档:字号度量与 4px 节奏——属「审美校准」,存量偏离多且修它们要动插件源码 */
145
+ const advisoryLintViolations = reportLegs
146
+ .filter((l) => ADVISORY_LEGS.has(l.label))
147
+ .reduce((sum, l) => sum + l.violations.length, 0);
141
148
 
142
149
  if (lintNoObject) {
143
150
  line(`⏭ ① lint 严格腿:${lintNoObject}——本仓**无对象**(不是「绿」,是「没有可查的东西」)。`);
144
151
  } else if (strictLintViolations > 0) {
145
152
  fail(
146
- `① lint 严格腿:${strictLintViolations} 处偏离(eslint ${strictEslintRows.length} + css 硬编码腿 ${cssLegViolations})` +
147
- `——SDK 的 \`npm run lint\` 只报告不拦,**CI 拦**。逐条见上方报告。`,
153
+ `① lint 严格腿:${strictLintViolations} 处偏离(eslint ${strictEslintRows.length} + ` +
154
+ strictLegs.map((l) => `${l.label} ${l.violations.length}`).join(" + ") +
155
+ `)——SDK 的 \`npm run lint\` 只报告不拦,**CI 拦**。逐条见上方报告。`,
148
156
  );
149
157
  } else {
150
158
  line(
151
- `✅ ① lint 严格腿:eslint 规则腿 ${report.files} 文件 + css 硬编码腿 零偏离` +
152
- `(本段判红的是「硬约束 1/2 那一档」)。`,
159
+ `✅ ① lint 严格腿:eslint 规则腿 ${report.files} 文件 + ` +
160
+ strictLegs.map((l) => `${l.label} 零偏离`).join(" + ") +
161
+ `(本段判红的是「硬约束」那一档)。`,
153
162
  );
154
163
  }
155
164
  if (ruleNotFound.length > 0) {
@@ -161,9 +170,12 @@ if (ruleNotFound.length > 0) {
161
170
  }
162
171
  if (advisoryLintViolations > 0) {
163
172
  line(
164
- ` ⚠ 附加腿(**报告不拦**):font-scale ${legCount("check-font-scale")} 处 / ` +
165
- `spacing-grid ${legCount("check-spacing-grid")} 处——字号度量与 4px 节奏属审美校准档` +
166
- `,逐条见上方报告;确属有意的用标准 disable 注释写明理由。`,
173
+ ` ⚠ 附加腿(**报告不拦**):` +
174
+ reportLegs
175
+ .filter((l) => ADVISORY_LEGS.has(l.label))
176
+ .map((l) => `${l.label.replace("check-", "")} ${l.violations.length} 处`)
177
+ .join(" / ") +
178
+ `——字号度量与 4px 节奏属审美校准档,逐条见上方报告;确属有意的用标准 disable 注释写明理由。`,
167
179
  );
168
180
  }
169
181
 
@@ -1,30 +1,33 @@
1
- /* {{displayName}} 样式示例(`npm run lint` 会照着下面三条查)。
2
- 三条纪律:
3
- · 颜色一律 var(--xxx),禁硬编码 hex——用户换主题时你的插件要跟着变;
4
- · 字号一律 var(--font-size-*)——用户调全局字号时它才跟着缩放,裸 px 不会;
5
- · padding / margin / gap 走 4px 节奏(4 的倍数)。 */
6
-
7
- .starter {
8
- padding: 24px;
9
- font-family: inherit;
10
- }
11
-
12
- .starter__title {
13
- margin: 0 0 8px;
14
- color: var(--text);
15
- }
16
-
17
- .starter__text {
18
- margin: 0 0 4px;
19
- color: var(--text-muted);
20
- }
21
-
22
- .starter__hint {
23
- margin: 0;
24
- color: var(--text-muted);
25
- font-size: var(--font-size-xs);
26
- }
27
-
28
- .starter__hint code {
29
- font-family: var(--font-mono, monospace);
30
- }
1
+ /* {{displayName}} 样式示例(`npm run lint` 会照着下面四条查)。
2
+ 四条纪律:
3
+ · 颜色一律 var(--xxx),禁硬编码 hex——用户换主题时你的插件要跟着变;
4
+ · 字号一律 var(--font-size-*)——用户调全局字号时它才跟着缩放,裸 px 不会;
5
+ · padding / margin / gap 走 4px 节奏(4 的倍数);
6
+ · 类名一律以 {{pluginName}}- 开头——插件视图里宿主、共享组件与**所有已加载插件**的
7
+ CSS 在同一张样式表里,裸类名(如 .starter)是全局标识符,会和别人的同名规则
8
+ 互相覆盖(不报错、只是长得不对)。 */
9
+
10
+ .{{pluginName}}-starter {
11
+ padding: 24px;
12
+ font-family: inherit;
13
+ }
14
+
15
+ .{{pluginName}}-starter__title {
16
+ margin: 0 0 8px;
17
+ color: var(--text);
18
+ }
19
+
20
+ .{{pluginName}}-starter__text {
21
+ margin: 0 0 4px;
22
+ color: var(--text-muted);
23
+ }
24
+
25
+ .{{pluginName}}-starter__hint {
26
+ margin: 0;
27
+ color: var(--text-muted);
28
+ font-size: var(--font-size-xs);
29
+ }
30
+
31
+ .{{pluginName}}-starter__hint code {
32
+ font-family: var(--font-mono, monospace);
33
+ }
@@ -1,35 +1,35 @@
1
- /**
2
- * {{displayName}}——LinkDesk 插件主视图(由 create-linkdesk-plugin 生成)。
3
- *
4
- * 视图插件契约(作者文档 01-plugin-api-contract.md):壳以 { isActive, tabId?, sourceId? }
5
- * 渲染本文件 default 导出的组件:
6
- * - isActive 本标签当前是否聚焦。keep-alive 下非聚焦标签仍在渲染,isActive 只用于
7
- * gate「聚焦才跑」的副作用(如自动保存),切勿用它整块 blank 掉内容。
8
- * - tabId 本标签页 id。
9
- * - sourceId 上下文数据(文件路径 / 数据源等),编辑器类插件用它定位内容。
10
- *
11
- * 样式:LinkDesk 主题色一律走 CSS 变量 var(--xxx)(见 index.css 示例),禁硬编码 hex。
12
- * 文案:用 t() 读——key 就是中文原文,英文译文放 i18n/en.json(见作者文档 05-ui-conventions.md)。
13
- * 壳已 external react/react-dom/react-i18next/i18next——构建不会打进包,插件工程无需 npm i 它们。
14
- */
15
-
16
- import { useTranslation } from "react-i18next";
17
- import "./index.css";
18
-
19
- export default function HelloPlugin(_props: { isActive?: boolean; tabId?: string; sourceId?: string }) {
20
- const { t } = useTranslation();
21
-
22
- return (
23
- <div className="starter">
24
- <h2 className="starter__title">{t("插件跑起来了 ✨")}</h2>
25
- <p className="starter__text">{t("这是你的第一个 LinkDesk 插件。")}</p>
26
- <p className="starter__hint">
27
- <code>src/index.tsx</code> {t("是插件本体——改它,浏览器预览即时刷新。")}
28
- </p>
29
- <p className="starter__hint">
30
- <code>npm run build</code> {t("打包出分发文件,可装进 LinkDesk 或发布到市场。")}
31
- </p>
32
- <p className="starter__hint">{t("目录该放哪、发布怎么做,都写在 README.md 里。")}</p>
33
- </div>
34
- );
35
- }
1
+ /**
2
+ * {{displayName}}——LinkDesk 插件主视图(由 create-linkdesk-plugin 生成)。
3
+ *
4
+ * 视图插件契约(作者文档 01-plugin-api-contract.md):壳以 { isActive, tabId?, sourceId? }
5
+ * 渲染本文件 default 导出的组件:
6
+ * - isActive 本标签当前是否聚焦。keep-alive 下非聚焦标签仍在渲染,isActive 只用于
7
+ * gate「聚焦才跑」的副作用(如自动保存),切勿用它整块 blank 掉内容。
8
+ * - tabId 本标签页 id。
9
+ * - sourceId 上下文数据(文件路径 / 数据源等),编辑器类插件用它定位内容。
10
+ *
11
+ * 样式:LinkDesk 主题色一律走 CSS 变量 var(--xxx)(见 index.css 示例),禁硬编码 hex。
12
+ * 文案:用 t() 读——key 就是中文原文,英文译文放 i18n/en.json(见作者文档 05-ui-conventions.md)。
13
+ * 壳已 external react/react-dom/react-i18next/i18next——构建不会打进包,插件工程无需 npm i 它们。
14
+ */
15
+
16
+ import { useTranslation } from "react-i18next";
17
+ import "./index.css";
18
+
19
+ export default function HelloPlugin(_props: { isActive?: boolean; tabId?: string; sourceId?: string }) {
20
+ const { t } = useTranslation();
21
+
22
+ return (
23
+ <div className="{{pluginName}}-starter">
24
+ <h2 className="{{pluginName}}-starter__title">{t("插件跑起来了 ✨")}</h2>
25
+ <p className="{{pluginName}}-starter__text">{t("这是你的第一个 LinkDesk 插件。")}</p>
26
+ <p className="{{pluginName}}-starter__hint">
27
+ <code>src/index.tsx</code> {t("是插件本体——改它,浏览器预览即时刷新。")}
28
+ </p>
29
+ <p className="{{pluginName}}-starter__hint">
30
+ <code>npm run build</code> {t("打包出分发文件,可装进 LinkDesk 或发布到市场。")}
31
+ </p>
32
+ <p className="{{pluginName}}-starter__hint">{t("目录该放哪、发布怎么做,都写在 README.md 里。")}</p>
33
+ </div>
34
+ );
35
+ }