Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/agents/capabilities/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Capability-centric architecture for agent tool management.
*
* Core principle: Integrations provide capabilities. Capabilities provide tools.
*
* ```
* Integration Category → Capabilities → Gadgets/Tools
* │ │ │
* pm → pm:read → ReadWorkItem, ListWorkItems
* pm:write → CreateWorkItem, UpdateWorkItem, PostComment
* pm:checklist → PMUpdateChecklistItem, PMDeleteChecklistItem
*
* scm → scm:read → GetPRDetails, GetPRDiff, GetPRChecks
* scm:comment → PostPRComment, UpdatePRComment
* scm:review → CreatePRReview
* scm:pr → CreatePR
*
* (built-in) → fs:read → ReadFile, ListDirectory, RipGrep, AstGrep
* fs:write → WriteFile, FileSearchAndReplace, FileMultiEdit
* shell:exec → Tmux, Sleep
* session:ctrl → Finish, TodoUpsert/Update/Delete
* ```
*/

// Registry
export {
CAPABILITIES,
CAPABILITY_REGISTRY,
type Capability,
type CapabilityDefinition,
getCapabilitiesByIntegration,
getCapabilityIntegration,
isBuiltInCapability,
isValidCapability,
} from './registry.js';

// Resolver
export {
buildGadgetsFromCapabilities,
createIntegrationChecker,
deriveIntegrations,
deriveRequiredIntegrations,
filterToolManifests,
generateUnavailableCapabilitiesNote,
getGadgetNamesFromCapabilities,
getSdkToolsFromCapabilities,
getUnavailableOptionalCapabilities,
type IntegrationChecker,
resolveEffectiveCapabilities,
} from './resolver.js';
260 changes: 260 additions & 0 deletions src/agents/capabilities/registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
/**
* Capability Registry
*
* Defines the mapping from capabilities to their source integrations,
* gadgets, SDK tools, and CLI tools.
*
* Core principle: Integrations provide capabilities. Capabilities provide tools.
*
* Integration Category → Capabilities → Gadgets/Tools
*/

import type { IntegrationCategory } from '../definitions/schema.js';

// ============================================================================
// Capability Types
// ============================================================================

/**
* All available capabilities in the system.
*
* Format: {source}:{action}
* - Built-in sources: fs (filesystem), shell, session
* - Integration sources: pm, scm, email, sms
*/
export const CAPABILITIES = [
// Built-in capabilities (always available, no integration required)
'fs:read',
'fs:write',
'shell:exec',
'session:ctrl',

// PM integration capabilities
'pm:read',
'pm:write',
'pm:checklist',

// SCM integration capabilities
'scm:read',
'scm:comment',
'scm:review',
'scm:pr',

// Email integration capabilities
'email:read',
'email:write',

// SMS integration capabilities
'sms:send',
] as const;

export type Capability = (typeof CAPABILITIES)[number];

/**
* Capability definition describing what a capability provides.
*/
export interface CapabilityDefinition {
/** Integration category that provides this capability (null = built-in) */
integration: IntegrationCategory | null;
/** Description for UI display */
description: string;
/** Gadget class names this capability enables */
gadgetNames: string[];
/** SDK tool names for Claude Code backend */
sdkToolNames: string[];
/** CLI tool commands for cascade-tools (currently unused but reserved) */
cliToolNames: string[];
}

// ============================================================================
// Capability Registry
// ============================================================================

/**
* Registry mapping capabilities to their definitions.
*
* This is the single source of truth for capability → tool mappings.
*/
export const CAPABILITY_REGISTRY: Record<Capability, CapabilityDefinition> = {
// -------------------------------------------------------------------------
// Built-in capabilities (always available)
// -------------------------------------------------------------------------

'fs:read': {
integration: null,
description: 'Read files, list directories, search code',
gadgetNames: ['ListDirectory', 'ReadFile', 'RipGrep', 'AstGrep'],
sdkToolNames: ['Read', 'Glob', 'Grep'],
cliToolNames: [],
},

'fs:write': {
integration: null,
description: 'Write and edit files',
gadgetNames: ['WriteFile', 'FileSearchAndReplace', 'FileMultiEdit', 'VerifyChanges'],
sdkToolNames: ['Write', 'Edit'],
cliToolNames: [],
},

'shell:exec': {
integration: null,
description: 'Execute shell commands',
gadgetNames: ['Tmux', 'Sleep'],
sdkToolNames: ['Bash'],
cliToolNames: [],
},

'session:ctrl': {
integration: null,
description: 'Session control and task tracking',
gadgetNames: ['Finish', 'TodoUpsert', 'TodoUpdateStatus', 'TodoDelete'],
sdkToolNames: [],
cliToolNames: [],
},

// -------------------------------------------------------------------------
// PM integration capabilities
// -------------------------------------------------------------------------

'pm:read': {
integration: 'pm',
description: 'Read work items from PM system',
gadgetNames: ['ReadWorkItem', 'ListWorkItems'],
sdkToolNames: [],
cliToolNames: [],
},

'pm:write': {
integration: 'pm',
description: 'Create and update work items, post comments',
gadgetNames: ['UpdateWorkItem', 'CreateWorkItem', 'PostComment', 'AddChecklist'],
sdkToolNames: [],
cliToolNames: [],
},

'pm:checklist': {
integration: 'pm',
description: 'Update and delete checklist items',
gadgetNames: ['PMUpdateChecklistItem', 'PMDeleteChecklistItem'],
sdkToolNames: [],
cliToolNames: [],
},

// -------------------------------------------------------------------------
// SCM integration capabilities
// -------------------------------------------------------------------------

'scm:read': {
integration: 'scm',
description: 'Read PR details, diffs, and checks',
gadgetNames: ['GetPRDetails', 'GetPRDiff', 'GetPRChecks'],
sdkToolNames: [],
cliToolNames: [],
},

'scm:comment': {
integration: 'scm',
description: 'Post and update PR comments',
gadgetNames: ['PostPRComment', 'UpdatePRComment', 'GetPRComments', 'ReplyToReviewComment'],
sdkToolNames: [],
cliToolNames: [],
},

'scm:review': {
integration: 'scm',
description: 'Submit code reviews',
gadgetNames: ['CreatePRReview'],
sdkToolNames: [],
cliToolNames: [],
},

'scm:pr': {
integration: 'scm',
description: 'Create pull requests',
gadgetNames: ['CreatePR'],
sdkToolNames: [],
cliToolNames: [],
},

// -------------------------------------------------------------------------
// Email integration capabilities
// -------------------------------------------------------------------------

'email:read': {
integration: 'email',
description: 'Search and read emails',
gadgetNames: ['SearchEmails', 'ReadEmail', 'MarkEmailAsSeen'],
sdkToolNames: [],
cliToolNames: [],
},

'email:write': {
integration: 'email',
description: 'Send and reply to emails',
gadgetNames: ['SendEmail', 'ReplyToEmail'],
sdkToolNames: [],
cliToolNames: [],
},

// -------------------------------------------------------------------------
// SMS integration capabilities
// -------------------------------------------------------------------------

'sms:send': {
integration: 'sms',
description: 'Send SMS messages',
gadgetNames: ['SendSms'],
sdkToolNames: [],
cliToolNames: [],
},
};

// ============================================================================
// Helper Functions
// ============================================================================

/**
* Get capabilities grouped by integration source for UI display.
*/
export function getCapabilitiesByIntegration(): Record<
IntegrationCategory | 'builtin',
Capability[]
> {
const groups: Record<IntegrationCategory | 'builtin', Capability[]> = {
builtin: [],
pm: [],
scm: [],
email: [],
sms: [],
};

for (const cap of CAPABILITIES) {
const def = CAPABILITY_REGISTRY[cap];
const key = def.integration ?? 'builtin';
groups[key].push(cap);
}

return groups;
}

/**
* Extract the integration category from a capability name.
* Returns null for built-in capabilities.
*/
export function getCapabilityIntegration(cap: Capability): IntegrationCategory | null {
return CAPABILITY_REGISTRY[cap].integration;
}

/**
* Check if a capability is built-in (no integration required).
*/
export function isBuiltInCapability(cap: Capability): boolean {
return CAPABILITY_REGISTRY[cap].integration === null;
}

/**
* Validate that a string is a valid capability.
*/
export function isValidCapability(value: string): value is Capability {
return CAPABILITIES.includes(value as Capability);
}
Loading