feat(plugin): 品牌图标用 deta.city logo(iconSmall/iconLarge + 契约守卫 E5),studio 0.3.12 / writer 0.1.3
CI / contract (push) Has been cancelled

plugin.json 的 interface 补 iconSmall/iconLarge = ./assets/logo.svg(与门户 favicon 同一份 brand 标),brandColor 由 #2F6F4E 改为 #333333 对齐品牌标与门店令牌色。契约校验新增 E5:图标必须是插件根内相对路径且文件存在(实测写坏能抓到)。
This commit is contained in:
ringo
2026-09-20 16:28:15 +08:00
parent d137a012c6
commit 774e27cfc8
9 changed files with 54 additions and 12 deletions
+5 -3
View File
@@ -1,6 +1,6 @@
{
"name": "studio",
"version": "0.3.11",
"version": "0.3.12",
"description": "DETA Studio 插件:以 AML 为唯一事实源编辑建筑模型,编译为建筑模型并执行规则校验。",
"author": {
"name": "DETA",
@@ -28,12 +28,14 @@
"Read",
"Write"
],
"brandColor": "#2F6F4E",
"brandColor": "#333333",
"websiteURL": "https://deta.city",
"defaultPrompt": [
"读取当前 AML 设计源码并说明建筑构成。",
"在 AML 中修改指定空间的层高,然后重新编译校验。",
"统计当前模型的围护结构面积与外窗面积。"
]
],
"iconSmall": "./assets/logo.svg",
"iconLarge": "./assets/logo.svg"
}
}
+3
View File
@@ -0,0 +1,3 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#333333" d="M 48 52 L 10 52 L 45 6 L 54.4 39.1 L 56.4 45.6 L 47.2 36 L 42.5 19.2 L 22.1 46 L 44 46 L 59 49.2 Z" />
</svg>

After

Width:  |  Height:  |  Size: 232 B

+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "deta-studio-plugin",
"version": "0.3.11",
"version": "0.3.12",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "deta-studio-plugin",
"version": "0.3.11",
"version": "0.3.12",
"license": "Proprietary"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "deta-studio-plugin",
"version": "0.3.11",
"version": "0.3.12",
"description": "DETA Studio:AML 建筑模型读写与编译校验(Codex 插件 / dsh 组合包 双壳)",
"type": "module",
"license": "Proprietary",
+5 -3
View File
@@ -1,6 +1,6 @@
{
"name": "writer",
"version": "0.1.2",
"version": "0.1.3",
"description": "DETA Writer 插件:读取建筑模型与模拟结果,产出报告 / 文档内容。",
"author": {
"name": "DETA",
@@ -27,11 +27,13 @@
"Read",
"Write"
],
"brandColor": "#2F6F4E",
"brandColor": "#333333",
"websiteURL": "https://deta.city",
"defaultPrompt": [
"读取当前项目的建筑模型,列出可用于报告的关键指标。",
"把本项目的围护结构与能耗结果整理成报告初稿,缺失数据如实标注。"
]
],
"iconSmall": "./assets/logo.svg",
"iconLarge": "./assets/logo.svg"
}
}
+3
View File
@@ -0,0 +1,3 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#333333" d="M 48 52 L 10 52 L 45 6 L 54.4 39.1 L 56.4 45.6 L 47.2 36 L 42.5 19.2 L 22.1 46 L 44 46 L 59 49.2 Z" />
</svg>

After

Width:  |  Height:  |  Size: 232 B

+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "deta-writer-plugin",
"version": "0.1.2",
"version": "0.1.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "deta-writer-plugin",
"version": "0.1.2",
"version": "0.1.3",
"license": "Proprietary"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "deta-writer-plugin",
"version": "0.1.2",
"version": "0.1.3",
"description": "DETA Writer:建筑性能报告与文档产出(Codex 插件 / dsh 组合包 双壳)",
"type": "module",
"license": "Proprietary",
+32
View File
@@ -69,6 +69,11 @@ const RULES = {
what: '出现开发检出路径(~/Dev/ant/ant-copilot)',
hint: '启动器应随包分发运行时;本机引擎包落地后本规则升级为 error',
},
E5: {
level: 'error',
what: '插件图标的路径不存在(interface.iconSmall / iconLarge 指向缺失文件或越出插件根)',
hint: '图标必须是插件根下的相对路径(如 ./assets/logo.svg),且文件真实存在——品牌标用 deta.city 的 logo.svg',
},
};
const HEADING_BAN = /工具一览|工具清单|工具列表|工具汇总|可用工具|能力一览|能力清单/;
@@ -145,6 +150,33 @@ for (const rel of ['.agents/plugins/marketplace.json', '.agents/plugins/api_mark
}
}
// E5:插件图标引用必须落在插件根内且真实存在(品牌标 = deta.city logo)
for (const pluginDir of ['plugins/studio', 'plugins/writer']) {
const manifest = join(ROOT, pluginDir, '.codex-plugin', 'plugin.json');
if (!existsSync(manifest)) continue;
let itf;
try {
itf = JSON.parse(readFileSync(manifest, 'utf8')).interface ?? {};
} catch {
continue; // 清单不合法由 validate_plugin.py 报
}
for (const key of ['iconSmall', 'iconLarge']) {
const val = String(itf[key] ?? '');
if (!val) {
add('E5', manifest, 1, `interface.${key} 未设置(品牌标应指向 ./assets/logo.svg)`);
continue;
}
if (/^https?:/i.test(val)) continue; // *Url 形态才是远端地址
if (val.includes('..') || !val.startsWith('./')) {
add('E5', manifest, 1, `${key} 必须是插件根内相对路径(收到 ${val})`);
continue;
}
if (!existsSync(join(ROOT, pluginDir, val.replace(/^\.\//, '')))) {
add('E5', manifest, 1, `${key} 指向的文件不存在:${val}`);
}
}
}
if (process.argv.includes('--json')) {
console.log(JSON.stringify({ findings, rules: RULES }, null, 2));
} else {