aidex_describe
Documents project details by adding or updating sections in summary.md for purpose, architecture, concepts, patterns, or notes.
Instructions
Add or update a section in the project summary (summary.md). Use to document project purpose, architecture, key concepts, or patterns.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to project with .aidex directory | |
| section | Yes | Section to update | |
| content | Yes | Content to add to the section | |
| replace | No | Replace existing section content (default: append) |
Implementation Reference
- src/server/tools.ts:217-243 (schema)Tool registration and input schema definition for aidex_describe. Defines the tool name, description, and input parameters (path, section, content, replace).{ name: `${TOOL_PREFIX}describe`, description: 'Add or update a section in the project summary (summary.md). Use to document project purpose, architecture, key concepts, or patterns.', inputSchema: { type: 'object', properties: { path: { type: 'string', description: `Path to project with ${INDEX_DIR} directory`, }, section: { type: 'string', enum: ['purpose', 'architecture', 'concepts', 'patterns', 'notes'], description: 'Section to update', }, content: { type: 'string', description: 'Content to add to the section', }, replace: { type: 'boolean', description: 'Replace existing section content (default: append)', }, }, required: ['path', 'section', 'content'], }, },
- src/server/tools.ts:591-592 (registration)Tool handler routing - maps the aidex_describe tool name to the handleDescribe function.case `${TOOL_PREFIX}describe`: return handleDescribe(args);
- src/server/tools.ts:1134-1171 (handler)MCP tool handler for aidex_describe. Validates parameters, calls the describe command, and formats the response for the MCP client./** * Handle describe */ function handleDescribe(args: Record<string, unknown>): { content: Array<{ type: string; text: string }> } { const path = args.path as string; const section = args.section as string; const content = args.content as string; if (!path || !section || !content) { return { content: [{ type: 'text', text: 'Error: path, section, and content parameters are required' }], }; } const validSections = ['purpose', 'architecture', 'concepts', 'patterns', 'notes']; if (!validSections.includes(section)) { return { content: [{ type: 'text', text: `Error: section must be one of: ${validSections.join(', ')}` }], }; } const result = describe({ path, section: section as 'purpose' | 'architecture' | 'concepts' | 'patterns' | 'notes', content, replace: args.replace as boolean | undefined, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error}` }], }; } return { content: [{ type: 'text', text: `✓ Updated section: ${result.section}` }], }; }
- src/commands/summary.ts:434-445 (schema)Type definitions for the describe command - DescribeParams and DescribeResult interfaces defining the input/output contract.export interface DescribeParams { path: string; section: 'purpose' | 'architecture' | 'concepts' | 'patterns' | 'notes'; content: string; replace?: boolean; // Replace existing section? Default: append } export interface DescribeResult { success: boolean; section: string; error?: string; }
- src/commands/summary.ts:447-518 (handler)Core implementation of the describe command. Reads/writes summary.md file, manages sections (purpose, architecture, concepts, patterns, notes), handles append vs replace modes.export function describe(params: DescribeParams): DescribeResult { const { path: projectPath, section, content, replace = false } = params; // Validate project path const indexDir = join(projectPath, INDEX_DIR); const dbPath = join(indexDir, 'index.db'); if (!existsSync(dbPath)) { return { success: false, section, error: `No ${PRODUCT_NAME} index found at ${projectPath}. Run ${TOOL_PREFIX}init first.`, }; } const summaryPath = join(indexDir, 'summary.md'); try { // Read existing summary or create new let summaryContent = ''; if (existsSync(summaryPath)) { summaryContent = readFileSync(summaryPath, 'utf-8'); } // Section headers const sectionHeaders: Record<string, string> = { purpose: '## Purpose', architecture: '## Architecture', concepts: '## Key Concepts', patterns: '## Patterns', notes: '## Notes', }; const header = sectionHeaders[section]; const sectionRegex = new RegExp(`^${header}\\n([\\s\\S]*?)(?=^## |$)`, 'm'); if (replace) { // Replace entire section if (sectionRegex.test(summaryContent)) { summaryContent = summaryContent.replace(sectionRegex, `${header}\n${content}\n\n`); } else { // Add new section at end summaryContent = summaryContent.trimEnd() + `\n\n${header}\n${content}\n`; } } else { // Append to section const match = summaryContent.match(sectionRegex); if (match) { const existingContent = match[1].trimEnd(); const newContent = existingContent ? `${existingContent}\n${content}` : content; summaryContent = summaryContent.replace(sectionRegex, `${header}\n${newContent}\n\n`); } else { // Add new section at end summaryContent = summaryContent.trimEnd() + `\n\n${header}\n${content}\n`; } } // Write back writeFileSync(summaryPath, summaryContent.trimStart()); return { success: true, section, }; } catch (err) { return { success: false, section, error: err instanceof Error ? err.message : String(err), }; } }