codesign-mcp-server 0.0.0-stage → 1.0.2
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 +310 -2
- package/dist/client.d.ts +85 -0
- package/dist/client.js +678 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.js +108 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +327 -0
- package/dist/index.js.map +1 -0
- package/dist/spec.d.ts +18 -0
- package/dist/spec.js +274 -0
- package/dist/spec.js.map +1 -0
- package/dist/tools.d.ts +59 -0
- package/dist/tools.js +156 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +173 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/concurrency.d.ts +2 -0
- package/dist/utils/concurrency.js +15 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/filename.d.ts +10 -0
- package/dist/utils/filename.js +32 -0
- package/dist/utils/filename.js.map +1 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +8 -0
- package/dist/version.js.map +1 -0
- package/package.json +52 -4
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
export interface ScreenRef {
|
|
2
|
+
id: number;
|
|
3
|
+
name: string;
|
|
4
|
+
}
|
|
5
|
+
export interface DesignRef {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
viewport: string;
|
|
9
|
+
screens: ScreenRef[];
|
|
10
|
+
}
|
|
11
|
+
export interface ShareInfo {
|
|
12
|
+
id: number;
|
|
13
|
+
title: string;
|
|
14
|
+
teamName: string;
|
|
15
|
+
permissions: {
|
|
16
|
+
commentable: boolean;
|
|
17
|
+
inspectable: boolean;
|
|
18
|
+
assetsDownloadable: boolean;
|
|
19
|
+
};
|
|
20
|
+
designs: DesignRef[];
|
|
21
|
+
}
|
|
22
|
+
export interface ScreenDetail {
|
|
23
|
+
id: number;
|
|
24
|
+
name: string;
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
designId: number;
|
|
28
|
+
source: string;
|
|
29
|
+
metaUrl?: string;
|
|
30
|
+
slicesUrl?: string;
|
|
31
|
+
previewUrl?: string;
|
|
32
|
+
slicesCount: number;
|
|
33
|
+
}
|
|
34
|
+
export interface LayerRect {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
}
|
|
40
|
+
export interface TextStyle {
|
|
41
|
+
fontName: string;
|
|
42
|
+
fontStyleName: string;
|
|
43
|
+
/** 渲染后的实际字号(已按设计稿缩放换算),不是排版原始值 */
|
|
44
|
+
size: number;
|
|
45
|
+
/** Photoshop 千分之一单位,换算 CSS 时 /1000 * size */
|
|
46
|
+
tracking?: number;
|
|
47
|
+
leading?: number;
|
|
48
|
+
allCaps?: boolean;
|
|
49
|
+
lineHeight?: number;
|
|
50
|
+
letterSpacing?: number;
|
|
51
|
+
color?: string;
|
|
52
|
+
textAlign?: string;
|
|
53
|
+
content?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface LayerFill {
|
|
56
|
+
type: string;
|
|
57
|
+
color?: string;
|
|
58
|
+
css?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface LayerBorder extends LayerFill {
|
|
61
|
+
/** 边框粗细 */
|
|
62
|
+
width?: number;
|
|
63
|
+
/** inside / outside / center */
|
|
64
|
+
position?: string;
|
|
65
|
+
style?: string;
|
|
66
|
+
}
|
|
67
|
+
/** 图层效果,`type` 为设计稿里的效果名(innerGlow / frameFX / dropShadow…) */
|
|
68
|
+
export interface LayerEffect {
|
|
69
|
+
type: string;
|
|
70
|
+
[key: string]: unknown;
|
|
71
|
+
}
|
|
72
|
+
export interface Layer {
|
|
73
|
+
id: string;
|
|
74
|
+
/** CoDesign 的 object_id,切图清单里用它关联图层 */
|
|
75
|
+
objectId: string;
|
|
76
|
+
name: string;
|
|
77
|
+
type: string;
|
|
78
|
+
rect: LayerRect;
|
|
79
|
+
visible: boolean;
|
|
80
|
+
opacity?: number;
|
|
81
|
+
fillOpacity?: number;
|
|
82
|
+
/** 圆角,按 topLeft/topRight/bottomRight/bottomLeft 顺序 */
|
|
83
|
+
radius?: number[];
|
|
84
|
+
fills?: LayerFill[];
|
|
85
|
+
borders?: LayerBorder[];
|
|
86
|
+
/** 阴影/发光/描边等效果 */
|
|
87
|
+
effects?: LayerEffect[];
|
|
88
|
+
/** 设计稿自带的 CSS 片段,是最可靠的样式来源 */
|
|
89
|
+
css?: string[];
|
|
90
|
+
text?: TextStyle;
|
|
91
|
+
images?: string[];
|
|
92
|
+
clipped?: boolean;
|
|
93
|
+
blendMode?: string;
|
|
94
|
+
rotation?: number;
|
|
95
|
+
/** 图层带矢量路径 */
|
|
96
|
+
isVector?: boolean;
|
|
97
|
+
children?: Layer[];
|
|
98
|
+
}
|
|
99
|
+
export interface LayerTree {
|
|
100
|
+
name: string;
|
|
101
|
+
width: number;
|
|
102
|
+
height: number;
|
|
103
|
+
/** 已经按 parent_id 重建成真正的嵌套树 */
|
|
104
|
+
layers: Layer[];
|
|
105
|
+
}
|
|
106
|
+
export interface SliceExport {
|
|
107
|
+
name: string;
|
|
108
|
+
scale: number;
|
|
109
|
+
format: string;
|
|
110
|
+
width: number;
|
|
111
|
+
height: number;
|
|
112
|
+
downloadUrl: string;
|
|
113
|
+
objectId: string;
|
|
114
|
+
}
|
|
115
|
+
export interface SliceItem {
|
|
116
|
+
id: string;
|
|
117
|
+
name: string;
|
|
118
|
+
rect: LayerRect;
|
|
119
|
+
exports: SliceExport[];
|
|
120
|
+
}
|
|
121
|
+
export interface DownloadResult {
|
|
122
|
+
name: string;
|
|
123
|
+
/** 相对 outDir 的路径,便于调用方定位 */
|
|
124
|
+
path: string;
|
|
125
|
+
/** 实际使用的导出倍率(默认 2x;该图层没有时会就近取) */
|
|
126
|
+
scale?: number;
|
|
127
|
+
/** 该图层没有请求的倍率,实际用了另一个倍率 */
|
|
128
|
+
substituted?: boolean;
|
|
129
|
+
width: number;
|
|
130
|
+
height: number;
|
|
131
|
+
bytes: number;
|
|
132
|
+
ok: boolean;
|
|
133
|
+
error?: string;
|
|
134
|
+
}
|
|
135
|
+
export interface SpecNode {
|
|
136
|
+
name: string;
|
|
137
|
+
type: string;
|
|
138
|
+
objectId: string;
|
|
139
|
+
box: {
|
|
140
|
+
left: number;
|
|
141
|
+
top: number;
|
|
142
|
+
width: number;
|
|
143
|
+
height: number;
|
|
144
|
+
};
|
|
145
|
+
style: string[];
|
|
146
|
+
text?: string;
|
|
147
|
+
}
|
|
148
|
+
export interface SpecResult {
|
|
149
|
+
screen: string;
|
|
150
|
+
size: {
|
|
151
|
+
width: number;
|
|
152
|
+
height: number;
|
|
153
|
+
};
|
|
154
|
+
cssWidth: number;
|
|
155
|
+
/** 设计稿宽度 -> 目标 CSS 宽度的缩放比 */
|
|
156
|
+
scale: number;
|
|
157
|
+
nodes: SpecNode[];
|
|
158
|
+
slices: {
|
|
159
|
+
name: string;
|
|
160
|
+
left: number;
|
|
161
|
+
top: number;
|
|
162
|
+
width: number;
|
|
163
|
+
height: number;
|
|
164
|
+
scale: number;
|
|
165
|
+
file: string;
|
|
166
|
+
}[];
|
|
167
|
+
notes: string[];
|
|
168
|
+
/** 图层被截断时的说明 */
|
|
169
|
+
truncated?: {
|
|
170
|
+
total: number;
|
|
171
|
+
returned: number;
|
|
172
|
+
};
|
|
173
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** 按固定并发度执行,保持结果顺序与输入一致 */
|
|
2
|
+
export async function mapLimit(items, limit, fn) {
|
|
3
|
+
const size = Math.max(1, Math.min(Math.floor(limit) || 1, items.length || 1));
|
|
4
|
+
const results = new Array(items.length);
|
|
5
|
+
let next = 0;
|
|
6
|
+
async function worker() {
|
|
7
|
+
while (next < items.length) {
|
|
8
|
+
const i = next++;
|
|
9
|
+
results[i] = await fn(items[i], i);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
await Promise.all(Array.from({ length: size }, worker));
|
|
13
|
+
return results;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=concurrency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/utils/concurrency.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAmB,EACnB,KAAa,EACb,EAA0C;IAE1C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,IAAI,KAAK,CAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,KAAK,UAAU,MAAM;QACnB,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 把图层名/画板名转成安全文件名。
|
|
3
|
+
* Windows 保留名(CON、NUL、COM1…)和非法的尾部点/空格也要处理,否则写文件会失败。
|
|
4
|
+
*/
|
|
5
|
+
export declare function sanitizeFilename(name: string, fallback?: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* 同名文件去重:第二次出现起追加 `_2`、`_3`…
|
|
8
|
+
* 返回一个可复用的命名器,同一目录内共享才能跨画板/跨批次去重。
|
|
9
|
+
*/
|
|
10
|
+
export declare function createNamer(): (base: string, ext: string) => string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 把图层名/画板名转成安全文件名。
|
|
3
|
+
* Windows 保留名(CON、NUL、COM1…)和非法的尾部点/空格也要处理,否则写文件会失败。
|
|
4
|
+
*/
|
|
5
|
+
export function sanitizeFilename(name, fallback = "unnamed") {
|
|
6
|
+
let out = name
|
|
7
|
+
// 保留空格和连字符,只替换真正非法的字符与控制字符
|
|
8
|
+
.replace(/[\\/:*?"<>|\x00-\x1f]/g, "_")
|
|
9
|
+
// Windows 不允许文件名以 . 或空格结尾
|
|
10
|
+
.replace(/[. ]+$/, "")
|
|
11
|
+
.trim();
|
|
12
|
+
if (/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|$)/i.test(out) ||
|
|
13
|
+
out.length > 120) {
|
|
14
|
+
out = out.replace(/^(con|prn|aux|nul|com[1-9]|lpt[1-9])/i, "_$1").slice(0, 120);
|
|
15
|
+
}
|
|
16
|
+
return out || fallback;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 同名文件去重:第二次出现起追加 `_2`、`_3`…
|
|
20
|
+
* 返回一个可复用的命名器,同一目录内共享才能跨画板/跨批次去重。
|
|
21
|
+
*/
|
|
22
|
+
export function createNamer() {
|
|
23
|
+
const used = new Map();
|
|
24
|
+
// 不区分大小写,避免 a.png / A.png 在 macOS/Windows 上互相覆盖
|
|
25
|
+
return (base, ext) => {
|
|
26
|
+
const key = `${base}.${ext}`.toLowerCase();
|
|
27
|
+
const n = (used.get(key) ?? 0) + 1;
|
|
28
|
+
used.set(key, n);
|
|
29
|
+
return n === 1 ? `${base}.${ext}` : `${base}_${n}.${ext}`;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=filename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filename.js","sourceRoot":"","sources":["../../src/utils/filename.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,QAAQ,GAAG,SAAS;IACjE,IAAI,GAAG,GAAG,IAAI;QACZ,2BAA2B;SAC1B,OAAO,CAAC,wBAAwB,EAAE,GAAG,CAAC;QACvC,0BAA0B;SACzB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,IAAI,EAAE,CAAC;IAEV,IACE,6CAA6C,CAAC,IAAI,CAAC,GAAG,CAAC;QACvD,GAAG,CAAC,MAAM,GAAG,GAAG,EAChB,CAAC;QACD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,GAAG,IAAI,QAAQ,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,gDAAgD;IAChD,OAAO,CAAC,IAAY,EAAE,GAAW,EAAU,EAAE;QAC3C,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codesign-mcp-server",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "MCP server for Tencent CoDesign — read design specs, layer annotations, and download slices",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"codesign-mcp-server": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/geniyangge/codesign-mcp-server.git"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/geniyangge/codesign-mcp-server#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/geniyangge/codesign-mcp-server/issues"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"registry": "https://registry.npmjs.org/",
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"dev": "tsc --watch",
|
|
29
|
+
"start": "node dist/index.js",
|
|
30
|
+
"version:check": "node scripts/version.mjs",
|
|
31
|
+
"version:sync": "node scripts/version.mjs --sync",
|
|
32
|
+
"test": "npm run version:check && tsc -p tsconfig.test.json && node --test dist-test/test/*.test.js",
|
|
33
|
+
"prepublishOnly": "npm run version:check && npm run build"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18.17"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"mcp",
|
|
40
|
+
"model-context-protocol",
|
|
41
|
+
"codesign",
|
|
42
|
+
"design",
|
|
43
|
+
"figma-alternative"
|
|
44
|
+
],
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
48
|
+
"zod": "^3.25.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^22.10.0",
|
|
52
|
+
"typescript": "^5.7.0"
|
|
53
|
+
}
|
|
54
|
+
}
|