Merge branch 'master' into codex/puzzle-clear-template-runtime-fixes

# Conflicts:
#	.hermes/shared-memory/decision-log.md
#	.hermes/shared-memory/project-overview.md
#	docs/【开发运维】本地开发验证与生产运维-2026-05-15.md
#	scripts/dev.test.ts
#	server-rs/crates/api-server/src/creation_entry_config.rs
#	server-rs/crates/api-server/src/wooden_fish.rs
#	server-rs/crates/module-auth/src/lib.rs
#	server-rs/crates/spacetime-client/src/wooden_fish.rs
#	server-rs/crates/spacetime-module/src/auth/procedures.rs
#	src/components/custom-world-home/creationWorkShelf.ts
#	src/components/platform-entry/PlatformEntryFlowShellImpl.tsx
#	src/components/rpg-entry/rpgEntryWorldPresentation.ts
#	src/services/miniGameDraftGenerationProgress.test.ts
#	src/services/miniGameDraftGenerationProgress.ts
This commit is contained in:
2026-06-04 11:24:14 +08:00
451 changed files with 18452 additions and 5266 deletions

View File

@@ -37,9 +37,7 @@ describe('miniGameDraftGenerationProgress', () => {
expect(progress?.steps[0]?.detail).toBe(
'建立可恢复草稿,整理首关描述与关卡结构,约 8 秒。',
);
expect(progress?.steps[2]?.detail).toBe(
'生成 1:1 拼图首图,预计 4 分钟。',
);
expect(progress?.steps[2]?.detail).toBe('生成 1:1 拼图首图,预计 4 分钟。');
expect(progress?.estimatedRemainingMs).toBe(446_500);
expect(progress?.overallProgress).toBe(0);
expect(progress?.steps[0]?.completed).toBeGreaterThan(0);
@@ -73,7 +71,7 @@ describe('miniGameDraftGenerationProgress', () => {
error: null,
};
const progress = buildMiniGameDraftGenerationProgress(state, 7000);
const progress = buildMiniGameDraftGenerationProgress(state, 130_000);
expect(progress?.overallProgress).toBeGreaterThan(0);
expect(progress?.overallProgress).toBeLessThan(88);
@@ -106,8 +104,8 @@ describe('miniGameDraftGenerationProgress', () => {
expect(longRunningProgress?.phaseId).toBe('compile');
expect(longRunningProgress?.steps[0]?.status).toBe('active');
expect(longRunningProgress?.steps[1]?.status).toBe('pending');
expect(longRunningProgress?.overallProgress).toBeLessThanOrEqual(98);
expect(longRunningProgress?.overallProgress).toBeGreaterThan(40);
expect(longRunningProgress?.overallProgress).toBeLessThan(5);
expect(longRunningProgress?.overallProgress).toBeGreaterThan(0);
expect(realProgress?.phaseId).toBe('puzzle-cover-image');
expect(realProgress?.steps[1]?.status).toBe('completed');
expect(realProgress?.steps[2]?.status).toBe('active');
@@ -146,7 +144,10 @@ describe('miniGameDraftGenerationProgress', () => {
};
const progress = buildMiniGameDraftGenerationProgress(state, 20_000);
const writeBackProgress = buildMiniGameDraftGenerationProgress(state, 206_000);
const writeBackProgress = buildMiniGameDraftGenerationProgress(
state,
206_000,
);
expect(progress?.steps.map((step) => step.label)).toEqual([
'编译首关草稿',
@@ -176,13 +177,14 @@ describe('miniGameDraftGenerationProgress', () => {
expect(progress?.phaseId).toBe('compile');
expect(progress?.overallProgress).toBeLessThan(88);
expect(progress?.overallProgress).toBeGreaterThan(80);
expect(progress?.overallProgress).toBeLessThan(5);
expect(progress?.overallProgress).toBeGreaterThan(0);
expect(progress?.estimatedRemainingMs).toBe(0);
expect(progress?.steps[0]?.status).toBe('active');
expect(progress?.steps[0]?.completed).toBe(0.98);
expect(progress?.steps.slice(1).every((step) => step.status === 'pending')).toBe(
true,
);
expect(
progress?.steps.slice(1).every((step) => step.status === 'pending'),
).toBe(true);
});
test('puzzle draft generation advances steps from backend progress percent only', () => {
@@ -222,9 +224,11 @@ describe('miniGameDraftGenerationProgress', () => {
);
expect(imageProgress?.phaseId).toBe('puzzle-cover-image');
expect(imageProgress?.overallProgress).toBeLessThan(88);
expect(imageProgress?.steps[2]?.status).toBe('active');
expect(imageProgress?.steps[3]?.status).toBe('pending');
expect(uiProgress?.phaseId).toBe('puzzle-ui-assets');
expect(uiProgress?.overallProgress).toBeLessThan(94);
expect(uiProgress?.steps[4]?.status).toBe('active');
expect(uiProgress?.steps[5]?.status).toBe('pending');
expect(writeProgress?.phaseId).toBe('puzzle-select-image');
@@ -250,6 +254,7 @@ describe('miniGameDraftGenerationProgress', () => {
const progress = buildMiniGameDraftGenerationProgress(state, 121_000);
expect(progress?.phaseId).toBe('puzzle-cover-image');
expect(progress?.overallProgress).toBeLessThan(88);
expect(progress?.steps[2]?.status).toBe('active');
expect(progress?.steps[2]?.completed).toBeLessThan(0.02);
});
@@ -600,11 +605,11 @@ describe('miniGameDraftGenerationProgress', () => {
floatingWords: ['幸运+1', '功德+1'],
});
expect(entries).toEqual([
{
id: 'wooden-fish-hit-object',
label: '敲击物',
value: '金色小木鱼',
expect(entries).toEqual([
{
id: 'wooden-fish-hit-object',
label: '敲击物',
value: '金色小木鱼',
},
{
id: 'wooden-fish-hit-sound',
@@ -615,9 +620,9 @@ describe('miniGameDraftGenerationProgress', () => {
id: 'wooden-fish-words',
label: '飘字',
value: '幸运+1、功德+1',
},
]);
});
},
]);
});
test('puzzle clear draft generation exposes atlas and slice pipeline', () => {
const state = createMiniGameDraftGenerationState('puzzle-clear');
@@ -669,56 +674,59 @@ describe('miniGameDraftGenerationProgress', () => {
]);
});
test('puzzle generation anchors expose form payload as the display source', () => {
const entries = buildPuzzleGenerationAnchorEntries({
sessionId: 'puzzle-session-1',
currentTurn: 1,
progressPercent: 0,
stage: 'collecting_anchors',
anchorPack: {
themePromise: {
key: 'themePromise',
label: '题材承诺',
value: '雨夜猫街',
status: 'locked',
},
visualSubject: {
key: 'visualSubject',
label: '画面主体',
value: '一只猫在雨夜灯牌下回头。',
status: 'locked',
},
visualMood: {
key: 'visualMood',
label: '视觉气质',
value: '清晰、适合拼图切块',
status: 'inferred',
},
compositionHooks: {
key: 'compositionHooks',
label: '拼图记忆点',
value: '主体轮廓、色块分区、局部细节',
status: 'inferred',
},
tagsAndForbidden: {
key: 'tagsAndForbidden',
label: '标签与禁忌',
value: '猫咪、雨夜、拼图;禁止标题字',
status: 'inferred',
test('puzzle generation anchors expose form payload as the display source', () => {
const entries = buildPuzzleGenerationAnchorEntries(
{
sessionId: 'puzzle-session-1',
currentTurn: 1,
progressPercent: 0,
stage: 'collecting_anchors',
anchorPack: {
themePromise: {
key: 'themePromise',
label: '题材承诺',
value: '雨夜猫街',
status: 'locked',
},
visualSubject: {
key: 'visualSubject',
label: '画面主体',
value: '一只猫在雨夜灯牌下回头。',
status: 'locked',
},
visualMood: {
key: 'visualMood',
label: '视觉气质',
value: '清晰、适合拼图切块',
status: 'inferred',
},
compositionHooks: {
key: 'compositionHooks',
label: '拼图记忆点',
value: '主体轮廓、色块分区、局部细节',
status: 'inferred',
},
tagsAndForbidden: {
key: 'tagsAndForbidden',
label: '标签与禁忌',
value: '猫咪、雨夜、拼图;禁止标题字',
status: 'inferred',
},
},
draft: null,
messages: [],
lastAssistantReply: null,
publishedProfileId: null,
suggestedActions: [],
resultPreview: null,
updatedAt: '2026-04-29T00:00:00.000Z',
},
draft: null,
messages: [],
lastAssistantReply: null,
publishedProfileId: null,
suggestedActions: [],
resultPreview: null,
updatedAt: '2026-04-29T00:00:00.000Z',
}, {
seedText: '一只猫在雨夜灯牌下回头。',
pictureDescription: '一只猫在雨夜灯牌下回头。',
referenceImageSrc: null,
});
{
seedText: '一只猫在雨夜灯牌下回头。',
pictureDescription: '一只猫在雨夜灯牌下回头。',
referenceImageSrc: null,
},
);
expect(entries).toEqual([
{