@compilr-dev/sdk 0.25.1 → 0.27.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.
Files changed (73) hide show
  1. package/dist/actions/registry.d.ts +1 -1
  2. package/dist/actions/registry.js +1 -1
  3. package/dist/index.d.ts +12 -8
  4. package/dist/index.js +7 -5
  5. package/dist/platform/tools/canvas-tools.js +11 -11
  6. package/dist/project-types/action-meta.d.ts +21 -7
  7. package/dist/project-types/action-meta.js +44 -213
  8. package/dist/project-types/index.d.ts +5 -3
  9. package/dist/project-types/index.js +3 -2
  10. package/dist/project-types/macro-meta.d.ts +39 -0
  11. package/dist/project-types/{skill-meta.js → macro-meta.js} +203 -12
  12. package/dist/project-types/macro-relevance.d.ts +47 -0
  13. package/dist/project-types/macro-relevance.js +58 -0
  14. package/dist/project-types/types.d.ts +23 -4
  15. package/dist/skills/book-macros.d.ts +10 -0
  16. package/dist/skills/{book-skills.js → book-macros.js} +6 -6
  17. package/dist/skills/business-macros.d.ts +11 -0
  18. package/dist/skills/{business-skills.js → business-macros.js} +7 -7
  19. package/dist/skills/canvas-exemplars.d.ts +2 -2
  20. package/dist/skills/canvas-exemplars.js +4 -4
  21. package/dist/skills/canvas-icons.d.ts +1 -1
  22. package/dist/skills/canvas-icons.js +2 -2
  23. package/dist/skills/canvas-macros.d.ts +11 -0
  24. package/dist/skills/{canvas-skills.js → canvas-macros.js} +6 -6
  25. package/dist/skills/content-macros.d.ts +10 -0
  26. package/dist/skills/{content-skills.js → content-macros.js} +6 -6
  27. package/dist/skills/course-macros.d.ts +9 -0
  28. package/dist/skills/{course-skills.js → course-macros.js} +5 -5
  29. package/dist/skills/index.d.ts +6 -2
  30. package/dist/skills/index.js +4 -2
  31. package/dist/skills/macro-invocation.d.ts +44 -0
  32. package/dist/skills/macro-invocation.js +63 -0
  33. package/dist/skills/macro-list.d.ts +54 -0
  34. package/dist/skills/macro-list.js +84 -0
  35. package/dist/skills/operations.js +4 -4
  36. package/dist/skills/platform-macros.d.ts +27 -0
  37. package/dist/skills/platform-macros.js +94 -0
  38. package/dist/skills/prompt-resolver.d.ts +8 -2
  39. package/dist/skills/prompt-resolver.js +14 -8
  40. package/dist/skills/research-macros.d.ts +10 -0
  41. package/dist/skills/{research-skills.js → research-macros.js} +6 -6
  42. package/dist/skills/resolver.d.ts +20 -9
  43. package/dist/skills/resolver.js +18 -21
  44. package/dist/skills/software-macros.d.ts +14 -0
  45. package/dist/skills/{software-skills.js → software-macros.js} +10 -10
  46. package/dist/skills/types.d.ts +2 -2
  47. package/dist/skills/types.js +4 -4
  48. package/dist/team/agent-templates.d.ts +0 -1
  49. package/dist/team/agent-templates.js +0 -2
  50. package/dist/team/custom-agents.d.ts +1 -2
  51. package/dist/team/custom-agents.js +1 -2
  52. package/dist/team/index.d.ts +5 -3
  53. package/dist/team/index.js +2 -1
  54. package/dist/team/{skill-requirements.d.ts → macro-requirements.d.ts} +20 -14
  55. package/dist/team/{skill-requirements.js → macro-requirements.js} +28 -22
  56. package/dist/team/macro-tool-gap.d.ts +42 -0
  57. package/dist/team/macro-tool-gap.js +69 -0
  58. package/dist/team/team-agent.d.ts +15 -2
  59. package/dist/team/team-agent.js +20 -10
  60. package/dist/team/types.d.ts +9 -4
  61. package/dist/team/workshop-data.d.ts +17 -5
  62. package/dist/team/workshop-data.js +13 -13
  63. package/package.json +1 -1
  64. package/dist/project-types/skill-meta.d.ts +0 -17
  65. package/dist/skills/book-skills.d.ts +0 -10
  66. package/dist/skills/business-skills.d.ts +0 -11
  67. package/dist/skills/canvas-skills.d.ts +0 -11
  68. package/dist/skills/content-skills.d.ts +0 -10
  69. package/dist/skills/course-skills.d.ts +0 -9
  70. package/dist/skills/platform-skills.d.ts +0 -20
  71. package/dist/skills/platform-skills.js +0 -87
  72. package/dist/skills/research-skills.d.ts +0 -10
  73. package/dist/skills/software-skills.d.ts +0 -14
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Software Development Skills
2
+ * Software Development Macros
3
3
  *
4
4
  * design, sketch, prd, refine, refine-item, architecture, session-notes, build, scaffold
5
5
  */
@@ -7,7 +7,7 @@ import { defineSkill } from '@compilr-dev/agents';
7
7
  // =============================================================================
8
8
  // From @compilr-dev/agents (7 skills)
9
9
  // =============================================================================
10
- export const designSkill = defineSkill({
10
+ export const designMacro = defineSkill({
11
11
  name: 'design',
12
12
  description: 'Interactive requirements gathering session that produces 5-15 actionable backlog items. Use when starting a new project from scratch or when the user has an idea but no clear requirements. Asks structured questions about goals, users, features, and constraints.',
13
13
  prompt: `You are in DESIGN MODE. Your goal is to gather enough information to populate the project backlog with 5-15 actionable items.
@@ -92,7 +92,7 @@ When you have enough information:
92
92
  ✓ User has approved the backlog`,
93
93
  tags: ['planning', 'requirements'],
94
94
  });
95
- export const refineSkill = defineSkill({
95
+ export const refineMacro = defineSkill({
96
96
  name: 'refine',
97
97
  description: 'Iteratively refine and expand existing project requirements. Use when the project already has an initial design or backlog but needs deeper detail, edge cases, or new features explored. Walks through each area asking targeted follow-up questions.',
98
98
  prompt: `You are in REFINE MODE. Your goal is to deepen and expand existing requirements based on user feedback.
@@ -171,7 +171,7 @@ For complex features:
171
171
  ✓ No open questions remain`,
172
172
  tags: ['planning', 'requirements'],
173
173
  });
174
- export const sketchSkill = defineSkill({
174
+ export const sketchMacro = defineSkill({
175
175
  name: 'sketch',
176
176
  description: 'Quick lightweight project outline using a few simple questions. Use for rapid brainstorming or when the user wants a fast first pass before committing to a full design session. Produces a high-level summary, not detailed backlog items.',
177
177
  prompt: `You are in SKETCH MODE. Ask 6 quick questions, then create backlog items.
@@ -210,7 +210,7 @@ RULES:
210
210
  - For fresh projects, ALWAYS add CHORE-001 scaffolding as first item`,
211
211
  tags: ['planning', 'requirements'],
212
212
  });
213
- export const refineItemSkill = defineSkill({
213
+ export const refineItemMacro = defineSkill({
214
214
  name: 'refine-item',
215
215
  description: 'Deep-dive refinement of a single backlog work item. Use when an item needs more detail — acceptance criteria, implementation notes, subtask breakdown, or dependency analysis. Reads the item from the database and produces an updated version.',
216
216
  prompt: `You are in FOCUSED REFINE MODE. Your goal is to refine a specific backlog item.
@@ -278,7 +278,7 @@ Based on user's choice:
278
278
  ✓ Changes are summarized`,
279
279
  tags: ['planning', 'requirements'],
280
280
  });
281
- export const architectureSkill = defineSkill({
281
+ export const architectureMacro = defineSkill({
282
282
  name: 'architecture',
283
283
  description: 'Create or update architecture documentation including ADRs, system diagrams, data models, and API designs. Use after requirements are defined. Reads the current backlog and project documents to produce architecture artifacts stored as project documents.',
284
284
  prompt: `You are in ARCHITECTURE MODE. Your goal is to create architecture documentation.
@@ -423,7 +423,7 @@ Generate appropriate documentation.
423
423
  ✓ User has reviewed the output`,
424
424
  tags: ['architecture', 'documentation'],
425
425
  });
426
- export const prdSkill = defineSkill({
426
+ export const prdMacro = defineSkill({
427
427
  name: 'prd',
428
428
  description: 'Create, amend, or enhance the Product Requirements Document. Use when formalizing requirements into a structured PRD with sections for overview, user personas, functional requirements, non-functional requirements, and success metrics. Stored as a project document.',
429
429
  prompt: `You are in PRD MODE. Your goal is to update or enhance the existing Product Requirements Document.
@@ -508,7 +508,7 @@ Based on section selected:
508
508
  ✓ Related backlog updates are suggested if needed`,
509
509
  tags: ['planning', 'requirements'],
510
510
  });
511
- export const sessionNotesSkill = defineSkill({
511
+ export const sessionNotesMacro = defineSkill({
512
512
  name: 'session-notes',
513
513
  description: 'Create structured session notes capturing work done, decisions made, and open questions. Use at the end of a work session to document progress. Reviews conversation history and produces a formatted summary stored as a project document.',
514
514
  prompt: `You are in SESSION NOTES MODE. Your goal is to create a structured summary of the current session.
@@ -602,7 +602,7 @@ CRITICAL: session notes are database documents. NEVER write a .md file (no write
602
602
  ✓ User has reviewed the note`,
603
603
  tags: ['documentation', 'session'],
604
604
  });
605
- export const buildSkill = defineSkill({
605
+ export const buildMacro = defineSkill({
606
606
  name: 'build',
607
607
  description: 'Implement a backlog work item end-to-end — read requirements, write code, run tests, and update the item status. Use when an item is ready to build. Follows a structured workflow: understand → plan → implement → verify → mark complete.',
608
608
  tags: ['implementation', 'coding'],
@@ -699,7 +699,7 @@ Before implementing, read these files for context:
699
699
  - Always run tests before marking complete`,
700
700
  version: '1.0.0',
701
701
  });
702
- export const scaffoldSkill = defineSkill({
702
+ export const scaffoldMacro = defineSkill({
703
703
  name: 'scaffold',
704
704
  description: 'Generate a complete project scaffold from the Application Model or tech stack selection. Use after the design phase to create the initial codebase — directory structure, configuration, boilerplate, and starter components. Supports multiple toolkits (React+Node, Next+Prisma, FastAPI, Go, static landing).',
705
705
  tags: ['setup', 'foundation', 'scaffolding'],
@@ -86,5 +86,5 @@ export interface CustomSkill {
86
86
  * A second copy of a list is a list that will disagree with the first. Deriving it costs one
87
87
  * import and cannot go stale.
88
88
  */
89
- export declare const RESERVED_SKILL_NAMES: readonly string[];
90
- export declare function isReservedSkillName(name: string): boolean;
89
+ export declare const RESERVED_MACRO_NAMES: readonly string[];
90
+ export declare function isReservedMacroName(name: string): boolean;
@@ -9,7 +9,7 @@
9
9
  * extensions live under the optional `compilr:` block, which
10
10
  * Anthropic-compatible runtimes ignore.
11
11
  */
12
- import { platformSkills } from './platform-skills.js';
12
+ import { platformMacros } from './platform-macros.js';
13
13
  /**
14
14
  * SDK skill names that are reserved — user/project skills cannot use these.
15
15
  *
@@ -27,7 +27,7 @@ import { platformSkills } from './platform-skills.js';
27
27
  * A second copy of a list is a list that will disagree with the first. Deriving it costs one
28
28
  * import and cannot go stale.
29
29
  */
30
- export const RESERVED_SKILL_NAMES = platformSkills.map((s) => s.name);
31
- export function isReservedSkillName(name) {
32
- return RESERVED_SKILL_NAMES.includes(name);
30
+ export const RESERVED_MACRO_NAMES = platformMacros.map((s) => s.name);
31
+ export function isReservedMacroName(name) {
32
+ return RESERVED_MACRO_NAMES.includes(name);
33
33
  }
@@ -21,7 +21,6 @@ export interface AgentTemplate {
21
21
  personality?: string;
22
22
  systemPromptAddition?: string;
23
23
  toolProfile?: string;
24
- enabledSkills?: string[];
25
24
  modelTier?: string;
26
25
  }
27
26
  /** List all saved templates */
@@ -60,7 +60,6 @@ export function saveTemplate(name, agent, description) {
60
60
  personality: agent.personality,
61
61
  systemPromptAddition: agent.systemPromptAddition,
62
62
  toolProfile: agent.toolConfig?.profile,
63
- enabledSkills: agent.enabledSkills,
64
63
  modelTier: agent.modelTier,
65
64
  };
66
65
  templates.push(template);
@@ -101,7 +100,6 @@ export function createAgentFromTemplate(template, agentId, existingAgents) {
101
100
  mascot: assignMascot(existingAgents),
102
101
  createdAt: new Date().toISOString(),
103
102
  toolConfig: template.toolProfile ? { profile: template.toolProfile } : undefined,
104
- enabledSkills: template.enabledSkills,
105
103
  modelTier: template.modelTier,
106
104
  };
107
105
  }
@@ -17,7 +17,6 @@ export interface CustomAgentDefinition {
17
17
  mascot: string;
18
18
  createdAt: string;
19
19
  toolConfig?: ToolConfig;
20
- enabledSkills?: string[];
21
20
  modelTier?: ModelTier;
22
21
  /** Custom instructions appended to the agent's system prompt (max 2000 chars) */
23
22
  systemPromptAddition?: string;
@@ -97,4 +96,4 @@ export declare function isAgentIdTaken(id: string, existingCustomAgents: CustomA
97
96
  /**
98
97
  * Create a new CustomAgentDefinition with auto-assigned mascot.
99
98
  */
100
- export declare function createCustomAgentDefinition(id: string, displayName: string, specialty: string, personality: string | undefined, existingAgents: CustomAgentDefinition[], toolConfig?: ToolConfig, enabledSkills?: string[], modelTier?: ModelTier, systemPromptAddition?: string): CustomAgentDefinition;
99
+ export declare function createCustomAgentDefinition(id: string, displayName: string, specialty: string, personality: string | undefined, existingAgents: CustomAgentDefinition[], toolConfig?: ToolConfig, modelTier?: ModelTier, systemPromptAddition?: string): CustomAgentDefinition;
@@ -191,7 +191,7 @@ export function isAgentIdTaken(id, existingCustomAgents, teamAgentIds, predefine
191
191
  /**
192
192
  * Create a new CustomAgentDefinition with auto-assigned mascot.
193
193
  */
194
- export function createCustomAgentDefinition(id, displayName, specialty, personality, existingAgents, toolConfig, enabledSkills, modelTier, systemPromptAddition) {
194
+ export function createCustomAgentDefinition(id, displayName, specialty, personality, existingAgents, toolConfig, modelTier, systemPromptAddition) {
195
195
  return {
196
196
  id,
197
197
  displayName,
@@ -200,7 +200,6 @@ export function createCustomAgentDefinition(id, displayName, specialty, personal
200
200
  mascot: assignMascot(existingAgents),
201
201
  createdAt: new Date().toISOString(),
202
202
  toolConfig: toolConfig ?? createDefaultToolConfig(),
203
- enabledSkills: enabledSkills ?? [], // Empty = all skills
204
203
  modelTier: modelTier ?? 'balanced', // Default tier
205
204
  systemPromptAddition: systemPromptAddition?.trim() || undefined,
206
205
  };
@@ -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';
@@ -24,7 +26,7 @@ export type { AgentTemplate } from './agent-templates.js';
24
26
  export { listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, } from './agent-templates.js';
25
27
  export type { PlanSubmitInfo, PlanSubmitResult, PlanModeExitInfo, PlanModeCallbacks, } from './plan-mode.js';
26
28
  export { PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './plan-mode.js';
27
- export type { AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, } from './workshop-data.js';
29
+ export type { AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopMacroDef, } from './workshop-data.js';
28
30
  export { buildAgentWorkshopData, buildSuggestedRolesMap } from './workshop-data.js';
29
31
  export type { ITeamPersistence, IArtifactStorage, ISessionRegistry } from './interfaces.js';
30
32
  export type { ParsedMention, ParsedInput } from './mention-parser.js';
@@ -37,8 +39,8 @@ export { wouldCreateLoop, recordAssignment, getAssignmentHistory, clearAssignmen
37
39
  export { DelegationTracker } from './delegation-tracker.js';
38
40
  export type { Delegation, DelegationStatus, DelegationResult, CompletionEvent, CreateDelegationOptions, DelegationStats, DelegationTrackerEvents, } from './delegation-tracker.js';
39
41
  export { setActiveSharedContext, getActiveSharedContext, recordTeamActivity } from './activity.js';
40
- export type { SkillToolRequirement } from './skill-requirements.js';
41
- export { SKILL_REQUIREMENTS, getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './skill-requirements.js';
42
+ export type { MacroToolRequirement } from './macro-requirements.js';
43
+ export { MACRO_REQUIREMENTS, getDefinedMacroNames, getMacroRequirements, checkMacroCompatibility, getCompatibleMacros, getAllRequiredTools, getMacrosByCategory, } from './macro-requirements.js';
42
44
  export { resolveAgentIdCollision } from './collision-utils.js';
43
45
  export { createDelegationStatusTool, createHandoffTool, createDelegateTool, createDelegateBackgroundTool, } from './delegation-tools.js';
44
46
  export type { HandoffResult, HandoffToolConfig, DelegateResult, DelegateToolConfig, DelegateBackgroundResult, DelegateBackgroundToolConfig, } from './delegation-tools.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';
@@ -29,7 +30,7 @@ export { wouldCreateLoop, recordAssignment, getAssignmentHistory, clearAssignmen
29
30
  export { DelegationTracker } from './delegation-tracker.js';
30
31
  // Activity recording
31
32
  export { setActiveSharedContext, getActiveSharedContext, recordTeamActivity } from './activity.js';
32
- export { SKILL_REQUIREMENTS, getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './skill-requirements.js';
33
+ export { MACRO_REQUIREMENTS, getDefinedMacroNames, getMacroRequirements, checkMacroCompatibility, getCompatibleMacros, getAllRequiredTools, getMacrosByCategory, } from './macro-requirements.js';
33
34
  // Collision utils
34
35
  export { resolveAgentIdCollision } from './collision-utils.js';
35
36
  // Delegation & Handoff tools (factory functions)
@@ -1,14 +1,20 @@
1
1
  /**
2
- * Skill Requirements Mapping
2
+ * Macro tool requirements.
3
3
  *
4
- * Maps skills to the tools they require to function properly.
5
- * This enables automatic filtering of incompatible skills based
6
- * on an agent's tool configuration.
4
+ * Maps each MACRO to the tools its text assumes, so an agent can be told before it starts that
5
+ * it cannot carry one out. A macro is a named prompt the USER invokes — `/design`, `/code-review`
6
+ * — which expands into a message.
7
+ *
8
+ * ⚠️ THIS IS NOT ABOUT SKILLS, DESPITE ITS FORMER NAME. It was called `MACRO_REQUIREMENTS` and
9
+ * rendered by `buildAgentWorkshopData` as if it were a catalogue of skills, which is how the
10
+ * agent editor came to offer 13 items that were all Commands. Verified: every one of the 13
11
+ * entries is a macro and none is an installed skill. Skills — the Anthropic kind the model
12
+ * chooses — declare their own requirements in `SKILL.md` under `compilr.requires`.
7
13
  */
8
- export interface SkillToolRequirement {
9
- /** Tools that MUST be available for this skill to work */
14
+ export interface MacroToolRequirement {
15
+ /** Tools that MUST be available for this macro to work */
10
16
  required: string[];
11
- /** Tools that enhance this skill but aren't strictly required */
17
+ /** Tools that enhance this macro but aren't strictly required */
12
18
  optional?: string[];
13
19
  /** Brief description of why these tools are needed */
14
20
  reason?: string;
@@ -20,23 +26,23 @@ export interface SkillToolRequirement {
20
26
  * - Required tools: The skill will fail without these
21
27
  * - Optional tools: The skill works better with these but can function without
22
28
  */
23
- export declare const SKILL_REQUIREMENTS: Record<string, SkillToolRequirement>;
29
+ export declare const MACRO_REQUIREMENTS: Record<string, MacroToolRequirement>;
24
30
  /**
25
31
  * Get all skill names that have requirements defined.
26
32
  */
27
- export declare function getDefinedSkillNames(): string[];
33
+ export declare function getDefinedMacroNames(): string[];
28
34
  /**
29
35
  * Get the tool requirements for a skill.
30
36
  */
31
- export declare function getSkillRequirements(skillName: string): SkillToolRequirement | undefined;
37
+ export declare function getMacroRequirements(macroName: string): MacroToolRequirement | undefined;
32
38
  /**
33
39
  * Check if a skill is compatible with a set of available tools.
34
40
  *
35
- * @param skillName - Name of the skill to check
41
+ * @param macroName - Name of the macro to check
36
42
  * @param availableTools - Set of tool names available to the agent
37
43
  * @returns Object with compatibility status and missing tools
38
44
  */
39
- export declare function checkSkillCompatibility(skillName: string, availableTools: Set<string> | string[]): {
45
+ export declare function checkMacroCompatibility(macroName: string, availableTools: Set<string> | string[]): {
40
46
  compatible: boolean;
41
47
  missingRequired: string[];
42
48
  missingOptional: string[];
@@ -48,7 +54,7 @@ export declare function checkSkillCompatibility(skillName: string, availableTool
48
54
  * @param allSkillNames - All skill names to check (default: defined skills)
49
55
  * @returns Object with compatible and incompatible skill names
50
56
  */
51
- export declare function getCompatibleSkills(availableTools: Set<string> | string[], allSkillNames?: string[]): {
57
+ export declare function getCompatibleMacros(availableTools: Set<string> | string[], allMacroNames?: string[]): {
52
58
  compatible: string[];
53
59
  incompatible: Array<{
54
60
  name: string;
@@ -63,4 +69,4 @@ export declare function getAllRequiredTools(): string[];
63
69
  /**
64
70
  * Get skills grouped by their primary category.
65
71
  */
66
- export declare function getSkillsByCategory(): Record<string, string[]>;
72
+ export declare function getMacrosByCategory(): Record<string, string[]>;
@@ -1,12 +1,18 @@
1
1
  /**
2
- * Skill Requirements Mapping
2
+ * Macro tool requirements.
3
3
  *
4
- * Maps skills to the tools they require to function properly.
5
- * This enables automatic filtering of incompatible skills based
6
- * on an agent's tool configuration.
4
+ * Maps each MACRO to the tools its text assumes, so an agent can be told before it starts that
5
+ * it cannot carry one out. A macro is a named prompt the USER invokes — `/design`, `/code-review`
6
+ * — which expands into a message.
7
+ *
8
+ * ⚠️ THIS IS NOT ABOUT SKILLS, DESPITE ITS FORMER NAME. It was called `MACRO_REQUIREMENTS` and
9
+ * rendered by `buildAgentWorkshopData` as if it were a catalogue of skills, which is how the
10
+ * agent editor came to offer 13 items that were all Commands. Verified: every one of the 13
11
+ * entries is a macro and none is an installed skill. Skills — the Anthropic kind the model
12
+ * chooses — declare their own requirements in `SKILL.md` under `compilr.requires`.
7
13
  */
8
14
  // =============================================================================
9
- // Skill Requirements
15
+ // Macro Requirements
10
16
  // =============================================================================
11
17
  /**
12
18
  * Maps skill names to their tool requirements.
@@ -15,7 +21,7 @@
15
21
  * - Required tools: The skill will fail without these
16
22
  * - Optional tools: The skill works better with these but can function without
17
23
  */
18
- export const SKILL_REQUIREMENTS = {
24
+ export const MACRO_REQUIREMENTS = {
19
25
  // Development skills
20
26
  'code-review': {
21
27
  required: ['read_file', 'glob', 'grep'],
@@ -104,33 +110,33 @@ export const SKILL_REQUIREMENTS = {
104
110
  /**
105
111
  * Get all skill names that have requirements defined.
106
112
  */
107
- export function getDefinedSkillNames() {
108
- return Object.keys(SKILL_REQUIREMENTS);
113
+ export function getDefinedMacroNames() {
114
+ return Object.keys(MACRO_REQUIREMENTS);
109
115
  }
110
116
  /**
111
117
  * Get the tool requirements for a skill.
112
118
  */
113
- export function getSkillRequirements(skillName) {
114
- return SKILL_REQUIREMENTS[skillName];
119
+ export function getMacroRequirements(macroName) {
120
+ return MACRO_REQUIREMENTS[macroName];
115
121
  }
116
122
  /**
117
123
  * Check if a skill is compatible with a set of available tools.
118
124
  *
119
- * @param skillName - Name of the skill to check
125
+ * @param macroName - Name of the macro to check
120
126
  * @param availableTools - Set of tool names available to the agent
121
127
  * @returns Object with compatibility status and missing tools
122
128
  */
123
- export function checkSkillCompatibility(skillName, availableTools) {
129
+ export function checkMacroCompatibility(macroName, availableTools) {
124
130
  const toolSet = availableTools instanceof Set ? availableTools : new Set(availableTools);
125
131
  // If no requirements defined, assume compatible
126
- if (!(skillName in SKILL_REQUIREMENTS)) {
132
+ if (!(macroName in MACRO_REQUIREMENTS)) {
127
133
  return {
128
134
  compatible: true,
129
135
  missingRequired: [],
130
136
  missingOptional: [],
131
137
  };
132
138
  }
133
- const requirement = SKILL_REQUIREMENTS[skillName];
139
+ const requirement = MACRO_REQUIREMENTS[macroName];
134
140
  const missingRequired = requirement.required.filter((t) => !toolSet.has(t));
135
141
  const missingOptional = (requirement.optional ?? []).filter((t) => !toolSet.has(t));
136
142
  return {
@@ -146,18 +152,18 @@ export function checkSkillCompatibility(skillName, availableTools) {
146
152
  * @param allSkillNames - All skill names to check (default: defined skills)
147
153
  * @returns Object with compatible and incompatible skill names
148
154
  */
149
- export function getCompatibleSkills(availableTools, allSkillNames) {
150
- const skillNames = allSkillNames ?? getDefinedSkillNames();
155
+ export function getCompatibleMacros(availableTools, allMacroNames) {
156
+ const macroNames = allMacroNames ?? getDefinedMacroNames();
151
157
  const compatible = [];
152
158
  const incompatible = [];
153
- for (const skillName of skillNames) {
154
- const result = checkSkillCompatibility(skillName, availableTools);
159
+ for (const macroName of macroNames) {
160
+ const result = checkMacroCompatibility(macroName, availableTools);
155
161
  if (result.compatible) {
156
- compatible.push(skillName);
162
+ compatible.push(macroName);
157
163
  }
158
164
  else {
159
165
  incompatible.push({
160
- name: skillName,
166
+ name: macroName,
161
167
  missingTools: result.missingRequired,
162
168
  });
163
169
  }
@@ -170,7 +176,7 @@ export function getCompatibleSkills(availableTools, allSkillNames) {
170
176
  */
171
177
  export function getAllRequiredTools() {
172
178
  const allTools = new Set();
173
- for (const requirement of Object.values(SKILL_REQUIREMENTS)) {
179
+ for (const requirement of Object.values(MACRO_REQUIREMENTS)) {
174
180
  for (const tool of requirement.required) {
175
181
  allTools.add(tool);
176
182
  }
@@ -180,7 +186,7 @@ export function getAllRequiredTools() {
180
186
  /**
181
187
  * Get skills grouped by their primary category.
182
188
  */
183
- export function getSkillsByCategory() {
189
+ export function getMacrosByCategory() {
184
190
  return {
185
191
  development: ['code-review', 'debug', 'explain', 'refactor'],
186
192
  security: ['security-review'],
@@ -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 — `MACRO_REQUIREMENTS` carries `required`, `optional`
11
+ * and a written `reason` per macro, and `checkMacroCompatibility` 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 MACRO_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 — `MACRO_REQUIREMENTS` carries `required`, `optional`
11
+ * and a written `reason` per macro, and `checkMacroCompatibility` 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 { MACRO_REQUIREMENTS, checkMacroCompatibility } from './macro-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 MACRO_REQUIREMENTS))
29
+ return null;
30
+ const { missingRequired, missingOptional } = checkMacroCompatibility(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: MACRO_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
+ }
@@ -67,9 +67,10 @@ export interface TeamAgentUpdate {
67
67
  personality?: string;
68
68
  toolProfile?: TeamAgentConfig['toolProfile'];
69
69
  toolFilter?: string[];
70
- enabledSkills?: string[];
71
70
  /** Which MCP servers this agent may reach. See `TeamAgent.mcpServers`. */
72
71
  mcpServers?: string[];
72
+ /** Which Skills this agent may choose. See `TeamAgent.grantedSkills`. */
73
+ grantedSkills?: string[];
73
74
  }
74
75
  /** What an edit did, and whether anyone needs telling. */
75
76
  export interface AgentUpdateResult {
@@ -187,6 +188,19 @@ export declare class TeamAgent {
187
188
  * from the profile name alone.
188
189
  */
189
190
  customGroups?: string[];
191
+ /**
192
+ * Skills this agent may CHOOSE. `undefined` = never asked, reaches everything eligible;
193
+ * `[]` = granted nothing. Same contract as `mcpServers`.
194
+ *
195
+ * ⚠️ THERE USED TO BE A SECOND FIELD, `enabledSkills`, AND IT HELD SOMETHING ELSE ENTIRELY.
196
+ * MACRO ids — the 13 its picker offered were `code-review`, `debug`, `design`, `prd` and
197
+ * friends, all things a user types. 0.25.0 wired Skills enforcement onto it and produced a
198
+ * live hazard: ticking "Code Review" wrote a name no installed skill has, so the agent
199
+ * silently got zero skills. It is deleted now. The MCP-style reading is legitimate HERE
200
+ * 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`.
@@ -199,7 +213,6 @@ export declare class TeamAgent {
199
213
  /**
200
214
  * Enabled skills (empty = all skills)
201
215
  */
202
- enabledSkills?: string[];
203
216
  /**
204
217
  * How the agent should sound. Tone only — never capability.
205
218
  *