@coralai/sps-cli 0.65.95 → 0.66.0
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/dist/console/index.d.ts.map +1 -1
- package/dist/console/index.js +2 -0
- package/dist/console/index.js.map +1 -1
- package/dist/console/routes/art.d.ts +41 -0
- package/dist/console/routes/art.d.ts.map +1 -1
- package/dist/console/routes/art.js +12 -267
- package/dist/console/routes/art.js.map +1 -1
- package/dist/console/routes/capabilities.d.ts +22 -0
- package/dist/console/routes/capabilities.d.ts.map +1 -0
- package/dist/console/routes/capabilities.js +37 -0
- package/dist/console/routes/capabilities.js.map +1 -0
- package/dist/console/routes/cards.d.ts.map +1 -1
- package/dist/console/routes/cards.js +26 -0
- package/dist/console/routes/cards.js.map +1 -1
- package/dist/console-assets/assets/{ShowcasePage-BCO-h0JV.js → ShowcasePage-Ct_TJCyO.js} +1 -1
- package/dist/console-assets/assets/{index-DT-bJh9j.css → index-CKvLXfFP.css} +1 -1
- package/dist/console-assets/assets/{index-C-y1kIT5.js → index-DnQSjy6_.js} +90 -90
- package/dist/console-assets/index.html +2 -2
- package/dist/core/art/ops.d.ts +16 -0
- package/dist/core/art/ops.d.ts.map +1 -0
- package/dist/core/art/ops.js +290 -0
- package/dist/core/art/ops.js.map +1 -0
- package/dist/{console/lib/artPaths.d.ts → core/art/paths.d.ts} +2 -2
- package/dist/core/art/paths.d.ts.map +1 -0
- package/dist/{console/lib/artPaths.js → core/art/paths.js} +11 -6
- package/dist/core/art/paths.js.map +1 -0
- package/dist/core/tools/ToolCardExecutor.d.ts +28 -0
- package/dist/core/tools/ToolCardExecutor.d.ts.map +1 -0
- package/dist/core/tools/ToolCardExecutor.js +37 -0
- package/dist/core/tools/ToolCardExecutor.js.map +1 -0
- package/dist/core/tools/artCapabilities.d.ts +3 -0
- package/dist/core/tools/artCapabilities.d.ts.map +1 -0
- package/dist/core/tools/artCapabilities.js +55 -0
- package/dist/core/tools/artCapabilities.js.map +1 -0
- package/dist/core/tools/cardRefs.d.ts +37 -0
- package/dist/core/tools/cardRefs.d.ts.map +1 -0
- package/dist/core/tools/cardRefs.js +83 -0
- package/dist/core/tools/cardRefs.js.map +1 -0
- package/dist/core/tools/registry.d.ts +80 -0
- package/dist/core/tools/registry.d.ts.map +1 -0
- package/dist/core/tools/registry.js +29 -0
- package/dist/core/tools/registry.js.map +1 -0
- package/dist/core/tools/rerunGraph.d.ts +29 -0
- package/dist/core/tools/rerunGraph.d.ts.map +1 -0
- package/dist/core/tools/rerunGraph.js +40 -0
- package/dist/core/tools/rerunGraph.js.map +1 -0
- package/dist/engines/StageEngine.d.ts +13 -0
- package/dist/engines/StageEngine.d.ts.map +1 -1
- package/dist/engines/StageEngine.js +72 -1
- package/dist/engines/StageEngine.js.map +1 -1
- package/dist/providers/MarkdownTaskBackend.d.ts +13 -0
- package/dist/providers/MarkdownTaskBackend.d.ts.map +1 -1
- package/dist/providers/MarkdownTaskBackend.js +45 -2
- package/dist/providers/MarkdownTaskBackend.js.map +1 -1
- package/dist/providers/llm/chatTools.d.ts.map +1 -1
- package/dist/providers/llm/chatTools.js +9 -1
- package/dist/providers/llm/chatTools.js.map +1 -1
- package/dist/services/AgentGenService.d.ts.map +1 -1
- package/dist/services/AgentGenService.js +2 -2
- package/dist/services/AgentGenService.js.map +1 -1
- package/dist/services/CardService.d.ts +29 -1
- package/dist/services/CardService.d.ts.map +1 -1
- package/dist/services/CardService.js +34 -0
- package/dist/services/CardService.js.map +1 -1
- package/dist/services/ChatService.d.ts.map +1 -1
- package/dist/services/ChatService.js +1 -1
- package/dist/services/ChatService.js.map +1 -1
- package/dist/services/MemoryService.d.ts +1 -1
- package/dist/services/MemoryService.d.ts.map +1 -1
- package/dist/services/MemoryService.js +2 -2
- package/dist/services/MemoryService.js.map +1 -1
- package/dist/services/ProjectService.d.ts.map +1 -1
- package/dist/services/ProjectService.js +2 -2
- package/dist/services/ProjectService.js.map +1 -1
- package/dist/services/SkillService.d.ts +1 -1
- package/dist/services/SkillService.d.ts.map +1 -1
- package/dist/services/SkillService.js +1 -1
- package/dist/services/SkillService.js.map +1 -1
- package/dist/services/SystemService.d.ts.map +1 -1
- package/dist/services/SystemService.js.map +1 -1
- package/dist/services/WorkerService.d.ts +1 -1
- package/dist/services/WorkerService.d.ts.map +1 -1
- package/dist/services/WorkerService.js +3 -4
- package/dist/services/WorkerService.js.map +1 -1
- package/dist/services/container.d.ts +2 -2
- package/dist/services/container.d.ts.map +1 -1
- package/dist/services/container.js +1 -1
- package/dist/services/container.js.map +1 -1
- package/dist/shared/types.d.ts +26 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/console/lib/artPaths.d.ts.map +0 -1
- package/dist/console/lib/artPaths.js.map +0 -1
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10
10
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-DnQSjy6_.js"></script>
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CKvLXfFP.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type DomainError } from '../../shared/errors.js';
|
|
2
|
+
type Body = Record<string, unknown>;
|
|
3
|
+
export declare function isDomainError(e: unknown): e is DomainError;
|
|
4
|
+
export declare const invalid: (code: string, msg: string, details?: Record<string, unknown>) => DomainError;
|
|
5
|
+
export declare function chromaKey(b: Body): Promise<Record<string, unknown>>;
|
|
6
|
+
export declare function rembg(b: Body): Promise<Record<string, unknown>>;
|
|
7
|
+
export declare function cleanAlpha(b: Body): Promise<Record<string, unknown>>;
|
|
8
|
+
export declare function residue(b: Body): Promise<Record<string, unknown>>;
|
|
9
|
+
export declare function inspect(b: Body): Promise<Record<string, unknown>>;
|
|
10
|
+
export declare function sliceSheet(b: Body): Promise<Record<string, unknown>>;
|
|
11
|
+
export declare function packAtlas(b: Body): Promise<Record<string, unknown>>;
|
|
12
|
+
export declare function normalizeSheet(b: Body): Promise<Record<string, unknown>>;
|
|
13
|
+
export declare function normalizeFrames(b: Body): Promise<Record<string, unknown>>;
|
|
14
|
+
export declare function resize(b: Body): Promise<Record<string, unknown>>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../../src/core/art/ops.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,wBAAwB,CAAC;AAGvE,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpC,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAE1D;AAED,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,WACrB,CAAC;AAiCnE,wBAAsB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAYzE;AAED,wBAAsB,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAOrE;AAED,wBAAsB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAO1E;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMvE;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA4CvE;AAED,wBAAsB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAyC1E;AAED,wBAAsB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwCzE;AAED,wBAAsB,cAAc,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgB9E;AAED,wBAAsB,eAAe,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAmC/E;AAED,wBAAsB,MAAM,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAOtE"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/art/ops
|
|
3
|
+
* @description 美术算子的**能力实现**:取参 → 路径围栏 → 调算法 → 落盘 → 回执形状。
|
|
4
|
+
*
|
|
5
|
+
* @layer core
|
|
6
|
+
*
|
|
7
|
+
* 🔴 **为什么这一层必须存在(2026-08-20 抽取):**
|
|
8
|
+
* 原来这十段住在 `console/routes/art.ts` 的路由回调里,而**那一层不是胶水,它是能力的一半** ——
|
|
9
|
+
* 取参、围栏(realpath)、落盘、回执形状全在那儿。
|
|
10
|
+
* 工具卡的执行器若直接登记 `providers/art/*` 的算法函数,这一半要**重写一遍**
|
|
11
|
+
* ⇒ 两份实现开始漂,而**路径处理漂了会出安全问题**。
|
|
12
|
+
* ⇒ 抽成这里的十个函数,**HTTP 路由与工具卡注册表都调它**。
|
|
13
|
+
* (同一招在 `templates.ts` 用过:抽出 `ingest`,推字节与拉 URL 共用。)
|
|
14
|
+
*
|
|
15
|
+
* 🔴 **算法件 `providers/art/*` 一行没动** —— 它们是 studio 整段移交的只读件。
|
|
16
|
+
* 本模块只搬"适配"那一半。
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ 这里**不做 HTTP 的事**:不认识 Context、不产生响应、不翻译状态码。
|
|
19
|
+
* 错误一律抛 `DomainError`,由调用方(路由 / 执行器)各自翻译 ——
|
|
20
|
+
* 因为"同一个失败在 HTTP 上是 422、在卡片上是卡片失败",翻译规则属于适配器,不属于能力。
|
|
21
|
+
*/
|
|
22
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
23
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
24
|
+
import { domainError } from '../../shared/errors.js';
|
|
25
|
+
import { resolveInputPath, resolveManifestPath, resolveOutputDir, resolveOutputPath } from './paths.js';
|
|
26
|
+
export function isDomainError(e) {
|
|
27
|
+
return typeof e === 'object' && e !== null && 'kind' in e && 'code' in e && 'message' in e;
|
|
28
|
+
}
|
|
29
|
+
export const invalid = (code, msg, details) => domainError('validation', code, msg, details ? { details } : {});
|
|
30
|
+
function str(b, k) {
|
|
31
|
+
const v = b[k];
|
|
32
|
+
return typeof v === 'string' && v.trim() !== '' ? v.trim() : undefined;
|
|
33
|
+
}
|
|
34
|
+
function reqStr(b, k) {
|
|
35
|
+
const v = str(b, k);
|
|
36
|
+
if (!v)
|
|
37
|
+
throw invalid('FIELD_REQUIRED', `缺必填字段 ${k}`, { field: k });
|
|
38
|
+
return v;
|
|
39
|
+
}
|
|
40
|
+
function num(b, k) {
|
|
41
|
+
const v = b[k];
|
|
42
|
+
if (v === undefined || v === null)
|
|
43
|
+
return undefined;
|
|
44
|
+
const n = typeof v === 'number' ? v : Number(v);
|
|
45
|
+
if (!Number.isFinite(n))
|
|
46
|
+
throw invalid('FIELD_INVALID', `${k} 不是数字:${String(v)}`, { field: k });
|
|
47
|
+
return n;
|
|
48
|
+
}
|
|
49
|
+
function reqNum(b, k) {
|
|
50
|
+
const n = num(b, k);
|
|
51
|
+
if (n === undefined)
|
|
52
|
+
throw invalid('FIELD_REQUIRED', `缺必填字段 ${k}`, { field: k });
|
|
53
|
+
return n;
|
|
54
|
+
}
|
|
55
|
+
function bool(b, k) {
|
|
56
|
+
return b[k] === true || b[k] === 'true';
|
|
57
|
+
}
|
|
58
|
+
/** `out` 省略 = 原地覆盖 `in`(同 CLI)。**但仍要过写围栏** —— 原地覆盖也是写。 */
|
|
59
|
+
async function outOf(b, inPath) {
|
|
60
|
+
const raw = str(b, 'out');
|
|
61
|
+
return await resolveOutputPath(raw ?? inPath, 'out');
|
|
62
|
+
}
|
|
63
|
+
export async function chromaKey(b) {
|
|
64
|
+
const { chromaKey } = await import('../../providers/art/pixels.js');
|
|
65
|
+
const inPath = await resolveInputPath(reqStr(b, 'in'));
|
|
66
|
+
const out = await outOf(b, inPath);
|
|
67
|
+
const opts = {};
|
|
68
|
+
const t = num(b, 'tolerance');
|
|
69
|
+
const f = num(b, 'feather');
|
|
70
|
+
if (t !== undefined)
|
|
71
|
+
opts.tolerance = t;
|
|
72
|
+
if (f !== undefined)
|
|
73
|
+
opts.feather = f;
|
|
74
|
+
const buf = await chromaKey(await readFile(inPath), opts);
|
|
75
|
+
await writeFile(out, buf);
|
|
76
|
+
return { out, bytes: buf.length };
|
|
77
|
+
}
|
|
78
|
+
export async function rembg(b) {
|
|
79
|
+
const { rembgRemove } = await import('../../providers/art/pixels.js');
|
|
80
|
+
const inPath = await resolveInputPath(reqStr(b, 'in'));
|
|
81
|
+
const out = await outOf(b, inPath);
|
|
82
|
+
const buf = await rembgRemove(await readFile(inPath));
|
|
83
|
+
await writeFile(out, buf);
|
|
84
|
+
return { out, bytes: buf.length };
|
|
85
|
+
}
|
|
86
|
+
export async function cleanAlpha(b) {
|
|
87
|
+
const { cleanAlpha } = await import('../../providers/art/pixels.js');
|
|
88
|
+
const inPath = await resolveInputPath(reqStr(b, 'in'));
|
|
89
|
+
const out = await outOf(b, inPath);
|
|
90
|
+
const buf = await cleanAlpha(await readFile(inPath), num(b, 'lo') ?? 30, num(b, 'hi') ?? 200);
|
|
91
|
+
await writeFile(out, buf);
|
|
92
|
+
return { out, bytes: buf.length };
|
|
93
|
+
}
|
|
94
|
+
export async function residue(b) {
|
|
95
|
+
const { magentaResidue, alreadyTransparent } = await import('../../providers/art/pixels.js');
|
|
96
|
+
const buf = await readFile(await resolveInputPath(reqStr(b, 'in')));
|
|
97
|
+
const [residue, transparent] = await Promise.all([magentaResidue(buf), alreadyTransparent(buf)]);
|
|
98
|
+
// needsRembg 直接给结论,省得调用方自己比阈值比错。
|
|
99
|
+
return { residue, alreadyTransparent: transparent, threshold: 0.005, needsRembg: !transparent && residue > 0.005 };
|
|
100
|
+
}
|
|
101
|
+
export async function inspect(b) {
|
|
102
|
+
const sharp = (await import('sharp')).default;
|
|
103
|
+
const { alreadyTransparent } = await import('../../providers/art/pixels.js');
|
|
104
|
+
const { logicalSize } = await import('../../providers/art/atlas.js');
|
|
105
|
+
const buf = await readFile(await resolveInputPath(reqStr(b, 'in')));
|
|
106
|
+
const meta = await sharp(buf).metadata();
|
|
107
|
+
const width = meta.width ?? 0;
|
|
108
|
+
const height = meta.height ?? 0;
|
|
109
|
+
const out = {
|
|
110
|
+
width,
|
|
111
|
+
height,
|
|
112
|
+
channels: meta.channels ?? 0,
|
|
113
|
+
hasAlpha: meta.hasAlpha ?? false,
|
|
114
|
+
alreadyTransparent: await alreadyTransparent(buf),
|
|
115
|
+
};
|
|
116
|
+
// 🔴 「合法缺席」vs「故障」要分开(studio 修正的那条):
|
|
117
|
+
// 路径②(资源库)的图**压根不属于任何一局游戏**,没有 manifest 也不该有 ——
|
|
118
|
+
// 按"缺就抛"会让 inspect 在那条路上**永远抛**。
|
|
119
|
+
// 所以:不给 manifest = 合法缺席 → 占屏比**字段整个不出现**;
|
|
120
|
+
// 给了但读不到/缺字段 = 故障 → 抛。
|
|
121
|
+
// ⚠️ 不返回 null 占位:「字段不存在」调用方拿不到会自己想办法,
|
|
122
|
+
// 「字段是 null」会被 `?? 0` / `< 50` 这类判断悄悄吃掉。
|
|
123
|
+
// **不能提供的答案,不要给一个形状正确的占位。**
|
|
124
|
+
const manifest = str(b, 'manifest');
|
|
125
|
+
if (manifest) {
|
|
126
|
+
const mp = await resolveManifestPath(manifest);
|
|
127
|
+
let logical;
|
|
128
|
+
try {
|
|
129
|
+
logical = logicalSize(mp);
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
// 🔴 **不透传原始异常消息**:JSON.parse 失败的消息会带文件原文片段。
|
|
133
|
+
// manifest 是唯一按非图片解析的入参,这是它单独需要处理的原因。
|
|
134
|
+
throw invalid('MANIFEST_INVALID', `manifest 无法解析或缺 width/height:${mp}`, {
|
|
135
|
+
field: 'manifest',
|
|
136
|
+
path: mp,
|
|
137
|
+
reason: e instanceof Error && /缺 width\/height/.test(e.message) ? 'missing-fields' : 'unreadable',
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
out.logicalWidth = logical.width;
|
|
141
|
+
out.logicalHeight = logical.height;
|
|
142
|
+
out.widthPctOfScreen = logical.width ? +((width / logical.width) * 100).toFixed(1) : null;
|
|
143
|
+
out.heightPctOfScreen = logical.height ? +((height / logical.height) * 100).toFixed(1) : null;
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
147
|
+
export async function sliceSheet(b) {
|
|
148
|
+
const { sliceSheet } = await import('../../providers/art/sheet.js');
|
|
149
|
+
const inPath = await resolveInputPath(reqStr(b, 'in'));
|
|
150
|
+
const cols = reqNum(b, 'cols');
|
|
151
|
+
const rows = reqNum(b, 'rows');
|
|
152
|
+
const r = await sliceSheet(await readFile(inPath), cols, rows, { grid: bool(b, 'grid') });
|
|
153
|
+
const outDirRaw = str(b, 'outDir');
|
|
154
|
+
const stem = str(b, 'name') ?? 'frame';
|
|
155
|
+
const outDir = outDirRaw ? await resolveOutputDir(outDirRaw) : undefined;
|
|
156
|
+
// 🔴 清单:**次序是数据,不是排序约定**。`frame_10.png` 字典序排在 `frame_2.png` 前面 ——
|
|
157
|
+
// 调用方靠文件名排 = 帧序乱、而每张图都对(最难看出的那种错)。
|
|
158
|
+
// 🔴 **空格占一个 index 并出现在清单里**(w/h 为 0 + empty:true)。跳过 = 其后所有帧索引前移,
|
|
159
|
+
// 而游戏按 `<id>_0/_1` 引用 —— 一个空格错位整套动画。
|
|
160
|
+
// ⚠️ 这条在 packSheet 内部保住过一次,**清单是新面,同一个坑要再堵一次**:
|
|
161
|
+
// 移交时保住的不变量不会自动跟到 HTTP 面上。
|
|
162
|
+
// Promise.all 保序 —— 见上:**次序是数据**,不是排序约定。
|
|
163
|
+
const items = await Promise.all(r.frames.map(async (buf, i) => {
|
|
164
|
+
const size = r.sizes[i] ?? { w: 0, h: 0 };
|
|
165
|
+
const file = `${stem}_${i}.png`;
|
|
166
|
+
if (outDir)
|
|
167
|
+
await writeFile(join(outDir, file), buf);
|
|
168
|
+
return {
|
|
169
|
+
index: i,
|
|
170
|
+
...(outDir ? { file } : {}),
|
|
171
|
+
w: size.w,
|
|
172
|
+
h: size.h,
|
|
173
|
+
...(size.w === 0 && size.h === 0 ? { empty: true } : {}),
|
|
174
|
+
};
|
|
175
|
+
}));
|
|
176
|
+
// ⚠️ `detected:true`(内容感知切)时 index 是**连通域顺序**,不是网格格位:
|
|
177
|
+
// 空区域根本不产生 cell,所以那条路上空格是**缺席**而非占位,frames 可能 ≠ cols×rows。
|
|
178
|
+
// 这正是 frames vs expectedFrames 要给出来的原因 —— 它是"要不要 grid:true 重来"的信号。
|
|
179
|
+
return {
|
|
180
|
+
frames: r.frames.length,
|
|
181
|
+
expectedFrames: cols * rows,
|
|
182
|
+
detected: r.detected,
|
|
183
|
+
sizes: r.sizes,
|
|
184
|
+
items,
|
|
185
|
+
...(outDir ? { outDir } : {}),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export async function packAtlas(b) {
|
|
189
|
+
const { packSheet } = await import('../../providers/art/sheet.js');
|
|
190
|
+
const { writeAtlasJson } = await import('../../providers/art/atlas.js');
|
|
191
|
+
const inPath = await resolveInputPath(reqStr(b, 'in'));
|
|
192
|
+
const cols = reqNum(b, 'cols');
|
|
193
|
+
const rows = reqNum(b, 'rows');
|
|
194
|
+
const opts = { grid: bool(b, 'grid') };
|
|
195
|
+
// 🔴 限制帧高**只能**走这里(切分后逐帧缩)。事后 resize 整张图集会把
|
|
196
|
+
// 「单帧上限」误当整图上限 —— 8 帧图集每帧变 1/8,而一切看起来都自洽。
|
|
197
|
+
const fmh = num(b, 'frameMaxHeight');
|
|
198
|
+
if (fmh !== undefined)
|
|
199
|
+
opts.frameMaxHeight = fmh;
|
|
200
|
+
const packed = await packSheet(await readFile(inPath), cols, rows, opts);
|
|
201
|
+
const out = await outOf(b, inPath);
|
|
202
|
+
const id = str(b, 'id');
|
|
203
|
+
const dir = id ? await resolveOutputDir(str(b, 'assetsDir') ?? dirname(out), 'assetsDir') : undefined;
|
|
204
|
+
// 🔴 与 CLI 面同一道断言(cbc3454):atlas 的 `meta.image` 由 `id` 推出(`${id}.png`),
|
|
205
|
+
// 而图落在 `out`。不自洽时 atlas 结构合法、坐标自洽,只有引擎加载时报「找不到图」。
|
|
206
|
+
// **先断言再落盘** —— 宁可什么都不写,也不写出一个指向空气的 atlas。
|
|
207
|
+
if (id && dir && resolve(dir, `${id}.png`) !== out) {
|
|
208
|
+
throw invalid('ATLAS_ID_OUT_MISMATCH', `out 与 id 不自洽:图落在 ${out},而 atlas 的 meta.image 会写 ${resolve(dir, `${id}.png`)}`, {
|
|
209
|
+
out,
|
|
210
|
+
expectedImage: resolve(dir, `${id}.png`),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
await writeFile(out, packed.buf);
|
|
214
|
+
let atlas;
|
|
215
|
+
if (id && dir) {
|
|
216
|
+
writeAtlasJson(dir, id, packed);
|
|
217
|
+
atlas = resolve(dir, `${id}.json`);
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
out,
|
|
221
|
+
width: packed.width,
|
|
222
|
+
height: packed.height,
|
|
223
|
+
frames: packed.frames.length,
|
|
224
|
+
expectedFrames: cols * rows,
|
|
225
|
+
detected: packed.detected,
|
|
226
|
+
...(atlas ? { atlas } : {}),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
export async function normalizeSheet(b) {
|
|
230
|
+
const { normalizeSheet } = await import('../../providers/art/sheet.js');
|
|
231
|
+
const inPath = await resolveInputPath(reqStr(b, 'in'));
|
|
232
|
+
const out = await outOf(b, inPath);
|
|
233
|
+
const r = await normalizeSheet(await readFile(inPath), reqNum(b, 'cols'), reqNum(b, 'rows'));
|
|
234
|
+
await writeFile(out, r.buf);
|
|
235
|
+
return {
|
|
236
|
+
out,
|
|
237
|
+
mode: 'sheet',
|
|
238
|
+
frames: r.frames,
|
|
239
|
+
cols: r.cols,
|
|
240
|
+
rows: r.rows,
|
|
241
|
+
cellWidth: r.cellWidth,
|
|
242
|
+
cellHeight: r.cellHeight,
|
|
243
|
+
detected: r.detected,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
export async function normalizeFrames(b) {
|
|
247
|
+
const { normalizeFrames } = await import('../../providers/art/frames.js');
|
|
248
|
+
const raw = b.in;
|
|
249
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
250
|
+
throw invalid('FIELD_REQUIRED', 'in 必须是非空的绝对路径数组', { field: 'in' });
|
|
251
|
+
}
|
|
252
|
+
const inputs = await Promise.all(raw.map((p, i) => resolveInputPath(String(p), `in[${i}]`)));
|
|
253
|
+
const opts = {};
|
|
254
|
+
const tw = num(b, 'targetWidth');
|
|
255
|
+
const th = num(b, 'targetHeight');
|
|
256
|
+
const pd = num(b, 'pad');
|
|
257
|
+
if (tw !== undefined)
|
|
258
|
+
opts.targetWidth = tw;
|
|
259
|
+
if (th !== undefined)
|
|
260
|
+
opts.targetHeight = th;
|
|
261
|
+
if (pd !== undefined)
|
|
262
|
+
opts.pad = pd;
|
|
263
|
+
const outDirRaw = str(b, 'outDir');
|
|
264
|
+
const outDir = outDirRaw ? await resolveOutputDir(outDirRaw) : undefined;
|
|
265
|
+
// outDir 省略 = 原地覆盖各输入 —— 逐个过写围栏(资源库可读不可写,原地覆盖会在那里被挡住,
|
|
266
|
+
// 这正是我们要的:studio 该把结果写进共享树再自己搬回资源库)。
|
|
267
|
+
const targets = await Promise.all(inputs.map((p, i) => outDir ? Promise.resolve(join(outDir, `frame_${i}.png`)) : resolveOutputPath(p, `in[${i}]`)));
|
|
268
|
+
const r = await normalizeFrames(await Promise.all(inputs.map((p) => readFile(p))), opts);
|
|
269
|
+
// 逐帧目标先按 index 定好再并发写 —— written 的**次序是数据**(调用方按它对帧)。
|
|
270
|
+
const written = r.frames.map((_, i) => targets[i] ?? join(outDir ?? dirname(inputs[0]), `frame_${i}.png`));
|
|
271
|
+
await Promise.all(r.frames.map((buf, i) => writeFile(written[i], buf)));
|
|
272
|
+
return {
|
|
273
|
+
mode: 'frames',
|
|
274
|
+
width: r.width,
|
|
275
|
+
height: r.height,
|
|
276
|
+
frames: r.frames.length,
|
|
277
|
+
written,
|
|
278
|
+
items: written.map((p, i) => ({ index: i, file: basename(p) })),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
export async function resize(b) {
|
|
282
|
+
const { resizeToFit } = await import('../../providers/art/frames.js');
|
|
283
|
+
const inPath = await resolveInputPath(reqStr(b, 'in'));
|
|
284
|
+
const out = await outOf(b, inPath);
|
|
285
|
+
const r = await resizeToFit(await readFile(inPath), reqNum(b, 'maxWidth'), reqNum(b, 'maxHeight'));
|
|
286
|
+
if (r.changed)
|
|
287
|
+
await writeFile(out, r.buf);
|
|
288
|
+
return { out, changed: r.changed, width: r.width, height: r.height };
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.js","sourceRoot":"","sources":["../../../src/core/art/ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* (`providers/art/withinDir.ts` 字符串版 vs 这里的 realpath 版,靠头注区分)——
|
|
5
5
|
* 同步这条路再要围栏时,**不能出现第三份**。
|
|
6
6
|
*/
|
|
7
|
-
export { isUnderRoot } from '
|
|
7
|
+
export { isUnderRoot } from '../pathFence.js';
|
|
8
8
|
/**
|
|
9
9
|
* 输入路径:绝对 + 存在 + 是文件 + 不超尺寸护栏。**不设根围栏**(见模块头)。
|
|
10
10
|
*/
|
|
@@ -26,4 +26,4 @@ export declare function resolveOutputDir(raw: string, field?: string): Promise<s
|
|
|
26
26
|
* (manifest 本来就在游戏 repo 里,也就是工作区树内,所以围它零代价。)
|
|
27
27
|
*/
|
|
28
28
|
export declare function resolveManifestPath(raw: string, field?: string): Promise<string>;
|
|
29
|
-
//# sourceMappingURL=
|
|
29
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/core/art/paths.ts"],"names":[],"mappings":"AA4CA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA2B9C;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBjF;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAenF;AAED,gDAAgD;AAChD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAcrF;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAY1F"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @module
|
|
2
|
+
* @module core/art/paths
|
|
3
3
|
* @description HTTP 面的路径校验与**写围栏**。设计见 docs/design/art-http-surface.md §5。
|
|
4
|
-
* @layer
|
|
4
|
+
* @layer core
|
|
5
|
+
*
|
|
6
|
+
* 🔴 **2026-08-20 从 `console/lib/artPaths` 挪到这里**:算子要被**两个适配器**共用
|
|
7
|
+
* (HTTP 面 / 工具卡执行器),而围栏是能力的一半 —— 留在 console 下会逼 core 反向依赖 console,
|
|
8
|
+
* 或者逼人**再写一份路径处理**。而**路径处理漂了会出安全问题**。
|
|
9
|
+
* (同一天在 `core/pathFence` 上用过同一招:安全判据不能有第二份。)
|
|
5
10
|
*
|
|
6
11
|
* 🔴 **为什么需要围栏(这是档B 引进的,不是既有缺陷):**
|
|
7
12
|
* CLI 以**调用者自己的身份**跑,写不到调用者本来就写不到的地方 —— 没有提升。
|
|
@@ -29,7 +34,7 @@
|
|
|
29
34
|
import { stat } from 'node:fs/promises';
|
|
30
35
|
import { dirname, isAbsolute } from 'node:path';
|
|
31
36
|
import { domainError } from '../../shared/errors.js';
|
|
32
|
-
import { workspacesRoot } from '
|
|
37
|
+
import { workspacesRoot } from '../workspacePaths.js';
|
|
33
38
|
/**
|
|
34
39
|
* 输入文件大小上限。**不是业务约束,是可用性护栏**:
|
|
35
40
|
* 入参是调用方给的任意路径,不设限则 `readFileSync` 一个巨大文件即可把进程打爆。
|
|
@@ -41,8 +46,8 @@ const MAX_INPUT_BYTES = 64 * 1024 * 1024;
|
|
|
41
46
|
* (`providers/art/withinDir.ts` 字符串版 vs 这里的 realpath 版,靠头注区分)——
|
|
42
47
|
* 同步这条路再要围栏时,**不能出现第三份**。
|
|
43
48
|
*/
|
|
44
|
-
export { isUnderRoot } from '
|
|
45
|
-
import { isUnderRoot, realResolve } from '
|
|
49
|
+
export { isUnderRoot } from '../pathFence.js';
|
|
50
|
+
import { isUnderRoot, realResolve } from '../pathFence.js';
|
|
46
51
|
/**
|
|
47
52
|
* 把路径解析到**真实位置**再判围栏 —— 否则一个软链就绕出去了。
|
|
48
53
|
* 目标可能尚不存在(输出文件),故解析其**父目录**的 realpath 再拼回文件名。
|
|
@@ -149,4 +154,4 @@ export async function resolveManifestPath(raw, field = 'manifest') {
|
|
|
149
154
|
}
|
|
150
155
|
return p;
|
|
151
156
|
}
|
|
152
|
-
//# sourceMappingURL=
|
|
157
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/core/art/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/tools/ToolCardExecutor
|
|
3
|
+
* @description 执行一张 `kind:'tool'` 卡:查注册表 → 校验参数 → 跑能力 → 回结果。
|
|
4
|
+
*
|
|
5
|
+
* @layer core
|
|
6
|
+
*
|
|
7
|
+
* 🔴 **它不认识 HTTP,也不认识卡片的状态机**:只回"成功/失败 + 结果",
|
|
8
|
+
* 移动卡片状态是调用方(StageEngine)的事。
|
|
9
|
+
* 理由与 `core/art/ops` 头注同一条:**同一个失败在 HTTP 上是 422、在卡片上是卡片失败**,
|
|
10
|
+
* 翻译规则属于适配器,不属于能力。
|
|
11
|
+
*
|
|
12
|
+
* 🔴 **async 能力尚未实现,而且是有意的**:今天注册表里**一个 async 能力都没有**
|
|
13
|
+
* (`art.generate` 属于被推迟的占位/音频迁移)。现在写 async + join 的执行路径
|
|
14
|
+
* = 造一条**没有任何东西会跑**的代码 —— 而没跑过的路径坏了没人知道。
|
|
15
|
+
* ⇒ 遇到 `mode:'async'` **响亮报错**,不静默按 sync 跑。
|
|
16
|
+
*/
|
|
17
|
+
import type { Card } from '../../shared/types.js';
|
|
18
|
+
import type { CapabilityContext, CapabilityRegistry } from './registry.js';
|
|
19
|
+
export type ToolCardOutcome = {
|
|
20
|
+
ok: true;
|
|
21
|
+
result: Record<string, unknown>;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
code: string;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function executeToolCard(card: Card, registry: CapabilityRegistry, ctx: CapabilityContext): Promise<ToolCardOutcome>;
|
|
28
|
+
//# sourceMappingURL=ToolCardExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolCardExecutor.d.ts","sourceRoot":"","sources":["../../../src/core/tools/ToolCardExecutor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE3E,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,eAAe,CAAC,CAmC1B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export async function executeToolCard(card, registry, ctx) {
|
|
2
|
+
if (card.kind !== 'tool') {
|
|
3
|
+
return { ok: false, code: 'NOT_A_TOOL_CARD', message: `seq ${card.seq} 的 kind 是 ${card.kind ?? 'worker'}` };
|
|
4
|
+
}
|
|
5
|
+
if (!card.tool) {
|
|
6
|
+
return { ok: false, code: 'TOOL_MISSING', message: `seq ${card.seq} 没有 tool 字段` };
|
|
7
|
+
}
|
|
8
|
+
const cap = registry.get(card.tool);
|
|
9
|
+
if (!cap) {
|
|
10
|
+
// 🔴 能力不存在要**指名**报:它多半是"这个项目没装那个模板",而不是拼错了。
|
|
11
|
+
return { ok: false, code: 'CAPABILITY_NOT_FOUND', message: `未注册的能力:${card.tool}` };
|
|
12
|
+
}
|
|
13
|
+
if (cap.mode === 'async') {
|
|
14
|
+
return {
|
|
15
|
+
ok: false,
|
|
16
|
+
code: 'ASYNC_NOT_IMPLEMENTED',
|
|
17
|
+
message: `能力 ${cap.id} 是 async,而 async/join 执行路径尚未实现(见模块头:今天没有 async 能力可跑)`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// 参数校验在**执行之前**整体做完 —— 与"枚举完再推第一个字节"同一条:
|
|
21
|
+
// 半跑的工具卡会留下一个改了一半的工作区,而卡片上只看到"失败"。
|
|
22
|
+
let input;
|
|
23
|
+
try {
|
|
24
|
+
input = cap.inputSchema.parse(card.input ?? {});
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
return { ok: false, code: 'INPUT_INVALID', message: e instanceof Error ? e.message : String(e) };
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
return { ok: true, result: await cap.run(input, ctx) };
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
const de = e;
|
|
34
|
+
return { ok: false, code: typeof de.code === 'string' ? de.code : 'TOOL_FAILED', message: de.message ?? String(e) };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=ToolCardExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolCardExecutor.js","sourceRoot":"","sources":["../../../src/core/tools/ToolCardExecutor.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAU,EACV,QAA4B,EAC5B,GAAsB;IAEtB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,IAAI,CAAC,GAAG,aAAa,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,EAAE,CAAC;IAC9G,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;IACpF,CAAC;IACD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,4CAA4C;QAC5C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,UAAU,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IACrF,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,sDAAsD;SAC5E,CAAC;IACJ,CAAC;IAED,yCAAyC;IACzC,mCAAmC;IACnC,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACnG,CAAC;IAED,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,CAAwC,CAAC;QACpD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACtH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artCapabilities.d.ts","sourceRoot":"","sources":["../../../src/core/tools/artCapabilities.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAkChD,wBAAgB,eAAe,IAAI,UAAU,EAAE,CAa9C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/tools/artCapabilities
|
|
3
|
+
* @description 把 `core/art/ops` 的十个算子登记成**内建能力**。
|
|
4
|
+
*
|
|
5
|
+
* @layer core
|
|
6
|
+
*
|
|
7
|
+
* 🔴 **这里只做登记,不重写取参/围栏/落盘** —— 那一半在 `ops` 里,
|
|
8
|
+
* HTTP 路由与本注册表**调同一份**。第 0 步重构的全部理由就是这个:
|
|
9
|
+
* 两份实现会漂,而**路径处理漂了会出安全问题**。
|
|
10
|
+
*
|
|
11
|
+
* ⚠️ `inputSchema` 在这里是**入口校验**,`ops` 内部仍有自己的必填检查 ——
|
|
12
|
+
* 两道不是重复:schema 让编排页能**在建卡时**报错,ops 让任何调用方都躲不过。
|
|
13
|
+
* (同族:客户端那道管"早失败、好错误",服务端那道管"安全边界"。)
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import * as ops from '../art/ops.js';
|
|
17
|
+
const builtIn = { kind: 'built-in' };
|
|
18
|
+
/** `in`/`out` 是**相对项目根**的路径;能力自己拼绝对路径,卡片给不了绝对路径。 */
|
|
19
|
+
const rel = z.string().min(1);
|
|
20
|
+
function op(id, summary, inputSchema, produces, fn) {
|
|
21
|
+
return {
|
|
22
|
+
id,
|
|
23
|
+
mode: 'sync',
|
|
24
|
+
inputSchema,
|
|
25
|
+
produces,
|
|
26
|
+
source: builtIn,
|
|
27
|
+
summary,
|
|
28
|
+
async run(input, ctx) {
|
|
29
|
+
const parsed = inputSchema.parse(input);
|
|
30
|
+
// 🔴 相对 → 绝对在**这里**拼:卡片只给逻辑路径,落点权是 sps 的。
|
|
31
|
+
const abs = (v) => (typeof v === 'string' ? `${ctx.projectDir}/${v}` : v);
|
|
32
|
+
const body = { ...parsed };
|
|
33
|
+
for (const k of ['in', 'out', 'outDir', 'assetsDir', 'manifest']) {
|
|
34
|
+
if (body[k] !== undefined)
|
|
35
|
+
body[k] = Array.isArray(body[k]) ? body[k].map(abs) : abs(body[k]);
|
|
36
|
+
}
|
|
37
|
+
return await fn(body);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function artCapabilities() {
|
|
42
|
+
return [
|
|
43
|
+
op('art.chromaKey', '按色度键抠图(洋红底)', z.object({ in: rel, out: rel.optional(), tolerance: z.number().optional(), feather: z.number().optional() }), ['<out>'], ops.chromaKey),
|
|
44
|
+
op('art.rembg', '调 rembg 服务去背景', z.object({ in: rel, out: rel.optional() }), ['<out>'], ops.rembg),
|
|
45
|
+
op('art.cleanAlpha', '清理半透明边缘', z.object({ in: rel, out: rel.optional(), lo: z.number().optional(), hi: z.number().optional() }), ['<out>'], ops.cleanAlpha),
|
|
46
|
+
op('art.residue', '只读判据:这张图值不值得交给模型', z.object({ in: rel }), [], ops.residue),
|
|
47
|
+
op('art.inspect', '只读:尺寸/通道/透明度(给 manifest 则回占屏比)', z.object({ in: rel, manifest: rel.optional() }), [], ops.inspect),
|
|
48
|
+
op('art.sliceSheet', '切图集为逐帧', z.object({ in: rel, cols: z.number(), rows: z.number(), grid: z.boolean().optional(), outDir: rel.optional(), name: z.string().optional() }), ['<outDir>/<name>_<i>.png'], ops.sliceSheet),
|
|
49
|
+
op('art.packAtlas', '打包图集 + 写 atlas json', z.object({ in: rel, cols: z.number(), rows: z.number(), out: rel.optional(), id: z.string().optional(), assetsDir: rel.optional(), grid: z.boolean().optional(), frameMaxHeight: z.number().optional() }), ['<out>', '<assetsDir>/<id>.json'], ops.packAtlas),
|
|
50
|
+
op('art.normalizeSheet', '把图集归一到统一格位', z.object({ in: rel, cols: z.number(), rows: z.number(), out: rel.optional() }), ['<out>'], ops.normalizeSheet),
|
|
51
|
+
op('art.normalizeFrames', '把逐帧归一到统一画布', z.object({ in: z.array(rel).min(1), outDir: rel.optional(), targetWidth: z.number().optional(), targetHeight: z.number().optional(), pad: z.number().optional() }), ['<outDir>/frame_<i>.png'], ops.normalizeFrames),
|
|
52
|
+
op('art.resize', '等比缩到不超过给定尺寸(**不适用于图集**)', z.object({ in: rel, maxWidth: z.number(), maxHeight: z.number(), out: rel.optional() }), ['<out>'], ops.resize),
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=artCapabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artCapabilities.js","sourceRoot":"","sources":["../../../src/core/tools/artCapabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/tools/cardRefs
|
|
3
|
+
* @description 卡片间引用:`${card:12.out}` —— 让下一张卡吃上一张卡的产物。
|
|
4
|
+
*
|
|
5
|
+
* @layer core
|
|
6
|
+
*
|
|
7
|
+
* 🔴 **引用必须跨波次**:被引用的卡 `order` 必须**严格小于**引用它的卡。
|
|
8
|
+
* 同波并行 ⇒ 同波内互相引用是**竞态**,而竞态的表现是"有时对有时错",
|
|
9
|
+
* 比恒错难查得多。⇒ 建卡/校验时就拒,不留到运行时才发现。
|
|
10
|
+
*
|
|
11
|
+
* 🔴 **引用不到要报错,不能静默留原文**:留原文的话参数会变成字符串
|
|
12
|
+
* `"${card:12.out}"` 一路传到能力里,最后表现为"文件不存在" ——
|
|
13
|
+
* 而真因在两步之前。**别让归因跑偏。**
|
|
14
|
+
*/
|
|
15
|
+
export interface CardRef {
|
|
16
|
+
seq: string;
|
|
17
|
+
path: string;
|
|
18
|
+
}
|
|
19
|
+
/** 扫出一份输入里的全部引用(不解析,只列出来 —— 校验与解析是两件事)。 */
|
|
20
|
+
export declare function collectRefs(input: unknown): CardRef[];
|
|
21
|
+
export type ResolveResult = {
|
|
22
|
+
ok: true;
|
|
23
|
+
input: unknown;
|
|
24
|
+
} | {
|
|
25
|
+
ok: false;
|
|
26
|
+
code: 'REF_NOT_FOUND' | 'REF_SAME_OR_LATER_WAVE';
|
|
27
|
+
message: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* 解析引用。
|
|
31
|
+
*
|
|
32
|
+
* @param outputs seq → 那张卡的产物(通常存在卡片 meta 的 `toolResult` 下)
|
|
33
|
+
* @param orderOf seq → 波次;用于跨波校验。取不到波次的卡按**拒绝**处理
|
|
34
|
+
* —— "不知道它在第几波"不能当成"它在前面"。
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveRefs(input: unknown, selfOrder: number, outputs: Map<string, Record<string, unknown>>, orderOf: Map<string, number>): ResolveResult;
|
|
37
|
+
//# sourceMappingURL=cardRefs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardRefs.d.ts","sourceRoot":"","sources":["../../../src/core/tools/cardRefs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CAYrD;AAWD,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC5B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,eAAe,GAAG,wBAAwB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC7C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,aAAa,CAiCf"}
|