@compilr-dev/sdk 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/skills/resolver.d.ts +11 -5
- package/dist/skills/resolver.js +17 -5
- package/dist/team/index.d.ts +2 -0
- package/dist/team/index.js +1 -0
- package/dist/team/macro-tool-gap.d.ts +42 -0
- package/dist/team/macro-tool-gap.js +69 -0
- package/dist/team/team-agent.d.ts +14 -0
- package/dist/team/team-agent.js +19 -1
- package/dist/team/types.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTr
|
|
|
39
39
|
export type { AgentTeamConfig, TeamAgentConfig, TeamAgentUpdate, AgentUpdateResult, ITeamPersistence, IArtifactStorage, ISessionRegistry, CustomAgentDefinition, AgentTemplate, AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, PlanSubmitInfo, PlanSubmitResult, PlanModeExitInfo, PlanModeCallbacks, ToolConfig as TeamToolConfig, ToolTier, ToolGroup, ProfileInfo, } from './team/index.js';
|
|
40
40
|
export type { AgentRole, RoleMetadata, ToolProfile, MascotExpression, BackgroundSessionInfo, SerializedTeam, SerializedTeamAgent, TeamMetadata, TeamEvent, TeamEventType, TeamEventHandler, Artifact, ArtifactType as TeamArtifactType, ArtifactSummary as TeamArtifactSummary, CreateArtifactOptions, UpdateArtifactOptions, SerializedArtifact, SharedContext, SharedProjectInfo, SharedTeamInfo, TeamRosterEntry, TeamActivity, TeamActivityType, SharedDecision, TokenBudget, SerializedSharedContext, ParsedMention, ParsedInput, ResolvedMention, ResolveOptions, ResolutionSource, Delegation, DelegationStatus, DelegationResult, CompletionEvent, CreateDelegationOptions, DelegationStats, DelegationTrackerEvents, HandoffResult, HandoffToolConfig, HandoffIntent, HandoffValidationResult, DelegateResult, DelegateToolConfig, DelegateBackgroundResult, DelegateBackgroundToolConfig, ConsultInput, ConsultResult, ConsultToolConfig, NormalizedRole, SkillToolRequirement, } from './team/index.js';
|
|
41
41
|
export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap, PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './team/index.js';
|
|
42
|
-
export { getToolsForProfile, detectProfileFromTools, isProfileReadOnly, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, createDefaultToolConfig, validateToolConfig, getAllGroupIds, getGroupInfo, getGroupsByTier, getGroupsForProfile, assignMascot, generateCustomAgentSystemPrompt, mcpServerOf, filterMcpToolsByGrant, MCP_TOOL_PREFIX, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, parseInputForMentions, getReferencedAgents, hasReferences, buildMessageWithContext, buildContextMap, findAgentForRole, findAgentById, getAvailableSpecialists, getSpecialistsSummary, hasSpecialists, suggestOwner, suggestOwners, matchesAgentExpertise, wouldCreateLoop, recordAssignment, getAssignmentHistory, clearAssignmentHistory, clearAllAssignmentHistory, canReassign, resolveAgentIdCollision, setActiveSharedContext, getActiveSharedContext, recordTeamActivity, getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './team/index.js';
|
|
42
|
+
export { getToolsForProfile, detectProfileFromTools, isProfileReadOnly, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, createDefaultToolConfig, validateToolConfig, getAllGroupIds, getGroupInfo, getGroupsByTier, getGroupsForProfile, assignMascot, generateCustomAgentSystemPrompt, mcpServerOf, filterMcpToolsByGrant, MCP_TOOL_PREFIX, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, parseInputForMentions, getReferencedAgents, hasReferences, buildMessageWithContext, buildContextMap, findAgentForRole, findAgentById, getAvailableSpecialists, getSpecialistsSummary, hasSpecialists, suggestOwner, suggestOwners, matchesAgentExpertise, wouldCreateLoop, recordAssignment, getAssignmentHistory, clearAssignmentHistory, clearAllAssignmentHistory, canReassign, resolveAgentIdCollision, setActiveSharedContext, getActiveSharedContext, recordTeamActivity, getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, macroToolGap, macroToolGapPreamble, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './team/index.js';
|
|
43
43
|
export { codingPreset, readOnlyPreset, resolvePreset } from './presets/index.js';
|
|
44
44
|
export type { Preset } from './presets/index.js';
|
|
45
45
|
export type { AnyTool } from './presets/types.js';
|
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ resolveAgentIdCollision,
|
|
|
67
67
|
// Activity
|
|
68
68
|
setActiveSharedContext, getActiveSharedContext, recordTeamActivity,
|
|
69
69
|
// Skills
|
|
70
|
-
getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './team/index.js';
|
|
70
|
+
getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, macroToolGap, macroToolGapPreamble, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './team/index.js';
|
|
71
71
|
// =============================================================================
|
|
72
72
|
// Presets
|
|
73
73
|
// =============================================================================
|
|
@@ -62,10 +62,15 @@ export declare function resolveSkillsForAgent(skills: CustomSkill[], context: Sk
|
|
|
62
62
|
* than once. Every judgement lives here: which fields of the agent matter, and what an absent
|
|
63
63
|
* allowlist means.
|
|
64
64
|
*
|
|
65
|
-
* ⚠️
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
65
|
+
* ⚠️ READS `grantedSkills`, NOT `enabledSkills`. Those are different fields for different things.
|
|
66
|
+
* `enabledSkills` holds COMMANDS — the 13 its picker offers are `code-review`, `debug`, `design`,
|
|
67
|
+
* `prd` and friends, all slash commands a user types — and 0.25.0 wired Skills enforcement onto
|
|
68
|
+
* it, so ticking "Code Review" wrote a name no installed skill has and the agent silently got
|
|
69
|
+
* zero skills.
|
|
70
|
+
*
|
|
71
|
+
* `grantedSkills` follows the MCP contract: `undefined` = never asked, reaches everything
|
|
72
|
+
* eligible; `[]` = granted nothing. That reading is legitimate here precisely because the field
|
|
73
|
+
* is new and nothing has a prior meaning.
|
|
69
74
|
*
|
|
70
75
|
* @param pool every skill installed for this machine/project, unfiltered
|
|
71
76
|
* @param agent the agent being built — role, id and its allowlist come from here
|
|
@@ -74,7 +79,8 @@ export declare function resolveSkillsForAgent(skills: CustomSkill[], context: Sk
|
|
|
74
79
|
export declare function resolveSkillsForTeamAgent(pool: CustomSkill[], agent: {
|
|
75
80
|
id: string;
|
|
76
81
|
role?: string;
|
|
77
|
-
enabledSkills
|
|
82
|
+
/** Skills this agent may choose. NOT `enabledSkills`, which holds Commands. */
|
|
83
|
+
grantedSkills?: readonly string[];
|
|
78
84
|
}, opts?: {
|
|
79
85
|
projectType?: string;
|
|
80
86
|
toolNames?: readonly string[];
|
package/dist/skills/resolver.js
CHANGED
|
@@ -46,6 +46,13 @@ export function resolveLayeredSkills(layers) {
|
|
|
46
46
|
*/
|
|
47
47
|
export function resolveSkillsForAgent(skills, context) {
|
|
48
48
|
const toolSet = context.toolNames instanceof Set ? context.toolNames : new Set(context.toolNames ?? []);
|
|
49
|
+
/*
|
|
50
|
+
⚠️ THIS SET COMES FROM `grantedSkills`, WHICH IS NEW — so `[]` correctly means "granted
|
|
51
|
+
nothing", the MCP contract. It does NOT come from `enabledSkills`, which holds Commands and
|
|
52
|
+
has always documented empty as "all skills"; 0.25.0 conflated the two and every custom agent
|
|
53
|
+
silently lost its skills. `resolveSkillsForTeamAgent` is the only caller that maps a field
|
|
54
|
+
onto this context, which is where that distinction is kept.
|
|
55
|
+
*/
|
|
49
56
|
const allowlist = context.enabledSkills ? new Set(context.enabledSkills) : null;
|
|
50
57
|
return skills.filter((skill) => {
|
|
51
58
|
if (skill.enabled === false)
|
|
@@ -87,10 +94,15 @@ export function resolveSkillsForAgent(skills, context) {
|
|
|
87
94
|
* than once. Every judgement lives here: which fields of the agent matter, and what an absent
|
|
88
95
|
* allowlist means.
|
|
89
96
|
*
|
|
90
|
-
* ⚠️
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
97
|
+
* ⚠️ READS `grantedSkills`, NOT `enabledSkills`. Those are different fields for different things.
|
|
98
|
+
* `enabledSkills` holds COMMANDS — the 13 its picker offers are `code-review`, `debug`, `design`,
|
|
99
|
+
* `prd` and friends, all slash commands a user types — and 0.25.0 wired Skills enforcement onto
|
|
100
|
+
* it, so ticking "Code Review" wrote a name no installed skill has and the agent silently got
|
|
101
|
+
* zero skills.
|
|
102
|
+
*
|
|
103
|
+
* `grantedSkills` follows the MCP contract: `undefined` = never asked, reaches everything
|
|
104
|
+
* eligible; `[]` = granted nothing. That reading is legitimate here precisely because the field
|
|
105
|
+
* is new and nothing has a prior meaning.
|
|
94
106
|
*
|
|
95
107
|
* @param pool every skill installed for this machine/project, unfiltered
|
|
96
108
|
* @param agent the agent being built — role, id and its allowlist come from here
|
|
@@ -100,7 +112,7 @@ export function resolveSkillsForTeamAgent(pool, agent, opts = {}) {
|
|
|
100
112
|
return resolveSkillsForAgent(pool, {
|
|
101
113
|
role: agent.role,
|
|
102
114
|
agentId: agent.id,
|
|
103
|
-
enabledSkills: agent.
|
|
115
|
+
enabledSkills: agent.grantedSkills,
|
|
104
116
|
projectType: opts.projectType,
|
|
105
117
|
toolNames: opts.toolNames,
|
|
106
118
|
});
|
package/dist/team/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
export { AgentTeam } from './team.js';
|
|
8
8
|
export type { AgentTeamConfig } from './team.js';
|
|
9
9
|
export { TeamAgent, isNarrowing, lostWriteAccess } from './team-agent.js';
|
|
10
|
+
export { macroToolGap, macroToolGapPreamble } from './macro-tool-gap.js';
|
|
11
|
+
export type { MacroToolGap } from './macro-tool-gap.js';
|
|
10
12
|
export { mcpServerOf, filterMcpToolsByGrant, MCP_TOOL_PREFIX } from './mcp-servers.js';
|
|
11
13
|
export type { TeamAgentUpdate, AgentUpdateResult } from './team-agent.js';
|
|
12
14
|
export { SharedContextManager } from './shared-context.js';
|
package/dist/team/index.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// Core classes
|
|
8
8
|
export { AgentTeam } from './team.js';
|
|
9
9
|
export { TeamAgent, isNarrowing, lostWriteAccess } from './team-agent.js';
|
|
10
|
+
export { macroToolGap, macroToolGapPreamble } from './macro-tool-gap.js';
|
|
10
11
|
export { mcpServerOf, filterMcpToolsByGrant, MCP_TOOL_PREFIX } from './mcp-servers.js';
|
|
11
12
|
export { SharedContextManager } from './shared-context.js';
|
|
12
13
|
export { ArtifactStore } from './artifacts.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telling an agent, up front, that a macro needs tools it does not have.
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ A MACRO'S TEXT ASSUMES TOOLS, AND NOTHING CHECKED. `/design` instructs the agent to use
|
|
5
|
+
* `ask_user` and `workitem_add`; sent to an agent that cannot reach those, it announces it is
|
|
6
|
+
* starting a requirements session and then fails partway, having already promised the user
|
|
7
|
+
* something it cannot deliver. The failure surfaces as the agent being broken rather than as a
|
|
8
|
+
* mismatch anyone can act on.
|
|
9
|
+
*
|
|
10
|
+
* The data for this has existed all along — `SKILL_REQUIREMENTS` carries `required`, `optional`
|
|
11
|
+
* and a written `reason` per macro, and `checkSkillCompatibility` does the comparison. Between
|
|
12
|
+
* them they had exactly one caller: a display hint in the CLI's agent wizard.
|
|
13
|
+
*
|
|
14
|
+
* ⚠️ THE WARNING GOES TO THE AGENT, NOT THE USER. A host-side dialog stops the user at a moment
|
|
15
|
+
* they cannot resolve — they do not know which tools `/design` needs or which teammate has them.
|
|
16
|
+
* The agent does know, once told, and is where the user is already looking: it can explain in one
|
|
17
|
+
* sentence and suggest the handoff.
|
|
18
|
+
*/
|
|
19
|
+
export interface MacroToolGap {
|
|
20
|
+
/** Tools the macro cannot work without. Non-empty whenever a gap is reported. */
|
|
21
|
+
missingRequired: string[];
|
|
22
|
+
/** Tools the macro uses when present. Reported so the agent can say what it will skip. */
|
|
23
|
+
missingOptional: string[];
|
|
24
|
+
/** The macro's own stated reason for needing them, from SKILL_REQUIREMENTS. */
|
|
25
|
+
reason: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* What this macro needs and this agent lacks, or `null` when there is nothing to say.
|
|
29
|
+
*
|
|
30
|
+
* `null` for an unknown macro is deliberate: only 13 have declared requirements, so silence means
|
|
31
|
+
* "not described", never "verified fine". Warning on an undeclared macro would train people to
|
|
32
|
+
* ignore the warning.
|
|
33
|
+
*/
|
|
34
|
+
export declare function macroToolGap(macroName: string, availableTools: Set<string> | readonly string[]): MacroToolGap | null;
|
|
35
|
+
/**
|
|
36
|
+
* A preamble to prepend to the macro's message, addressed to the agent.
|
|
37
|
+
*
|
|
38
|
+
* ⚠️ IT TELLS THE AGENT WHAT TO DO, NOT JUST WHAT IS WRONG. "You lack write_file" invites it to
|
|
39
|
+
* try anyway and fail at the first call. Naming the consequence and the recovery — say so, offer
|
|
40
|
+
* the handoff — is what turns a broken turn into a useful one.
|
|
41
|
+
*/
|
|
42
|
+
export declare function macroToolGapPreamble(macroName: string, gap: MacroToolGap): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telling an agent, up front, that a macro needs tools it does not have.
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ A MACRO'S TEXT ASSUMES TOOLS, AND NOTHING CHECKED. `/design` instructs the agent to use
|
|
5
|
+
* `ask_user` and `workitem_add`; sent to an agent that cannot reach those, it announces it is
|
|
6
|
+
* starting a requirements session and then fails partway, having already promised the user
|
|
7
|
+
* something it cannot deliver. The failure surfaces as the agent being broken rather than as a
|
|
8
|
+
* mismatch anyone can act on.
|
|
9
|
+
*
|
|
10
|
+
* The data for this has existed all along — `SKILL_REQUIREMENTS` carries `required`, `optional`
|
|
11
|
+
* and a written `reason` per macro, and `checkSkillCompatibility` does the comparison. Between
|
|
12
|
+
* them they had exactly one caller: a display hint in the CLI's agent wizard.
|
|
13
|
+
*
|
|
14
|
+
* ⚠️ THE WARNING GOES TO THE AGENT, NOT THE USER. A host-side dialog stops the user at a moment
|
|
15
|
+
* they cannot resolve — they do not know which tools `/design` needs or which teammate has them.
|
|
16
|
+
* The agent does know, once told, and is where the user is already looking: it can explain in one
|
|
17
|
+
* sentence and suggest the handoff.
|
|
18
|
+
*/
|
|
19
|
+
import { SKILL_REQUIREMENTS, checkSkillCompatibility } from './skill-requirements.js';
|
|
20
|
+
/**
|
|
21
|
+
* What this macro needs and this agent lacks, or `null` when there is nothing to say.
|
|
22
|
+
*
|
|
23
|
+
* `null` for an unknown macro is deliberate: only 13 have declared requirements, so silence means
|
|
24
|
+
* "not described", never "verified fine". Warning on an undeclared macro would train people to
|
|
25
|
+
* ignore the warning.
|
|
26
|
+
*/
|
|
27
|
+
export function macroToolGap(macroName, availableTools) {
|
|
28
|
+
if (!(macroName in SKILL_REQUIREMENTS))
|
|
29
|
+
return null;
|
|
30
|
+
const { missingRequired, missingOptional } = checkSkillCompatibility(macroName, [
|
|
31
|
+
...availableTools,
|
|
32
|
+
]);
|
|
33
|
+
// Optional tools alone are not worth interrupting for — the macro still works without them.
|
|
34
|
+
if (missingRequired.length === 0)
|
|
35
|
+
return null;
|
|
36
|
+
return {
|
|
37
|
+
missingRequired,
|
|
38
|
+
missingOptional,
|
|
39
|
+
// Every entry carries one; the fallback exists because the index signature cannot say so.
|
|
40
|
+
reason: SKILL_REQUIREMENTS[macroName].reason ?? 'carry out this workflow',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A preamble to prepend to the macro's message, addressed to the agent.
|
|
45
|
+
*
|
|
46
|
+
* ⚠️ IT TELLS THE AGENT WHAT TO DO, NOT JUST WHAT IS WRONG. "You lack write_file" invites it to
|
|
47
|
+
* try anyway and fail at the first call. Naming the consequence and the recovery — say so, offer
|
|
48
|
+
* the handoff — is what turns a broken turn into a useful one.
|
|
49
|
+
*/
|
|
50
|
+
export function macroToolGapPreamble(macroName, gap) {
|
|
51
|
+
const missing = gap.missingRequired.join(', ');
|
|
52
|
+
const alsoMissing = gap.missingOptional.length > 0
|
|
53
|
+
? ` It also uses ${gap.missingOptional.join(', ')}, which you do not have.`
|
|
54
|
+
: '';
|
|
55
|
+
/*
|
|
56
|
+
The stored reasons are written as "Needs to gather requirements and create backlog", so
|
|
57
|
+
splicing one in after "needs them to" reads "needs them to: Needs to gather…". Strip the
|
|
58
|
+
lead-in rather than rewrite 13 table entries whose phrasing is fine on its own.
|
|
59
|
+
*/
|
|
60
|
+
const purpose = gap.reason.replace(/^\s*needs?\s+to\s+/i, '').replace(/\.$/, '');
|
|
61
|
+
return [
|
|
62
|
+
`[System] The /${macroName} workflow below needs tools you do not have: ${missing}.`,
|
|
63
|
+
`It needs them to ${purpose}.${alsoMissing}`,
|
|
64
|
+
'',
|
|
65
|
+
'Do NOT start the workflow and fail partway. Tell the user in one or two sentences what you ' +
|
|
66
|
+
'cannot do and why, and if a teammate has those tools, suggest handing off to them. ' +
|
|
67
|
+
'If part of the workflow is still useful without those tools, say which part and offer it.',
|
|
68
|
+
].join('\n');
|
|
69
|
+
}
|
|
@@ -70,6 +70,8 @@ export interface TeamAgentUpdate {
|
|
|
70
70
|
enabledSkills?: string[];
|
|
71
71
|
/** Which MCP servers this agent may reach. See `TeamAgent.mcpServers`. */
|
|
72
72
|
mcpServers?: string[];
|
|
73
|
+
/** Which Skills this agent may choose. See `TeamAgent.grantedSkills`. */
|
|
74
|
+
grantedSkills?: string[];
|
|
73
75
|
}
|
|
74
76
|
/** What an edit did, and whether anyone needs telling. */
|
|
75
77
|
export interface AgentUpdateResult {
|
|
@@ -187,6 +189,18 @@ export declare class TeamAgent {
|
|
|
187
189
|
* from the profile name alone.
|
|
188
190
|
*/
|
|
189
191
|
customGroups?: string[];
|
|
192
|
+
/**
|
|
193
|
+
* Skills this agent may CHOOSE. `undefined` = never asked, reaches everything eligible;
|
|
194
|
+
* `[]` = granted nothing. Same contract as `mcpServers`.
|
|
195
|
+
*
|
|
196
|
+
* ⚠️ NOT `enabledSkills`, WHICH IS A DIFFERENT FIELD FOR A DIFFERENT THING. That one holds
|
|
197
|
+
* COMMANDS — the 13 names its picker offers are `code-review`, `debug`, `design`, `prd` and
|
|
198
|
+
* friends, all slash commands a user types. 0.25.0 wired Skills enforcement onto it and
|
|
199
|
+
* produced a live hazard: ticking "Code Review" wrote a name no installed skill has, so the
|
|
200
|
+
* agent silently got zero skills. The MCP-style reading is legitimate HERE only because this
|
|
201
|
+
* field is new and nothing has a prior meaning.
|
|
202
|
+
*/
|
|
203
|
+
grantedSkills?: string[];
|
|
190
204
|
/**
|
|
191
205
|
* MCP servers this agent may reach. `undefined` = a pre-grants agent, which reaches all;
|
|
192
206
|
* `[]` = granted nothing. See `TeamAgentConfig.mcpServers`.
|
package/dist/team/team-agent.js
CHANGED
|
@@ -203,6 +203,18 @@ export class TeamAgent {
|
|
|
203
203
|
* from the profile name alone.
|
|
204
204
|
*/
|
|
205
205
|
customGroups;
|
|
206
|
+
/**
|
|
207
|
+
* Skills this agent may CHOOSE. `undefined` = never asked, reaches everything eligible;
|
|
208
|
+
* `[]` = granted nothing. Same contract as `mcpServers`.
|
|
209
|
+
*
|
|
210
|
+
* ⚠️ NOT `enabledSkills`, WHICH IS A DIFFERENT FIELD FOR A DIFFERENT THING. That one holds
|
|
211
|
+
* COMMANDS — the 13 names its picker offers are `code-review`, `debug`, `design`, `prd` and
|
|
212
|
+
* friends, all slash commands a user types. 0.25.0 wired Skills enforcement onto it and
|
|
213
|
+
* produced a live hazard: ticking "Code Review" wrote a name no installed skill has, so the
|
|
214
|
+
* agent silently got zero skills. The MCP-style reading is legitimate HERE only because this
|
|
215
|
+
* field is new and nothing has a prior meaning.
|
|
216
|
+
*/
|
|
217
|
+
grantedSkills;
|
|
206
218
|
/**
|
|
207
219
|
* MCP servers this agent may reach. `undefined` = a pre-grants agent, which reaches all;
|
|
208
220
|
* `[]` = granted nothing. See `TeamAgentConfig.mcpServers`.
|
|
@@ -271,6 +283,7 @@ export class TeamAgent {
|
|
|
271
283
|
this.toolProfile = config.toolProfile;
|
|
272
284
|
this.customGroups = config.customGroups;
|
|
273
285
|
this.mcpServers = config.mcpServers;
|
|
286
|
+
this.grantedSkills = config.grantedSkills;
|
|
274
287
|
this.enabledSkills = config.enabledSkills;
|
|
275
288
|
this.personality = config.personality;
|
|
276
289
|
this.autoApproveHandoff = config.autoApproveHandoff;
|
|
@@ -407,7 +420,8 @@ export class TeamAgent {
|
|
|
407
420
|
(patch.toolFilter !== undefined && !sameStrings(patch.toolFilter, this.toolFilter)) ||
|
|
408
421
|
(patch.enabledSkills !== undefined &&
|
|
409
422
|
!sameStrings(patch.enabledSkills, this.enabledSkills)) ||
|
|
410
|
-
(patch.mcpServers !== undefined && !sameStrings(patch.mcpServers, this.mcpServers))
|
|
423
|
+
(patch.mcpServers !== undefined && !sameStrings(patch.mcpServers, this.mcpServers)) ||
|
|
424
|
+
(patch.grantedSkills !== undefined && !sameStrings(patch.grantedSkills, this.grantedSkills));
|
|
411
425
|
/*
|
|
412
426
|
Delegated: `setModelTier` no-ops when the tier is unchanged and stashes for rebuild
|
|
413
427
|
when it is not. Its `rebuilt` contribution is folded in below.
|
|
@@ -446,6 +460,8 @@ export class TeamAgent {
|
|
|
446
460
|
this.personality = patch.personality;
|
|
447
461
|
if (patch.mcpServers !== undefined)
|
|
448
462
|
this.mcpServers = patch.mcpServers;
|
|
463
|
+
if (patch.grantedSkills !== undefined)
|
|
464
|
+
this.grantedSkills = patch.grantedSkills;
|
|
449
465
|
/*
|
|
450
466
|
⚠️ THE PROFILE IS A LABEL; `toolFilter` IS THE ENFORCEMENT. `initialize()` passes
|
|
451
467
|
`toolFilter` to the factory and never looks at `toolProfile`, so setting the profile
|
|
@@ -758,6 +774,7 @@ export class TeamAgent {
|
|
|
758
774
|
toolProfile: this.toolProfile,
|
|
759
775
|
customGroups: this.customGroups,
|
|
760
776
|
mcpServers: this.mcpServers,
|
|
777
|
+
grantedSkills: this.grantedSkills,
|
|
761
778
|
enabledSkills: this.enabledSkills,
|
|
762
779
|
modelTier: this.modelTier,
|
|
763
780
|
autoApproveHandoff: this.autoApproveHandoff,
|
|
@@ -815,6 +832,7 @@ export class TeamAgent {
|
|
|
815
832
|
toolProfile: data.toolProfile,
|
|
816
833
|
customGroups: data.customGroups,
|
|
817
834
|
mcpServers: data.mcpServers,
|
|
835
|
+
grantedSkills: data.grantedSkills,
|
|
818
836
|
enabledSkills: data.enabledSkills,
|
|
819
837
|
modelTier: data.modelTier,
|
|
820
838
|
autoApproveHandoff: data.autoApproveHandoff,
|
package/dist/team/types.d.ts
CHANGED
|
@@ -147,6 +147,8 @@ export interface TeamAgentConfig {
|
|
|
147
147
|
* agent the whole machine.
|
|
148
148
|
*/
|
|
149
149
|
mcpServers?: string[];
|
|
150
|
+
/** Skills this agent may choose — see TeamAgent.grantedSkills. Not `enabledSkills`. */
|
|
151
|
+
grantedSkills?: string[];
|
|
150
152
|
/**
|
|
151
153
|
* Enabled skills for this agent
|
|
152
154
|
* Empty array means all skills, non-empty means filtered
|
|
@@ -188,6 +190,8 @@ export interface SerializedTeamAgent {
|
|
|
188
190
|
customGroups?: string[];
|
|
189
191
|
/** See TeamAgentConfig.mcpServers — undefined means a pre-grants agent, which reaches all. */
|
|
190
192
|
mcpServers?: string[];
|
|
193
|
+
/** Skills this agent may choose — see TeamAgent.grantedSkills. Not `enabledSkills`. */
|
|
194
|
+
grantedSkills?: string[];
|
|
191
195
|
enabledSkills?: string[];
|
|
192
196
|
modelTier?: ModelTier;
|
|
193
197
|
autoApproveHandoff?: boolean;
|