@compilr-dev/sdk 0.25.1 → 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 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,11 +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
- * ⚠️ `enabledSkills` DOES NOT FOLLOW THE MCP GRANT CONTRACT, and must not be made to. There,
66
- * `[]` means "granted nothing" because the field was new. Here both `undefined` and `[]` mean
67
- * "unrestricted": the field predates choosable skills, `createCustomAgentDefinition` normalises
68
- * `undefined` to `[]`, and every UI that collects it says empty means all. Only a NON-EMPTY list
69
- * filters.
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.
70
74
  *
71
75
  * @param pool every skill installed for this machine/project, unfiltered
72
76
  * @param agent the agent being built — role, id and its allowlist come from here
@@ -75,7 +79,8 @@ export declare function resolveSkillsForAgent(skills: CustomSkill[], context: Sk
75
79
  export declare function resolveSkillsForTeamAgent(pool: CustomSkill[], agent: {
76
80
  id: string;
77
81
  role?: string;
78
- enabledSkills?: readonly string[];
82
+ /** Skills this agent may choose. NOT `enabledSkills`, which holds Commands. */
83
+ grantedSkills?: readonly string[];
79
84
  }, opts?: {
80
85
  projectType?: string;
81
86
  toolNames?: readonly string[];
@@ -47,20 +47,13 @@ export function resolveLayeredSkills(layers) {
47
47
  export function resolveSkillsForAgent(skills, context) {
48
48
  const toolSet = context.toolNames instanceof Set ? context.toolNames : new Set(context.toolNames ?? []);
49
49
  /*
50
- ⚠️ AN EMPTY ALLOWLIST MEANS "UNRESTRICTED", NOT "NOTHING" — the opposite of the MCP grant
51
- contract, and deliberately so. `enabledSkills` predates model-choosable skills and already had
52
- a meaning, stated in three places: `CustomAgentDefinition.enabledSkills` is documented "Empty =
53
- all skills, non-empty = filtered", `createCustomAgentDefinition` normalises `undefined` to `[]`
54
- with the same comment, and Desktop's spawn dialog tells the user "Empty = all skills enabled".
55
-
56
- 0.25.0 copied the MCP reading (`[]` = granted nothing) onto this field and inverted it. Because
57
- the definition normalises to `[]`, EVERY custom agent ever created carries one — so every one
58
- of them silently got no skills at all, having been told empty meant everything.
59
-
60
- MCP grants could afford the stricter reading because they were new and nothing had a prior
61
- meaning. This field is not new. Honour what the UI has been promising.
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.
62
55
  */
63
- const allowlist = context.enabledSkills?.length ? new Set(context.enabledSkills) : null;
56
+ const allowlist = context.enabledSkills ? new Set(context.enabledSkills) : null;
64
57
  return skills.filter((skill) => {
65
58
  if (skill.enabled === false)
66
59
  return false;
@@ -101,11 +94,15 @@ export function resolveSkillsForAgent(skills, context) {
101
94
  * than once. Every judgement lives here: which fields of the agent matter, and what an absent
102
95
  * allowlist means.
103
96
  *
104
- * ⚠️ `enabledSkills` DOES NOT FOLLOW THE MCP GRANT CONTRACT, and must not be made to. There,
105
- * `[]` means "granted nothing" because the field was new. Here both `undefined` and `[]` mean
106
- * "unrestricted": the field predates choosable skills, `createCustomAgentDefinition` normalises
107
- * `undefined` to `[]`, and every UI that collects it says empty means all. Only a NON-EMPTY list
108
- * filters.
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.
109
106
  *
110
107
  * @param pool every skill installed for this machine/project, unfiltered
111
108
  * @param agent the agent being built — role, id and its allowlist come from here
@@ -115,7 +112,7 @@ export function resolveSkillsForTeamAgent(pool, agent, opts = {}) {
115
112
  return resolveSkillsForAgent(pool, {
116
113
  role: agent.role,
117
114
  agentId: agent.id,
118
- enabledSkills: agent.enabledSkills,
115
+ enabledSkills: agent.grantedSkills,
119
116
  projectType: opts.projectType,
120
117
  toolNames: opts.toolNames,
121
118
  });
@@ -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';
@@ -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`.
@@ -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,
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/sdk",
3
- "version": "0.25.1",
3
+ "version": "0.26.0",
4
4
  "description": "Universal agent runtime for building AI-powered applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",