mirror of
https://github.com/tiennm99/ccs.git
synced 2026-08-12 18:24:22 +00:00
fix(dashboard): align droid config diagnostics with factory paths
- replace ~/.config/factory/config.json diagnostics with legacy ~/.factory/config.json - keep ~/.factory/settings.json as the primary BYOK source in UI + API payload - update droid dashboard tests and frontend typings for legacyConfig
This commit is contained in:
@@ -48,7 +48,7 @@ export interface DroidDashboardDiagnostics {
|
|||||||
binary: DroidBinaryDiagnostics;
|
binary: DroidBinaryDiagnostics;
|
||||||
files: {
|
files: {
|
||||||
settings: DroidConfigFileDiagnostics;
|
settings: DroidConfigFileDiagnostics;
|
||||||
globalConfig: DroidConfigFileDiagnostics;
|
legacyConfig: DroidConfigFileDiagnostics;
|
||||||
};
|
};
|
||||||
byok: DroidByokDiagnostics;
|
byok: DroidByokDiagnostics;
|
||||||
warnings: string[];
|
warnings: string[];
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import type {
|
|||||||
interface DroidConfigPaths {
|
interface DroidConfigPaths {
|
||||||
settingsPath: string;
|
settingsPath: string;
|
||||||
settingsDisplayPath: string;
|
settingsDisplayPath: string;
|
||||||
globalConfigPath: string;
|
legacyConfigPath: string;
|
||||||
globalConfigDisplayPath: string;
|
legacyConfigDisplayPath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JsonFileProbe {
|
interface JsonFileProbe {
|
||||||
@@ -57,25 +57,18 @@ export function resolveDroidConfigPaths(
|
|||||||
homeDir?: string;
|
homeDir?: string;
|
||||||
} = {}
|
} = {}
|
||||||
): DroidConfigPaths {
|
): DroidConfigPaths {
|
||||||
const platform = options.platform ?? process.platform;
|
|
||||||
const env = options.env ?? process.env;
|
const env = options.env ?? process.env;
|
||||||
const homeDir = options.homeDir ?? os.homedir();
|
const homeDir = options.homeDir ?? os.homedir();
|
||||||
|
|
||||||
const byokBase = env.CCS_HOME || homeDir;
|
const byokBase = env.CCS_HOME || homeDir;
|
||||||
const settingsPath = path.join(byokBase, '.factory', 'settings.json');
|
const settingsPath = path.join(byokBase, '.factory', 'settings.json');
|
||||||
|
const legacyConfigPath = path.join(byokBase, '.factory', 'config.json');
|
||||||
const globalConfigRoot =
|
|
||||||
platform === 'win32'
|
|
||||||
? env.APPDATA || path.join(homeDir, 'AppData', 'Roaming')
|
|
||||||
: env.XDG_CONFIG_HOME || path.join(homeDir, '.config');
|
|
||||||
const globalConfigPath = path.join(globalConfigRoot, 'factory', 'config.json');
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
settingsPath,
|
settingsPath,
|
||||||
settingsDisplayPath: '~/.factory/settings.json',
|
settingsDisplayPath: '~/.factory/settings.json',
|
||||||
globalConfigPath,
|
legacyConfigPath,
|
||||||
globalConfigDisplayPath:
|
legacyConfigDisplayPath: '~/.factory/config.json',
|
||||||
platform === 'win32' ? '%APPDATA%/factory/config.json' : '~/.config/factory/config.json',
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,10 +218,10 @@ export function getDroidDashboardDiagnostics(): DroidDashboardDiagnostics {
|
|||||||
'BYOK settings',
|
'BYOK settings',
|
||||||
paths.settingsDisplayPath
|
paths.settingsDisplayPath
|
||||||
);
|
);
|
||||||
const globalConfigProbe = readJsonFileProbe(
|
const legacyConfigProbe = readJsonFileProbe(
|
||||||
paths.globalConfigPath,
|
paths.legacyConfigPath,
|
||||||
'Global config',
|
'Legacy config',
|
||||||
paths.globalConfigDisplayPath
|
paths.legacyConfigDisplayPath
|
||||||
);
|
);
|
||||||
|
|
||||||
const byok = summarizeDroidCustomModels(settingsProbe.json?.customModels);
|
const byok = summarizeDroidCustomModels(settingsProbe.json?.customModels);
|
||||||
@@ -242,8 +235,8 @@ export function getDroidDashboardDiagnostics(): DroidDashboardDiagnostics {
|
|||||||
if (byok.invalidModelEntryCount > 0) {
|
if (byok.invalidModelEntryCount > 0) {
|
||||||
warnings.push(`${byok.invalidModelEntryCount} customModels entries are malformed.`);
|
warnings.push(`${byok.invalidModelEntryCount} customModels entries are malformed.`);
|
||||||
}
|
}
|
||||||
if (globalConfigProbe.diagnostics.parseError) {
|
if (legacyConfigProbe.diagnostics.parseError) {
|
||||||
warnings.push('Global Droid config JSON is invalid.');
|
warnings.push('Legacy Droid config (~/.factory/config.json) JSON is invalid.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -257,7 +250,7 @@ export function getDroidDashboardDiagnostics(): DroidDashboardDiagnostics {
|
|||||||
},
|
},
|
||||||
files: {
|
files: {
|
||||||
settings: settingsProbe.diagnostics,
|
settings: settingsProbe.diagnostics,
|
||||||
globalConfig: globalConfigProbe.diagnostics,
|
legacyConfig: legacyConfigProbe.diagnostics,
|
||||||
},
|
},
|
||||||
byok,
|
byok,
|
||||||
warnings,
|
warnings,
|
||||||
@@ -271,6 +264,7 @@ export function getDroidDashboardDiagnostics(): DroidDashboardDiagnostics {
|
|||||||
],
|
],
|
||||||
notes: [
|
notes: [
|
||||||
'BYOK custom models are read from ~/.factory/settings.json customModels[]',
|
'BYOK custom models are read from ~/.factory/settings.json customModels[]',
|
||||||
|
'Factory docs mention legacy support for ~/.factory/config.json',
|
||||||
'Interactive model selection uses settings.model (custom:<alias>)',
|
'Interactive model selection uses settings.model (custom:<alias>)',
|
||||||
'droid exec supports --model for one-off execution mode',
|
'droid exec supports --model for one-off execution mode',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -29,31 +29,26 @@ describe('droid-dashboard-service', () => {
|
|||||||
platform: 'darwin',
|
platform: 'darwin',
|
||||||
env: {
|
env: {
|
||||||
CCS_HOME: '/tmp/ccs-home',
|
CCS_HOME: '/tmp/ccs-home',
|
||||||
XDG_CONFIG_HOME: '/tmp/xdg',
|
|
||||||
} as NodeJS.ProcessEnv,
|
} as NodeJS.ProcessEnv,
|
||||||
homeDir: '/Users/tester',
|
homeDir: '/Users/tester',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(resolved.settingsPath).toBe('/tmp/ccs-home/.factory/settings.json');
|
expect(resolved.settingsPath).toBe('/tmp/ccs-home/.factory/settings.json');
|
||||||
expect(resolved.globalConfigPath).toBe('/tmp/xdg/factory/config.json');
|
expect(resolved.legacyConfigPath).toBe('/tmp/ccs-home/.factory/config.json');
|
||||||
expect(resolved.settingsDisplayPath).toBe('~/.factory/settings.json');
|
expect(resolved.settingsDisplayPath).toBe('~/.factory/settings.json');
|
||||||
expect(resolved.globalConfigDisplayPath).toBe('~/.config/factory/config.json');
|
expect(resolved.legacyConfigDisplayPath).toBe('~/.factory/config.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resolves droid config paths on windows platforms', () => {
|
it('resolves droid config paths on windows platforms', () => {
|
||||||
const resolved = resolveDroidConfigPaths({
|
const resolved = resolveDroidConfigPaths({
|
||||||
platform: 'win32',
|
platform: 'win32',
|
||||||
env: {
|
env: {} as NodeJS.ProcessEnv,
|
||||||
APPDATA: 'C:/Users/test/AppData/Roaming',
|
|
||||||
} as NodeJS.ProcessEnv,
|
|
||||||
homeDir: 'C:/Users/test',
|
homeDir: 'C:/Users/test',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(resolved.settingsPath).toBe(path.join('C:/Users/test', '.factory', 'settings.json'));
|
expect(resolved.settingsPath).toBe(path.join('C:/Users/test', '.factory', 'settings.json'));
|
||||||
expect(resolved.globalConfigPath).toBe(
|
expect(resolved.legacyConfigPath).toBe(path.join('C:/Users/test', '.factory', 'config.json'));
|
||||||
path.join('C:/Users/test/AppData/Roaming', 'factory', 'config.json')
|
expect(resolved.legacyConfigDisplayPath).toBe('~/.factory/config.json');
|
||||||
);
|
|
||||||
expect(resolved.globalConfigDisplayPath).toBe('%APPDATA%/factory/config.json');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('masks api key preview with only suffix', () => {
|
it('masks api key preview with only suffix', () => {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export interface DroidDashboardDiagnostics {
|
|||||||
binary: DroidBinaryDiagnostics;
|
binary: DroidBinaryDiagnostics;
|
||||||
files: {
|
files: {
|
||||||
settings: DroidConfigFileDiagnostics;
|
settings: DroidConfigFileDiagnostics;
|
||||||
globalConfig: DroidConfigFileDiagnostics;
|
legacyConfig: DroidConfigFileDiagnostics;
|
||||||
};
|
};
|
||||||
byok: {
|
byok: {
|
||||||
activeModelSelector: string | null;
|
activeModelSelector: string | null;
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ export function DroidPage() {
|
|||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-3">
|
<CardContent className="space-y-3">
|
||||||
{[diagnostics.files.settings, diagnostics.files.globalConfig].map((file) => (
|
{[diagnostics.files.settings, diagnostics.files.legacyConfig].map((file) => (
|
||||||
<div key={file.label} className="rounded-md border p-3 space-y-1.5">
|
<div key={file.label} className="rounded-md border p-3 space-y-1.5">
|
||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<span className="font-medium text-sm">{file.label}</span>
|
<span className="font-medium text-sm">{file.label}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user