loadcontext
Retrieve detailed, formatted information about software development entities like projects, components, features, and tasks. Understand entity relationships, project structure, task dependencies, and milestone progress for informed decision-making.
Instructions
A powerful tool for retrieving rich, contextual information about specific software development entities, providing formatted details based on entity type.
When to use this tool:
Retrieving detailed information about a specific project, component, feature, or other development entity
Exploring relationships between software development entities
Examining project status, components, features, tasks, and issues
Understanding the structure and elements of a software component
Reviewing milestone progress and completion metrics
Examining task details, dependencies, and task sequencing
Exploring feature implementations and technical requirements
Analyzing the project knowledge graph to understand entity relationships
Preparing for work on a specific entity by establishing context
Key features:
Provides contextually rich, formatted information about software development entities
Adapts output format based on entity type (project, component, feature, task, etc.)
Presents both direct entity information and related elements
Organizes information in a clear, hierarchical structure
Automatically identifies entity relationships and presents them systematically
Parameters explained:
entityName: Required - The name of the entity to retrieve context for
Example: "AuthService", "UserProfile", "LoginFeature"
entityType: Optional - The type of entity being retrieved
Default: "project"
Accepted values: "project", "component", "task", "issue", "milestone", "decision", "feature", "technology", "documentation", "dependency", "developer"
Helps the system format the output appropriately
sessionId: Optional - The current session identifier
Typically provided by startsession
Used for tracking entity views within the session
Each entity type returns specialized context information:
Project: Shows status, components, active features, active tasks, active issues, upcoming milestones, team members, recent decisions, and task sequencing information
Component: Displays parent projects, implemented features, technologies used, active issues, documentation, and dependencies
Feature: Shows status, priority, description, requirements, implementing components, and related tasks
Task: Displays project, status, priority, description, related issues, blocking items, preceding tasks, and following tasks
Milestone: Shows status, progress percentage, and tasks grouped by completion status (complete, active, inactive)
Other Entity Types: Shows observations and both incoming and outgoing relationships within the knowledge graph
You should:
Specify the exact entity name for accurate retrieval
Provide the entity type when possible for optimally formatted results
Start with project entities to get a high-level overview
Explore components to understand technical architecture
Examine features to see functional requirements and implementations
Review tasks to understand specific work items and their status
Analyze task sequencing to understand dependencies and workflow
Use status information to focus on active or incomplete work
Consider priority information when planning next steps
Use milestone context to track progress toward completion
After retrieving context, follow up on specific entities of interest
Use in conjunction with startsession to maintain session tracking
Remember that this tool only retrieves existing information; use buildcontext to add new entities
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| entityName | Yes | ||
| entityType | No | ||
| sessionId | No |
Implementation Reference
- index.ts:1352-1744 (registration)Registration of the 'loadcontext' MCP tool using McpServer.tool() method, including schema and handler.server.tool( "loadcontext", toolDescriptions["loadcontext"], { entityName: z.string(), entityType: z.string().optional(), sessionId: z.string().optional() }, async ({ entityName, entityType = "project", sessionId }) => { try { // Validate session if ID is provided if (sessionId) { const sessionStates = await loadSessionStates(); if (!sessionStates.has(sessionId)) { console.warn(`Warning: Session ${sessionId} not found, but proceeding with context load`); // Initialize it anyway for more robustness sessionStates.set(sessionId, []); await saveSessionStates(sessionStates); } // Track that this entity was loaded in this session const sessionState = sessionStates.get(sessionId) || []; const loadEvent = { type: 'context_loaded', timestamp: new Date().toISOString(), entityName, entityType }; sessionState.push(loadEvent); sessionStates.set(sessionId, sessionState); await saveSessionStates(sessionStates); } // Get entity const entityGraph = await knowledgeGraphManager.searchNodes(entityName); if (entityGraph.entities.length === 0) { throw new Error(`Entity ${entityName} not found`); } // Find the exact entity by name (case-sensitive match) const entity = entityGraph.entities.find(e => e.name === entityName); if (!entity) { throw new Error(`Entity ${entityName} not found`); } // Get status and priority const status = await knowledgeGraphManager.getEntityStatus(entityName) || "unknown"; const priority = await knowledgeGraphManager.getEntityPriority(entityName); // Format observations for display (show all observations) const observationsList = entity.observations.length > 0 ? entity.observations.map(obs => `- ${obs}`).join("\n") : "No observations"; // Different context loading based on entity type let contextMessage = ""; if (entityType === "project") { // Get project status const projectStatus = await knowledgeGraphManager.getProjectStatus(entityName); // Format project context const componentsText = projectStatus.components?.map((component: Entity) => { return `- **${component.name}**${component.observations.length > 0 ? `: ${component.observations[0]}` : ''}`; }).join("\n") || "No components found"; const featuresText = projectStatus.activeFeatures?.map((feature: Entity) => { const featureStatus = projectStatus.statuses[feature.name] || "unknown"; return `- **${feature.name}** (${featureStatus})${feature.observations.length > 0 ? `: ${feature.observations.join(', ')}` : ''}`; }).join("\n") || "No active features found"; const tasksText = projectStatus.activeTasks?.map((task: Entity) => { const taskStatus = projectStatus.statuses[task.name] || "unknown"; const taskPriority = projectStatus.priorities[task.name] || "normal"; return `- **${task.name}** (${taskStatus}, ${taskPriority} priority)${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No active tasks found"; const issuesText = projectStatus.activeIssues?.map((issue: Entity) => { const issueStatus = projectStatus.statuses[issue.name] || "unknown"; return `- **${issue.name}** (${issueStatus})${issue.observations.length > 0 ? `: ${issue.observations.join(', ')}` : ''}`; }).join("\n") || "No active issues found"; const milestonesText = projectStatus.upcomingMilestones?.map((milestone: Entity) => { const milestoneStatus = projectStatus.statuses[milestone.name] || "unknown"; return `- **${milestone.name}** (${milestoneStatus})${milestone.observations.length > 0 ? `: ${milestone.observations.join(', ')}` : ''}`; }).join("\n") || "No upcoming milestones found"; const decisionsText = projectStatus.recentDecisions?.map((decision: Entity) => { return `- **${decision.name}**${decision.observations.length > 0 ? `: ${decision.observations.join(', ')}` : ''}`; }).join("\n") || "No recent decisions"; // Task sequencing information const sequencingText = Object.keys(projectStatus.taskSequencing || {}).length > 0 ? Object.entries(projectStatus.taskSequencing).map(([taskName, sequence]: [string, any]) => { return `- **${taskName}**:\n - Precedes: ${sequence.followingTasks.length > 0 ? sequence.followingTasks.join(', ') : 'None'}\n - Follows: ${sequence.precedingTasks.length > 0 ? sequence.precedingTasks.join(', ') : 'None'}`; }).join("\n") : "No task sequencing information available"; contextMessage = `# Software Development Project Context: ${entityName} ## Project Overview - **Status**: ${status} - **Priority**: ${priority || "N/A"} ## Observations ${observationsList} ## Components ${componentsText} ## Active Features ${featuresText} ## Active Tasks ${tasksText} ## Active Issues ${issuesText} ## Upcoming Milestones ${milestonesText} ## Recent Decisions ${decisionsText} ## Task Sequencing ${sequencingText}`; } else if (entityType === "component") { // Get component context const componentContext = await knowledgeGraphManager.getComponentContext(entityName); const projectsText = componentContext.projects?.map((project: Entity) => { return `- **${project.name}**${project.observations.length > 0 ? `: ${project.observations.join(', ')}` : ''}`; }).join("\n") || "No parent projects found"; const featuresText = componentContext.features?.map((feature: Entity) => { const featureStatus = componentContext.statuses[feature.name] || "unknown"; return `- **${feature.name}** (${featureStatus})${feature.observations.length > 0 ? `: ${feature.observations.join(', ')}` : ''}`; }).join("\n") || "No implemented features found"; const technologiesText = componentContext.technologies?.map((tech: Entity) => { return `- **${tech.name}**${tech.observations.length > 0 ? `: ${tech.observations.join(', ')}` : ''}`; }).join("\n") || "No technologies specified"; const issuesText = componentContext.activeIssues?.map((issue: Entity) => { const issueStatus = componentContext.statuses[issue.name] || "unknown"; return `- **${issue.name}** (${issueStatus})${issue.observations.length > 0 ? `: ${issue.observations.join(', ')}` : ''}`; }).join("\n") || "No active issues found"; const dependenciesText = componentContext.dependencies?.map((dep: Entity) => { return `- **${dep.name}** (${dep.entityType})${dep.observations.length > 0 ? `: ${dep.observations.join(', ')}` : ''}`; }).join("\n") || "No dependencies found"; const documentationText = componentContext.documentation?.map((doc: Entity) => { return `- **${doc.name}**${doc.observations.length > 0 ? `: ${doc.observations.join(', ')}` : ''}`; }).join("\n") || "No documentation found"; contextMessage = `# Component Context: ${entityName} ## Overview - **Status**: ${status} - **Priority**: ${priority || "N/A"} ## Observations ${observationsList} ## Part of Projects ${projectsText} ## Technologies ${technologiesText} ## Implemented Features ${featuresText} ## Dependencies ${dependenciesText} ## Active Issues ${issuesText} ## Documentation ${documentationText}`; } else if (entityType === "feature") { // Get related entities const relatedEntities = await knowledgeGraphManager.getRelatedEntities(entityName); // Find implementing components const implementingComponents = relatedEntities.incomingRelations .filter((rel: { relation: Relation; source: Entity }) => rel.relation.relationType === "implements") .map((rel: { relation: Relation; source: Entity }) => rel.source); const componentsText = implementingComponents.map((component: Entity) => { return `- **${component.name}**${component.observations.length > 0 ? `: ${component.observations.join(', ')}` : ''}`; }).join("\n") || "No implementing components found"; // Find related tasks const relatedTasks = [...relatedEntities.incomingRelations, ...relatedEntities.outgoingRelations] .filter((rel: { relation: Relation; source?: Entity; target?: Entity }) => rel.relation.relationType === "related_to" && (rel.source?.entityType === "task" || rel.target?.entityType === "task") ) .map((rel: { relation: Relation; source?: Entity; target?: Entity }) => rel.source?.entityType === "task" ? rel.source : rel.target ) .filter((entity): entity is Entity => entity !== undefined); // Get status for each task const taskStatuses: Record<string, string> = {}; for (const task of relatedTasks) { const taskStatus = await knowledgeGraphManager.getEntityStatus(task.name); if (taskStatus) { taskStatuses[task.name] = taskStatus; } } const tasksText = relatedTasks.map((task: Entity) => { const taskStatus = taskStatuses[task.name] || "unknown"; return `- **${task.name}** (${taskStatus})${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No related tasks found"; // Find requirements const requirements = relatedEntities.incomingRelations .filter((rel: { relation: Relation; source: Entity }) => rel.relation.relationType === "required_by") .map((rel: { relation: Relation; source: Entity }) => rel.source); const requirementsText = requirements.map((req: Entity) => { return `- **${req.name}**${req.observations.length > 0 ? `: ${req.observations.join(', ')}` : ''}`; }).join("\n") || "No requirements specified"; contextMessage = `# Feature Context: ${entityName} ## Overview - **Status**: ${status} - **Priority**: ${priority || "normal"} ## Observations ${observationsList} ## Requirements ${requirementsText} ## Implementing Components ${componentsText} ## Related Tasks ${tasksText}`; } else if (entityType === "task") { // Get related entities const relatedEntities = await knowledgeGraphManager.getRelatedEntities(entityName); // Find related issues const relatedIssues = relatedEntities.outgoingRelations .filter((rel: { relation: Relation; target: Entity }) => rel.relation.relationType === "resolves") .map((rel: { relation: Relation; target: Entity }) => rel.target); // Get status for each issue const issueStatuses: Record<string, string> = {}; for (const issue of relatedIssues) { const issueStatus = await knowledgeGraphManager.getEntityStatus(issue.name); if (issueStatus) { issueStatuses[issue.name] = issueStatus; } } const issuesText = relatedIssues.map((issue: Entity) => { const issueStatus = issueStatuses[issue.name] || "unknown"; return `- **${issue.name}** (${issueStatus})${issue.observations.length > 0 ? `: ${issue.observations.join(', ')}` : ''}`; }).join("\n") || "No related issues found"; // Find parent project const parentProjects = relatedEntities.incomingRelations .filter((rel: { relation: Relation; source: Entity }) => rel.relation.relationType === "contains" && rel.source.entityType === "project") .map((rel: { relation: Relation; source: Entity }) => rel.source); const projectName = parentProjects.length > 0 ? parentProjects[0].name : "Unknown project"; // Find blocking tasks or issues const blockingItems = relatedEntities.outgoingRelations .filter((rel: { relation: Relation; target: Entity }) => rel.relation.relationType === "blocked_by") .map((rel: { relation: Relation; target: Entity }) => rel.target); // Get status for each blocking item const blockingStatuses: Record<string, string> = {}; for (const item of blockingItems) { const itemStatus = await knowledgeGraphManager.getEntityStatus(item.name); if (itemStatus) { blockingStatuses[item.name] = itemStatus; } } const blockingText = blockingItems.map((item: Entity) => { const itemStatus = blockingStatuses[item.name] || "unknown"; return `- **${item.name}** (${item.entityType}, ${itemStatus})${item.observations.length > 0 ? `: ${item.observations.join(', ')}` : ''}`; }).join("\n") || "No blocking items"; // Find task sequencing const precedingTasks: string[] = []; const followingTasks: string[] = []; // Get the graph to find sequencing relations const graph = await knowledgeGraphManager.readGraph(); for (const relation of graph.relations) { if (relation.from === entityName && relation.relationType === 'precedes') { followingTasks.push(relation.to); } if (relation.to === entityName && relation.relationType === 'precedes') { precedingTasks.push(relation.from); } } const sequencingText = `### Preceding Tasks\n${precedingTasks.length > 0 ? precedingTasks.map(t => `- ${t}`).join('\n') : 'None'}\n\n### Following Tasks\n${followingTasks.length > 0 ? followingTasks.map(t => `- ${t}`).join('\n') : 'None'}`; contextMessage = `# Task Context: ${entityName} ## Overview - **Project**: ${projectName} - **Status**: ${status} - **Priority**: ${priority || "normal"} ## Observations ${observationsList} ## Related Issues ${issuesText} ## Blocked By ${blockingText} ## Task Sequencing ${sequencingText}`; } else if (entityType === "milestone") { // Get milestone progress const milestoneProgress = await knowledgeGraphManager.getMilestoneProgress(entityName); contextMessage = `# Milestone Context: ${entityName} ## Overview - **Status**: ${status} - **Progress**: ${milestoneProgress.progress?.percentage || 0}% complete - **Complete**: ${milestoneProgress.progress?.complete ? "Yes" : "No"} ## Observations ${observationsList} ## Tasks ### Completed (${milestoneProgress.tasks?.completed?.length || 0}) ${milestoneProgress.tasks?.completed?.map((task: Entity) => { return `- **${task.name}**${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No completed tasks"} ### In Progress (${milestoneProgress.tasks?.inProgress?.length || 0}) ${milestoneProgress.tasks?.inProgress?.map((task: Entity) => { return `- **${task.name}**${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No in-progress tasks"} ### Not Started (${milestoneProgress.tasks?.notStarted?.length || 0}) ${milestoneProgress.tasks?.notStarted?.map((task: Entity) => { return `- **${task.name}**${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No not-started tasks"} ## Task Sequencing ${Object.keys(milestoneProgress.taskSequencing || {}).length > 0 ? Object.entries(milestoneProgress.taskSequencing).map(([taskName, sequence]: [string, any]) => { return `- **${taskName}**:\n - Precedes: ${sequence.followingTasks.length > 0 ? sequence.followingTasks.join(', ') : 'None'}\n - Follows: ${sequence.precedingTasks.length > 0 ? sequence.precedingTasks.join(', ') : 'None'}`; }).join("\n") : "No task sequencing information available"}`; } return { content: [{ type: "text", text: contextMessage }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }, null, 2) }] }; } } );
- index.ts:1355-1359 (schema)Zod input schema defining parameters for the loadcontext tool: required entityName, optional entityType and sessionId.{ entityName: z.string(), entityType: z.string().optional(), sessionId: z.string().optional() },
- index.ts:1360-1743 (handler)Core handler logic: handles session tracking, entity lookup via searchNodes, retrieves status/priority, and generates detailed markdown context summaries tailored to entity types (project, component, feature, task, milestone) using specialized KnowledgeGraphManager methods.async ({ entityName, entityType = "project", sessionId }) => { try { // Validate session if ID is provided if (sessionId) { const sessionStates = await loadSessionStates(); if (!sessionStates.has(sessionId)) { console.warn(`Warning: Session ${sessionId} not found, but proceeding with context load`); // Initialize it anyway for more robustness sessionStates.set(sessionId, []); await saveSessionStates(sessionStates); } // Track that this entity was loaded in this session const sessionState = sessionStates.get(sessionId) || []; const loadEvent = { type: 'context_loaded', timestamp: new Date().toISOString(), entityName, entityType }; sessionState.push(loadEvent); sessionStates.set(sessionId, sessionState); await saveSessionStates(sessionStates); } // Get entity const entityGraph = await knowledgeGraphManager.searchNodes(entityName); if (entityGraph.entities.length === 0) { throw new Error(`Entity ${entityName} not found`); } // Find the exact entity by name (case-sensitive match) const entity = entityGraph.entities.find(e => e.name === entityName); if (!entity) { throw new Error(`Entity ${entityName} not found`); } // Get status and priority const status = await knowledgeGraphManager.getEntityStatus(entityName) || "unknown"; const priority = await knowledgeGraphManager.getEntityPriority(entityName); // Format observations for display (show all observations) const observationsList = entity.observations.length > 0 ? entity.observations.map(obs => `- ${obs}`).join("\n") : "No observations"; // Different context loading based on entity type let contextMessage = ""; if (entityType === "project") { // Get project status const projectStatus = await knowledgeGraphManager.getProjectStatus(entityName); // Format project context const componentsText = projectStatus.components?.map((component: Entity) => { return `- **${component.name}**${component.observations.length > 0 ? `: ${component.observations[0]}` : ''}`; }).join("\n") || "No components found"; const featuresText = projectStatus.activeFeatures?.map((feature: Entity) => { const featureStatus = projectStatus.statuses[feature.name] || "unknown"; return `- **${feature.name}** (${featureStatus})${feature.observations.length > 0 ? `: ${feature.observations.join(', ')}` : ''}`; }).join("\n") || "No active features found"; const tasksText = projectStatus.activeTasks?.map((task: Entity) => { const taskStatus = projectStatus.statuses[task.name] || "unknown"; const taskPriority = projectStatus.priorities[task.name] || "normal"; return `- **${task.name}** (${taskStatus}, ${taskPriority} priority)${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No active tasks found"; const issuesText = projectStatus.activeIssues?.map((issue: Entity) => { const issueStatus = projectStatus.statuses[issue.name] || "unknown"; return `- **${issue.name}** (${issueStatus})${issue.observations.length > 0 ? `: ${issue.observations.join(', ')}` : ''}`; }).join("\n") || "No active issues found"; const milestonesText = projectStatus.upcomingMilestones?.map((milestone: Entity) => { const milestoneStatus = projectStatus.statuses[milestone.name] || "unknown"; return `- **${milestone.name}** (${milestoneStatus})${milestone.observations.length > 0 ? `: ${milestone.observations.join(', ')}` : ''}`; }).join("\n") || "No upcoming milestones found"; const decisionsText = projectStatus.recentDecisions?.map((decision: Entity) => { return `- **${decision.name}**${decision.observations.length > 0 ? `: ${decision.observations.join(', ')}` : ''}`; }).join("\n") || "No recent decisions"; // Task sequencing information const sequencingText = Object.keys(projectStatus.taskSequencing || {}).length > 0 ? Object.entries(projectStatus.taskSequencing).map(([taskName, sequence]: [string, any]) => { return `- **${taskName}**:\n - Precedes: ${sequence.followingTasks.length > 0 ? sequence.followingTasks.join(', ') : 'None'}\n - Follows: ${sequence.precedingTasks.length > 0 ? sequence.precedingTasks.join(', ') : 'None'}`; }).join("\n") : "No task sequencing information available"; contextMessage = `# Software Development Project Context: ${entityName} ## Project Overview - **Status**: ${status} - **Priority**: ${priority || "N/A"} ## Observations ${observationsList} ## Components ${componentsText} ## Active Features ${featuresText} ## Active Tasks ${tasksText} ## Active Issues ${issuesText} ## Upcoming Milestones ${milestonesText} ## Recent Decisions ${decisionsText} ## Task Sequencing ${sequencingText}`; } else if (entityType === "component") { // Get component context const componentContext = await knowledgeGraphManager.getComponentContext(entityName); const projectsText = componentContext.projects?.map((project: Entity) => { return `- **${project.name}**${project.observations.length > 0 ? `: ${project.observations.join(', ')}` : ''}`; }).join("\n") || "No parent projects found"; const featuresText = componentContext.features?.map((feature: Entity) => { const featureStatus = componentContext.statuses[feature.name] || "unknown"; return `- **${feature.name}** (${featureStatus})${feature.observations.length > 0 ? `: ${feature.observations.join(', ')}` : ''}`; }).join("\n") || "No implemented features found"; const technologiesText = componentContext.technologies?.map((tech: Entity) => { return `- **${tech.name}**${tech.observations.length > 0 ? `: ${tech.observations.join(', ')}` : ''}`; }).join("\n") || "No technologies specified"; const issuesText = componentContext.activeIssues?.map((issue: Entity) => { const issueStatus = componentContext.statuses[issue.name] || "unknown"; return `- **${issue.name}** (${issueStatus})${issue.observations.length > 0 ? `: ${issue.observations.join(', ')}` : ''}`; }).join("\n") || "No active issues found"; const dependenciesText = componentContext.dependencies?.map((dep: Entity) => { return `- **${dep.name}** (${dep.entityType})${dep.observations.length > 0 ? `: ${dep.observations.join(', ')}` : ''}`; }).join("\n") || "No dependencies found"; const documentationText = componentContext.documentation?.map((doc: Entity) => { return `- **${doc.name}**${doc.observations.length > 0 ? `: ${doc.observations.join(', ')}` : ''}`; }).join("\n") || "No documentation found"; contextMessage = `# Component Context: ${entityName} ## Overview - **Status**: ${status} - **Priority**: ${priority || "N/A"} ## Observations ${observationsList} ## Part of Projects ${projectsText} ## Technologies ${technologiesText} ## Implemented Features ${featuresText} ## Dependencies ${dependenciesText} ## Active Issues ${issuesText} ## Documentation ${documentationText}`; } else if (entityType === "feature") { // Get related entities const relatedEntities = await knowledgeGraphManager.getRelatedEntities(entityName); // Find implementing components const implementingComponents = relatedEntities.incomingRelations .filter((rel: { relation: Relation; source: Entity }) => rel.relation.relationType === "implements") .map((rel: { relation: Relation; source: Entity }) => rel.source); const componentsText = implementingComponents.map((component: Entity) => { return `- **${component.name}**${component.observations.length > 0 ? `: ${component.observations.join(', ')}` : ''}`; }).join("\n") || "No implementing components found"; // Find related tasks const relatedTasks = [...relatedEntities.incomingRelations, ...relatedEntities.outgoingRelations] .filter((rel: { relation: Relation; source?: Entity; target?: Entity }) => rel.relation.relationType === "related_to" && (rel.source?.entityType === "task" || rel.target?.entityType === "task") ) .map((rel: { relation: Relation; source?: Entity; target?: Entity }) => rel.source?.entityType === "task" ? rel.source : rel.target ) .filter((entity): entity is Entity => entity !== undefined); // Get status for each task const taskStatuses: Record<string, string> = {}; for (const task of relatedTasks) { const taskStatus = await knowledgeGraphManager.getEntityStatus(task.name); if (taskStatus) { taskStatuses[task.name] = taskStatus; } } const tasksText = relatedTasks.map((task: Entity) => { const taskStatus = taskStatuses[task.name] || "unknown"; return `- **${task.name}** (${taskStatus})${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No related tasks found"; // Find requirements const requirements = relatedEntities.incomingRelations .filter((rel: { relation: Relation; source: Entity }) => rel.relation.relationType === "required_by") .map((rel: { relation: Relation; source: Entity }) => rel.source); const requirementsText = requirements.map((req: Entity) => { return `- **${req.name}**${req.observations.length > 0 ? `: ${req.observations.join(', ')}` : ''}`; }).join("\n") || "No requirements specified"; contextMessage = `# Feature Context: ${entityName} ## Overview - **Status**: ${status} - **Priority**: ${priority || "normal"} ## Observations ${observationsList} ## Requirements ${requirementsText} ## Implementing Components ${componentsText} ## Related Tasks ${tasksText}`; } else if (entityType === "task") { // Get related entities const relatedEntities = await knowledgeGraphManager.getRelatedEntities(entityName); // Find related issues const relatedIssues = relatedEntities.outgoingRelations .filter((rel: { relation: Relation; target: Entity }) => rel.relation.relationType === "resolves") .map((rel: { relation: Relation; target: Entity }) => rel.target); // Get status for each issue const issueStatuses: Record<string, string> = {}; for (const issue of relatedIssues) { const issueStatus = await knowledgeGraphManager.getEntityStatus(issue.name); if (issueStatus) { issueStatuses[issue.name] = issueStatus; } } const issuesText = relatedIssues.map((issue: Entity) => { const issueStatus = issueStatuses[issue.name] || "unknown"; return `- **${issue.name}** (${issueStatus})${issue.observations.length > 0 ? `: ${issue.observations.join(', ')}` : ''}`; }).join("\n") || "No related issues found"; // Find parent project const parentProjects = relatedEntities.incomingRelations .filter((rel: { relation: Relation; source: Entity }) => rel.relation.relationType === "contains" && rel.source.entityType === "project") .map((rel: { relation: Relation; source: Entity }) => rel.source); const projectName = parentProjects.length > 0 ? parentProjects[0].name : "Unknown project"; // Find blocking tasks or issues const blockingItems = relatedEntities.outgoingRelations .filter((rel: { relation: Relation; target: Entity }) => rel.relation.relationType === "blocked_by") .map((rel: { relation: Relation; target: Entity }) => rel.target); // Get status for each blocking item const blockingStatuses: Record<string, string> = {}; for (const item of blockingItems) { const itemStatus = await knowledgeGraphManager.getEntityStatus(item.name); if (itemStatus) { blockingStatuses[item.name] = itemStatus; } } const blockingText = blockingItems.map((item: Entity) => { const itemStatus = blockingStatuses[item.name] || "unknown"; return `- **${item.name}** (${item.entityType}, ${itemStatus})${item.observations.length > 0 ? `: ${item.observations.join(', ')}` : ''}`; }).join("\n") || "No blocking items"; // Find task sequencing const precedingTasks: string[] = []; const followingTasks: string[] = []; // Get the graph to find sequencing relations const graph = await knowledgeGraphManager.readGraph(); for (const relation of graph.relations) { if (relation.from === entityName && relation.relationType === 'precedes') { followingTasks.push(relation.to); } if (relation.to === entityName && relation.relationType === 'precedes') { precedingTasks.push(relation.from); } } const sequencingText = `### Preceding Tasks\n${precedingTasks.length > 0 ? precedingTasks.map(t => `- ${t}`).join('\n') : 'None'}\n\n### Following Tasks\n${followingTasks.length > 0 ? followingTasks.map(t => `- ${t}`).join('\n') : 'None'}`; contextMessage = `# Task Context: ${entityName} ## Overview - **Project**: ${projectName} - **Status**: ${status} - **Priority**: ${priority || "normal"} ## Observations ${observationsList} ## Related Issues ${issuesText} ## Blocked By ${blockingText} ## Task Sequencing ${sequencingText}`; } else if (entityType === "milestone") { // Get milestone progress const milestoneProgress = await knowledgeGraphManager.getMilestoneProgress(entityName); contextMessage = `# Milestone Context: ${entityName} ## Overview - **Status**: ${status} - **Progress**: ${milestoneProgress.progress?.percentage || 0}% complete - **Complete**: ${milestoneProgress.progress?.complete ? "Yes" : "No"} ## Observations ${observationsList} ## Tasks ### Completed (${milestoneProgress.tasks?.completed?.length || 0}) ${milestoneProgress.tasks?.completed?.map((task: Entity) => { return `- **${task.name}**${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No completed tasks"} ### In Progress (${milestoneProgress.tasks?.inProgress?.length || 0}) ${milestoneProgress.tasks?.inProgress?.map((task: Entity) => { return `- **${task.name}**${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No in-progress tasks"} ### Not Started (${milestoneProgress.tasks?.notStarted?.length || 0}) ${milestoneProgress.tasks?.notStarted?.map((task: Entity) => { return `- **${task.name}**${task.observations.length > 0 ? `: ${task.observations.join(', ')}` : ''}`; }).join("\n") || "No not-started tasks"} ## Task Sequencing ${Object.keys(milestoneProgress.taskSequencing || {}).length > 0 ? Object.entries(milestoneProgress.taskSequencing).map(([taskName, sequence]: [string, any]) => { return `- **${taskName}**:\n - Precedes: ${sequence.followingTasks.length > 0 ? sequence.followingTasks.join(', ') : 'None'}\n - Follows: ${sequence.precedingTasks.length > 0 ? sequence.precedingTasks.join(', ') : 'None'}`; }).join("\n") : "No task sequencing information available"}`; } return { content: [{ type: "text", text: contextMessage }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }, null, 2) }] }; } }
- index.ts:436-582 (helper)Helper method getProjectStatus used by loadcontext for project entity type to gather comprehensive project context.async getProjectStatus(projectName: string): Promise<any> { const graph = await this.loadGraph(); // Find the project entity const project = graph.entities.find(e => e.name === projectName && e.entityType === 'project'); if (!project) { throw new Error(`Project '${projectName}' not found`); } // Find components that are part of this project const components: Entity[] = []; // Find features, issues, tasks, milestones related to this project const features: Entity[] = []; const issues: Entity[] = []; const tasks: Entity[] = []; const milestones: Entity[] = []; // Find entities directly related to the project for (const relation of graph.relations) { if (relation.from === projectName || relation.to === projectName) { const relatedEntity = graph.entities.find(e => (relation.from === projectName && e.name === relation.to) || (relation.to === projectName && e.name === relation.from) ); if (relatedEntity) { if (relatedEntity.entityType === 'component') components.push(relatedEntity); if (relatedEntity.entityType === 'feature') features.push(relatedEntity); if (relatedEntity.entityType === 'issue') issues.push(relatedEntity); if (relatedEntity.entityType === 'task') tasks.push(relatedEntity); if (relatedEntity.entityType === 'milestone') milestones.push(relatedEntity); } } } // Find entities related to components of the project for (const component of components) { for (const relation of graph.relations) { if (relation.from === component.name || relation.to === component.name) { const relatedEntity = graph.entities.find(e => (relation.from === component.name && e.name === relation.to) || (relation.to === component.name && e.name === relation.from) ); if (relatedEntity) { if (relatedEntity.entityType === 'feature' && !features.some(f => f.name === relatedEntity.name)) { features.push(relatedEntity); } if (relatedEntity.entityType === 'issue' && !issues.some(i => i.name === relatedEntity.name)) { issues.push(relatedEntity); } if (relatedEntity.entityType === 'task' && !tasks.some(t => t.name === relatedEntity.name)) { tasks.push(relatedEntity); } } } } } // Get active tasks and issues const statuses: Record<string, string> = {}; const priorities: Record<string, string> = {}; // Load status and priority for tasks and issues for (const entity of [...tasks, ...issues, ...features, ...milestones]) { const status = await this.getEntityStatus(entity.name); if (status) { statuses[entity.name] = status; } const priority = await this.getEntityPriority(entity.name); if (priority) { priorities[entity.name] = priority; } } // Filter active tasks and issues based on status const activeTasks = tasks.filter(task => { const status = statuses[task.name]; return status ? status === 'active' : true; }); const activeIssues = issues.filter(issue => { const status = statuses[issue.name]; return status ? status === 'active' : true; }); // Find upcoming milestones const upcomingMilestones = milestones.filter(milestone => { const status = statuses[milestone.name]; return status ? status === 'active' : true; }); // Get decision history const decisions = graph.entities.filter(e => e.entityType === 'decision' && graph.relations.some(r => (r.from === e.name && r.to === projectName) || (r.to === e.name && r.from === projectName) ) ); // Find task sequencing const taskSequencing: Record<string, string[]> = {}; for (const task of tasks) { const precedingTasks: string[] = []; const followingTasks: string[] = []; // Find tasks that this task precedes for (const relation of graph.relations) { if (relation.from === task.name && relation.relationType === 'precedes') { followingTasks.push(relation.to); } if (relation.to === task.name && relation.relationType === 'precedes') { precedingTasks.push(relation.from); } } if (precedingTasks.length > 0 || followingTasks.length > 0) { taskSequencing[task.name] = { precedingTasks, followingTasks } as any; } } return { project, components, activeFeatures: features.filter(f => { const status = statuses[f.name]; return status ? status === 'active' : true; }), activeTasks, activeIssues, upcomingMilestones, allFeatures: features, allIssues: issues, allTasks: tasks, allMilestones: milestones, recentDecisions: decisions.slice(0, 5), // Limit to 5 most recent decisions statuses, // Include status mapping for reference priorities, // Include priority mapping for reference taskSequencing // Include task sequencing information }; }
- index.ts:385-409 (helper)Helper method searchNodes used by loadcontext to find the target entity by name.async searchNodes(query: string): Promise<KnowledgeGraph> { const graph = await this.loadGraph(); // Filter entities const filteredEntities = graph.entities.filter(e => e.name.toLowerCase().includes(query.toLowerCase()) || e.entityType.toLowerCase().includes(query.toLowerCase()) || e.observations.some(o => o.toLowerCase().includes(query.toLowerCase())) ); // Create a Set of filtered entity names for quick lookup const filteredEntityNames = new Set(filteredEntities.map(e => e.name)); // Filter relations to only include those between filtered entities const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to) ); const filteredGraph: KnowledgeGraph = { entities: filteredEntities, relations: filteredRelations, }; return filteredGraph; }