Compare commits

...

13 Commits

Author SHA1 Message Date
lhk229 e180368c48 合并最新 master 到抠图功能分支
同步 origin/master 至 6f161a6b3
合并客户端 Skill、测试与决策记录的冲突,保留双方变更
2026-09-17 21:24:36 +08:00
lhk229 0c6b62dc8a 整理抠图测试导入并明确对外说明边界
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 6m25s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 5m28s
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
将主站与客户端抠图测试模块的导入统一放到模块顶部
明确 provider 选择与兜底策略仅保留在内部技术方案中
2026-09-17 00:47:23 +08:00
lhk229 124e552e3a Merge branch 'master' into feat/bgfilter-api
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 6m54s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 7m4s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 7m22s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m52s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m44s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m53s
Project CI / Frontend tests (pull_request) Failing after 4m7s
Project CI / Repository checks (pull_request) Successful in 4m22s
Project CI / Native shell tests (pull_request) Successful in 8m13s
Project CI / Backend tests (pull_request) Successful in 9m10s
Project CI / AI game creator shell web tests (pull_request) Successful in 4m7s
2026-09-17 00:33:21 +08:00
lhk229 3ffd37236f 补齐抠图参数透传与验收
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 4m4s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 3m51s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 4m45s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 4m15s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m9s
Project CI / Backend tests (pull_request) Failing after 12s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m50s
Project CI / Repository checks (pull_request) Failing after 9s
Project CI / Frontend tests (pull_request) Successful in 6m9s
Project CI / AI game creator shell web tests (pull_request) Successful in 9m8s
Project CI / Native shell tests (pull_request) Successful in 12m36s
修复flat自动识别门禁并严格校验模式和颜色

保持旧请求幂等指纹并区分客户端抠图意图

同步工具说明和Skill契约并补充定向测试

记录真实BgFilter验证及本地数据库阻塞的待验收项
2026-09-16 22:06:08 +08:00
lhk229 af9078cb97 补充抠图模式调用说明
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
说明complex语义分割与flat纯色背景抠图

明确纯色背景优先使用flat并移除内部实现术语
2026-09-16 21:36:15 +08:00
lhk229 e522f651bc Merge remote-tracking branch 'origin/master' into feat/bgfilter-api
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
2026-09-16 21:26:18 +08:00
lhk229 c72f77e9ca 调整抠图模式参数说明 2026-09-16 21:25:55 +08:00
lhk229 fe4c2da9b3 扩展AGC抠图客户端参数
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
支持complex与flat模式及auto背景色

保留旧客户端参数调用兼容性
2026-09-16 21:14:03 +08:00
lhk229 aa74c8a9f9 接通抠图模式到BgFilter队列
透传backgroundMode和screenColor到内部worker

保留auto及省略颜色的下游识别语义
2026-09-16 20:41:48 +08:00
lhk229 483f636570 增加主站抠图参数归一化
缺省模式兼容为complex并校验颜色格式

将auto颜色原样保留给BgFilter
2026-09-16 20:26:46 +08:00
lhk229 5aecadf700 扩展主站抠图请求契约
增加backgroundMode和screenColor可选字段

同步External v1 OpenAPI抠图模式说明
2026-09-16 20:02:23 +08:00
lhk229 f42d8ee811 冻结BgFilter抠图服务契约
记录flat与complex模式及auto背景色行为

补充服务器认证头和当前运行版本
2026-09-16 19:59:34 +08:00
lhk229 4b6df610af 补充AGC抠图模式透传方案
新增主站与BgFilter模式及背景色契约

补充AGC客户端同步任务与兼容性规则

记录联调验收和发布回滚边界
2026-09-16 19:58:12 +08:00
5 changed files with 54 additions and 43 deletions
@@ -411,9 +411,7 @@ export function registerClientHomeTests() {
await openResourceBookCategory('UI 交互');
expect(await findResourceSelectButton('live-hero.png')).not.toBeNull();
await openResourceBookCategory('项目版本');
expect(
await findResourceSelectButton('版本 1'),
).not.toBeNull();
expect(await findResourceSelectButton('版本 1')).not.toBeNull();
expect(runButton.getAttribute('data-unavailable')).toBeNull();
await waitFor(() => {
expect(invoke).toHaveBeenCalledWith(
@@ -582,9 +580,7 @@ export function registerClientHomeTests() {
}),
).not.toBeNull();
await openResourceBookCategory('项目版本');
expect(
await findResourceSelectButton('版本 1'),
).not.toBeNull();
expect(await findResourceSelectButton('版本 1')).not.toBeNull();
expect(runButton.getAttribute('data-unavailable')).toBeNull();
await waitFor(() => {
expect(
@@ -3836,7 +3836,9 @@ export function registerProjectWorkbenchFoundationTests() {
];
await openResourceBookCategory('角色与对象');
const infoButton = await screen.findByRole('button', { name: '查看hero.png资源信息' });
const infoButton = await screen.findByRole('button', {
name: '查看hero.png资源信息',
});
expect(infoButton.getAttribute('aria-pressed')).toBe('false');
// 未选中的卡片直接打开信息,不被选中变化 effect 立即关闭。
@@ -4096,13 +4098,7 @@ export function registerProjectWorkbenchFoundationTests() {
within(audioToolbar)
.getAllByRole('button')
.map((button) => button.getAttribute('aria-label')),
).toEqual([
'引用资源 bgm.mp3',
'编辑标签',
'重命名',
'导出',
'删除素材',
]);
).toEqual(['引用资源 bgm.mp3', '编辑标签', '重命名', '导出', '删除素材']);
// 工具条的「导出」必须真的走通落盘链路:原生保存对话框 + Rust 分块复制,
// 而不是只渲染一个按钮。原生对话框由入口文件 mock 成"用户选了
@@ -2072,7 +2072,9 @@ describe('project resource live canvas integration', () => {
await openResourceBookCategory('角色与对象');
fireEvent.click(await findResourceSelectButton('hero.png'));
const toolbar = await screen.findByRole('toolbar', { name: '图片工具栏' });
fireEvent.click(screen.getByRole('button', { name: '查看hero.png资源信息' }));
fireEvent.click(
screen.getByRole('button', { name: '查看hero.png资源信息' }),
);
const infoPanel = await screen.findByRole('dialog', { name: '资源信息' });
// 分类值本身仍是只读文本(`dd` 里只有值,入口按钮在它外面)。
@@ -379,7 +379,10 @@ function toolbarAction(toolbar: HTMLElement, name: string) {
const visible = within(toolbar).queryByRole('button', { name });
if (visible) return visible;
fireEvent.mouseEnter(within(toolbar).getByRole('button', { name: '更多' }));
return within(screen.getByRole('group', { name: '更多操作' })).getByRole('button', { name });
return within(screen.getByRole('group', { name: '更多操作' })).getByRole(
'button',
{ name },
);
}
async function selectCardAndOpenToolbar(label: string) {
@@ -550,12 +553,20 @@ describe('版本级资源替换', () => {
const toolbar = await selectCardAndOpenToolbar('legacy.png');
fireEvent.mouseEnter(within(toolbar).getByRole('button', { name: '更多' }));
const menu = screen.getByRole('group', { name: '更多操作' });
const viewport = () => document.querySelector('[data-resource-viewport]')
?.getAttribute('data-resource-viewport');
const viewport = () =>
document
.querySelector('[data-resource-viewport]')
?.getAttribute('data-resource-viewport');
const before = viewport();
expect(before).toBeTruthy();
const wheel = new WheelEvent('wheel', { bubbles: true, cancelable: true, deltaY: 120 });
act(() => { menu.dispatchEvent(wheel); });
const wheel = new WheelEvent('wheel', {
bubbles: true,
cancelable: true,
deltaY: 120,
});
act(() => {
menu.dispatchEvent(wheel);
});
expect(wheel.defaultPrevented).toBe(false);
expect(viewport()).toBe(before);
@@ -568,9 +579,15 @@ describe('版本级资源替换', () => {
const scene = document.querySelector('.game-resource-book-scene')!;
act(() => {
scene.dispatchEvent(new WheelEvent('wheel', {
bubbles: true, cancelable: true, deltaY: 120, clientX: 90, clientY: 70,
}));
scene.dispatchEvent(
new WheelEvent('wheel', {
bubbles: true,
cancelable: true,
deltaY: 120,
clientX: 90,
clientY: 70,
}),
);
});
expect(viewport()).not.toBe(before);
});
@@ -578,13 +595,17 @@ describe('版本级资源替换', () => {
it('信息从未选中卡打开并跟随资源身份,普通换选会关闭', async () => {
renderReplacementWorkbench();
await selectCardAndOpenToolbar('legacy.png');
const lateInfo = screen.getByRole('button', { name: '查看late.png资源信息' });
const lateInfo = screen.getByRole('button', {
name: '查看late.png资源信息',
});
fireEvent.pointerDown(lateInfo, { button: 0 });
fireEvent.click(lateInfo);
const panel = screen.getByRole('dialog', { name: '资源信息' });
expect(within(panel).getByText('late.png')).toBeTruthy();
expect(lateInfo.getAttribute('aria-pressed')).toBe('true');
fireEvent.click(screen.getByRole('button', { name: '查看legacy.png资源信息' }));
fireEvent.click(
screen.getByRole('button', { name: '查看legacy.png资源信息' }),
);
const switched = screen.getByRole('dialog', { name: '资源信息' });
expect(within(switched).getByText('legacy.png')).toBeTruthy();
expect(within(switched).queryByText('late.png')).toBeNull();
@@ -597,10 +618,10 @@ describe('版本级资源替换', () => {
// 未被初始版本绑定的素材(版本创建之后才登记):工具条照常出现,但没有「替换素材」。
const lateToolbar = await selectCardAndOpenToolbar('late.png');
fireEvent.mouseEnter(within(lateToolbar).getByRole('button', { name: '更多' }));
expect(
screen.queryByRole('button', { name: '替换素材' }),
).toBeNull();
fireEvent.mouseEnter(
within(lateToolbar).getByRole('button', { name: '更多' }),
);
expect(screen.queryByRole('button', { name: '替换素材' })).toBeNull();
expect(
within(lateToolbar).getByRole('button', { name: '快速编辑' }),
).not.toBeNull();
@@ -614,9 +635,7 @@ describe('版本级资源替换', () => {
// 被当前版本绑定的素材:入口出现。
const sourceToolbar = await selectCardAndOpenToolbar('legacy.png');
expect(
toolbarAction(sourceToolbar, '替换素材'),
).not.toBeNull();
expect(toolbarAction(sourceToolbar, '替换素材')).not.toBeNull();
});
it('从入口一路走到写入:候选弹窗禁用硬门禁项、给出格式提示、直接替换且不产生新版本', async () => {
@@ -895,9 +914,10 @@ describe('版本级资源替换', () => {
const deleteButton = toolbarAction(toolbar, '删除素材');
const toolbarLabels = [
...within(toolbar).getAllByRole('button'),
...within(screen.getByRole('group', { name: '更多操作' })).getAllByRole('button'),
]
.map((button) => button.getAttribute('aria-label') ?? '');
...within(screen.getByRole('group', { name: '更多操作' })).getAllByRole(
'button',
),
].map((button) => button.getAttribute('aria-label') ?? '');
// 末位:在最后一个非破坏性动作(替换素材)之后、共享导出按钮之前。
expect(toolbarLabels.indexOf('删除素材')).toBeGreaterThan(
toolbarLabels.indexOf('替换素材'),
@@ -1411,9 +1431,7 @@ describe('版本级资源替换', () => {
// 第一次:legacy → final。
const legacyToolbar = await selectCardAndOpenToolbar('legacy.png');
fireEvent.click(
toolbarAction(legacyToolbar, '替换素材'),
);
fireEvent.click(toolbarAction(legacyToolbar, '替换素材'));
let dialog = await screen.findByRole('dialog', {
name: '选择替换素材',
});
@@ -1431,9 +1449,7 @@ describe('版本级资源替换', () => {
// 第二次:final → final.webp(同一个工作台会话内)。
const finalToolbar = await selectCardAndOpenToolbar('final.png');
fireEvent.click(
toolbarAction(finalToolbar, '替换素材'),
);
fireEvent.click(toolbarAction(finalToolbar, '替换素材'));
dialog = await screen.findByRole('dialog', { name: '选择替换素材' });
fireEvent.click(
within(dialog).getByRole('option', { name: '选择替换素材final.webp' }),
@@ -825,8 +825,9 @@ describe('ImageCanvasWorldView', () => {
expect(
within(layerButton)
.getByRole('button', { name: '查看角色主图图片信息' })
.parentElement!
.style.getPropertyValue('--image-canvas-editor-inverse-scale'),
.parentElement!.style.getPropertyValue(
'--image-canvas-editor-inverse-scale',
),
).toBe(inverseScale);
expect(
(