import * as plugins from '../plugins.js'; import { AiDoc } from '../classes.aidoc.js'; import { ProjectContext } from './projectcontext.js'; export interface INextCommitObject { recommendedNextVersionLevel: 'fix' | 'feat' | 'BREAKING CHANGE'; // the recommended next version level of the project recommendedNextVersionScope: string; // the recommended scope name of the next version, like "core" or "cli", or specific class names. recommendedNextVersionMessage: string; // the commit message. Don't put fix() feat() or BREAKING CHANGE in the message. Please just the message itself. recommendedNextVersionDetauls: string[]; // detailed bullet points for the changelog recommendedNextVersion: string; // the recommended next version of the project, x.x.x changelog?: string; // the changelog for the next version } export class Commit { private aiDocsRef: AiDoc; private projectDir: string; constructor(aiDocsRef: AiDoc, projectDirArg: string) { this.aiDocsRef = aiDocsRef; this.projectDir = projectDirArg; } public async buildNextCommitObject(): Promise { const smartgitInstance = new plugins.smartgit.Smartgit(); await smartgitInstance.init(); const gitRepo = await plugins.smartgit.GitRepo.fromOpeningRepoDir( smartgitInstance, this.projectDir ); const diffString = await gitRepo.getUncommittedDiff(); const projectContext = new ProjectContext(this.projectDir); let contextString = await projectContext.update(); contextString = ` ${contextString} Below is the diff of the uncommitted changes. If nothing is changed, there are no changes: ${diffString || 'No changes.'} `; let result = await this.aiDocsRef.openaiInstance.chat({ systemMessage: ` You create a commit message for a git commit. The commit message should be based on the files in the project. You should not include any licensing information. You should not include any personal information. Important: Answer only in valid JSON. Your answer should be parseable with JSON.parse() without modifying anything. Here is the structure of the JSON you should return: interface { recommendedNextVersionLevel: 'fix' | 'feat' | 'BREAKING CHANGE'; // the recommended next version level of the project recommendedNextVersionScope: string; // the recommended scope name of the next version, like "core" or "cli", or specific class names. recommendedNextVersionMessage: string; // the commit message. Don't put fix() feat() or BREAKING CHANGE in the message. Please just the message itself. recommendedNextVersionDetails: string[]; // detailed bullet points for the changelog recommendedNextVersion: string; // the recommended next version of the project, x.x.x } You are being given the files of the project. You should use them to create the commit message. Also you are given a diff `, messageHistory: [], userMessage: contextString, }); // console.log(result.message); const resultObject: INextCommitObject = JSON.parse( result.message.replace('```json', '').replace('```', '') ); // lets build the changelog based on that const commitMessages = await gitRepo.getAllCommitMessages(); const previousChangelogPath = plugins.path.join(this.projectDir, 'changelog.md'); let previousChangelog: plugins.smartfile.SmartFile; if (await plugins.smartfile.fs.fileExists(previousChangelogPath)) { previousChangelog = await plugins.smartfile.SmartFile.fromFilePath(previousChangelogPath); } if (!previousChangelog) { let result2 = await this.aiDocsRef.openaiInstance.chat({ messageHistory: [], systemMessage: ` You are building a changelog.md file for the project. Omit commits and versions that lack relevant changes. A changelog entry should look like this: ## yyyy-mm-dd - x.x.x - scope here main descriptiom here - detailed bullet points follow You are given: * the commit messages of the project Only return the changelog file, so it can be written directly to changelog.md`, userMessage: ` Here are the commit messages: ${commitMessages.join('\n')} `, }); previousChangelog = await plugins.smartfile.SmartFile.fromString(previousChangelogPath, result2.message, 'utf8'); } let oldChangelog = previousChangelog.contents.toString().replace('# Changelog\n\n', ''); let newDateString = new plugins.smarttime.ExtendedDate().exportToEuropeanDate(); let newChangelog = `# Changelog\n\n${ `## ${newDateString} - {{nextVersion}} - {{nextVersionScope}} {{nextVersionMessage}} {{nextVersionDetails}} `}\n\n${oldChangelog}\n`; resultObject.changelog = newChangelog; return resultObject; } }