@compilr-dev/sdk 0.1.27 → 0.2.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 (40) hide show
  1. package/dist/index.d.ts +6 -2
  2. package/dist/index.js +27 -1
  3. package/dist/meta-tools/registry.js +4 -2
  4. package/dist/team/activity.d.ts +21 -0
  5. package/dist/team/activity.js +34 -0
  6. package/dist/team/agent-selection.d.ts +53 -0
  7. package/dist/team/agent-selection.js +88 -0
  8. package/dist/team/artifacts.d.ts +175 -0
  9. package/dist/team/artifacts.js +279 -0
  10. package/dist/team/collision-utils.d.ts +16 -0
  11. package/dist/team/collision-utils.js +28 -0
  12. package/dist/team/context-resolver.d.ts +97 -0
  13. package/dist/team/context-resolver.js +322 -0
  14. package/dist/team/custom-agents.d.ts +68 -0
  15. package/dist/team/custom-agents.js +150 -0
  16. package/dist/team/delegation-tracker.d.ts +147 -0
  17. package/dist/team/delegation-tracker.js +215 -0
  18. package/dist/team/index.d.ts +34 -0
  19. package/dist/team/index.js +30 -0
  20. package/dist/team/interfaces.d.ts +36 -0
  21. package/dist/team/interfaces.js +7 -0
  22. package/dist/team/mention-parser.d.ts +64 -0
  23. package/dist/team/mention-parser.js +138 -0
  24. package/dist/team/shared-context.d.ts +293 -0
  25. package/dist/team/shared-context.js +673 -0
  26. package/dist/team/skill-requirements.d.ts +66 -0
  27. package/dist/team/skill-requirements.js +178 -0
  28. package/dist/team/task-assignment.d.ts +69 -0
  29. package/dist/team/task-assignment.js +123 -0
  30. package/dist/team/task-suggestion.d.ts +31 -0
  31. package/dist/team/task-suggestion.js +84 -0
  32. package/dist/team/team-agent.d.ts +201 -0
  33. package/dist/team/team-agent.js +492 -0
  34. package/dist/team/team.d.ts +297 -0
  35. package/dist/team/team.js +615 -0
  36. package/dist/team/tool-config.d.ts +110 -0
  37. package/dist/team/tool-config.js +739 -0
  38. package/dist/team/types.d.ts +211 -0
  39. package/dist/team/types.js +638 -0
  40. package/package.json +1 -1
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Skill Requirements Mapping
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.
7
+ */
8
+ export interface SkillToolRequirement {
9
+ /** Tools that MUST be available for this skill to work */
10
+ required: string[];
11
+ /** Tools that enhance this skill but aren't strictly required */
12
+ optional?: string[];
13
+ /** Brief description of why these tools are needed */
14
+ reason?: string;
15
+ }
16
+ /**
17
+ * Maps skill names to their tool requirements.
18
+ *
19
+ * Based on analysis of each skill's prompt and what tools it uses:
20
+ * - Required tools: The skill will fail without these
21
+ * - Optional tools: The skill works better with these but can function without
22
+ */
23
+ export declare const SKILL_REQUIREMENTS: Record<string, SkillToolRequirement>;
24
+ /**
25
+ * Get all skill names that have requirements defined.
26
+ */
27
+ export declare function getDefinedSkillNames(): string[];
28
+ /**
29
+ * Get the tool requirements for a skill.
30
+ */
31
+ export declare function getSkillRequirements(skillName: string): SkillToolRequirement | undefined;
32
+ /**
33
+ * Check if a skill is compatible with a set of available tools.
34
+ *
35
+ * @param skillName - Name of the skill to check
36
+ * @param availableTools - Set of tool names available to the agent
37
+ * @returns Object with compatibility status and missing tools
38
+ */
39
+ export declare function checkSkillCompatibility(skillName: string, availableTools: Set<string> | string[]): {
40
+ compatible: boolean;
41
+ missingRequired: string[];
42
+ missingOptional: string[];
43
+ };
44
+ /**
45
+ * Get all skills that are compatible with a set of available tools.
46
+ *
47
+ * @param availableTools - Tools available to the agent
48
+ * @param allSkillNames - All skill names to check (default: defined skills)
49
+ * @returns Object with compatible and incompatible skill names
50
+ */
51
+ export declare function getCompatibleSkills(availableTools: Set<string> | string[], allSkillNames?: string[]): {
52
+ compatible: string[];
53
+ incompatible: Array<{
54
+ name: string;
55
+ missingTools: string[];
56
+ }>;
57
+ };
58
+ /**
59
+ * Get all required tools across all skills.
60
+ * Useful for showing what tools are needed for full skill support.
61
+ */
62
+ export declare function getAllRequiredTools(): string[];
63
+ /**
64
+ * Get skills grouped by their primary category.
65
+ */
66
+ export declare function getSkillsByCategory(): Record<string, string[]>;
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Skill Requirements Mapping
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.
7
+ */
8
+ // =============================================================================
9
+ // Skill Requirements
10
+ // =============================================================================
11
+ /**
12
+ * Maps skill names to their tool requirements.
13
+ *
14
+ * Based on analysis of each skill's prompt and what tools it uses:
15
+ * - Required tools: The skill will fail without these
16
+ * - Optional tools: The skill works better with these but can function without
17
+ */
18
+ export const SKILL_REQUIREMENTS = {
19
+ // Development skills
20
+ 'code-review': {
21
+ required: ['read_file', 'glob', 'grep'],
22
+ optional: ['git_status', 'git_diff'],
23
+ reason: 'Needs to read and search code files',
24
+ },
25
+ debug: {
26
+ required: ['read_file', 'glob', 'grep'],
27
+ optional: ['bash', 'run_tests', 'edit'],
28
+ reason: 'Needs to read code, optionally run tests and fix issues',
29
+ },
30
+ explain: {
31
+ required: ['read_file', 'glob'],
32
+ optional: ['grep'],
33
+ reason: 'Needs to read actual code to explain it',
34
+ },
35
+ refactor: {
36
+ required: ['read_file', 'write_file', 'edit', 'glob', 'grep'],
37
+ optional: ['run_tests', 'run_lint', 'git_diff'],
38
+ reason: 'Needs full file access to restructure code safely',
39
+ },
40
+ // Security skills
41
+ 'security-review': {
42
+ required: ['read_file', 'glob', 'grep'],
43
+ optional: ['bash', 'find_vulnerabilities', 'check_outdated'],
44
+ reason: 'Needs to search for security patterns in code',
45
+ },
46
+ // Planning skills
47
+ planning: {
48
+ required: ['read_file', 'glob'],
49
+ optional: ['ask_user', 'ask_user_simple', 'todo_write'],
50
+ reason: 'Needs to understand codebase to plan effectively',
51
+ },
52
+ design: {
53
+ required: ['ask_user', 'workitem_add'],
54
+ optional: ['detect_project', 'document_save', 'edit'],
55
+ reason: 'Needs to gather requirements and create backlog',
56
+ },
57
+ refine: {
58
+ required: ['workitem_query', 'workitem_update', 'ask_user_simple'],
59
+ optional: ['ask_user', 'todo_write'],
60
+ reason: 'Needs to read and update backlog items',
61
+ },
62
+ sketch: {
63
+ required: ['ask_user_simple', 'workitem_add'],
64
+ optional: ['detect_project', 'todo_write'],
65
+ reason: 'Quick outline needs user input and backlog creation',
66
+ },
67
+ 'refine-item': {
68
+ required: ['workitem_query', 'workitem_update', 'ask_user_simple'],
69
+ optional: ['ask_user'],
70
+ reason: 'Needs to read specific item and update it',
71
+ },
72
+ // Documentation skills
73
+ architecture: {
74
+ required: ['read_file', 'write_file', 'edit'],
75
+ optional: ['backlog_read', 'ask_user', 'glob'],
76
+ reason: 'Creates architecture documents',
77
+ },
78
+ prd: {
79
+ required: ['read_file', 'edit', 'ask_user_simple'],
80
+ optional: ['ask_user', 'backlog_read'],
81
+ reason: 'Reads and updates PRD document',
82
+ },
83
+ 'session-notes': {
84
+ required: ['write_file'],
85
+ optional: ['read_file', 'ask_user_simple'],
86
+ reason: 'Creates session note documents',
87
+ },
88
+ };
89
+ // =============================================================================
90
+ // Helper Functions
91
+ // =============================================================================
92
+ /**
93
+ * Get all skill names that have requirements defined.
94
+ */
95
+ export function getDefinedSkillNames() {
96
+ return Object.keys(SKILL_REQUIREMENTS);
97
+ }
98
+ /**
99
+ * Get the tool requirements for a skill.
100
+ */
101
+ export function getSkillRequirements(skillName) {
102
+ return SKILL_REQUIREMENTS[skillName];
103
+ }
104
+ /**
105
+ * Check if a skill is compatible with a set of available tools.
106
+ *
107
+ * @param skillName - Name of the skill to check
108
+ * @param availableTools - Set of tool names available to the agent
109
+ * @returns Object with compatibility status and missing tools
110
+ */
111
+ export function checkSkillCompatibility(skillName, availableTools) {
112
+ const toolSet = availableTools instanceof Set ? availableTools : new Set(availableTools);
113
+ // If no requirements defined, assume compatible
114
+ if (!(skillName in SKILL_REQUIREMENTS)) {
115
+ return {
116
+ compatible: true,
117
+ missingRequired: [],
118
+ missingOptional: [],
119
+ };
120
+ }
121
+ const requirement = SKILL_REQUIREMENTS[skillName];
122
+ const missingRequired = requirement.required.filter((t) => !toolSet.has(t));
123
+ const missingOptional = (requirement.optional ?? []).filter((t) => !toolSet.has(t));
124
+ return {
125
+ compatible: missingRequired.length === 0,
126
+ missingRequired,
127
+ missingOptional,
128
+ };
129
+ }
130
+ /**
131
+ * Get all skills that are compatible with a set of available tools.
132
+ *
133
+ * @param availableTools - Tools available to the agent
134
+ * @param allSkillNames - All skill names to check (default: defined skills)
135
+ * @returns Object with compatible and incompatible skill names
136
+ */
137
+ export function getCompatibleSkills(availableTools, allSkillNames) {
138
+ const skillNames = allSkillNames ?? getDefinedSkillNames();
139
+ const compatible = [];
140
+ const incompatible = [];
141
+ for (const skillName of skillNames) {
142
+ const result = checkSkillCompatibility(skillName, availableTools);
143
+ if (result.compatible) {
144
+ compatible.push(skillName);
145
+ }
146
+ else {
147
+ incompatible.push({
148
+ name: skillName,
149
+ missingTools: result.missingRequired,
150
+ });
151
+ }
152
+ }
153
+ return { compatible, incompatible };
154
+ }
155
+ /**
156
+ * Get all required tools across all skills.
157
+ * Useful for showing what tools are needed for full skill support.
158
+ */
159
+ export function getAllRequiredTools() {
160
+ const allTools = new Set();
161
+ for (const requirement of Object.values(SKILL_REQUIREMENTS)) {
162
+ for (const tool of requirement.required) {
163
+ allTools.add(tool);
164
+ }
165
+ }
166
+ return Array.from(allTools).sort();
167
+ }
168
+ /**
169
+ * Get skills grouped by their primary category.
170
+ */
171
+ export function getSkillsByCategory() {
172
+ return {
173
+ development: ['code-review', 'debug', 'explain', 'refactor'],
174
+ security: ['security-review'],
175
+ planning: ['planning', 'design', 'refine', 'sketch', 'refine-item'],
176
+ documentation: ['architecture', 'prd', 'session-notes'],
177
+ };
178
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Task Assignment - Loop prevention and assignment tracking
3
+ *
4
+ * Prevents reassignment loops where tasks bounce between agents
5
+ * (e.g., A → B → A within a short time window).
6
+ */
7
+ /**
8
+ * Record of a task reassignment
9
+ */
10
+ interface AssignmentRecord {
11
+ from: string;
12
+ to: string;
13
+ timestamp: number;
14
+ }
15
+ /**
16
+ * Check if an assignment would create a loop
17
+ *
18
+ * A loop is detected if:
19
+ * - The task was recently assigned from B to A
20
+ * - And we're now trying to assign from A to B
21
+ *
22
+ * @param taskId - The task ID (todo ID or work item ID)
23
+ * @param from - The current owner (or 'unassigned')
24
+ * @param to - The target owner
25
+ * @returns true if this would create a loop
26
+ */
27
+ export declare function wouldCreateLoop(taskId: string, from: string, to: string): boolean;
28
+ /**
29
+ * Record a task assignment
30
+ *
31
+ * @param taskId - The task ID (todo ID or work item ID)
32
+ * @param from - The previous owner (or 'unassigned')
33
+ * @param to - The new owner
34
+ */
35
+ export declare function recordAssignment(taskId: string, from: string, to: string): void;
36
+ /**
37
+ * Get assignment history for a task
38
+ *
39
+ * @param taskId - The task ID
40
+ * @returns Array of recent assignment records
41
+ */
42
+ export declare function getAssignmentHistory(taskId: string): AssignmentRecord[];
43
+ /**
44
+ * Clear assignment history for a task
45
+ * Call this when a task is completed or deleted
46
+ *
47
+ * @param taskId - The task ID
48
+ */
49
+ export declare function clearAssignmentHistory(taskId: string): void;
50
+ /**
51
+ * Clear all assignment history
52
+ * Useful for testing or session reset
53
+ */
54
+ export declare function clearAllAssignmentHistory(): void;
55
+ /**
56
+ * Check if an agent can reassign a task
57
+ *
58
+ * Rules:
59
+ * - Owner can always reassign their own tasks
60
+ * - PM can reassign any task (coordinator role)
61
+ * - Unassigned tasks can be claimed by anyone
62
+ *
63
+ * @param currentOwner - Current owner of the task (or null for unassigned)
64
+ * @param requestingAgent - Agent trying to reassign
65
+ * @param isPm - Whether the requesting agent is PM/coordinator
66
+ * @returns true if the agent can reassign
67
+ */
68
+ export declare function canReassign(currentOwner: string | null, requestingAgent: string, isPm?: boolean): boolean;
69
+ export {};
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Task Assignment - Loop prevention and assignment tracking
3
+ *
4
+ * Prevents reassignment loops where tasks bounce between agents
5
+ * (e.g., A → B → A within a short time window).
6
+ */
7
+ /**
8
+ * In-memory tracking of recent reassignments per task
9
+ * Map of taskId → list of recent assignments
10
+ */
11
+ const recentAssignments = new Map();
12
+ /**
13
+ * How long to remember assignments (30 minutes)
14
+ */
15
+ const ASSIGNMENT_MEMORY_MS = 30 * 60 * 1000;
16
+ /**
17
+ * Clean up old assignment records
18
+ */
19
+ function cleanupOldRecords(taskId) {
20
+ const records = recentAssignments.get(taskId);
21
+ if (!records)
22
+ return;
23
+ const now = Date.now();
24
+ const filtered = records.filter((r) => now - r.timestamp < ASSIGNMENT_MEMORY_MS);
25
+ if (filtered.length === 0) {
26
+ recentAssignments.delete(taskId);
27
+ }
28
+ else {
29
+ recentAssignments.set(taskId, filtered);
30
+ }
31
+ }
32
+ /**
33
+ * Check if an assignment would create a loop
34
+ *
35
+ * A loop is detected if:
36
+ * - The task was recently assigned from B to A
37
+ * - And we're now trying to assign from A to B
38
+ *
39
+ * @param taskId - The task ID (todo ID or work item ID)
40
+ * @param from - The current owner (or 'unassigned')
41
+ * @param to - The target owner
42
+ * @returns true if this would create a loop
43
+ */
44
+ export function wouldCreateLoop(taskId, from, to) {
45
+ cleanupOldRecords(taskId);
46
+ const records = recentAssignments.get(taskId);
47
+ if (!records || records.length === 0) {
48
+ return false;
49
+ }
50
+ // Check for reverse assignment in recent history
51
+ return records.some((r) => r.from === to && r.to === from);
52
+ }
53
+ /**
54
+ * Record a task assignment
55
+ *
56
+ * @param taskId - The task ID (todo ID or work item ID)
57
+ * @param from - The previous owner (or 'unassigned')
58
+ * @param to - The new owner
59
+ */
60
+ export function recordAssignment(taskId, from, to) {
61
+ cleanupOldRecords(taskId);
62
+ const records = recentAssignments.get(taskId) || [];
63
+ records.push({
64
+ from,
65
+ to,
66
+ timestamp: Date.now(),
67
+ });
68
+ recentAssignments.set(taskId, records);
69
+ }
70
+ /**
71
+ * Get assignment history for a task
72
+ *
73
+ * @param taskId - The task ID
74
+ * @returns Array of recent assignment records
75
+ */
76
+ export function getAssignmentHistory(taskId) {
77
+ cleanupOldRecords(taskId);
78
+ return [...(recentAssignments.get(taskId) || [])];
79
+ }
80
+ /**
81
+ * Clear assignment history for a task
82
+ * Call this when a task is completed or deleted
83
+ *
84
+ * @param taskId - The task ID
85
+ */
86
+ export function clearAssignmentHistory(taskId) {
87
+ recentAssignments.delete(taskId);
88
+ }
89
+ /**
90
+ * Clear all assignment history
91
+ * Useful for testing or session reset
92
+ */
93
+ export function clearAllAssignmentHistory() {
94
+ recentAssignments.clear();
95
+ }
96
+ /**
97
+ * Check if an agent can reassign a task
98
+ *
99
+ * Rules:
100
+ * - Owner can always reassign their own tasks
101
+ * - PM can reassign any task (coordinator role)
102
+ * - Unassigned tasks can be claimed by anyone
103
+ *
104
+ * @param currentOwner - Current owner of the task (or null for unassigned)
105
+ * @param requestingAgent - Agent trying to reassign
106
+ * @param isPm - Whether the requesting agent is PM/coordinator
107
+ * @returns true if the agent can reassign
108
+ */
109
+ export function canReassign(currentOwner, requestingAgent, isPm = false) {
110
+ // Unassigned tasks can be claimed by anyone
111
+ if (!currentOwner) {
112
+ return true;
113
+ }
114
+ // Owner can always reassign their own tasks
115
+ if (currentOwner === requestingAgent) {
116
+ return true;
117
+ }
118
+ // PM/coordinator can reassign any task
119
+ if (isPm) {
120
+ return true;
121
+ }
122
+ return false;
123
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Task Suggestion - Auto-suggest owner based on task content
3
+ *
4
+ * Uses keyword matching to suggest which agent should own a task.
5
+ * This is used as a hint when creating tasks without explicit owner.
6
+ */
7
+ /**
8
+ * Suggest an owner agent based on task content
9
+ *
10
+ * @param content - The task content/title to analyze
11
+ * @param availableAgents - List of available agent IDs in the team
12
+ * @returns Suggested agent ID, or undefined if no match
13
+ */
14
+ export declare function suggestOwner(content: string, availableAgents: string[]): string | undefined;
15
+ /**
16
+ * Get all agents that might be relevant for a task
17
+ * Returns multiple suggestions in priority order
18
+ *
19
+ * @param content - The task content/title to analyze
20
+ * @param availableAgents - List of available agent IDs in the team
21
+ * @returns Array of suggested agent IDs, in priority order
22
+ */
23
+ export declare function suggestOwners(content: string, availableAgents: string[]): string[];
24
+ /**
25
+ * Check if a task content strongly matches a specific agent's expertise
26
+ *
27
+ * @param content - The task content/title to analyze
28
+ * @param agentId - The agent ID to check
29
+ * @returns true if the content strongly matches the agent's expertise
30
+ */
31
+ export declare function matchesAgentExpertise(content: string, agentId: string): boolean;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Task Suggestion - Auto-suggest owner based on task content
3
+ *
4
+ * Uses keyword matching to suggest which agent should own a task.
5
+ * This is used as a hint when creating tasks without explicit owner.
6
+ */
7
+ /**
8
+ * Mapping of keywords to agent roles
9
+ */
10
+ const KEYWORD_TO_AGENT = [
11
+ // Architecture
12
+ { pattern: /\b(design|architect|api|schema|structure|pattern|trade-?off)\b/i, agent: 'arch' },
13
+ // Quality Assurance
14
+ {
15
+ pattern: /\b(test|qa|coverage|e2e|unit|integration|regression|bug|fix|validate)\b/i,
16
+ agent: 'qa',
17
+ },
18
+ // Development
19
+ { pattern: /\b(implement|code|refactor|debug|function|class|method|feature)\b/i, agent: 'dev' },
20
+ // Operations/DevOps
21
+ {
22
+ pattern: /\b(deploy|ci|cd|docker|infra|kubernetes|k8s|pipeline|release|build|monitor)\b/i,
23
+ agent: 'ops',
24
+ },
25
+ // Documentation
26
+ { pattern: /\b(document|readme|docs|tutorial|guide|explain|write up)\b/i, agent: 'docs' },
27
+ // Business Analysis
28
+ {
29
+ pattern: /\b(requirement|story|acceptance|criteria|stakeholder|user story|epic)\b/i,
30
+ agent: 'ba',
31
+ },
32
+ // Project Management
33
+ {
34
+ pattern: /\b(plan|track|coordinate|sprint|timeline|prioriti[zs]e|schedule|status)\b/i,
35
+ agent: 'pm',
36
+ },
37
+ ];
38
+ /**
39
+ * Suggest an owner agent based on task content
40
+ *
41
+ * @param content - The task content/title to analyze
42
+ * @param availableAgents - List of available agent IDs in the team
43
+ * @returns Suggested agent ID, or undefined if no match
44
+ */
45
+ export function suggestOwner(content, availableAgents) {
46
+ for (const { pattern, agent } of KEYWORD_TO_AGENT) {
47
+ if (pattern.test(content) && availableAgents.includes(agent)) {
48
+ return agent;
49
+ }
50
+ }
51
+ return undefined;
52
+ }
53
+ /**
54
+ * Get all agents that might be relevant for a task
55
+ * Returns multiple suggestions in priority order
56
+ *
57
+ * @param content - The task content/title to analyze
58
+ * @param availableAgents - List of available agent IDs in the team
59
+ * @returns Array of suggested agent IDs, in priority order
60
+ */
61
+ export function suggestOwners(content, availableAgents) {
62
+ const suggestions = [];
63
+ for (const { pattern, agent } of KEYWORD_TO_AGENT) {
64
+ if (pattern.test(content) && availableAgents.includes(agent) && !suggestions.includes(agent)) {
65
+ suggestions.push(agent);
66
+ }
67
+ }
68
+ return suggestions;
69
+ }
70
+ /**
71
+ * Check if a task content strongly matches a specific agent's expertise
72
+ *
73
+ * @param content - The task content/title to analyze
74
+ * @param agentId - The agent ID to check
75
+ * @returns true if the content strongly matches the agent's expertise
76
+ */
77
+ export function matchesAgentExpertise(content, agentId) {
78
+ for (const { pattern, agent } of KEYWORD_TO_AGENT) {
79
+ if (agent === agentId && pattern.test(content)) {
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }