merge: 최신 main을 transport 권한과 커맨드 내구 행렬에 통합한다

This commit is contained in:
2026-08-24 07:41:28 +00:00
34 changed files with 974 additions and 300 deletions
@@ -380,6 +380,7 @@ describe('admin profile navigation API', () => {
profileName: 'che:2',
profile: 'che',
instanceKey: '2',
displayName: '체 [2]',
currentScenario: '2',
meta: { korName: '체' },
},
@@ -9,6 +9,7 @@ import {
buildSharedProfileFrontendCommands,
buildWorkspaceCommands,
planProfileReconcile,
resolveProfileArchiveServerName,
resolveResetLifecycleStatus,
} from '../src/orchestrator/gatewayOrchestrator.js';
import { GATEWAY_PROFILE_ORDER } from '../src/profileOrder.js';
@@ -134,6 +135,30 @@ describe('resolveResetLifecycleStatus', () => {
});
});
describe('resolveProfileArchiveServerName', () => {
it('uses the configured Gateway name and never the runtime instance key', () => {
expect(
resolveProfileArchiveServerName({
...buildProfile(),
profile: 'hwe',
profileName: 'hwe:default',
meta: { korName: ' 훼 ' },
})
).toBe('훼');
});
it('uses the canonical profile label when Gateway has no override', () => {
expect(
resolveProfileArchiveServerName({
...buildProfile(),
profile: 'hwe',
profileName: 'hwe:default',
meta: {},
})
).toBe('훼');
});
});
describe('buildProcessDefinitions', () => {
const processConfig = {
workspaceRoot: '/srv/sammo/main',
+10
View File
@@ -4,6 +4,7 @@ import {
GATEWAY_PROFILE_KOREAN_NAMES,
GATEWAY_PROFILE_ORDER,
orderGatewayProfiles,
resolveGatewayProfileDisplayName,
resolveGatewayProfileKoreanName,
} from '../src/profileOrder.js';
@@ -56,3 +57,12 @@ describe('resolveGatewayProfileKoreanName', () => {
expect(resolveGatewayProfileKoreanName('custom')).toBe('custom');
});
});
describe('resolveGatewayProfileDisplayName', () => {
it('hides the default instance key and distinguishes non-default instances', () => {
expect(resolveGatewayProfileDisplayName('che', 'default')).toBe('체');
expect(resolveGatewayProfileDisplayName('hwe', '2')).toBe('훼 [2]');
expect(resolveGatewayProfileDisplayName('che', 'default', ' 천하서버 ')).toBe('천하서버');
expect(resolveGatewayProfileDisplayName('custom', 'blue')).toBe('custom [blue]');
});
});
@@ -3,6 +3,16 @@ import { describe, expect, it } from 'vitest';
import { listScenarioPreviews, resolveGitCommitSha } from '../src/scenario/scenarioCatalog.js';
describe('scenarioCatalog git ref support', () => {
it('includes the CHE zero-season dawn scenario in the local catalog', async () => {
const previews = await listScenarioPreviews();
expect(previews.find((scenario) => scenario.id === 916)).toMatchObject({
id: 916,
title: '【공백지】 여명',
year: 180,
});
});
it('resolves HEAD to a commit hash', async () => {
const commitSha = await resolveGitCommitSha('HEAD');
expect(commitSha).toMatch(/^[0-9a-f]{40}$/i);
@@ -18,6 +28,11 @@ describe('scenarioCatalog git ref support', () => {
expect(previews.every((scenario) => scenario.fiction === null || Number.isInteger(scenario.fiction))).toBe(
true
);
expect(previews.find((scenario) => scenario.id === 916)).toMatchObject({
id: 916,
title: '【공백지】 여명',
year: 180,
});
});
it('rejects without crashing when git cannot be spawned', async () => {