mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 18:18:43 +00:00
feat(auth): add --bare flag and MCP server sync for profiles
- Add --bare flag to `ccs auth create` to skip shared symlinks (commands/, skills/, agents/, settings.json). Bare profiles are clean instances without ClaudeKit or other global extensions. `ccs sync` respects bare flag and skips re-linking. - Add MCP server sync from global ~/.claude.json to instances. Claude Code stores MCP config in ~/.claude.json (not settings.json), which was invisible to CCS profiles using CLAUDE_CONFIG_DIR isolation. Selective copy of mcpServers key only (not OAuth sessions/caches). `ccs sync` refreshes MCP servers across all non-bare instances. Closes #691 Closes #692
This commit is contained in:
@@ -91,6 +91,9 @@ class AuthCommands {
|
||||
` ${color('ccs auth create backup --context-group sprint-a --deeper-continuity', 'command')}`
|
||||
);
|
||||
console.log('');
|
||||
console.log(` ${dim('# Create clean profile without shared commands/skills/agents')}`);
|
||||
console.log(` ${color('ccs auth create sandbox --bare', 'command')}`);
|
||||
console.log('');
|
||||
console.log(` ${dim('# Set work as default')}`);
|
||||
console.log(` ${color('ccs auth default work', 'command')}`);
|
||||
console.log('');
|
||||
@@ -116,6 +119,9 @@ class AuthCommands {
|
||||
console.log(
|
||||
` ${color('--deeper-continuity', 'command')} Advanced shared mode: sync additional continuity artifacts`
|
||||
);
|
||||
console.log(
|
||||
` ${color('--bare', 'command')} Create clean profile without shared symlinks (no CK/commands/skills)`
|
||||
);
|
||||
console.log(
|
||||
` ${color('--yes, -y', 'command')} Skip confirmation prompts (remove)`
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ function sanitizeProfileNameForInstance(name: string): string {
|
||||
*/
|
||||
export async function handleCreate(ctx: CommandContext, args: string[]): Promise<void> {
|
||||
await initUI();
|
||||
const { profileName, force, shareContext, contextGroup, deeperContinuity, unknownFlags } =
|
||||
const { profileName, force, shareContext, contextGroup, deeperContinuity, bare, unknownFlags } =
|
||||
parseArgs(args);
|
||||
|
||||
if (unknownFlags && unknownFlags.length > 0) {
|
||||
@@ -39,7 +39,7 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
console.log(fail(`Unknown option(s): ${unknownList}`));
|
||||
console.log('');
|
||||
console.log(
|
||||
`Usage: ${color('ccs auth create <profile> [--force] [--share-context] [--context-group <name>] [--deeper-continuity]', 'command')}`
|
||||
`Usage: ${color('ccs auth create <profile> [--force] [--bare] [--share-context] [--context-group <name>] [--deeper-continuity]', 'command')}`
|
||||
);
|
||||
console.log(`Help: ${color('ccs auth --help', 'command')}`);
|
||||
console.log('');
|
||||
@@ -50,7 +50,7 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
console.log(fail('Profile name is required'));
|
||||
console.log('');
|
||||
console.log(
|
||||
`Usage: ${color('ccs auth create <profile> [--force] [--share-context] [--context-group <name>] [--deeper-continuity]', 'command')}`
|
||||
`Usage: ${color('ccs auth create <profile> [--force] [--bare] [--share-context] [--context-group <name>] [--deeper-continuity]', 'command')}`
|
||||
);
|
||||
console.log('');
|
||||
console.log('Example:');
|
||||
@@ -179,7 +179,9 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
try {
|
||||
// Create instance directory
|
||||
console.log(info(`Creating profile: ${profileName}`));
|
||||
const instancePath = await ctx.instanceMgr.ensureInstance(profileName, contextPolicy);
|
||||
const instancePath = await ctx.instanceMgr.ensureInstance(profileName, contextPolicy, {
|
||||
bare: !!bare,
|
||||
});
|
||||
|
||||
// Create/update profile entry based on config mode
|
||||
if (useUnifiedConfig) {
|
||||
@@ -188,10 +190,14 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
ctx.registry.updateAccountUnified(profileName, {
|
||||
context_mode: contextMetadata.context_mode,
|
||||
context_group: contextMetadata.context_group,
|
||||
...(bare ? { bare: true } : {}),
|
||||
});
|
||||
ctx.registry.touchAccountUnified(profileName);
|
||||
} else {
|
||||
ctx.registry.createAccountUnified(profileName, contextMetadata);
|
||||
ctx.registry.createAccountUnified(profileName, {
|
||||
...contextMetadata,
|
||||
...(bare ? { bare: true } : {}),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Use legacy profiles.json
|
||||
@@ -200,12 +206,14 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
type: 'account',
|
||||
context_mode: contextMetadata.context_mode,
|
||||
context_group: contextMetadata.context_group,
|
||||
...(bare ? { bare: true } : {}),
|
||||
});
|
||||
} else {
|
||||
ctx.registry.createProfile(profileName, {
|
||||
type: 'account',
|
||||
context_mode: contextMetadata.context_mode,
|
||||
context_group: contextMetadata.context_group,
|
||||
...(bare ? { bare: true } : {}),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -262,7 +270,8 @@ export async function handleCreate(ctx: CommandContext, args: string[]): Promise
|
||||
`Profile: ${profileName}\n` +
|
||||
`Instance: ${instancePath}\n` +
|
||||
`Type: account\n` +
|
||||
`Context: ${formatAccountContextPolicy(contextPolicy)}`,
|
||||
`Context: ${formatAccountContextPolicy(contextPolicy)}` +
|
||||
(bare ? '\nMode: bare (no shared symlinks)' : ''),
|
||||
'Profile Created'
|
||||
)
|
||||
);
|
||||
|
||||
@@ -63,6 +63,7 @@ export async function handleShow(ctx: CommandContext, args: string[]): Promise<v
|
||||
continuity_mode: contextPolicy.mode === 'shared' ? contextPolicy.continuityMode : null,
|
||||
instance_path: instancePath,
|
||||
session_count: sessionCount,
|
||||
...(profile.bare ? { bare: true } : {}),
|
||||
};
|
||||
console.log(JSON.stringify(output, null, 2));
|
||||
return;
|
||||
@@ -80,6 +81,7 @@ export async function handleShow(ctx: CommandContext, args: string[]): Promise<v
|
||||
['Created', new Date(profile.created).toLocaleString()],
|
||||
['Last Used', profile.last_used ? new Date(profile.last_used).toLocaleString() : 'Never'],
|
||||
['Context', formatAccountContextPolicy(contextPolicy)],
|
||||
...(profile.bare ? [['Bare', 'yes (no shared symlinks)']] : []),
|
||||
['Sessions', `${sessionCount}`],
|
||||
];
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ export interface AuthCommandArgs {
|
||||
shareContext?: boolean;
|
||||
contextGroup?: string;
|
||||
deeperContinuity?: boolean;
|
||||
bare?: boolean;
|
||||
unknownFlags?: string[];
|
||||
}
|
||||
|
||||
@@ -39,6 +40,7 @@ export interface ProfileOutput {
|
||||
continuity_mode?: 'standard' | 'deeper' | null;
|
||||
instance_path?: string;
|
||||
session_count?: number;
|
||||
bare?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,6 +75,7 @@ export function parseArgs(args: string[]): AuthCommandArgs {
|
||||
'-y',
|
||||
'--share-context',
|
||||
'--deeper-continuity',
|
||||
'--bare',
|
||||
]);
|
||||
const knownValueFlags = new Set(['--context-group']);
|
||||
|
||||
@@ -125,6 +128,7 @@ export function parseArgs(args: string[]): AuthCommandArgs {
|
||||
yes: args.includes('--yes') || args.includes('-y'),
|
||||
shareContext: args.includes('--share-context'),
|
||||
deeperContinuity: args.includes('--deeper-continuity'),
|
||||
bare: args.includes('--bare'),
|
||||
contextGroup,
|
||||
unknownFlags: [...unknownFlags],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user