Skip to content

Commit 267dfa8

Browse files
committed
Remove custom skills
1 parent 817d862 commit 267dfa8

18 files changed

Lines changed: 382 additions & 1731 deletions

src/agents/index.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import {
66
type PluginConfig,
77
SUBAGENT_NAMES,
88
} from '../config';
9-
import { getAgentMcpList } from '../tools/skill/builtin';
9+
import { getAgentMcpList } from '../config/agent-mcps';
10+
import { getSkillPermissionsForAgent } from '../cli/skills';
11+
1012
import { createDesignerAgent } from './designer';
1113
import { createExplorerAgent } from './explorer';
1214
import { createFixerAgent } from './fixer';
@@ -41,7 +43,7 @@ function getOverride(
4143
return (
4244
overrides[name] ??
4345
overrides[
44-
Object.keys(AGENT_ALIASES).find((k) => AGENT_ALIASES[k] === name) ?? ''
46+
Object.keys(AGENT_ALIASES).find((k) => AGENT_ALIASES[k] === name) ?? ''
4547
]
4648
);
4749
}
@@ -63,19 +65,41 @@ function applyOverrides(
6365

6466
/**
6567
* Apply default permissions to an agent.
66-
* Currently sets 'question' permission to 'allow' for all agents.
68+
* Sets 'question' permission to 'allow' and includes skill permission presets.
69+
*/
70+
/**
71+
* Apply default permissions to an agent.
72+
* Sets 'question' permission to 'allow' and includes skill permission presets.
73+
* If configuredSkills is provided, it honors that list instead of defaults.
6774
*/
68-
function applyDefaultPermissions(agent: AgentDefinition): void {
75+
function applyDefaultPermissions(
76+
agent: AgentDefinition,
77+
configuredSkills?: string[],
78+
): void {
6979
const existing = (agent.config.permission ?? {}) as Record<
7080
string,
71-
'ask' | 'allow' | 'deny'
81+
'ask' | 'allow' | 'deny' | Record<string, 'ask' | 'allow' | 'deny'>
7282
>;
83+
84+
// Get skill-specific permissions for this agent
85+
const skillPermissions = getSkillPermissionsForAgent(
86+
agent.name,
87+
configuredSkills,
88+
);
89+
7390
agent.config.permission = {
7491
...existing,
7592
question: 'allow',
93+
// Apply skill permissions as nested object under 'skill' key
94+
skill: {
95+
...(typeof existing.skill === 'object' ? existing.skill : {}),
96+
...skillPermissions,
97+
},
7698
} as SDKAgentConfig['permission'];
7799
}
78100

101+
102+
79103
// Agent Classification
80104

81105
export type SubagentName = (typeof SUBAGENT_NAMES)[number];
@@ -130,12 +154,13 @@ export function createAgents(config?: PluginConfig): AgentDefinition[] {
130154
);
131155
});
132156

133-
// 2. Apply overrides to each agent
157+
// 2. Apply overrides and default permissions to each agent
134158
const allSubAgents = protoSubAgents.map((agent) => {
135159
const override = getOverride(agentOverrides, agent.name);
136160
if (override) {
137161
applyOverrides(agent, override);
138162
}
163+
applyDefaultPermissions(agent, override?.skills);
139164
return agent;
140165
});
141166

@@ -149,8 +174,8 @@ export function createAgents(config?: PluginConfig): AgentDefinition[] {
149174
orchestratorPrompts.prompt,
150175
orchestratorPrompts.appendPrompt,
151176
);
152-
applyDefaultPermissions(orchestrator);
153177
const oOverride = getOverride(agentOverrides, 'orchestrator');
178+
applyDefaultPermissions(orchestrator, oOverride?.skills);
154179
if (oOverride) {
155180
applyOverrides(orchestrator, oOverride);
156181
}

src/cli/install.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
isOpenCodeInstalled,
1010
writeLiteConfig,
1111
} from './config-manager';
12+
import { RECOMMENDED_SKILLS, installSkill } from './skills';
1213
import type {
1314
BooleanArg,
1415
ConfigMergeResult,
@@ -155,6 +156,7 @@ function argsToConfig(args: InstallArgs): InstallConfig {
155156
hasOpenAI: args.openai === 'yes',
156157
hasOpencodeZen: true, // Always enabled - free models available to all users
157158
hasTmux: args.tmux === 'yes',
159+
installSkills: args.skills === 'yes',
158160
};
159161
}
160162

@@ -213,11 +215,25 @@ async function runInteractiveMode(
213215
// console.log()
214216
// }
215217

218+
// Skills prompt
219+
console.log(`${BOLD}Recommended Skills:${RESET}`);
220+
for (const skill of RECOMMENDED_SKILLS) {
221+
console.log(` ${SYMBOLS.bullet} ${BOLD}${skill.name}${RESET}: ${skill.description}`);
222+
}
223+
console.log();
224+
const skills = await askYesNo(
225+
rl,
226+
'Install recommended skills?',
227+
'yes',
228+
);
229+
console.log();
230+
216231
return {
217232
hasAntigravity: antigravity === 'yes',
218233
hasOpenAI: openai === 'yes',
219234
hasOpencodeZen: true,
220235
hasTmux: false,
236+
installSkills: skills === 'yes',
221237
};
222238
} finally {
223239
rl.close();
@@ -233,6 +249,7 @@ async function runInstall(config: InstallConfig): Promise<number> {
233249
// Calculate total steps dynamically
234250
let totalSteps = 4; // Base: check opencode, add plugin, disable default agents, write lite config
235251
if (config.hasAntigravity) totalSteps += 1; // provider config only (no auth plugin needed)
252+
if (config.installSkills) totalSteps += 1; // skills installation
236253

237254
let step = 1;
238255

@@ -259,6 +276,22 @@ async function runInstall(config: InstallConfig): Promise<number> {
259276
const liteResult = writeLiteConfig(config);
260277
if (!handleStepResult(liteResult, 'Config written')) return 1;
261278

279+
// Install skills if requested
280+
if (config.installSkills) {
281+
printStep(step++, totalSteps, 'Installing recommended skills...');
282+
let skillsInstalled = 0;
283+
for (const skill of RECOMMENDED_SKILLS) {
284+
printInfo(`Installing ${skill.name}...`);
285+
if (installSkill(skill)) {
286+
printSuccess(`Installed: ${skill.name}`);
287+
skillsInstalled++;
288+
} else {
289+
printWarning(`Failed to install: ${skill.name}`);
290+
}
291+
}
292+
printSuccess(`${skillsInstalled}/${RECOMMENDED_SKILLS.length} skills installed`);
293+
}
294+
262295
// Summary
263296
console.log();
264297
console.log(formatConfigSummary(config));

src/cli/providers.test.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ describe('providers', () => {
1010
hasOpenAI: false,
1111
hasOpencodeZen: false,
1212
hasTmux: false,
13+
installSkills: false,
1314
});
1415

1516
expect(config.preset).toBe('cliproxy');
@@ -32,6 +33,7 @@ describe('providers', () => {
3233
hasOpenAI: true,
3334
hasOpencodeZen: false,
3435
hasTmux: false,
36+
installSkills: false,
3537
});
3638

3739
expect(config.preset).toBe('cliproxy');
@@ -54,6 +56,7 @@ describe('providers', () => {
5456
hasOpenAI: true,
5557
hasOpencodeZen: false,
5658
hasTmux: false,
59+
installSkills: false,
5760
});
5861

5962
expect(config.preset).toBe('openai');
@@ -74,6 +77,7 @@ describe('providers', () => {
7477
hasOpenAI: false,
7578
hasOpencodeZen: false,
7679
hasTmux: false,
80+
installSkills: false,
7781
});
7882

7983
expect(config.preset).toBe('zen-free');
@@ -92,6 +96,7 @@ describe('providers', () => {
9296
hasOpenAI: false,
9397
hasOpencodeZen: true,
9498
hasTmux: false,
99+
installSkills: false,
95100
});
96101

97102
expect(config.preset).toBe('zen-free');
@@ -109,6 +114,7 @@ describe('providers', () => {
109114
hasOpenAI: false,
110115
hasOpencodeZen: false,
111116
hasTmux: true,
117+
installSkills: false,
112118
});
113119

114120
expect(config.tmux).toBeDefined();
@@ -121,19 +127,28 @@ describe('providers', () => {
121127
hasOpenAI: false,
122128
hasOpencodeZen: false,
123129
hasTmux: false,
130+
installSkills: true,
124131
});
125132

126133
const agents = (config.presets as any).cliproxy;
127-
expect(agents.orchestrator.skills).toContain('*');
128-
expect(agents.fixer.skills).toBeDefined();
134+
// Orchestrator should always have '*'
135+
expect(agents.orchestrator.skills).toEqual(['*']);
136+
137+
// Designer should have 'agent-browser'
138+
expect(agents.designer.skills).toContain('agent-browser');
139+
140+
// Fixer should have no skills by default (empty recommended list)
141+
expect(agents.fixer.skills).toEqual([]);
129142
});
130143

144+
131145
test('generateLiteConfig includes mcps field', () => {
132146
const config = generateLiteConfig({
133147
hasAntigravity: true,
134148
hasOpenAI: false,
135149
hasOpencodeZen: false,
136150
hasTmux: false,
151+
installSkills: false,
137152
});
138153

139154
const agents = (config.presets as any).cliproxy;
@@ -149,6 +164,7 @@ describe('providers', () => {
149164
hasOpenAI: false,
150165
hasOpencodeZen: false,
151166
hasTmux: false,
167+
installSkills: false,
152168
});
153169

154170
const agents = (config.presets as any)['zen-free'];

src/cli/providers.ts

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import {
2-
DEFAULT_AGENT_MCPS,
3-
DEFAULT_AGENT_SKILLS,
4-
} from '../tools/skill/builtin';
1+
import { DEFAULT_AGENT_MCPS } from '../config/agent-mcps';
2+
import { RECOMMENDED_SKILLS } from './skills';
53
import type { InstallConfig } from './types';
64

5+
76
/**
87
* Provider configurations for Cliproxy (Antigravity via cliproxy)
98
*/
@@ -111,7 +110,7 @@ export function generateLiteConfig(
111110
designer: {
112111
model: 'cliproxy/gemini-3-flash-preview',
113112
variant: 'medium',
114-
skills: ['playwright'],
113+
skills: ['agent-browser'],
115114
mcps: [],
116115
},
117116
fixer: {
@@ -151,7 +150,7 @@ export function generateLiteConfig(
151150
designer: {
152151
model: 'cliproxy/gemini-3-flash-preview',
153152
variant: 'medium',
154-
skills: ['playwright'],
153+
skills: ['agent-browser'],
155154
mcps: [],
156155
},
157156
fixer: {
@@ -171,19 +170,30 @@ export function generateLiteConfig(
171170
{ model: string; variant?: string; skills: string[]; mcps: string[] }
172171
> =>
173172
Object.fromEntries(
174-
Object.entries(models).map(([k, v]) => [
175-
k,
176-
{
177-
model: v.model,
178-
variant: v.variant,
179-
skills:
180-
DEFAULT_AGENT_SKILLS[k as keyof typeof DEFAULT_AGENT_SKILLS] ??
181-
[],
182-
mcps:
183-
DEFAULT_AGENT_MCPS[k as keyof typeof DEFAULT_AGENT_MCPS] ?? [],
184-
},
185-
]),
173+
Object.entries(models).map(([agentName, v]) => {
174+
const skills =
175+
agentName === 'orchestrator'
176+
? ['*']
177+
: RECOMMENDED_SKILLS.filter(
178+
(s) =>
179+
s.allowedAgents.includes('*') ||
180+
s.allowedAgents.includes(agentName),
181+
).map((s) => s.skillName);
182+
183+
return [
184+
agentName,
185+
{
186+
model: v.model,
187+
variant: v.variant,
188+
skills,
189+
mcps:
190+
DEFAULT_AGENT_MCPS[agentName as keyof typeof DEFAULT_AGENT_MCPS] ??
191+
[],
192+
},
193+
];
194+
}),
186195
);
196+
187197
(config.presets as Record<string, unknown>).openai = createAgents(
188198
MODEL_MAPPINGS.openai,
189199
);
@@ -197,18 +207,29 @@ export function generateLiteConfig(
197207
{ model: string; variant?: string; skills: string[]; mcps: string[] }
198208
> =>
199209
Object.fromEntries(
200-
Object.entries(models).map(([k, v]) => [
201-
k,
202-
{
203-
model: v.model,
204-
variant: v.variant,
205-
skills:
206-
DEFAULT_AGENT_SKILLS[k as keyof typeof DEFAULT_AGENT_SKILLS] ??
207-
[],
208-
mcps:
209-
DEFAULT_AGENT_MCPS[k as keyof typeof DEFAULT_AGENT_MCPS] ?? [],
210-
},
211-
]),
210+
Object.entries(models).map(([agentName, v]) => {
211+
const skills =
212+
agentName === 'orchestrator'
213+
? ['*']
214+
: RECOMMENDED_SKILLS.filter(
215+
(s) =>
216+
s.allowedAgents.includes('*') ||
217+
s.allowedAgents.includes(agentName),
218+
).map((s) => s.skillName);
219+
220+
221+
return [
222+
agentName,
223+
{
224+
model: v.model,
225+
variant: v.variant,
226+
skills,
227+
mcps:
228+
DEFAULT_AGENT_MCPS[agentName as keyof typeof DEFAULT_AGENT_MCPS] ??
229+
[],
230+
},
231+
];
232+
}),
212233
);
213234
(config.presets as Record<string, unknown>)['zen-free'] = createAgents(
214235
MODEL_MAPPINGS['zen-free'],

0 commit comments

Comments
 (0)