This commit is contained in:
2025-12-15 14:34:02 +00:00
parent 9cae46e2fe
commit bcded1eafa
22 changed files with 288 additions and 3620 deletions

View File

@@ -17,20 +17,6 @@ export class Readme {
public async build() {
let finalReadmeString = ``;
// Use the new TaskContextFactory for optimized context
const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(
this.projectDir,
this.aiDocsRef.openaiInstance
);
await taskContextFactory.initialize();
// Generate context specifically for readme task
const contextResult = await taskContextFactory.createContextForReadme();
const contextString = contextResult.context;
// Log token usage statistics
console.log(`Token usage - Context: ${contextResult.tokenCount}, Files: ${contextResult.includedFiles.length + contextResult.trimmedFiles.length}, Savings: ${contextResult.tokenSavings}`);
// lets first check legal before introducung any cost
const projectContext = new ProjectContext(this.projectDir);
const npmExtraJson = JSON.parse(
@@ -42,50 +28,88 @@ export class Readme {
console.log(error);
}
let result = await this.aiDocsRef.openaiInstance.chat({
systemMessage: `
You create markdown readmes for npm projects. You only output the markdown readme.
// Gather project context upfront to avoid token explosion from filesystem tool
const contextString = await projectContext.convertFilesToContext([
(await projectContext.gatherFiles()).smartfilePackageJSON,
(await projectContext.gatherFiles()).smartfilesReadme,
(await projectContext.gatherFiles()).smartfilesReadmeHints,
(await projectContext.gatherFiles()).smartfilesNpmextraJSON,
...(await projectContext.gatherFiles()).smartfilesMod,
]);
The Readme should follow the following template:
// Use DualAgentOrchestrator for readme generation
const readmeOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
guardianPolicyPrompt: `
You validate README generation.
APPROVE if:
- README follows proper markdown format
- Contains Install and Usage sections
- Code examples are correct TypeScript/ESM syntax
- Documentation is comprehensive and helpful
REJECT if:
- README is incomplete or poorly formatted
- Contains licensing information (added separately)
- Uses CommonJS syntax instead of ESM
- Contains "in conclusion" or similar filler
`,
});
await readmeOrchestrator.start();
const readmeTaskPrompt = `
You create markdown READMEs for npm projects. You only output the markdown readme.
Analyze the project files provided below to understand the codebase, then generate a comprehensive README.
The README should follow this template:
# Project Name
[
The name is the module name of package.json
The description is in the description field of package.json
]
[The name from package.json and description]
## Install
[
Write a short text on how to install the project
]
[Short text on how to install the project]
## Usage
[
[
Give code examples here.
Construct sensible scenarios for the user.
Make sure to show a complete set of features of the module.
Don't omit use cases.
It does not matter how much time you need.
ALWAYS USE ESM SYNTAX AND TYPESCRIPT.
DON'T CHICKEN OUT. Write at least 4000 words. More if necessary.
If there is already a readme, take the Usage section as base. Remove outdated content, and expand and improve upon the valid parts.
Super important: Check for completenes.
Don't include any licensing information. This will be added in a later step.
Avoid "in conclusions".
Good to know:
* npmextra.json contains overall module information.
* readme.hints.md provides valuable hints about module ideas.
Write at least 4000 words. More if necessary.
If there is already a readme, take the Usage section as base. Remove outdated content, expand and improve.
Check for completeness.
Don't include any licensing information. This will be added later.
Avoid "in conclusion" statements.
]
`,
messageHistory: [],
userMessage: contextString,
});
finalReadmeString += result.message + '\n' + legalInfo;
Here are the project files:
${contextString}
Generate the README based on these files.
`;
const readmeResult = await readmeOrchestrator.run(readmeTaskPrompt);
await readmeOrchestrator.stop();
if (!readmeResult.success) {
throw new Error(`README generation failed: ${readmeResult.status}`);
}
// Clean up markdown formatting if wrapped in code blocks
let resultMessage = readmeResult.result
.replace(/^```markdown\n?/i, '')
.replace(/\n?```$/i, '');
finalReadmeString += resultMessage + '\n' + legalInfo;
console.log(`\n======================\n`);
console.log(result.message);
console.log(resultMessage);
console.log(`\n======================\n`);
const readme = (await projectContext.gatherFiles()).smartfilesReadme;
@@ -96,60 +120,95 @@ The Readme should follow the following template:
const tsPublishInstance = new plugins.tspublish.TsPublish();
const subModules = await tsPublishInstance.getModuleSubDirs(paths.cwd);
logger.log('info', `Found ${Object.keys(subModules).length} sub modules`);
for (const subModule of Object.keys(subModules)) {
logger.log('info', `Building readme for ${subModule}`);
const subModuleContextString = await projectContext.update();
let result = await this.aiDocsRef.openaiInstance.chat({
systemMessage: `
You create markdown readmes for npm projects. You only output the markdown readme.
IMPORTANT: YOU ARE NOW CREATING THE README FOR THE FOLLOWING SUB MODULE: ${subModule} !!!!!!!!!!!
The Sub Module will be published with the following data:
${JSON.stringify(await plugins.fsInstance.file(plugins.path.join(paths.cwd, subModule, 'tspublish.json')).encoding('utf8').read(), null, 2)}
const tspublishData = await plugins.fsInstance
.file(plugins.path.join(paths.cwd, subModule, 'tspublish.json'))
.encoding('utf8')
.read();
The Readme should follow the following template:
# Project Name
[
The name is the module name of package.json
The description is in the description field of package.json
]
## Install
[
Write a short text on how to install the project
]
## Usage
[
Give code examples here.
Construct sensible scenarios for the user.
Make sure to show a complete set of features of the module.
Don't omit use cases.
It does not matter how much time you need.
ALWAYS USE ESM SYNTAX AND TYPESCRIPT.
DON'T CHICKEN OUT. Write at least 4000 words. More if necessary.
If there is already a readme, take the Usage section as base. Remove outdated content, and expand and improve upon the valid parts.
Super important: Check for completenes.
Don't include any licensing information. This will be added in a later step.
Avoid "in conclusions".
Good to know:
* npmextra.json contains overall module information.
* readme.hints.md provides valuable hints about module ideas.
* Your output lands directly in the readme.md file.
* Don't use \`\`\` at the beginning or the end. It'll cause problems. Only use it for codeblocks. You are directly writing markdown. No need to introduce it weirdly.
]
`,
messageHistory: [],
userMessage: subModuleContextString,
// Gather submodule context
const subModuleContext = new ProjectContext(plugins.path.join(paths.cwd, subModule));
let subModuleContextString = '';
try {
const subModuleFiles = await subModuleContext.gatherFiles();
subModuleContextString = await subModuleContext.convertFilesToContext([
subModuleFiles.smartfilePackageJSON,
subModuleFiles.smartfilesNpmextraJSON,
...subModuleFiles.smartfilesMod,
]);
} catch (e) {
// Submodule may not have all files, continue with what we have
logger.log('warn', `Could not gather full context for ${subModule}`);
}
// Create a new orchestrator for each submodule
const subModuleOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
guardianPolicyPrompt: `
You validate README generation for submodules.
APPROVE comprehensive, well-formatted markdown with ESM TypeScript examples.
REJECT incomplete READMEs or those with licensing info.
`,
});
const subModuleReadmeString = result.message + '\n' + legalInfo;
await plugins.fsInstance.file(plugins.path.join(paths.cwd, subModule, 'readme.md')).encoding('utf8').write(subModuleReadmeString);
logger.log('success', `Built readme for ${subModule}`);
await subModuleOrchestrator.start();
const subModulePrompt = `
You create markdown READMEs for npm projects. You only output the markdown readme.
SUB MODULE: ${subModule}
IMPORTANT: YOU ARE CREATING THE README FOR THIS SUB MODULE: ${subModule}
The Sub Module will be published with:
${JSON.stringify(tspublishData, null, 2)}
Generate a README following the template:
# Project Name
[name and description from package.json]
## Install
[installation instructions]
## Usage
[
Code examples with complete features.
ESM TypeScript syntax only.
Write at least 4000 words.
No licensing information.
No "in conclusion".
]
Don't use \`\`\` at the beginning or end. Only for code blocks.
Here are the submodule files:
${subModuleContextString}
Generate the README based on these files.
`;
const subModuleResult = await subModuleOrchestrator.run(subModulePrompt);
await subModuleOrchestrator.stop();
if (subModuleResult.success) {
const subModuleReadmeString = subModuleResult.result
.replace(/^```markdown\n?/i, '')
.replace(/\n?```$/i, '') + '\n' + legalInfo;
await plugins.fsInstance
.file(plugins.path.join(paths.cwd, subModule, 'readme.md'))
.encoding('utf8')
.write(subModuleReadmeString);
logger.log('success', `Built readme for ${subModule}`);
} else {
logger.log('error', `Failed to build readme for ${subModule}: ${subModuleResult.status}`);
}
}
return result.message;
return resultMessage;
}
}