import type { AiDoc } from '../classes.aidoc.js'; import * as plugins from '../plugins.js'; import { ProjectContext } from './projectcontext.js'; import { logger } from '../logging.js'; interface IDescriptionInterface { description: string; keywords: string[]; } export class Description { // INSTANCE private aiDocsRef: AiDoc; private projectDir: string; constructor(aiDocsRef: AiDoc, projectDirArg: string) { this.aiDocsRef = aiDocsRef; this.projectDir = projectDirArg; } public async build() { // Use runAgent with filesystem tool for agent-driven exploration const fsTools = plugins.smartagentTools.filesystemTool({ rootDir: this.projectDir }); const descriptionSystemPrompt = ` You create project descriptions and keywords for npm packages. You have access to filesystem tools to explore the project. IMPORTANT RULES: - Only READ files (package.json, .smartconfig.json, source files in ts/) - Do NOT write, delete, or modify any files - Your final response must be valid JSON only - Description must be a clear, concise one-sentence summary - Keywords must be relevant to the project's use cases - Both description and keywords fields must be present - Do NOT wrap JSON in markdown code blocks `; const descriptionTaskPrompt = ` PROJECT DIRECTORY: ${this.projectDir} Use the filesystem tools to explore the project and understand what it does: 1. First, use list_directory to see the project structure 2. Read package.json to understand the package name and current description 3. Read .smartconfig.json if it exists for additional metadata 4. Read key source files in ts/ directory to understand the implementation Then generate a description and keywords based on your exploration. Your FINAL response must be valid JSON adhering to this interface: { description: string; // a sensible short, one sentence description of the project keywords: string[]; // an array of tags that describe the project based on use cases } Important: Answer only in valid JSON. Your answer should be parseable with JSON.parse() without modifying anything. Don't wrap the JSON in \`\`\`json\`\`\` - just return the raw JSON object. `; logger.log('info', 'Starting description generation with agent...'); const descriptionResult = await plugins.smartagent.runAgent({ model: this.aiDocsRef.model, prompt: descriptionTaskPrompt, system: descriptionSystemPrompt, tools: fsTools, maxSteps: 15, onToolCall: (toolName) => logger.log('info', `[Description] Tool call: ${toolName}`), }); console.log(descriptionResult.text); const resultObject: IDescriptionInterface = JSON.parse( descriptionResult.text.replace('```json', '').replace('```', ''), ); // Use ProjectContext to get file handles for writing const projectContext = new ProjectContext(this.projectDir); const files = await projectContext.gatherFiles(); // Update smartconfig.json const smartconfigJson = files.smartfilesNpmextraJSON; const smartconfigJsonContent = JSON.parse(smartconfigJson.contents.toString()); smartconfigJsonContent['gitzone'].module.description = resultObject.description; smartconfigJsonContent['gitzone'].module.keywords = resultObject.keywords; smartconfigJson.contents = Buffer.from(JSON.stringify(smartconfigJsonContent, null, 2)); await smartconfigJson.write(); // Update package.json const packageJson = files.smartfilePackageJSON; const packageJsonContent = JSON.parse(packageJson.contents.toString()); packageJsonContent.description = resultObject.description; packageJsonContent.keywords = resultObject.keywords; packageJson.contents = Buffer.from(JSON.stringify(packageJsonContent, null, 2)); await packageJson.write(); console.log(`\n======================\n`); console.log(JSON.stringify(resultObject, null, 2)); console.log(`\n======================\n`); return descriptionResult.text; } }