@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.
- package/dist/index.d.ts +6 -2
- package/dist/index.js +27 -1
- package/dist/meta-tools/registry.js +4 -2
- package/dist/team/activity.d.ts +21 -0
- package/dist/team/activity.js +34 -0
- package/dist/team/agent-selection.d.ts +53 -0
- package/dist/team/agent-selection.js +88 -0
- package/dist/team/artifacts.d.ts +175 -0
- package/dist/team/artifacts.js +279 -0
- package/dist/team/collision-utils.d.ts +16 -0
- package/dist/team/collision-utils.js +28 -0
- package/dist/team/context-resolver.d.ts +97 -0
- package/dist/team/context-resolver.js +322 -0
- package/dist/team/custom-agents.d.ts +68 -0
- package/dist/team/custom-agents.js +150 -0
- package/dist/team/delegation-tracker.d.ts +147 -0
- package/dist/team/delegation-tracker.js +215 -0
- package/dist/team/index.d.ts +34 -0
- package/dist/team/index.js +30 -0
- package/dist/team/interfaces.d.ts +36 -0
- package/dist/team/interfaces.js +7 -0
- package/dist/team/mention-parser.d.ts +64 -0
- package/dist/team/mention-parser.js +138 -0
- package/dist/team/shared-context.d.ts +293 -0
- package/dist/team/shared-context.js +673 -0
- package/dist/team/skill-requirements.d.ts +66 -0
- package/dist/team/skill-requirements.js +178 -0
- package/dist/team/task-assignment.d.ts +69 -0
- package/dist/team/task-assignment.js +123 -0
- package/dist/team/task-suggestion.d.ts +31 -0
- package/dist/team/task-suggestion.js +84 -0
- package/dist/team/team-agent.d.ts +201 -0
- package/dist/team/team-agent.js +492 -0
- package/dist/team/team.d.ts +297 -0
- package/dist/team/team.js +615 -0
- package/dist/team/tool-config.d.ts +110 -0
- package/dist/team/tool-config.js +739 -0
- package/dist/team/types.d.ts +211 -0
- package/dist/team/types.js +638 -0
- 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
|
+
}
|