@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,739 @@
1
+ /**
2
+ * Tool Configuration for Custom Agents
3
+ *
4
+ * Defines tool groups, profiles, and helpers for configuring
5
+ * which tools a custom agent can access.
6
+ *
7
+ * Tool names are defined as string constants below. These cover all tools
8
+ * from @compilr-dev/agents, @compilr-dev/agents-coding, and platform tools.
9
+ */
10
+ import { TOOL_NAMES as BASE_TOOL_NAMES } from '@compilr-dev/agents';
11
+ /**
12
+ * Extended tool names covering all tools across the ecosystem.
13
+ * Base tools from @compilr-dev/agents, plus coding, platform, and team tools.
14
+ */
15
+ const TOOL_NAMES = {
16
+ // Base tools (from @compilr-dev/agents)
17
+ ...BASE_TOOL_NAMES,
18
+ // Task ownership
19
+ TODO_CLAIM: 'todo_claim',
20
+ TODO_HANDOFF: 'todo_handoff',
21
+ // User interaction
22
+ ASK_USER: 'ask_user',
23
+ ASK_USER_SIMPLE: 'ask_user_simple',
24
+ // Delegation
25
+ DELEGATE: 'delegate',
26
+ DELEGATE_BACKGROUND: 'delegate_background',
27
+ DELEGATION_STATUS: 'delegation_status',
28
+ HANDOFF: 'handoff',
29
+ // CLI guide
30
+ COMPILR_GUIDE: 'compilr_guide',
31
+ // Meta-tools
32
+ LIST_TOOLS: 'list_tools',
33
+ GET_TOOL_INFO: 'get_tool_info',
34
+ USE_TOOL: 'use_tool',
35
+ // Git tools (from @compilr-dev/agents-coding)
36
+ GIT_STATUS: 'git_status',
37
+ GIT_DIFF: 'git_diff',
38
+ GIT_LOG: 'git_log',
39
+ GIT_BLAME: 'git_blame',
40
+ GIT_FILE_HISTORY: 'git_file_history',
41
+ GIT_COMMIT: 'git_commit',
42
+ GIT_BRANCH: 'git_branch',
43
+ GIT_STASH: 'git_stash',
44
+ // Project analysis
45
+ DETECT_PROJECT: 'detect_project',
46
+ FIND_PROJECT_ROOT: 'find_project_root',
47
+ GET_FILE_STRUCTURE: 'get_file_structure',
48
+ GET_COMPLEXITY: 'get_complexity',
49
+ READ_FUNCTION: 'read_function',
50
+ READ_CLASS: 'read_class',
51
+ READ_TYPE: 'read_type',
52
+ // Runners
53
+ RUN_TESTS: 'run_tests',
54
+ RUN_LINT: 'run_lint',
55
+ RUN_BUILD: 'run_build',
56
+ RUN_FORMAT: 'run_format',
57
+ // Code search
58
+ FIND_DEFINITION: 'find_definition',
59
+ FIND_REFERENCES: 'find_references',
60
+ FIND_TODOS: 'find_todos',
61
+ // Dependencies
62
+ CHECK_OUTDATED: 'check_outdated',
63
+ FIND_VULNERABILITIES: 'find_vulnerabilities',
64
+ ANALYZE_TEST_COVERAGE: 'analyze_test_coverage',
65
+ // Backlog / work items
66
+ WORKITEM_QUERY: 'workitem_query',
67
+ WORKITEM_STATUS_COUNTS: 'workitem_status_counts',
68
+ WORKITEM_ADD: 'workitem_add',
69
+ WORKITEM_UPDATE: 'workitem_update',
70
+ WORKITEM_DELETE: 'workitem_delete',
71
+ WORKITEM_NEXT: 'workitem_next',
72
+ WORKITEM_ADVANCE_STEP: 'workitem_advance_step',
73
+ WORKITEM_CLAIM: 'workitem_claim',
74
+ WORKITEM_HANDOFF: 'workitem_handoff',
75
+ // Documents
76
+ PROJECT_DOCUMENT_ADD: 'document_save',
77
+ PROJECT_DOCUMENT_GET: 'document_get',
78
+ PROJECT_DOCUMENT_LIST: 'document_list',
79
+ PROJECT_DOCUMENT_DELETE: 'document_delete',
80
+ // Plans
81
+ PLAN_CREATE: 'plan_create',
82
+ PLAN_UPDATE: 'plan_update',
83
+ PLAN_GET: 'plan_get',
84
+ PLAN_LIST: 'plan_list',
85
+ PLAN_DELETE: 'plan_delete',
86
+ // Artifacts
87
+ ARTIFACT_SAVE: 'artifact_save',
88
+ ARTIFACT_GET: 'artifact_get',
89
+ ARTIFACT_LIST: 'artifact_list',
90
+ ARTIFACT_DELETE: 'artifact_delete',
91
+ // Anchors
92
+ ANCHOR_ADD: 'anchor_add',
93
+ ANCHOR_LIST: 'anchor_list',
94
+ ANCHOR_REMOVE: 'anchor_remove',
95
+ // Project DB
96
+ PROJECT_GET: 'project_get',
97
+ PROJECT_LIST: 'project_list',
98
+ PROJECT_UPDATE: 'project_update',
99
+ };
100
+ // =============================================================================
101
+ // Tool Groups
102
+ // =============================================================================
103
+ /**
104
+ * All tool groups organized by functionality.
105
+ * These cover all ~50 tools in the CLI.
106
+ *
107
+ * Tool names use TOOL_NAMES constants for consistency.
108
+ */
109
+ export const TOOL_GROUPS = {
110
+ // ============= DIRECT TOOLS (15) =============
111
+ file_read: {
112
+ label: 'File Reading',
113
+ tools: [TOOL_NAMES.READ_FILE, TOOL_NAMES.GLOB, TOOL_NAMES.GREP],
114
+ readOnly: true,
115
+ tier: 'direct',
116
+ },
117
+ file_write: {
118
+ label: 'File Writing',
119
+ tools: [TOOL_NAMES.WRITE_FILE, TOOL_NAMES.EDIT],
120
+ readOnly: false,
121
+ tier: 'direct',
122
+ },
123
+ shell: {
124
+ label: 'Shell Commands',
125
+ tools: [TOOL_NAMES.BASH, TOOL_NAMES.BASH_OUTPUT, TOOL_NAMES.KILL_SHELL],
126
+ readOnly: false,
127
+ tier: 'direct',
128
+ },
129
+ tasks: {
130
+ label: 'Task Tracking',
131
+ tools: [
132
+ TOOL_NAMES.TODO_WRITE,
133
+ TOOL_NAMES.TODO_READ,
134
+ TOOL_NAMES.TODO_CLAIM,
135
+ TOOL_NAMES.TODO_HANDOFF,
136
+ ],
137
+ readOnly: false,
138
+ tier: 'direct',
139
+ },
140
+ interaction: {
141
+ label: 'User Interaction',
142
+ tools: [TOOL_NAMES.ASK_USER, TOOL_NAMES.ASK_USER_SIMPLE, TOOL_NAMES.SUGGEST],
143
+ readOnly: true,
144
+ tier: 'direct',
145
+ },
146
+ coordinator: {
147
+ label: 'Coordination',
148
+ tools: [TOOL_NAMES.DELEGATE, TOOL_NAMES.DELEGATE_BACKGROUND, TOOL_NAMES.DELEGATION_STATUS],
149
+ readOnly: false,
150
+ tier: 'direct',
151
+ note: 'Coordinator-only: delegation to specialists (foreground, background, status query)',
152
+ },
153
+ handoff: {
154
+ label: 'Agent Handoff',
155
+ tools: [TOOL_NAMES.HANDOFF],
156
+ readOnly: false,
157
+ tier: 'direct',
158
+ note: 'Hand off current task to another specialist or coordinator',
159
+ },
160
+ guide: {
161
+ label: 'CLI Documentation',
162
+ tools: [TOOL_NAMES.COMPILR_GUIDE],
163
+ readOnly: true,
164
+ tier: 'direct',
165
+ note: 'Always available: helps agents answer CLI questions',
166
+ },
167
+ meta: {
168
+ label: 'Tool Discovery',
169
+ tools: [TOOL_NAMES.LIST_TOOLS, TOOL_NAMES.GET_TOOL_INFO, TOOL_NAMES.USE_TOOL],
170
+ readOnly: true, // Meta-tools themselves are read-only
171
+ tier: 'direct',
172
+ note: 'Required for accessing meta-registry tools',
173
+ },
174
+ // ============= META-REGISTRY TOOLS (34+) =============
175
+ // Accessed via use_tool("name", args)
176
+ git_read: {
177
+ label: 'Git (Read)',
178
+ tools: [
179
+ TOOL_NAMES.GIT_STATUS,
180
+ TOOL_NAMES.GIT_DIFF,
181
+ TOOL_NAMES.GIT_LOG,
182
+ TOOL_NAMES.GIT_BLAME,
183
+ TOOL_NAMES.GIT_FILE_HISTORY,
184
+ ],
185
+ readOnly: true,
186
+ tier: 'meta',
187
+ },
188
+ git_write: {
189
+ label: 'Git (Write)',
190
+ tools: [TOOL_NAMES.GIT_COMMIT, TOOL_NAMES.GIT_BRANCH, TOOL_NAMES.GIT_STASH],
191
+ readOnly: false,
192
+ tier: 'meta',
193
+ },
194
+ project: {
195
+ label: 'Project Analysis',
196
+ tools: [
197
+ TOOL_NAMES.DETECT_PROJECT,
198
+ TOOL_NAMES.FIND_PROJECT_ROOT,
199
+ TOOL_NAMES.GET_FILE_STRUCTURE,
200
+ TOOL_NAMES.GET_COMPLEXITY,
201
+ TOOL_NAMES.READ_FUNCTION,
202
+ TOOL_NAMES.READ_CLASS,
203
+ TOOL_NAMES.READ_TYPE,
204
+ ],
205
+ readOnly: true,
206
+ tier: 'meta',
207
+ note: 'Includes smart file reading (read_function, read_class, read_type)',
208
+ },
209
+ runners: {
210
+ label: 'Runners (Test/Build/Lint)',
211
+ tools: [TOOL_NAMES.RUN_TESTS, TOOL_NAMES.RUN_LINT, TOOL_NAMES.RUN_BUILD, TOOL_NAMES.RUN_FORMAT],
212
+ readOnly: false, // Can have side effects
213
+ tier: 'meta',
214
+ },
215
+ search: {
216
+ label: 'Code Search',
217
+ tools: [TOOL_NAMES.FIND_DEFINITION, TOOL_NAMES.FIND_REFERENCES, TOOL_NAMES.FIND_TODOS],
218
+ readOnly: true,
219
+ tier: 'meta',
220
+ },
221
+ dependencies: {
222
+ label: 'Dependency Analysis',
223
+ tools: [
224
+ TOOL_NAMES.CHECK_OUTDATED,
225
+ TOOL_NAMES.FIND_VULNERABILITIES,
226
+ TOOL_NAMES.ANALYZE_TEST_COVERAGE,
227
+ ],
228
+ readOnly: true,
229
+ tier: 'meta',
230
+ },
231
+ backlog_read: {
232
+ label: 'Backlog (Read)',
233
+ tools: [TOOL_NAMES.WORKITEM_QUERY, TOOL_NAMES.WORKITEM_STATUS_COUNTS],
234
+ readOnly: true,
235
+ tier: 'meta',
236
+ },
237
+ backlog_write: {
238
+ label: 'Backlog (Write)',
239
+ tools: [
240
+ TOOL_NAMES.WORKITEM_ADD,
241
+ TOOL_NAMES.WORKITEM_UPDATE,
242
+ TOOL_NAMES.WORKITEM_DELETE,
243
+ TOOL_NAMES.WORKITEM_NEXT,
244
+ TOOL_NAMES.WORKITEM_ADVANCE_STEP,
245
+ TOOL_NAMES.WORKITEM_CLAIM,
246
+ TOOL_NAMES.WORKITEM_HANDOFF,
247
+ ],
248
+ readOnly: false,
249
+ tier: 'meta',
250
+ },
251
+ documents: {
252
+ label: 'Project Documents',
253
+ tools: [
254
+ TOOL_NAMES.PROJECT_DOCUMENT_ADD,
255
+ TOOL_NAMES.PROJECT_DOCUMENT_GET,
256
+ TOOL_NAMES.PROJECT_DOCUMENT_LIST,
257
+ TOOL_NAMES.PROJECT_DOCUMENT_DELETE,
258
+ ],
259
+ readOnly: false,
260
+ tier: 'meta',
261
+ },
262
+ plans: {
263
+ label: 'Planning',
264
+ tools: [
265
+ TOOL_NAMES.PLAN_CREATE,
266
+ TOOL_NAMES.PLAN_UPDATE,
267
+ TOOL_NAMES.PLAN_GET,
268
+ TOOL_NAMES.PLAN_LIST,
269
+ TOOL_NAMES.PLAN_DELETE,
270
+ ],
271
+ readOnly: false,
272
+ tier: 'meta',
273
+ },
274
+ artifacts: {
275
+ label: 'Team Artifacts',
276
+ tools: [
277
+ TOOL_NAMES.ARTIFACT_SAVE,
278
+ TOOL_NAMES.ARTIFACT_GET,
279
+ TOOL_NAMES.ARTIFACT_LIST,
280
+ TOOL_NAMES.ARTIFACT_DELETE,
281
+ ],
282
+ readOnly: false,
283
+ tier: 'meta',
284
+ },
285
+ anchors: {
286
+ label: 'Context Anchors',
287
+ tools: [TOOL_NAMES.ANCHOR_ADD, TOOL_NAMES.ANCHOR_LIST, TOOL_NAMES.ANCHOR_REMOVE],
288
+ readOnly: false,
289
+ tier: 'meta',
290
+ },
291
+ project_db: {
292
+ label: 'Project Database',
293
+ tools: [TOOL_NAMES.PROJECT_GET, TOOL_NAMES.PROJECT_LIST, TOOL_NAMES.PROJECT_UPDATE],
294
+ readOnly: false,
295
+ tier: 'meta',
296
+ note: 'Project metadata management',
297
+ },
298
+ subagents: {
299
+ label: 'Subagent Delegation',
300
+ tools: [TOOL_NAMES.TASK],
301
+ readOnly: false,
302
+ tier: 'direct',
303
+ note: 'Delegate tasks to specialized subagents',
304
+ },
305
+ };
306
+ // =============================================================================
307
+ // Tool Profiles
308
+ // =============================================================================
309
+ /**
310
+ * Predefined tool profiles mapping profile name to included groups.
311
+ */
312
+ export const TOOL_PROFILES = {
313
+ // Full access - all groups
314
+ full: Object.keys(TOOL_GROUPS),
315
+ // Read-only - safe exploration
316
+ 'read-only': [
317
+ 'file_read',
318
+ 'interaction',
319
+ 'guide',
320
+ 'meta',
321
+ 'git_read',
322
+ 'project',
323
+ 'search',
324
+ 'dependencies',
325
+ 'backlog_read',
326
+ ],
327
+ // Developer - coding tasks
328
+ developer: [
329
+ 'file_read',
330
+ 'file_write',
331
+ 'shell',
332
+ 'tasks',
333
+ 'interaction',
334
+ 'handoff',
335
+ 'guide',
336
+ 'subagents',
337
+ 'meta',
338
+ 'git_read',
339
+ 'git_write',
340
+ 'project',
341
+ 'project_db',
342
+ 'runners',
343
+ 'search',
344
+ 'backlog_read',
345
+ 'backlog_write',
346
+ 'documents',
347
+ 'plans',
348
+ 'artifacts',
349
+ 'anchors',
350
+ ],
351
+ // Security - security audits
352
+ security: [
353
+ 'file_read',
354
+ 'shell',
355
+ 'interaction',
356
+ 'handoff',
357
+ 'guide',
358
+ 'meta',
359
+ 'git_read',
360
+ 'project',
361
+ 'search',
362
+ 'dependencies',
363
+ ],
364
+ // Docs - documentation only
365
+ docs: ['file_read', 'file_write', 'interaction', 'handoff', 'guide', 'meta', 'project', 'search'],
366
+ // DevOps - CI/CD tasks
367
+ devops: [
368
+ 'file_read',
369
+ 'file_write',
370
+ 'shell',
371
+ 'tasks',
372
+ 'interaction',
373
+ 'handoff',
374
+ 'guide',
375
+ 'meta',
376
+ 'git_read',
377
+ 'git_write',
378
+ 'project',
379
+ 'project_db',
380
+ 'runners',
381
+ 'dependencies',
382
+ ],
383
+ // QA - testing
384
+ qa: [
385
+ 'file_read',
386
+ 'shell',
387
+ 'tasks',
388
+ 'interaction',
389
+ 'handoff',
390
+ 'guide',
391
+ 'meta',
392
+ 'git_read',
393
+ 'project',
394
+ 'runners',
395
+ 'search',
396
+ 'dependencies',
397
+ ],
398
+ // Architect - design and analysis (no direct implementation)
399
+ architect: [
400
+ 'file_read',
401
+ 'tasks',
402
+ 'interaction',
403
+ 'handoff',
404
+ 'guide',
405
+ 'meta',
406
+ 'git_read',
407
+ 'project',
408
+ 'search',
409
+ 'dependencies',
410
+ 'backlog_read',
411
+ 'documents',
412
+ 'plans',
413
+ 'artifacts',
414
+ 'anchors',
415
+ ],
416
+ // Planner (PM) - project management (no code modification)
417
+ planner: [
418
+ 'file_read',
419
+ 'tasks',
420
+ 'interaction',
421
+ 'handoff',
422
+ 'guide',
423
+ 'meta',
424
+ 'git_read',
425
+ 'project',
426
+ 'project_db',
427
+ 'backlog_read',
428
+ 'backlog_write',
429
+ 'documents',
430
+ 'plans',
431
+ 'artifacts',
432
+ 'anchors',
433
+ ],
434
+ // Analyst (BA) - requirements gathering (minimal technical tools)
435
+ analyst: [
436
+ 'file_read',
437
+ 'tasks',
438
+ 'interaction',
439
+ 'handoff',
440
+ 'guide',
441
+ 'meta',
442
+ 'project',
443
+ 'backlog_read',
444
+ 'backlog_write',
445
+ 'documents',
446
+ 'artifacts',
447
+ 'anchors',
448
+ ],
449
+ // Custom - user selected (groups specified in customGroups)
450
+ custom: [],
451
+ };
452
+ export const PROFILE_INFO = {
453
+ full: {
454
+ label: 'Full Access',
455
+ description: 'All tools available (default)',
456
+ isReadOnly: false,
457
+ },
458
+ 'read-only': {
459
+ label: 'Read Only',
460
+ description: 'Safe exploration - no file writes or destructive ops',
461
+ isReadOnly: true,
462
+ },
463
+ developer: {
464
+ label: 'Developer',
465
+ description: 'Full coding capabilities without destructive git ops',
466
+ isReadOnly: false,
467
+ },
468
+ security: {
469
+ label: 'Security Reviewer',
470
+ description: 'Security audits - read files, run analysis tools',
471
+ isReadOnly: true,
472
+ },
473
+ docs: {
474
+ label: 'Documentation',
475
+ description: 'Read and write documentation files',
476
+ isReadOnly: false,
477
+ },
478
+ devops: {
479
+ label: 'DevOps',
480
+ description: 'CI/CD tasks - runners, git, shell',
481
+ isReadOnly: false,
482
+ },
483
+ qa: {
484
+ label: 'QA / Testing',
485
+ description: 'Testing tasks - read code, run tests, analyze coverage',
486
+ isReadOnly: true,
487
+ },
488
+ architect: {
489
+ label: 'Architect',
490
+ description: 'Design and analysis - read code, create artifacts, no direct edits',
491
+ isReadOnly: true,
492
+ },
493
+ planner: {
494
+ label: 'Planner',
495
+ description: 'Project management - backlog, documents, no code modification',
496
+ isReadOnly: true,
497
+ },
498
+ analyst: {
499
+ label: 'Analyst',
500
+ description: 'Requirements gathering - user stories, documents, business analysis',
501
+ isReadOnly: true,
502
+ },
503
+ custom: {
504
+ label: 'Custom',
505
+ description: 'Select tool groups manually',
506
+ isReadOnly: false,
507
+ },
508
+ };
509
+ // =============================================================================
510
+ // Helper Functions
511
+ // =============================================================================
512
+ /**
513
+ * Get all tool names for a given profile.
514
+ *
515
+ * @param profile - The tool profile
516
+ * @param customGroups - Custom groups (when profile is 'custom')
517
+ * @returns Array of tool names
518
+ */
519
+ export function getToolsForProfile(profile, customGroups) {
520
+ const groups = profile === 'custom' ? (customGroups ?? []) : TOOL_PROFILES[profile];
521
+ const tools = [];
522
+ for (const groupId of groups) {
523
+ if (groupId in TOOL_GROUPS) {
524
+ tools.push(...TOOL_GROUPS[groupId].tools);
525
+ }
526
+ }
527
+ return [...new Set(tools)]; // Deduplicate
528
+ }
529
+ /**
530
+ * Get all group IDs for a profile.
531
+ */
532
+ export function getGroupsForProfile(profile) {
533
+ return TOOL_PROFILES[profile];
534
+ }
535
+ /**
536
+ * Get the profile that best matches a set of tools.
537
+ * Used for displaying current config in UI.
538
+ */
539
+ export function detectProfileFromTools(tools) {
540
+ const toolSet = new Set(tools);
541
+ const allTools = getToolsForProfile('full');
542
+ // Full access if all tools included
543
+ if (allTools.every((t) => toolSet.has(t))) {
544
+ return 'full';
545
+ }
546
+ // Check each profile
547
+ for (const profile of Object.keys(TOOL_PROFILES)) {
548
+ if (profile === 'full' || profile === 'custom')
549
+ continue;
550
+ const profileTools = getToolsForProfile(profile);
551
+ if (profileTools.length === tools.length && profileTools.every((t) => toolSet.has(t))) {
552
+ return profile;
553
+ }
554
+ }
555
+ return 'custom';
556
+ }
557
+ /**
558
+ * Check if a profile only includes read-only groups.
559
+ */
560
+ export function isProfileReadOnly(profile, customGroups) {
561
+ const groups = profile === 'custom' ? (customGroups ?? []) : TOOL_PROFILES[profile];
562
+ return groups.every((groupId) => {
563
+ if (!(groupId in TOOL_GROUPS)) {
564
+ return true; // Unknown group treated as read-only
565
+ }
566
+ return TOOL_GROUPS[groupId].readOnly;
567
+ });
568
+ }
569
+ /**
570
+ * Get all available group IDs.
571
+ */
572
+ export function getAllGroupIds() {
573
+ return Object.keys(TOOL_GROUPS);
574
+ }
575
+ /**
576
+ * Get group info by ID.
577
+ */
578
+ export function getGroupInfo(groupId) {
579
+ return TOOL_GROUPS[groupId];
580
+ }
581
+ /**
582
+ * Get groups organized by tier.
583
+ */
584
+ export function getGroupsByTier() {
585
+ const direct = [];
586
+ const meta = [];
587
+ for (const [id, group] of Object.entries(TOOL_GROUPS)) {
588
+ if (group.tier === 'direct') {
589
+ direct.push(id);
590
+ }
591
+ else {
592
+ meta.push(id);
593
+ }
594
+ }
595
+ return { direct, meta };
596
+ }
597
+ /**
598
+ * Create a default tool config (full access).
599
+ */
600
+ export function createDefaultToolConfig() {
601
+ return {
602
+ profile: 'full',
603
+ };
604
+ }
605
+ /**
606
+ * Validate a tool config.
607
+ */
608
+ export function validateToolConfig(config) {
609
+ if (!config.profile) {
610
+ return { valid: false, error: 'Profile is required' };
611
+ }
612
+ if (!(config.profile in TOOL_PROFILES)) {
613
+ return { valid: false, error: `Unknown profile: ${config.profile}` };
614
+ }
615
+ if (config.profile === 'custom' && (!config.customGroups || config.customGroups.length === 0)) {
616
+ return { valid: false, error: 'Custom profile requires at least one group' };
617
+ }
618
+ if (config.customGroups) {
619
+ for (const groupId of config.customGroups) {
620
+ if (!(groupId in TOOL_GROUPS)) {
621
+ return { valid: false, error: `Unknown group: ${groupId}` };
622
+ }
623
+ }
624
+ }
625
+ return { valid: true };
626
+ }
627
+ /**
628
+ * Generate self-awareness text for system prompt.
629
+ * Tells the agent about its tool limitations.
630
+ */
631
+ export function generateToolAwarenessPrompt(config) {
632
+ const profile = config.profile;
633
+ const profileInfo = PROFILE_INFO[profile];
634
+ const groups = profile === 'custom' ? (config.customGroups ?? []) : TOOL_PROFILES[profile];
635
+ const isReadOnly = config.readOnly || isProfileReadOnly(profile, config.customGroups);
636
+ const lines = [
637
+ '## Your Capabilities',
638
+ '',
639
+ `You are configured with the "${profileInfo.label}" tool profile.`,
640
+ `Available tool groups: ${groups.join(', ')}`,
641
+ '',
642
+ ];
643
+ if (isReadOnly) {
644
+ lines.push('**You have READ-ONLY access.** You cannot modify files directly.');
645
+ lines.push('');
646
+ }
647
+ // Add specific limitations based on profile
648
+ const allGroups = getAllGroupIds();
649
+ const missingGroups = allGroups.filter((g) => !groups.includes(g));
650
+ if (missingGroups.length > 0 && missingGroups.length < allGroups.length / 2) {
651
+ lines.push('## Tool Limitations');
652
+ lines.push('');
653
+ lines.push('The following capabilities are NOT available to you:');
654
+ for (const groupId of missingGroups) {
655
+ // groupId is guaranteed to exist (from getAllGroupIds)
656
+ const group = TOOL_GROUPS[groupId];
657
+ lines.push(`- ${group.label}: ${group.tools.join(', ')}`);
658
+ }
659
+ lines.push('');
660
+ }
661
+ lines.push('## When You Cannot Help');
662
+ lines.push('');
663
+ lines.push('If a user requests something outside your capabilities:');
664
+ lines.push('1. Acknowledge what they want to do');
665
+ lines.push('2. Explain your tool limitations');
666
+ lines.push('3. Suggest which team agent can help (e.g., "Try $dev for code modifications")');
667
+ return lines.join('\n');
668
+ }
669
+ /**
670
+ * Generate delegation guidance for the coordinator.
671
+ * Explains how to use the delegate tool effectively.
672
+ */
673
+ export function generateCoordinatorGuidance() {
674
+ return `## Task Delegation
675
+
676
+ As the coordinator, you have two delegation tools:
677
+
678
+ ### \`delegate\` (Foreground)
679
+ Switches the active agent to a specialist. The user interacts directly with the specialist.
680
+ - Use when the user should work directly with the specialist
681
+ - Requires user approval before switching
682
+
683
+ ### \`delegate_background\` (Background — Coordinator Mode)
684
+ Runs a specialist in background while you stay in the foreground.
685
+ - Use when orchestrating multiple tasks across specialists
686
+ - Specialists work independently; you're notified on completion
687
+ - Can delegate to multiple specialists in parallel
688
+ - Associate delegations with todos via \`todoIndex\` for plan tracking
689
+
690
+ ### Choosing the Right Specialist
691
+ Look at the **Your Team** roster in the shared context above. Each agent has:
692
+ - A **role** (e.g., Developer, Architect, QA)
693
+ - An **expertise** list (e.g., "system design, API design")
694
+
695
+ Match the task to the agent whose expertise best fits. For example:
696
+ - Architecture/design tasks → agent with design/architecture expertise
697
+ - Implementation/coding → agent with development/debugging expertise
698
+ - Testing/quality review → agent with testing/QA expertise
699
+ - Planning/requirements → agent with planning/coordination expertise
700
+
701
+ If no specialist matches well, handle the task yourself rather than delegating poorly.
702
+
703
+ ### Todo Ownership
704
+ When creating todos (via todo_write), ALWAYS assign an owner:
705
+ - Use your own agent ID ("default") for tasks you will handle yourself
706
+ - Use the specialist's agent ID for tasks you plan to delegate to them
707
+ - Never leave todos unassigned — unassigned todos confuse specialists who may try to work on them
708
+
709
+ ### Guidelines
710
+ - Break complex tasks into clear, independent sub-tasks
711
+ - Delegate sub-tasks to the most appropriate specialist based on their expertise
712
+ - Each delegation should have a clear expected output
713
+ - For sequential work, wait for completion before chaining the next delegation
714
+ - For parallel work, delegate multiple tasks simultaneously`;
715
+ }
716
+ /**
717
+ * Generate delegation suggestion guidance for specialists.
718
+ * Explains how to suggest other specialists when appropriate.
719
+ */
720
+ export function generateSpecialistGuidance(role) {
721
+ return `## Collaborating with Team
722
+
723
+ You are a specialist focused on ${role}-related tasks.
724
+
725
+ When a request is outside your expertise or could benefit from another specialist:
726
+ 1. Use the \`handoff\` tool to transfer the task to the right specialist
727
+ 2. Provide a clear task description and reason for the handoff
728
+ 3. The user will be asked to approve the handoff before switching
729
+
730
+ Examples:
731
+ - Architecture questions → handoff to $arch
732
+ - Implementation tasks → handoff to $dev
733
+ - Testing strategy → handoff to $qa
734
+
735
+ Note: If you were handed this task by another agent, you cannot re-hand it off
736
+ (except back to the coordinator). Complete the task or return it.
737
+
738
+ Focus on what you do best - don't try to do everything yourself.`;
739
+ }