Merge branch 'master' into codex/fix-main-canvas-reference-images
Project CI / Repository checks (pull_request) Successful in 1m8s
Project CI / Frontend tests (pull_request) Successful in 3m29s
Project CI / Backend tests (pull_request) Successful in 4m7s
Project CI / Native shell tests (pull_request) Successful in 16m21s

This commit is contained in:
2026-08-12 18:56:38 +08:00
8 changed files with 93 additions and 54 deletions
@@ -1688,8 +1688,8 @@ for (const snippet of [
"'write_game_creator_app_config'",
'aria-label="运行时配置"',
'LLM API Key',
'showDeveloperEditorApi',
'开发者 External Editor API Key',
'External Editor Base URL',
'External Editor API Key',
'runtime_config.save',
"'/run:运行自检,启动本地 HTTP 预览并载入客户端运行视图'",
"'activate_local_game_preview'",
-1
View File
@@ -11187,7 +11187,6 @@ export function App({
{runtimeConfigOpen ? (
<RuntimeConfigDialog
projectPath={localProject?.projectPath}
showDeveloperEditorApi={devMode}
onClose={() => setRuntimeConfigOpen(false)}
onLog={(entry) => setCommandLog((current) => [...current, entry])}
/>
@@ -522,12 +522,10 @@ function normalizeRuntimeConfigDraft(
export function RuntimeConfigDialog({
projectPath,
showDeveloperEditorApi = false,
onClose,
onLog,
}: {
projectPath?: string;
showDeveloperEditorApi?: boolean;
onClose: () => void;
onLog?: (entry: string) => void;
}) {
@@ -1381,38 +1379,28 @@ export function RuntimeConfigDialog({
})}
</>
) : null}
{showDeveloperEditorApi ? (
<>
<label>
External Editor Base URL
<input
aria-label="开发者 External Editor Base URL"
value={runtimeConfigDraft.editorApi.baseUrl}
onChange={(event) =>
updateRuntimeEditorConfig(
'baseUrl',
event.currentTarget.value,
)
}
/>
</label>
<label>
External Editor API Key
<input
aria-label="开发者 External Editor API Key"
autoComplete="off"
type="password"
value={runtimeConfigDraft.editorApi.apiKey}
onChange={(event) =>
updateRuntimeEditorConfig(
'apiKey',
event.currentTarget.value,
)
}
/>
</label>
</>
) : null}
<label>
External Editor Base URL
<input
aria-label="External Editor Base URL"
value={runtimeConfigDraft.editorApi.baseUrl}
onChange={(event) =>
updateRuntimeEditorConfig('baseUrl', event.currentTarget.value)
}
/>
</label>
<label>
External Editor API Key
<input
aria-label="External Editor API Key"
autoComplete="off"
type="password"
value={runtimeConfigDraft.editorApi.apiKey}
onChange={(event) =>
updateRuntimeEditorConfig('apiKey', event.currentTarget.value)
}
/>
</label>
<section className="runtime-mcp-section" aria-label="MCP servers">
<header className="runtime-mcp-header">
<div>
@@ -4278,6 +4278,48 @@ export function registerProjectSupervisorSurfaceTests() {
);
});
it('exposes External Editor credentials from the game-chat settings', async () => {
const invoke = vi.fn(async (command: string) => {
if (command === 'read_game_creator_app_config') {
return {
path: '/home/test/AppData/game-creator.config.json',
config: {
editorApi: {
baseUrl: 'http://127.0.0.1:8082',
apiKey: 'game-chat-editor-secret',
},
},
};
}
throw new Error(`unexpected invoke ${command}`);
});
window.__TAURI__ = { core: { invoke } };
renderGameChatStatus({
runtime: gameChatRuntimeState(),
viewOverrides: {
onOpenRuntimeConfig: vi.fn(),
runtimeConfigOpen: true,
},
});
expect(
await screen.findByRole('dialog', { name: '运行时配置' }),
).not.toBeNull();
expect(screen.getByLabelText('External Editor Base URL')).toHaveProperty(
'value',
'http://127.0.0.1:8082',
);
expect(screen.getByLabelText('External Editor API Key')).toHaveProperty(
'type',
'password',
);
expect(
screen
.getByLabelText('External Editor API Key')
.getAttribute('autocomplete'),
).toBe('off');
});
it('opens the dedicated game-chat release without platform authentication', async () => {
const fetchMock = vi
.spyOn(globalThis, 'fetch')
@@ -434,6 +434,19 @@ export function registerRuntimeSettingsTests() {
'value',
'12000',
);
expect(screen.getByLabelText('External Editor Base URL')).toHaveProperty(
'value',
'http://127.0.0.1:8082',
);
expect(screen.getByLabelText('External Editor API Key')).toHaveProperty(
'type',
'password',
);
expect(
screen
.getByLabelText('External Editor API Key')
.getAttribute('autocomplete'),
).toBe('off');
fireEvent.change(screen.getByLabelText('LLM 模型'), {
target: { value: 'gpt-launcher-updated' },
});
@@ -856,15 +869,13 @@ export function registerPublishedRuntimeSettingsTests() {
expect(
screen.getByLabelText('LLM API Key').getAttribute('autocomplete'),
).toBe('off');
expect(
screen.getByLabelText('开发者 External Editor API Key'),
).toHaveProperty(
expect(screen.getByLabelText('External Editor API Key')).toHaveProperty(
'type',
'password',
);
expect(
screen
.getByLabelText('开发者 External Editor API Key')
.getByLabelText('External Editor API Key')
.getAttribute('autocomplete'),
).toBe('off');
expect(screen.getByLabelText('Planner LLM API Key')).toHaveProperty(
@@ -1007,13 +1018,10 @@ export function registerPublishedRuntimeSettingsTests() {
target: { value: 'ark' },
},
);
fireEvent.change(
screen.getByLabelText('开发者 External Editor Base URL'),
{
fireEvent.change(screen.getByLabelText('External Editor Base URL'), {
target: { value: 'http://127.0.0.1:8099' },
},
);
fireEvent.change(screen.getByLabelText('开发者 External Editor API Key'), {
});
fireEvent.change(screen.getByLabelText('External Editor API Key'), {
target: { value: 'editor-new-secret' },
});
fireEvent.click(
@@ -1166,9 +1174,10 @@ export function registerPublishedRuntimeSettingsTests() {
'value',
'12000',
);
expect(
screen.getByLabelText('开发者 External Editor Base URL'),
).toHaveProperty('value', 'http://127.0.0.1:8082');
expect(screen.getByLabelText('External Editor Base URL')).toHaveProperty(
'value',
'http://127.0.0.1:8082',
);
fireEvent.click(
within(runtimeConfigDialog).getByRole('button', { name: '保存' }),
);