Files
tsdoc/ts/aidocs_classes/description.ts
2025-12-15 15:14:16 +00:00

126 lines
4.6 KiB
TypeScript

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 DualAgentOrchestrator with filesystem tool for agent-driven exploration
const descriptionOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
maxIterations: 15,
maxResultChars: 10000, // Limit tool output to prevent token explosion
maxHistoryMessages: 15, // Limit history window
logPrefix: '[Description]',
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
guardianPolicyPrompt: `
You validate description generation tool calls and outputs.
APPROVE tool calls for:
- Reading package.json, npmextra.json, or source files in the ts/ directory
- Listing directory contents to understand project structure
- Using tree to see project structure
REJECT tool calls for:
- Reading files outside the project directory
- Writing, deleting, or modifying any files
- Any destructive operations
For final output, APPROVE if:
- JSON is valid and parseable
- Description is a clear, concise one-sentence summary
- Keywords are relevant to the project's use cases
- Both description and keywords fields are present
REJECT final output if:
- JSON is malformed or wrapped in markdown code blocks
- Description is too long or vague
- Keywords are irrelevant or generic
`,
});
// Register scoped filesystem tool for agent exploration
descriptionOrchestrator.registerScopedFilesystemTool(this.projectDir);
await descriptionOrchestrator.start();
const descriptionTaskPrompt = `
You create a project description and keywords for an npm package.
PROJECT DIRECTORY: ${this.projectDir}
Use the filesystem tool to explore the project and understand what it does:
1. First, use tree to see the project structure
2. Read package.json to understand the package name and current description
3. Read npmextra.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.
`;
const descriptionResult = await descriptionOrchestrator.run(descriptionTaskPrompt);
await descriptionOrchestrator.stop();
if (!descriptionResult.success) {
throw new Error(`Description generation failed: ${descriptionResult.status}`);
}
console.log(descriptionResult.result);
const resultObject: IDescriptionInterface = JSON.parse(
descriptionResult.result.replace('```json', '').replace('```', ''),
);
// Use ProjectContext to get file handles for writing
const projectContext = new ProjectContext(this.projectDir);
const files = await projectContext.gatherFiles();
// Update npmextra.json
const npmextraJson = files.smartfilesNpmextraJSON;
const npmextraJsonContent = JSON.parse(npmextraJson.contents.toString());
npmextraJsonContent['@git.zone/cli'].module.description = resultObject.description;
npmextraJsonContent['@git.zone/cli'].module.keywords = resultObject.keywords;
npmextraJson.contents = Buffer.from(JSON.stringify(npmextraJsonContent, null, 2));
await npmextraJson.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.result;
}
}