This commit is contained in:
2025-12-15 15:54:25 +00:00
parent 3485392979
commit 90af6eb1b1
3 changed files with 55 additions and 23 deletions

View File

@@ -29,7 +29,7 @@
"@push.rocks/early": "^4.0.4", "@push.rocks/early": "^4.0.4",
"@push.rocks/npmextra": "^5.3.3", "@push.rocks/npmextra": "^5.3.3",
"@push.rocks/qenv": "^6.1.3", "@push.rocks/qenv": "^6.1.3",
"@push.rocks/smartagent": "file:../../push.rocks/smartagent", "@push.rocks/smartagent": "1.2.5",
"@push.rocks/smartai": "^0.8.0", "@push.rocks/smartai": "^0.8.0",
"@push.rocks/smartcli": "^4.0.19", "@push.rocks/smartcli": "^4.0.19",
"@push.rocks/smartdelay": "^3.0.5", "@push.rocks/smartdelay": "^3.0.5",

11
pnpm-lock.yaml generated
View File

@@ -21,8 +21,8 @@ importers:
specifier: ^6.1.3 specifier: ^6.1.3
version: 6.1.3 version: 6.1.3
'@push.rocks/smartagent': '@push.rocks/smartagent':
specifier: file:../../push.rocks/smartagent specifier: 1.2.5
version: file:../../push.rocks/smartagent(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76) version: 1.2.5(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)
'@push.rocks/smartai': '@push.rocks/smartai':
specifier: ^0.8.0 specifier: ^0.8.0
version: 0.8.0(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76) version: 0.8.0(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)
@@ -1155,8 +1155,8 @@ packages:
'@push.rocks/qenv@6.1.3': '@push.rocks/qenv@6.1.3':
resolution: {integrity: sha512-+z2hsAU/7CIgpYLFqvda8cn9rUBMHqLdQLjsFfRn5jPoD7dJ5rFlpkbhfM4Ws8mHMniwWaxGKo+q/YBhtzRBLg==} resolution: {integrity: sha512-+z2hsAU/7CIgpYLFqvda8cn9rUBMHqLdQLjsFfRn5jPoD7dJ5rFlpkbhfM4Ws8mHMniwWaxGKo+q/YBhtzRBLg==}
'@push.rocks/smartagent@file:../../push.rocks/smartagent': '@push.rocks/smartagent@1.2.5':
resolution: {directory: ../../push.rocks/smartagent, type: directory} resolution: {integrity: sha512-qV7zyHbp5p5ySg16uipjIdYzKM85fn5/l97pKlZz9awRZhOcvYblmypQRKHlMc+O2mVevxLY4Q/6pzYwI8UXvw==}
'@push.rocks/smartai@0.8.0': '@push.rocks/smartai@0.8.0':
resolution: {integrity: sha512-guzi28meUDc3mydC8kpoA+4pzExRQqygXYFDD4qQSWPpIRHQ7qhpeNqJzrrGezT1yOH5Gb9taPEGwT56hI+nwQ==} resolution: {integrity: sha512-guzi28meUDc3mydC8kpoA+4pzExRQqygXYFDD4qQSWPpIRHQ7qhpeNqJzrrGezT1yOH5Gb9taPEGwT56hI+nwQ==}
@@ -6920,7 +6920,7 @@ snapshots:
'@push.rocks/smartlog': 3.1.10 '@push.rocks/smartlog': 3.1.10
'@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpath': 6.0.0
'@push.rocks/smartagent@file:../../push.rocks/smartagent(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)': '@push.rocks/smartagent@1.2.5(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)':
dependencies: dependencies:
'@push.rocks/smartai': 0.8.0(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76) '@push.rocks/smartai': 0.8.0(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)
'@push.rocks/smartbrowser': 2.0.8(typescript@5.9.3) '@push.rocks/smartbrowser': 2.0.8(typescript@5.9.3)
@@ -6928,6 +6928,7 @@ snapshots:
'@push.rocks/smartfs': 1.2.0 '@push.rocks/smartfs': 1.2.0
'@push.rocks/smartrequest': 5.0.1 '@push.rocks/smartrequest': 5.0.1
'@push.rocks/smartshell': 3.3.0 '@push.rocks/smartshell': 3.3.0
minimatch: 10.1.1
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
- bare-abort-controller - bare-abort-controller

View File

@@ -116,7 +116,6 @@ export class Commit {
} }
// Use DualAgentOrchestrator for commit message generation // Use DualAgentOrchestrator for commit message generation
// Note: No filesystem tool needed - the diff already contains all change information
const commitOrchestrator = new plugins.smartagent.DualAgentOrchestrator({ const commitOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
smartAiInstance: this.aiDocsRef.smartAiInstance, smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai', defaultProvider: 'openai',
@@ -125,43 +124,65 @@ export class Commit {
guardianPolicyPrompt: ` guardianPolicyPrompt: `
You validate commit messages for semantic versioning compliance. You validate commit messages for semantic versioning compliance.
APPROVE if: APPROVE tool calls for:
- Reading package.json or source files to understand project context
- Using tree to see project structure
- Listing directory contents
REJECT tool calls for:
- Reading files outside the project directory
- Writing, deleting, or modifying any files
- Any destructive operations
APPROVE final output if:
- Version level (fix/feat/BREAKING CHANGE) matches the scope of changes in the diff - Version level (fix/feat/BREAKING CHANGE) matches the scope of changes in the diff
- Commit message is clear, professional, and follows conventional commit conventions - Commit message is clear, professional, and follows conventional commit conventions
- No personal information, licensing details, or AI mentions (Claude/Codex) included - No personal information, licensing details, or AI mentions (Claude/Codex) included
- JSON structure is valid with all required fields - JSON structure is valid with all required fields
- Scope accurately reflects the changed modules/files - Scope accurately reflects the changed modules/files
REJECT with specific feedback if: REJECT final output if:
- Version level doesn't match the scope of changes (e.g., "feat" for a typo fix should be "fix") - Version level doesn't match the scope of changes (e.g., "feat" for a typo fix should be "fix")
- Message is vague, unprofessional, or contains sensitive information - Message is vague, unprofessional, or contains sensitive information
- JSON is malformed or missing required fields - JSON is malformed or missing required fields
`, `,
}); });
// Register scoped filesystem tool for agent exploration
commitOrchestrator.registerScopedFilesystemTool(this.projectDir, [
'.nogit/**',
'node_modules/**',
'.git/**',
'dist/**',
'dist_*/**',
]);
await commitOrchestrator.start(); await commitOrchestrator.start();
const commitTaskPrompt = ` const commitTaskPrompt = `
You create a commit message for a git commit. You create a commit message for a git commit.
Project directory: ${this.projectDir} Project directory: ${this.projectDir}
You have access to a filesystem tool to explore the project if needed:
- Use tree to see project structure
- Use read to read package.json or source files for context
Analyze the git diff below to understand what changed and generate a commit message. Analyze the git diff below to understand what changed and generate a commit message.
You should not include any licensing information or personal information. You should not include any licensing information or personal information.
Never mention CLAUDE code, or codex. Never mention CLAUDE code, or codex.
Important: Answer only in valid JSON. Your final output (inside the task_complete tags) must be ONLY valid JSON - the raw JSON object, nothing else.
No explanations, no summaries, no markdown - just the JSON object that can be parsed with JSON.parse().
Your answer should be parseable with JSON.parse() without modifying anything. Here is the structure of the JSON you must return:
Here is the structure of the JSON you should return: {
"recommendedNextVersionLevel": "fix" | "feat" | "BREAKING CHANGE",
interface { "recommendedNextVersionScope": "string",
recommendedNextVersionLevel: 'fix' | 'feat' | 'BREAKING CHANGE'; // the recommended next version level "recommendedNextVersionMessage": "string",
recommendedNextVersionScope: string; // scope name like "core", "cli", or specific class names "recommendedNextVersionDetails": ["string"],
recommendedNextVersionMessage: string; // the commit message (don't include fix/feat prefix) "recommendedNextVersion": "x.x.x"
recommendedNextVersionDetails: string[]; // detailed bullet points for the changelog
recommendedNextVersion: string; // the recommended next version x.x.x
} }
For recommendedNextVersionDetails, only add entries that have obvious value to the reader. For recommendedNextVersionDetails, only add entries that have obvious value to the reader.
@@ -170,7 +191,7 @@ Here is the git diff showing what changed:
${processedDiffString} ${processedDiffString}
Generate the commit message based on these changes. Analyze these changes and output the JSON commit message object.
`; `;
const commitResult = await commitOrchestrator.run(commitTaskPrompt); const commitResult = await commitOrchestrator.run(commitTaskPrompt);
@@ -180,9 +201,19 @@ Generate the commit message based on these changes.
throw new Error(`Commit message generation failed: ${commitResult.status}`); throw new Error(`Commit message generation failed: ${commitResult.status}`);
} }
const resultObject: INextCommitObject = JSON.parse( // Extract JSON from result - handle cases where AI adds text around it
commitResult.result.replace('```json', '').replace('```', '') let jsonString = commitResult.result
); .replace(/```json\n?/gi, '')
.replace(/```\n?/gi, '');
// Try to find JSON object in the result
const jsonMatch = jsonString.match(/\{[\s\S]*\}/);
if (!jsonMatch) {
throw new Error(`Could not find JSON object in result: ${jsonString.substring(0, 100)}...`);
}
jsonString = jsonMatch[0];
const resultObject: INextCommitObject = JSON.parse(jsonString);
const previousChangelogPath = plugins.path.join(this.projectDir, 'changelog.md'); const previousChangelogPath = plugins.path.join(this.projectDir, 'changelog.md');
let previousChangelog: plugins.smartfile.SmartFile; let previousChangelog: plugins.smartfile.SmartFile;