mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
fix(auth): de-duplicate error output and validate legacy profiles in default
exitWithError() already prints '[X] <msg>', so the preceding console.log(fail()) calls double-printed every auth error. Remove the redundant logs and fold richer hints (e.g. --force) into the single exitWithError message. Also make 'auth default' accept a profile registered only in legacy profiles.json under unified mode.
This commit is contained in:
1 parent
e44babd8cc
commit
191396149f
8 files changed
+27
-30
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { initUI, color, dim, fail, info, ok } from '../../utils/ui';
|
||||
import { initUI, color, dim, info, ok } from '../../utils/ui';
|
||||
import { exitWithError } from '../../errors';
|
||||
import { ExitCode } from '../../errors/exit-codes';
|
||||
import {
|
||||
@@ -44,7 +44,6 @@ export async function handleBackup(ctx: CommandContext, args: string[]): Promise
|
||||
});
|
||||
|
||||
if (!profileName) {
|
||||
console.log(fail('Profile name is required'));
|
||||
console.log('');
|
||||
console.log(`Usage: ${color('ccs auth backup <profile|default> [--json]', 'command')}`);
|
||||
exitWithError('Profile name is required', ExitCode.PROFILE_ERROR);
|
||||
|
||||
@@ -53,7 +53,6 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
});
|
||||
|
||||
if (!profileName) {
|
||||
console.log(fail('Profile name is required'));
|
||||
console.log('');
|
||||
console.log(
|
||||
`Usage: ${color('ccs auth create <profile> [--force] [--bare] [--share-context] [--context-group <name>] [--deeper-continuity]', 'command')}`
|
||||
@@ -65,20 +64,21 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
}
|
||||
|
||||
if (!isValidAccountProfileName(profileName)) {
|
||||
const error =
|
||||
'Invalid profile name. Use letters/numbers/dash/underscore and start with a letter.';
|
||||
console.log(fail(error));
|
||||
console.log('');
|
||||
exitWithError(error, ExitCode.PROFILE_ERROR);
|
||||
exitWithError(
|
||||
'Invalid profile name. Use letters/numbers/dash/underscore and start with a letter.',
|
||||
ExitCode.PROFILE_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
// Check if profile already exists (check both legacy and unified)
|
||||
const existsLegacy = ctx.registry.hasProfile(profileName);
|
||||
const existsUnified = ctx.registry.hasAccountUnified(profileName);
|
||||
if (!force && (existsLegacy || existsUnified)) {
|
||||
console.log(fail(`Profile already exists: ${profileName}`));
|
||||
console.log(` Use ${color('--force', 'command')} to overwrite`);
|
||||
exitWithError(`Profile already exists: ${profileName}`, ExitCode.PROFILE_ERROR);
|
||||
// Keep the --force hint in the exitWithError message so it appears in the single output line
|
||||
exitWithError(
|
||||
`Profile already exists: ${profileName}\n Use --force to overwrite`,
|
||||
ExitCode.PROFILE_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
const normalizedName = sanitizeProfileNameForInstance(profileName);
|
||||
@@ -87,10 +87,10 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
);
|
||||
|
||||
if (collidingName) {
|
||||
const error = `Profile "${profileName}" conflicts with existing profile "${collidingName}" on filesystem.`;
|
||||
console.log(fail(error));
|
||||
console.log('');
|
||||
exitWithError(error, ExitCode.PROFILE_ERROR);
|
||||
exitWithError(
|
||||
`Profile "${profileName}" conflicts with existing profile "${collidingName}" on filesystem.`,
|
||||
ExitCode.PROFILE_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
const resolvedContext = resolveCreateAccountContext({
|
||||
@@ -100,8 +100,6 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
});
|
||||
|
||||
if (resolvedContext.error) {
|
||||
console.log(fail(resolvedContext.error));
|
||||
console.log('');
|
||||
exitWithError(resolvedContext.error, ExitCode.PROFILE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ export async function handleDefault(ctx: CommandContext, args: string[]): Promis
|
||||
});
|
||||
|
||||
if (!profileName) {
|
||||
console.log(fail('Profile name is required'));
|
||||
console.log('');
|
||||
console.log(`Usage: ${color('ccs auth default <profile>', 'command')}`);
|
||||
exitWithError('Profile name is required', ExitCode.PROFILE_ERROR);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { initUI, color, ok, fail, info } from '../../utils/ui';
|
||||
import { initUI, color, ok, info } from '../../utils/ui';
|
||||
import { InteractivePrompt } from '../../utils/prompt';
|
||||
|
||||
import { exitWithError } from '../../errors';
|
||||
@@ -26,7 +26,6 @@ export async function handleRemove(ctx: CommandContext, args: string[]): Promise
|
||||
});
|
||||
|
||||
if (!profileName) {
|
||||
console.log(fail('Profile name is required'));
|
||||
console.log('');
|
||||
console.log(`Usage: ${color('ccs auth remove <profile> [--yes]', 'command')}`);
|
||||
exitWithError('Profile name is required', ExitCode.PROFILE_ERROR);
|
||||
@@ -37,7 +36,6 @@ export async function handleRemove(ctx: CommandContext, args: string[]): Promise
|
||||
const existsUnified = ctx.registry.hasAccountUnified(profileName);
|
||||
|
||||
if (!existsLegacy && !existsUnified) {
|
||||
console.log(fail(`Profile not found: ${profileName}`));
|
||||
exitWithError(`Profile not found: ${profileName}`, ExitCode.PROFILE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { initUI, header, color, fail, ok, table } from '../../utils/ui';
|
||||
import { initUI, header, color, ok, table } from '../../utils/ui';
|
||||
import { resolveAccountContextPolicy } from '../account-context';
|
||||
import {
|
||||
isSharedResourceMode,
|
||||
@@ -30,7 +30,6 @@ export async function handleResources(ctx: CommandContext, args: string[]): Prom
|
||||
});
|
||||
|
||||
if (!profileName) {
|
||||
console.log(fail('Profile name is required'));
|
||||
console.log('');
|
||||
console.log(
|
||||
`Usage: ${color('ccs auth resources <profile> [--mode shared|profile-local] [--json]', 'command')}`
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { initUI, header, color, fail, table } from '../../utils/ui';
|
||||
import { initUI, header, color, table } from '../../utils/ui';
|
||||
import { resolveAccountContextPolicy, formatAccountContextPolicy } from '../account-context';
|
||||
import { describeSettingsSync, summarizeAccountHistory } from '../account-profile-diagnostics';
|
||||
import { resolveConfiguredPlainCcsResumeLane } from '../resume-lane-diagnostics';
|
||||
@@ -33,7 +33,6 @@ export async function handleShow(ctx: CommandContext, args: string[]): Promise<v
|
||||
});
|
||||
|
||||
if (!profileName) {
|
||||
console.log(fail('Profile name is required'));
|
||||
console.log('');
|
||||
console.log(`Usage: ${color('ccs auth show <profile> [--json]', 'command')}`);
|
||||
exitWithError('Profile name is required', ExitCode.PROFILE_ERROR);
|
||||
|
||||
@@ -8,7 +8,7 @@ import ProfileRegistry from '../profile-registry';
|
||||
import { InstanceManager } from '../../management/instance-manager';
|
||||
import { exitWithError } from '../../errors';
|
||||
import { ExitCode } from '../../errors/exit-codes';
|
||||
import { color, fail } from '../../utils/ui';
|
||||
import { color } from '../../utils/ui';
|
||||
|
||||
// Re-export for backward compatibility
|
||||
export { formatRelativeTime } from '../../utils/time';
|
||||
@@ -100,7 +100,6 @@ export function rejectUnsupportedAuthOptions(
|
||||
}
|
||||
|
||||
const unknownList = unsupportedOptions.map((flag) => `"${flag}"`).join(', ');
|
||||
console.log(fail(`Unknown option(s): ${unknownList}`));
|
||||
console.log('');
|
||||
console.log(`Usage: ${color(options.usage, 'command')}`);
|
||||
console.log(`Help: ${color('ccs auth --help', 'command')}`);
|
||||
|
||||
@@ -376,13 +376,19 @@ export class ProfileRegistry {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default profile in unified config
|
||||
* Set default profile in unified config.
|
||||
* Accepts names from unified config (accounts, profiles, cliproxy variants)
|
||||
* as well as legacy profiles.json so that mixed-mode installs work correctly.
|
||||
*/
|
||||
setDefaultUnified(name: string): void {
|
||||
// Check legacy registry outside the mutate callback to avoid re-reading inside the transaction.
|
||||
const legacyData = this._read();
|
||||
const existsLegacy = !!legacyData.profiles[name];
|
||||
|
||||
mutateConfig((config) => {
|
||||
const exists =
|
||||
const existsUnified =
|
||||
config.accounts[name] || config.profiles[name] || config.cliproxy?.variants?.[name];
|
||||
if (!exists) {
|
||||
if (!existsUnified && !existsLegacy) {
|
||||
throw new ProfileError(`Profile not found: ${name}`, name);
|
||||
}
|
||||
config.default = name;
|
||||
|
||||
Reference in new issue
Block a user