mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
feat: implement subagents configuration management
- Added a new function to retrieve subagents configuration from settings, allowing users to enable/disable subagents and select sources for loading them. - Updated the AgentService to incorporate subagents configuration, dynamically adding tools based on the settings. - Enhanced the UI components to manage subagents, including a settings section for enabling/disabling and selecting sources. - Introduced a new hook for managing subagents settings state and interactions. These changes improve the flexibility and usability of subagents within the application, enhancing user experience and configuration options.
This commit is contained in:
@@ -293,6 +293,29 @@ export async function getSkillsConfiguration(settingsService: SettingsService):
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Subagents configuration from settings.
|
||||
* Returns configuration for enabling subagents and which sources to load from.
|
||||
*
|
||||
* @param settingsService - Settings service instance
|
||||
* @returns Subagents configuration with enabled state, sources, and tool inclusion flag
|
||||
*/
|
||||
export async function getSubagentsConfiguration(settingsService: SettingsService): Promise<{
|
||||
enabled: boolean;
|
||||
sources: Array<'user' | 'project'>;
|
||||
shouldIncludeInTools: boolean;
|
||||
}> {
|
||||
const settings = await settingsService.getGlobalSettings();
|
||||
const enabled = settings.enableSubagents ?? true; // Default enabled
|
||||
const sources = settings.subagentsSources ?? ['user', 'project']; // Default both sources
|
||||
|
||||
return {
|
||||
enabled,
|
||||
sources,
|
||||
shouldIncludeInTools: enabled && sources.length > 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom subagents from settings, merging global and project-level definitions.
|
||||
* Project-level subagents take precedence over global ones with the same name.
|
||||
|
||||
@@ -72,17 +72,10 @@ export class ClaudeProvider extends BaseProvider {
|
||||
// Build Claude SDK options
|
||||
// AUTONOMOUS MODE: Always bypass permissions for fully autonomous operation
|
||||
const hasMcpServers = options.mcpServers && Object.keys(options.mcpServers).length > 0;
|
||||
const defaultTools = [
|
||||
'Read',
|
||||
'Write',
|
||||
'Edit',
|
||||
'Glob',
|
||||
'Grep',
|
||||
'Bash',
|
||||
'WebSearch',
|
||||
'WebFetch',
|
||||
'Skill',
|
||||
];
|
||||
// Base tools available to all agents
|
||||
// Note: 'Skill' and 'Task' tools are added dynamically by agent-service.ts
|
||||
// based on whether skills/subagents are enabled in settings
|
||||
const defaultTools = ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash', 'WebSearch', 'WebFetch'];
|
||||
|
||||
// AUTONOMOUS MODE: Always bypass permissions and allow unrestricted tools
|
||||
// Only restrict tools when no MCP servers are configured
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
getMCPServersFromSettings,
|
||||
getPromptCustomization,
|
||||
getSkillsConfiguration,
|
||||
getSubagentsConfiguration,
|
||||
getCustomSubagents,
|
||||
} from '../lib/settings-helpers.js';
|
||||
|
||||
@@ -248,10 +249,16 @@ export class AgentService {
|
||||
? await getSkillsConfiguration(this.settingsService)
|
||||
: { enabled: false, sources: [] as Array<'user' | 'project'>, shouldIncludeInTools: false };
|
||||
|
||||
// Get custom subagents from settings (merge global + project-level)
|
||||
const customSubagents = this.settingsService
|
||||
? await getCustomSubagents(this.settingsService, effectiveWorkDir)
|
||||
: undefined;
|
||||
// Get Subagents configuration from settings
|
||||
const subagentsConfig = this.settingsService
|
||||
? await getSubagentsConfiguration(this.settingsService)
|
||||
: { enabled: false, sources: [] as Array<'user' | 'project'>, shouldIncludeInTools: false };
|
||||
|
||||
// Get custom subagents from settings (merge global + project-level) only if enabled
|
||||
const customSubagents =
|
||||
this.settingsService && subagentsConfig.enabled
|
||||
? await getCustomSubagents(this.settingsService, effectiveWorkDir)
|
||||
: undefined;
|
||||
|
||||
// Load project context files (CLAUDE.md, CODE_QUALITY.md, etc.)
|
||||
const contextResult = await loadContextFiles({
|
||||
@@ -297,18 +304,34 @@ export class AgentService {
|
||||
const settingSources = [...new Set([...sdkSettingSources, ...skillSettingSources])];
|
||||
|
||||
// Enhance allowedTools with Skills and Subagents tools
|
||||
// These tools are not in the provider's default set - they're added dynamically based on settings
|
||||
const needsSkillTool = skillsConfig.shouldIncludeInTools;
|
||||
const needsTaskTool =
|
||||
subagentsConfig.shouldIncludeInTools &&
|
||||
customSubagents &&
|
||||
Object.keys(customSubagents).length > 0;
|
||||
|
||||
// Base tools that match the provider's default set
|
||||
const baseTools = ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash', 'WebSearch', 'WebFetch'];
|
||||
|
||||
if (allowedTools) {
|
||||
allowedTools = [...allowedTools]; // Create a copy to avoid mutating SDK options
|
||||
// Add Skill tool if skills are enabled
|
||||
if (skillsConfig.shouldIncludeInTools && !allowedTools.includes('Skill')) {
|
||||
if (needsSkillTool && !allowedTools.includes('Skill')) {
|
||||
allowedTools.push('Skill');
|
||||
}
|
||||
// Add Task tool if custom subagents are configured
|
||||
if (
|
||||
customSubagents &&
|
||||
Object.keys(customSubagents).length > 0 &&
|
||||
!allowedTools.includes('Task')
|
||||
) {
|
||||
if (needsTaskTool && !allowedTools.includes('Task')) {
|
||||
allowedTools.push('Task');
|
||||
}
|
||||
} else if (needsSkillTool || needsTaskTool) {
|
||||
// If no allowedTools specified but we need to add Skill/Task tools,
|
||||
// build the full list including base tools
|
||||
allowedTools = [...baseTools];
|
||||
if (needsSkillTool) {
|
||||
allowedTools.push('Skill');
|
||||
}
|
||||
if (needsTaskTool) {
|
||||
allowedTools.push('Task');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,17 +96,9 @@ describe('claude-provider.ts', () => {
|
||||
expect(sdk.query).toHaveBeenCalledWith({
|
||||
prompt: 'Test',
|
||||
options: expect.objectContaining({
|
||||
allowedTools: [
|
||||
'Read',
|
||||
'Write',
|
||||
'Edit',
|
||||
'Glob',
|
||||
'Grep',
|
||||
'Bash',
|
||||
'WebSearch',
|
||||
'WebFetch',
|
||||
'Skill',
|
||||
],
|
||||
// Note: 'Skill' and 'Task' tools are added dynamically by agent-service.ts
|
||||
// based on settings, not included in base default tools
|
||||
allowedTools: ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash', 'WebSearch', 'WebFetch'],
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Subagents Settings Hook - Manages Subagents configuration state
|
||||
*
|
||||
* Provides state management for enabling/disabling Subagents and
|
||||
* configuring which sources to load Subagents from (user/project).
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useAppStore } from '@/store/app-store';
|
||||
import { toast } from 'sonner';
|
||||
import { getElectronAPI } from '@/lib/electron';
|
||||
|
||||
export function useSubagentsSettings() {
|
||||
const enabled = useAppStore((state) => state.enableSubagents);
|
||||
const sources = useAppStore((state) => state.subagentsSources);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const updateEnabled = async (newEnabled: boolean) => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const api = getElectronAPI();
|
||||
if (!api.settings) {
|
||||
throw new Error('Settings API not available');
|
||||
}
|
||||
await api.settings.updateGlobal({ enableSubagents: newEnabled });
|
||||
// Update local store after successful server update
|
||||
useAppStore.setState({ enableSubagents: newEnabled });
|
||||
toast.success(newEnabled ? 'Subagents enabled' : 'Subagents disabled');
|
||||
} catch (error) {
|
||||
toast.error('Failed to update subagents settings');
|
||||
console.error(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const updateSources = async (newSources: Array<'user' | 'project'>) => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const api = getElectronAPI();
|
||||
if (!api.settings) {
|
||||
throw new Error('Settings API not available');
|
||||
}
|
||||
await api.settings.updateGlobal({ subagentsSources: newSources });
|
||||
// Update local store after successful server update
|
||||
useAppStore.setState({ subagentsSources: newSources });
|
||||
toast.success('Subagents sources updated');
|
||||
} catch (error) {
|
||||
toast.error('Failed to update subagents sources');
|
||||
console.error(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
enabled,
|
||||
sources,
|
||||
updateEnabled,
|
||||
updateSources,
|
||||
isLoading,
|
||||
};
|
||||
}
|
||||
@@ -1,26 +1,62 @@
|
||||
/**
|
||||
* Subagents Section - UI for viewing filesystem-based agents
|
||||
* Subagents Section - UI for managing Subagents configuration
|
||||
*
|
||||
* Allows users to enable/disable Subagents and select which directories
|
||||
* to load Subagents from (user ~/.claude/agents/ or project .claude/agents/).
|
||||
*
|
||||
* Displays agents discovered from:
|
||||
* - User-level: ~/.claude/agents/
|
||||
* - Project-level: .claude/agents/
|
||||
*
|
||||
* Read-only view - agents are managed by editing .md files directly.
|
||||
*/
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Bot, RefreshCw, Loader2, Users, ExternalLink } from 'lucide-react';
|
||||
import {
|
||||
Bot,
|
||||
RefreshCw,
|
||||
Loader2,
|
||||
Users,
|
||||
ExternalLink,
|
||||
Globe,
|
||||
FolderOpen,
|
||||
Sparkles,
|
||||
} from 'lucide-react';
|
||||
import { useSubagents } from './hooks/use-subagents';
|
||||
import { useSubagentsSettings } from './hooks/use-subagents-settings';
|
||||
import { SubagentCard } from './subagent-card';
|
||||
|
||||
export function SubagentsSection() {
|
||||
const { subagentsWithScope, isLoading, hasProject, refreshFilesystemAgents } = useSubagents();
|
||||
const {
|
||||
subagentsWithScope,
|
||||
isLoading: isLoadingAgents,
|
||||
hasProject,
|
||||
refreshFilesystemAgents,
|
||||
} = useSubagents();
|
||||
const {
|
||||
enabled,
|
||||
sources,
|
||||
updateEnabled,
|
||||
updateSources,
|
||||
isLoading: isLoadingSettings,
|
||||
} = useSubagentsSettings();
|
||||
|
||||
const isLoading = isLoadingAgents || isLoadingSettings;
|
||||
|
||||
const handleRefresh = async () => {
|
||||
await refreshFilesystemAgents();
|
||||
};
|
||||
|
||||
const toggleSource = (source: 'user' | 'project') => {
|
||||
if (sources.includes(source)) {
|
||||
updateSources(sources.filter((s: 'user' | 'project') => s !== source));
|
||||
} else {
|
||||
updateSources([...sources, source]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
@@ -39,7 +75,7 @@ export function SubagentsSection() {
|
||||
<div>
|
||||
<h3 className="font-semibold text-base flex items-center gap-2">
|
||||
Custom Subagents
|
||||
{subagentsWithScope.length > 0 && (
|
||||
{enabled && subagentsWithScope.length > 0 && (
|
||||
<span className="text-xs font-normal px-2 py-0.5 rounded-full bg-violet-500/20 text-violet-500">
|
||||
{subagentsWithScope.length} agent{subagentsWithScope.length !== 1 ? 's' : ''}
|
||||
</span>
|
||||
@@ -50,57 +86,169 @@ export function SubagentsSection() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleRefresh}
|
||||
<Switch
|
||||
id="enable-subagents"
|
||||
checked={enabled}
|
||||
onCheckedChange={updateEnabled}
|
||||
disabled={isLoading}
|
||||
title="Refresh agents from disk"
|
||||
className="gap-2"
|
||||
>
|
||||
{isLoading ? (
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<RefreshCw className="h-4 w-4" />
|
||||
)}
|
||||
<span className="text-xs">Refresh</span>
|
||||
</Button>
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-6">
|
||||
{subagentsWithScope.length === 0 ? (
|
||||
<div className="text-center py-8 text-muted-foreground">
|
||||
<Users className="w-12 h-12 mx-auto mb-3 opacity-30" />
|
||||
<p className="text-sm font-medium">No agents found</p>
|
||||
<p className="text-xs mt-2 max-w-sm mx-auto">
|
||||
Create <code className="text-xs bg-muted px-1 rounded">.md</code> files in{' '}
|
||||
<code className="text-xs bg-muted px-1 rounded">~/.claude/agents/</code>
|
||||
{hasProject && (
|
||||
<>
|
||||
{' or '}
|
||||
<code className="text-xs bg-muted px-1 rounded">.claude/agents/</code>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
<div className="p-6 space-y-4">
|
||||
{/* Sources Selection */}
|
||||
{enabled && (
|
||||
<div className="space-y-3">
|
||||
<Label className="text-xs uppercase tracking-wide text-muted-foreground">
|
||||
Load Subagents from
|
||||
</Label>
|
||||
<div className="grid gap-2">
|
||||
{/* User Subagents Option */}
|
||||
<label
|
||||
htmlFor="subagent-source-user"
|
||||
className={cn(
|
||||
'flex items-center gap-3 p-3 rounded-xl border cursor-pointer transition-all duration-200',
|
||||
sources.includes('user')
|
||||
? 'border-violet-500/50 bg-violet-500/10'
|
||||
: 'border-border/50 bg-accent/20 hover:bg-accent/30'
|
||||
)}
|
||||
>
|
||||
<Checkbox
|
||||
id="subagent-source-user"
|
||||
checked={sources.includes('user')}
|
||||
onCheckedChange={() => toggleSource('user')}
|
||||
disabled={isLoading}
|
||||
className="data-[state=checked]:bg-violet-500 data-[state=checked]:border-violet-500"
|
||||
/>
|
||||
<div className="w-8 h-8 rounded-lg bg-muted/50 flex items-center justify-center shrink-0">
|
||||
<Globe className="w-4 h-4 text-muted-foreground" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<span className="text-sm font-medium">User Subagents</span>
|
||||
<span className="block text-xs text-muted-foreground mt-0.5 truncate">
|
||||
~/.claude/agents/ — Available across all projects
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
{/* Project Subagents Option */}
|
||||
<label
|
||||
htmlFor="subagent-source-project"
|
||||
className={cn(
|
||||
'flex items-center gap-3 p-3 rounded-xl border cursor-pointer transition-all duration-200',
|
||||
sources.includes('project')
|
||||
? 'border-violet-500/50 bg-violet-500/10'
|
||||
: 'border-border/50 bg-accent/20 hover:bg-accent/30'
|
||||
)}
|
||||
>
|
||||
<Checkbox
|
||||
id="subagent-source-project"
|
||||
checked={sources.includes('project')}
|
||||
onCheckedChange={() => toggleSource('project')}
|
||||
disabled={isLoading}
|
||||
className="data-[state=checked]:bg-violet-500 data-[state=checked]:border-violet-500"
|
||||
/>
|
||||
<div className="w-8 h-8 rounded-lg bg-muted/50 flex items-center justify-center shrink-0">
|
||||
<FolderOpen className="w-4 h-4 text-muted-foreground" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<span className="text-sm font-medium">Project Subagents</span>
|
||||
<span className="block text-xs text-muted-foreground mt-0.5 truncate">
|
||||
.claude/agents/ — Version-controlled with project
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Agents List */}
|
||||
{enabled && (
|
||||
<>
|
||||
{/* Refresh Button */}
|
||||
<div className="flex items-center justify-between">
|
||||
<Label className="text-xs uppercase tracking-wide text-muted-foreground">
|
||||
Discovered Agents
|
||||
</Label>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleRefresh}
|
||||
disabled={isLoading}
|
||||
title="Refresh agents from disk"
|
||||
className="gap-1.5 h-7 px-2 text-xs"
|
||||
>
|
||||
{isLoadingAgents ? (
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
) : (
|
||||
<RefreshCw className="h-3.5 w-3.5" />
|
||||
)}
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{subagentsWithScope.length === 0 ? (
|
||||
<div className="text-center py-6 text-muted-foreground border border-dashed border-border/50 rounded-xl">
|
||||
<Users className="w-10 h-10 mx-auto mb-2 opacity-30" />
|
||||
<p className="text-sm font-medium">No agents found</p>
|
||||
<p className="text-xs mt-1 max-w-sm mx-auto">
|
||||
Create <code className="text-xs bg-muted px-1 rounded">.md</code> files in{' '}
|
||||
{sources.includes('user') && (
|
||||
<code className="text-xs bg-muted px-1 rounded">~/.claude/agents/</code>
|
||||
)}
|
||||
{sources.includes('user') && sources.includes('project') && ' or '}
|
||||
{sources.includes('project') && (
|
||||
<code className="text-xs bg-muted px-1 rounded">.claude/agents/</code>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{subagentsWithScope.map((agent) => (
|
||||
<SubagentCard
|
||||
key={`${agent.type}-${agent.source || agent.scope}-${agent.name}`}
|
||||
agent={agent}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Help Text */}
|
||||
{enabled && (
|
||||
<div className="rounded-xl border border-border/30 bg-muted/30 p-4 space-y-3">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="w-6 h-6 rounded-md bg-brand-500/20 flex items-center justify-center shrink-0 mt-0.5">
|
||||
<Sparkles className="w-3.5 h-3.5 text-brand-500" />
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground space-y-1">
|
||||
<p className="font-medium text-foreground/80">Auto-Discovery</p>
|
||||
<p>
|
||||
Subagents are automatically discovered when agents start. Define agents as{' '}
|
||||
<code className="text-xs bg-muted px-1 rounded">AGENT.md</code> files or{' '}
|
||||
<code className="text-xs bg-muted px-1 rounded">agent-name.md</code> files.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href="https://code.claude.com/docs/en/agents"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1.5 mt-4 text-xs text-brand-500 hover:text-brand-400 transition-colors"
|
||||
className="flex items-center gap-2 text-xs text-brand-500 hover:text-brand-400 transition-colors"
|
||||
>
|
||||
<ExternalLink className="w-3.5 h-3.5" />
|
||||
View Agents documentation
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{subagentsWithScope.map((agent) => (
|
||||
<SubagentCard
|
||||
key={`${agent.type}-${agent.source || agent.scope}-${agent.name}`}
|
||||
agent={agent}
|
||||
/>
|
||||
))}
|
||||
)}
|
||||
|
||||
{/* Disabled State Empty Message */}
|
||||
{!enabled && (
|
||||
<div className="text-center py-6 text-muted-foreground">
|
||||
<Bot className="w-10 h-10 mx-auto mb-3 opacity-30" />
|
||||
<p className="text-sm">Subagents are disabled</p>
|
||||
<p className="text-xs mt-1">Enable to load custom agent definitions</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -236,6 +236,8 @@ export async function syncSettingsToServer(): Promise<boolean> {
|
||||
mcpServers: state.mcpServers,
|
||||
enableSkills: state.enableSkills,
|
||||
skillsSources: state.skillsSources,
|
||||
enableSubagents: state.enableSubagents,
|
||||
subagentsSources: state.subagentsSources,
|
||||
promptCustomization: state.promptCustomization,
|
||||
projects: state.projects,
|
||||
trashedProjects: state.trashedProjects,
|
||||
|
||||
@@ -516,6 +516,10 @@ export interface AppState {
|
||||
enableSkills: boolean; // Enable Skills functionality (loads from .claude/skills/ directories)
|
||||
skillsSources: Array<'user' | 'project'>; // Which directories to load Skills from
|
||||
|
||||
// Subagents Configuration
|
||||
enableSubagents: boolean; // Enable Custom Subagents functionality (loads from .claude/agents/ directories)
|
||||
subagentsSources: Array<'user' | 'project'>; // Which directories to load Subagents from
|
||||
|
||||
// Prompt Customization
|
||||
promptCustomization: PromptCustomization; // Custom prompts for Auto Mode, Agent, Backlog Plan, Enhancement
|
||||
|
||||
@@ -1028,6 +1032,8 @@ const initialState: AppState = {
|
||||
mcpServers: [], // No MCP servers configured by default
|
||||
enableSkills: true, // Skills enabled by default
|
||||
skillsSources: ['user', 'project'] as Array<'user' | 'project'>, // Load from both sources by default
|
||||
enableSubagents: true, // Subagents enabled by default
|
||||
subagentsSources: ['user', 'project'] as Array<'user' | 'project'>, // Load from both sources by default
|
||||
promptCustomization: {}, // Empty by default - all prompts use built-in defaults
|
||||
aiProfiles: DEFAULT_AI_PROFILES,
|
||||
projectAnalysis: null,
|
||||
|
||||
@@ -504,7 +504,21 @@ export interface GlobalSettings {
|
||||
|
||||
// Subagents Configuration
|
||||
/**
|
||||
* Custom subagent definitions for specialized task delegation
|
||||
* Enable Custom Subagents functionality (loads from .claude/agents/ directories)
|
||||
* @default true
|
||||
*/
|
||||
enableSubagents?: boolean;
|
||||
|
||||
/**
|
||||
* Which directories to load Subagents from
|
||||
* - 'user': ~/.claude/agents/ (personal agents)
|
||||
* - 'project': .claude/agents/ (project-specific agents)
|
||||
* @default ['user', 'project']
|
||||
*/
|
||||
subagentsSources?: Array<'user' | 'project'>;
|
||||
|
||||
/**
|
||||
* Custom subagent definitions for specialized task delegation (programmatic)
|
||||
* Key: agent name (e.g., 'code-reviewer', 'test-runner')
|
||||
* Value: agent configuration
|
||||
*/
|
||||
@@ -707,6 +721,10 @@ export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
|
||||
enableSandboxMode: false,
|
||||
skipSandboxWarning: false,
|
||||
mcpServers: [],
|
||||
enableSkills: true,
|
||||
skillsSources: ['user', 'project'],
|
||||
enableSubagents: true,
|
||||
subagentsSources: ['user', 'project'],
|
||||
};
|
||||
|
||||
/** Default credentials (empty strings - user must provide API keys) */
|
||||
|
||||
Reference in New Issue
Block a user