cast-code 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +217 -0
- package/dist/app.module.js +45 -0
- package/dist/app.module.js.map +1 -0
- package/dist/common/common.module.js +49 -0
- package/dist/common/common.module.js.map +1 -0
- package/dist/common/constants/index.js +105 -0
- package/dist/common/constants/index.js.map +1 -0
- package/dist/common/index.js +24 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/services/config.service.js +119 -0
- package/dist/common/services/config.service.js.map +1 -0
- package/dist/common/services/llm.service.js +56 -0
- package/dist/common/services/llm.service.js.map +1 -0
- package/dist/common/services/markdown-parser.service.js +101 -0
- package/dist/common/services/markdown-parser.service.js.map +1 -0
- package/dist/common/services/markdown-renderer.service.js +220 -0
- package/dist/common/services/markdown-renderer.service.js.map +1 -0
- package/dist/common/services/multi-llm.service.js +115 -0
- package/dist/common/services/multi-llm.service.js.map +1 -0
- package/dist/common/types/index.js +20 -0
- package/dist/common/types/index.js.map +1 -0
- package/dist/common/types/markdown.types.js +6 -0
- package/dist/common/types/markdown.types.js.map +1 -0
- package/dist/main.js +84 -0
- package/dist/main.js.map +1 -0
- package/dist/modules/agents/agents.module.js +43 -0
- package/dist/modules/agents/agents.module.js.map +1 -0
- package/dist/modules/agents/definitions/architect.md +35 -0
- package/dist/modules/agents/definitions/backend.md +43 -0
- package/dist/modules/agents/definitions/coder.md +34 -0
- package/dist/modules/agents/definitions/devops.md +42 -0
- package/dist/modules/agents/definitions/frontend.md +46 -0
- package/dist/modules/agents/definitions/reviewer.md +35 -0
- package/dist/modules/agents/definitions/tester.md +41 -0
- package/dist/modules/agents/index.js +23 -0
- package/dist/modules/agents/index.js.map +1 -0
- package/dist/modules/agents/services/agent-loader.service.js +150 -0
- package/dist/modules/agents/services/agent-loader.service.js.map +1 -0
- package/dist/modules/agents/services/agent-registry.service.js +108 -0
- package/dist/modules/agents/services/agent-registry.service.js.map +1 -0
- package/dist/modules/agents/types/agent.types.js +6 -0
- package/dist/modules/agents/types/agent.types.js.map +1 -0
- package/dist/modules/agents/types/index.js +20 -0
- package/dist/modules/agents/types/index.js.map +1 -0
- package/dist/modules/config/config.module.js +38 -0
- package/dist/modules/config/config.module.js.map +1 -0
- package/dist/modules/config/index.js +24 -0
- package/dist/modules/config/index.js.map +1 -0
- package/dist/modules/config/services/config-commands.service.js +405 -0
- package/dist/modules/config/services/config-commands.service.js.map +1 -0
- package/dist/modules/config/services/config-manager.service.js +175 -0
- package/dist/modules/config/services/config-manager.service.js.map +1 -0
- package/dist/modules/config/services/init-config.service.js +238 -0
- package/dist/modules/config/services/init-config.service.js.map +1 -0
- package/dist/modules/config/types/config.types.js +163 -0
- package/dist/modules/config/types/config.types.js.map +1 -0
- package/dist/modules/config/types/index.js +20 -0
- package/dist/modules/config/types/index.js.map +1 -0
- package/dist/modules/core/core.module.js +60 -0
- package/dist/modules/core/core.module.js.map +1 -0
- package/dist/modules/core/index.js +22 -0
- package/dist/modules/core/index.js.map +1 -0
- package/dist/modules/core/services/deep-agent.service.js +575 -0
- package/dist/modules/core/services/deep-agent.service.js.map +1 -0
- package/dist/modules/core/services/plan-mode.service.js +225 -0
- package/dist/modules/core/services/plan-mode.service.js.map +1 -0
- package/dist/modules/git/git.module.js +48 -0
- package/dist/modules/git/git.module.js.map +1 -0
- package/dist/modules/git/index.js +23 -0
- package/dist/modules/git/index.js.map +1 -0
- package/dist/modules/git/services/code-review.service.js +330 -0
- package/dist/modules/git/services/code-review.service.js.map +1 -0
- package/dist/modules/git/services/commit-generator.service.js +403 -0
- package/dist/modules/git/services/commit-generator.service.js.map +1 -0
- package/dist/modules/git/services/index.js +21 -0
- package/dist/modules/git/services/index.js.map +1 -0
- package/dist/modules/git/services/monorepo-detector.service.js +338 -0
- package/dist/modules/git/services/monorepo-detector.service.js.map +1 -0
- package/dist/modules/git/services/pr-generator.service.js +429 -0
- package/dist/modules/git/services/pr-generator.service.js.map +1 -0
- package/dist/modules/git/services/release-notes.service.js +426 -0
- package/dist/modules/git/services/release-notes.service.js.map +1 -0
- package/dist/modules/git/types/git.types.js +6 -0
- package/dist/modules/git/types/git.types.js.map +1 -0
- package/dist/modules/git/types/index.js +20 -0
- package/dist/modules/git/types/index.js.map +1 -0
- package/dist/modules/mcp/catalog/mcp-templates.js +606 -0
- package/dist/modules/mcp/catalog/mcp-templates.js.map +1 -0
- package/dist/modules/mcp/index.js +23 -0
- package/dist/modules/mcp/index.js.map +1 -0
- package/dist/modules/mcp/mcp.module.js +35 -0
- package/dist/modules/mcp/mcp.module.js.map +1 -0
- package/dist/modules/mcp/services/mcp-client.service.js +289 -0
- package/dist/modules/mcp/services/mcp-client.service.js.map +1 -0
- package/dist/modules/mcp/services/mcp-registry.service.js +197 -0
- package/dist/modules/mcp/services/mcp-registry.service.js.map +1 -0
- package/dist/modules/mcp/types/index.js +20 -0
- package/dist/modules/mcp/types/index.js.map +1 -0
- package/dist/modules/mcp/types/mcp.types.js +6 -0
- package/dist/modules/mcp/types/mcp.types.js.map +1 -0
- package/dist/modules/memory/index.js +23 -0
- package/dist/modules/memory/index.js.map +1 -0
- package/dist/modules/memory/memory.module.js +35 -0
- package/dist/modules/memory/memory.module.js.map +1 -0
- package/dist/modules/memory/services/memory-tools.service.js +78 -0
- package/dist/modules/memory/services/memory-tools.service.js.map +1 -0
- package/dist/modules/memory/services/memory.service.js +169 -0
- package/dist/modules/memory/services/memory.service.js.map +1 -0
- package/dist/modules/memory/types/index.js +20 -0
- package/dist/modules/memory/types/index.js.map +1 -0
- package/dist/modules/memory/types/memory.types.js +6 -0
- package/dist/modules/memory/types/memory.types.js.map +1 -0
- package/dist/modules/mentions/index.js +22 -0
- package/dist/modules/mentions/index.js.map +1 -0
- package/dist/modules/mentions/mentions.module.js +32 -0
- package/dist/modules/mentions/mentions.module.js.map +1 -0
- package/dist/modules/mentions/services/mentions.service.js +336 -0
- package/dist/modules/mentions/services/mentions.service.js.map +1 -0
- package/dist/modules/mentions/types/index.js +20 -0
- package/dist/modules/mentions/types/index.js.map +1 -0
- package/dist/modules/mentions/types/mention.types.js +19 -0
- package/dist/modules/mentions/types/mention.types.js.map +1 -0
- package/dist/modules/permissions/index.js +23 -0
- package/dist/modules/permissions/index.js.map +1 -0
- package/dist/modules/permissions/permissions.module.js +35 -0
- package/dist/modules/permissions/permissions.module.js.map +1 -0
- package/dist/modules/permissions/services/permission.service.js +269 -0
- package/dist/modules/permissions/services/permission.service.js.map +1 -0
- package/dist/modules/permissions/services/prompt.service.js +116 -0
- package/dist/modules/permissions/services/prompt.service.js.map +1 -0
- package/dist/modules/permissions/types/permission.types.js +32 -0
- package/dist/modules/permissions/types/permission.types.js.map +1 -0
- package/dist/modules/project/index.js +24 -0
- package/dist/modules/project/index.js.map +1 -0
- package/dist/modules/project/project.module.js +38 -0
- package/dist/modules/project/project.module.js.map +1 -0
- package/dist/modules/project/services/project-analyzer.service.js +1063 -0
- package/dist/modules/project/services/project-analyzer.service.js.map +1 -0
- package/dist/modules/project/services/project-context.service.js +62 -0
- package/dist/modules/project/services/project-context.service.js.map +1 -0
- package/dist/modules/project/services/project-loader.service.js +147 -0
- package/dist/modules/project/services/project-loader.service.js.map +1 -0
- package/dist/modules/project/types/index.js +20 -0
- package/dist/modules/project/types/index.js.map +1 -0
- package/dist/modules/project/types/project.types.js +6 -0
- package/dist/modules/project/types/project.types.js.map +1 -0
- package/dist/modules/repl/index.js +21 -0
- package/dist/modules/repl/index.js.map +1 -0
- package/dist/modules/repl/repl.module.js +66 -0
- package/dist/modules/repl/repl.module.js.map +1 -0
- package/dist/modules/repl/services/commands/agent-commands.service.js +196 -0
- package/dist/modules/repl/services/commands/agent-commands.service.js.map +1 -0
- package/dist/modules/repl/services/commands/git-commands.service.js +500 -0
- package/dist/modules/repl/services/commands/git-commands.service.js.map +1 -0
- package/dist/modules/repl/services/commands/mcp-commands.service.js +579 -0
- package/dist/modules/repl/services/commands/mcp-commands.service.js.map +1 -0
- package/dist/modules/repl/services/commands/project-commands.service.js +226 -0
- package/dist/modules/repl/services/commands/project-commands.service.js.map +1 -0
- package/dist/modules/repl/services/commands/repl-commands.service.js +254 -0
- package/dist/modules/repl/services/commands/repl-commands.service.js.map +1 -0
- package/dist/modules/repl/services/repl.service.js +647 -0
- package/dist/modules/repl/services/repl.service.js.map +1 -0
- package/dist/modules/repl/services/smart-input.js +544 -0
- package/dist/modules/repl/services/smart-input.js.map +1 -0
- package/dist/modules/repl/services/welcome-screen.service.js +117 -0
- package/dist/modules/repl/services/welcome-screen.service.js.map +1 -0
- package/dist/modules/repl/utils/prompts-with-esc.js +187 -0
- package/dist/modules/repl/utils/prompts-with-esc.js.map +1 -0
- package/dist/modules/repl/utils/theme.js +185 -0
- package/dist/modules/repl/utils/theme.js.map +1 -0
- package/dist/modules/skills/definitions/general/file-operations.md +60 -0
- package/dist/modules/skills/definitions/general/git-operations.md +59 -0
- package/dist/modules/skills/definitions/general/planning.md +86 -0
- package/dist/modules/skills/definitions/general/search.md +59 -0
- package/dist/modules/skills/definitions/specialized/api-design.md +85 -0
- package/dist/modules/skills/definitions/specialized/database-operations.md +78 -0
- package/dist/modules/skills/definitions/specialized/frontend-bootstrap.md +71 -0
- package/dist/modules/skills/definitions/specialized/react-patterns.md +77 -0
- package/dist/modules/skills/definitions/specialized/testing-strategies.md +79 -0
- package/dist/modules/skills/index.js +23 -0
- package/dist/modules/skills/index.js.map +1 -0
- package/dist/modules/skills/services/skill-loader.service.js +130 -0
- package/dist/modules/skills/services/skill-loader.service.js.map +1 -0
- package/dist/modules/skills/services/skill-registry.service.js +96 -0
- package/dist/modules/skills/services/skill-registry.service.js.map +1 -0
- package/dist/modules/skills/skills.module.js +38 -0
- package/dist/modules/skills/skills.module.js.map +1 -0
- package/dist/modules/skills/types/index.js +20 -0
- package/dist/modules/skills/types/index.js.map +1 -0
- package/dist/modules/skills/types/skill.types.js +6 -0
- package/dist/modules/skills/types/skill.types.js.map +1 -0
- package/dist/modules/tasks/index.js +24 -0
- package/dist/modules/tasks/index.js.map +1 -0
- package/dist/modules/tasks/services/plan-executor.service.js +199 -0
- package/dist/modules/tasks/services/plan-executor.service.js.map +1 -0
- package/dist/modules/tasks/services/plan-mode.service.js +118 -0
- package/dist/modules/tasks/services/plan-mode.service.js.map +1 -0
- package/dist/modules/tasks/services/plan-persistence.service.js +148 -0
- package/dist/modules/tasks/services/plan-persistence.service.js.map +1 -0
- package/dist/modules/tasks/services/task-management.service.js +255 -0
- package/dist/modules/tasks/services/task-management.service.js.map +1 -0
- package/dist/modules/tasks/services/task-tools.service.js +270 -0
- package/dist/modules/tasks/services/task-tools.service.js.map +1 -0
- package/dist/modules/tasks/tasks.module.js +49 -0
- package/dist/modules/tasks/tasks.module.js.map +1 -0
- package/dist/modules/tasks/types/task.types.js +21 -0
- package/dist/modules/tasks/types/task.types.js.map +1 -0
- package/dist/modules/tools/index.js +24 -0
- package/dist/modules/tools/index.js.map +1 -0
- package/dist/modules/tools/services/filesystem-tools.service.js +450 -0
- package/dist/modules/tools/services/filesystem-tools.service.js.map +1 -0
- package/dist/modules/tools/services/search-tools.service.js +63 -0
- package/dist/modules/tools/services/search-tools.service.js.map +1 -0
- package/dist/modules/tools/services/shell-tools.service.js +194 -0
- package/dist/modules/tools/services/shell-tools.service.js.map +1 -0
- package/dist/modules/tools/services/tools-registry.service.js +83 -0
- package/dist/modules/tools/services/tools-registry.service.js.map +1 -0
- package/dist/modules/tools/tools.module.js +46 -0
- package/dist/modules/tools/tools.module.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "CommitGeneratorService", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return CommitGeneratorService;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _common = require("@nestjs/common");
|
|
12
|
+
const _child_process = require("child_process");
|
|
13
|
+
const _messages = require("@langchain/core/messages");
|
|
14
|
+
const _multillmservice = require("../../../common/services/multi-llm.service");
|
|
15
|
+
const _monorepodetectorservice = require("./monorepo-detector.service");
|
|
16
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
17
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
18
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
19
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
20
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
21
|
+
}
|
|
22
|
+
function _ts_metadata(k, v) {
|
|
23
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
24
|
+
}
|
|
25
|
+
let CommitGeneratorService = class CommitGeneratorService {
|
|
26
|
+
getDiffInfo() {
|
|
27
|
+
try {
|
|
28
|
+
const cwd = process.cwd();
|
|
29
|
+
const staged = (0, _child_process.execSync)('git diff --cached', {
|
|
30
|
+
cwd,
|
|
31
|
+
encoding: 'utf-8'
|
|
32
|
+
});
|
|
33
|
+
const unstaged = (0, _child_process.execSync)('git diff', {
|
|
34
|
+
cwd,
|
|
35
|
+
encoding: 'utf-8'
|
|
36
|
+
});
|
|
37
|
+
const stats = (0, _child_process.execSync)('git diff --stat', {
|
|
38
|
+
cwd,
|
|
39
|
+
encoding: 'utf-8'
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
staged,
|
|
43
|
+
unstaged,
|
|
44
|
+
stagedFiles: this.extractFiles(staged),
|
|
45
|
+
unstagedFiles: this.extractFiles(unstaged),
|
|
46
|
+
stats
|
|
47
|
+
};
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
hasChanges() {
|
|
53
|
+
try {
|
|
54
|
+
const output = (0, _child_process.execSync)('git status --porcelain', {
|
|
55
|
+
cwd: process.cwd(),
|
|
56
|
+
encoding: 'utf-8'
|
|
57
|
+
});
|
|
58
|
+
return output.trim().length > 0;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async generateCommitMessage() {
|
|
64
|
+
const diffInfo = this.getDiffInfo();
|
|
65
|
+
if (!diffInfo) return null;
|
|
66
|
+
const monorepoInfo = this.monorepoDetector.detectMonorepo(process.cwd());
|
|
67
|
+
const allFiles = [
|
|
68
|
+
...diffInfo.stagedFiles,
|
|
69
|
+
...diffInfo.unstagedFiles
|
|
70
|
+
];
|
|
71
|
+
const scope = this.monorepoDetector.determineScope(allFiles, monorepoInfo);
|
|
72
|
+
const llm = this.multiLlmService.createModel('cheap');
|
|
73
|
+
const prompt = this.buildCommitPrompt(diffInfo, scope);
|
|
74
|
+
const response = await llm.invoke([
|
|
75
|
+
new _messages.SystemMessage(this.getCommitSystemPrompt()),
|
|
76
|
+
new _messages.HumanMessage(prompt)
|
|
77
|
+
]);
|
|
78
|
+
const message = this.extractContent(response.content);
|
|
79
|
+
return this.cleanCommitMessage(message);
|
|
80
|
+
}
|
|
81
|
+
async splitCommits() {
|
|
82
|
+
const diffInfo = this.getDiffInfo();
|
|
83
|
+
if (!diffInfo) return null;
|
|
84
|
+
const monorepoInfo = this.monorepoDetector.detectMonorepo(process.cwd());
|
|
85
|
+
const allFiles = [
|
|
86
|
+
...diffInfo.stagedFiles,
|
|
87
|
+
...diffInfo.unstagedFiles
|
|
88
|
+
];
|
|
89
|
+
const llm = this.multiLlmService.createModel('cheap');
|
|
90
|
+
const splitPrompt = this.buildSplitPrompt(diffInfo, allFiles);
|
|
91
|
+
const splitResponse = await llm.invoke([
|
|
92
|
+
new _messages.SystemMessage(this.getSplitSystemPrompt()),
|
|
93
|
+
new _messages.HumanMessage(splitPrompt)
|
|
94
|
+
]);
|
|
95
|
+
const splitContent = this.extractContent(splitResponse.content);
|
|
96
|
+
const commitGroups = this.parseCommitGroups(splitContent);
|
|
97
|
+
if (!commitGroups?.length) return null;
|
|
98
|
+
const validGroups = commitGroups.filter((group)=>Array.isArray(group.files) && group.files.length > 0);
|
|
99
|
+
if (validGroups.length === 0) return null;
|
|
100
|
+
for (const group of validGroups){
|
|
101
|
+
if (!group.scope) {
|
|
102
|
+
group.scope = this.monorepoDetector.determineScope(group.files, monorepoInfo);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const splitCommits = [];
|
|
106
|
+
for (const group of validGroups){
|
|
107
|
+
const message = await this.generateMessageForGroup(group, diffInfo);
|
|
108
|
+
splitCommits.push({
|
|
109
|
+
...group,
|
|
110
|
+
message
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return splitCommits;
|
|
114
|
+
}
|
|
115
|
+
executeCommit(message, autoStage = true) {
|
|
116
|
+
try {
|
|
117
|
+
const cwd = process.cwd();
|
|
118
|
+
if (autoStage) {
|
|
119
|
+
(0, _child_process.execSync)('git add -A', {
|
|
120
|
+
cwd
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
(0, _child_process.execSync)('git commit -F -', {
|
|
124
|
+
cwd,
|
|
125
|
+
input: `${message}\n`,
|
|
126
|
+
encoding: 'utf-8'
|
|
127
|
+
});
|
|
128
|
+
return true;
|
|
129
|
+
} catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
executePush() {
|
|
134
|
+
try {
|
|
135
|
+
const cwd = process.cwd();
|
|
136
|
+
const branch = (0, _child_process.execSync)('git branch --show-current', {
|
|
137
|
+
cwd,
|
|
138
|
+
encoding: 'utf-8'
|
|
139
|
+
}).trim();
|
|
140
|
+
(0, _child_process.execSync)(`git push origin ${branch}`, {
|
|
141
|
+
cwd,
|
|
142
|
+
encoding: 'utf-8'
|
|
143
|
+
});
|
|
144
|
+
return {
|
|
145
|
+
success: true
|
|
146
|
+
};
|
|
147
|
+
} catch (error) {
|
|
148
|
+
const message = error.message || 'Push failed';
|
|
149
|
+
if (message.includes('rejected') || message.includes('diverged')) {
|
|
150
|
+
return {
|
|
151
|
+
success: false,
|
|
152
|
+
error: 'Push rejected. Run "git pull --rebase" first.'
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
success: false,
|
|
157
|
+
error: message
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
executeSplitCommits(commits) {
|
|
162
|
+
const cwd = process.cwd();
|
|
163
|
+
let committedCount = 0;
|
|
164
|
+
let originalHead;
|
|
165
|
+
try {
|
|
166
|
+
originalHead = (0, _child_process.execSync)('git rev-parse HEAD', {
|
|
167
|
+
cwd,
|
|
168
|
+
encoding: 'utf-8'
|
|
169
|
+
}).trim();
|
|
170
|
+
for (const commit of commits){
|
|
171
|
+
(0, _child_process.execSync)('git reset', {
|
|
172
|
+
cwd
|
|
173
|
+
});
|
|
174
|
+
for (const file of commit.files){
|
|
175
|
+
try {
|
|
176
|
+
(0, _child_process.execSync)(`git add "${file}"`, {
|
|
177
|
+
cwd
|
|
178
|
+
});
|
|
179
|
+
} catch {}
|
|
180
|
+
}
|
|
181
|
+
const staged = (0, _child_process.execSync)('git diff --cached --name-only', {
|
|
182
|
+
cwd,
|
|
183
|
+
encoding: 'utf-8'
|
|
184
|
+
});
|
|
185
|
+
if (!staged.trim()) continue;
|
|
186
|
+
(0, _child_process.execSync)('git commit -F -', {
|
|
187
|
+
cwd,
|
|
188
|
+
input: `${commit.message}\n`,
|
|
189
|
+
encoding: 'utf-8'
|
|
190
|
+
});
|
|
191
|
+
committedCount++;
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
success: true,
|
|
195
|
+
committed: committedCount
|
|
196
|
+
};
|
|
197
|
+
} catch (error) {
|
|
198
|
+
return {
|
|
199
|
+
success: false,
|
|
200
|
+
committed: committedCount,
|
|
201
|
+
error: error.message || 'Failed to execute commits',
|
|
202
|
+
originalHead
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async refineCommitMessage(currentMessage, userSuggestion, diffInfo) {
|
|
207
|
+
const llm = this.multiLlmService.createModel('cheap');
|
|
208
|
+
const prompt = `Current commit message: ${currentMessage}\n\nUser suggestion: ${userSuggestion}\n\nDiff:\n${diffInfo.staged.slice(0, 3000)}`;
|
|
209
|
+
const response = await llm.invoke([
|
|
210
|
+
new _messages.SystemMessage(this.getRefineSystemPrompt()),
|
|
211
|
+
new _messages.HumanMessage(prompt)
|
|
212
|
+
]);
|
|
213
|
+
const message = this.extractContent(response.content);
|
|
214
|
+
return this.cleanCommitMessage(message);
|
|
215
|
+
}
|
|
216
|
+
extractFiles(diff) {
|
|
217
|
+
const files = new Set();
|
|
218
|
+
const lines = diff.split('\n');
|
|
219
|
+
for (const line of lines){
|
|
220
|
+
if (line.startsWith('diff --git')) {
|
|
221
|
+
const match = line.match(/diff --git a\/(.+?) b\/(.+?)$/);
|
|
222
|
+
if (match) {
|
|
223
|
+
files.add(match[2]);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return Array.from(files);
|
|
228
|
+
}
|
|
229
|
+
extractContent(content) {
|
|
230
|
+
if (typeof content === 'string') return content;
|
|
231
|
+
if (Array.isArray(content) && content.length > 0) {
|
|
232
|
+
const first = content[0];
|
|
233
|
+
if (typeof first === 'object' && first !== null && 'text' in first) {
|
|
234
|
+
return String(first.text);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return String(content);
|
|
238
|
+
}
|
|
239
|
+
cleanCommitMessage(message) {
|
|
240
|
+
return message.trim().replace(/^["']|["']$/g, '').replace(/\n/g, ' ').trim();
|
|
241
|
+
}
|
|
242
|
+
buildCommitPrompt(diffInfo, scope) {
|
|
243
|
+
const scopeHint = scope ? `\n\nThis is a monorepo. The changes are primarily in the "${scope}" module.` : '';
|
|
244
|
+
let fullDiff = '';
|
|
245
|
+
if (diffInfo.staged) {
|
|
246
|
+
fullDiff += `=== Staged changes ===\n${diffInfo.staged}\n\n`;
|
|
247
|
+
}
|
|
248
|
+
if (diffInfo.unstaged) {
|
|
249
|
+
fullDiff += `=== Unstaged changes ===\n${diffInfo.unstaged}\n\n`;
|
|
250
|
+
}
|
|
251
|
+
const maxLength = 10000;
|
|
252
|
+
if (fullDiff.length > maxLength) {
|
|
253
|
+
fullDiff = fullDiff.slice(0, maxLength) + '\n\n... (truncated)';
|
|
254
|
+
}
|
|
255
|
+
return `Generate a conventional commit message for the following changes.${scopeHint}\n\nFiles changed:\n${diffInfo.stats}\n\n${fullDiff}`;
|
|
256
|
+
}
|
|
257
|
+
buildSplitPrompt(diffInfo, files) {
|
|
258
|
+
let fullDiff = '';
|
|
259
|
+
if (diffInfo.staged) {
|
|
260
|
+
fullDiff += `=== Staged changes ===\n${diffInfo.staged}\n\n`;
|
|
261
|
+
}
|
|
262
|
+
if (diffInfo.unstaged) {
|
|
263
|
+
fullDiff += `=== Unstaged changes ===\n${diffInfo.unstaged}\n\n`;
|
|
264
|
+
}
|
|
265
|
+
const maxLength = 8000;
|
|
266
|
+
if (fullDiff.length > maxLength) {
|
|
267
|
+
fullDiff = fullDiff.slice(0, maxLength) + '\n\n... (truncated)';
|
|
268
|
+
}
|
|
269
|
+
return `Analyze all the files below and group them into logical commits.\n\nFiles: ${files.join(', ')}\n\nStats:\n${diffInfo.stats}\n\n${fullDiff}`;
|
|
270
|
+
}
|
|
271
|
+
async generateMessageForGroup(group, diffInfo) {
|
|
272
|
+
const llm = this.multiLlmService.createModel('cheap');
|
|
273
|
+
const scopePart = group.scope ? `(${group.scope})` : '';
|
|
274
|
+
const prompt = `Generate a conventional commit message (max 72 chars) for:\n\nType: ${group.type}${scopePart}\nFiles: ${group.files.join(', ')}\nDescription: ${group.description}\n\nIMPORTANT: Return ONLY the commit message in format: "type(scope): description" or "type: description"\nThe message MUST be in English.`;
|
|
275
|
+
const response = await llm.invoke([
|
|
276
|
+
new _messages.SystemMessage(this.getCommitSystemPrompt()),
|
|
277
|
+
new _messages.HumanMessage(prompt)
|
|
278
|
+
]);
|
|
279
|
+
let message = this.extractContent(response.content);
|
|
280
|
+
message = this.cleanCommitMessage(message);
|
|
281
|
+
if (!message.includes(':')) {
|
|
282
|
+
const scope = group.scope ? `(${group.scope})` : '';
|
|
283
|
+
message = `${group.type}${scope}: ${message}`;
|
|
284
|
+
}
|
|
285
|
+
return message;
|
|
286
|
+
}
|
|
287
|
+
parseCommitGroups(content) {
|
|
288
|
+
const jsonMatch = content.match(/```json\s*([\s\S]*?)\s*```/);
|
|
289
|
+
if (jsonMatch) {
|
|
290
|
+
try {
|
|
291
|
+
const parsed = JSON.parse(jsonMatch[1]);
|
|
292
|
+
if (parsed.commits && Array.isArray(parsed.commits)) {
|
|
293
|
+
return parsed.commits;
|
|
294
|
+
}
|
|
295
|
+
} catch {}
|
|
296
|
+
}
|
|
297
|
+
try {
|
|
298
|
+
const parsed = JSON.parse(content);
|
|
299
|
+
if (parsed.commits && Array.isArray(parsed.commits)) {
|
|
300
|
+
return parsed.commits;
|
|
301
|
+
}
|
|
302
|
+
} catch {}
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
getCommitSystemPrompt() {
|
|
306
|
+
return `You are a Git commit message expert. Generate concise commit messages following Conventional Commits.
|
|
307
|
+
|
|
308
|
+
**Available types:**
|
|
309
|
+
- feat: new feature
|
|
310
|
+
- fix: bug fix
|
|
311
|
+
- docs: documentation
|
|
312
|
+
- style: formatting (no logic change)
|
|
313
|
+
- refactor: refactoring (no functionality change)
|
|
314
|
+
- perf: performance improvement
|
|
315
|
+
- test: tests
|
|
316
|
+
- build: build/dependencies
|
|
317
|
+
- ci: continuous integration
|
|
318
|
+
- chore: general tasks
|
|
319
|
+
- cleanup: code cleanup
|
|
320
|
+
- remove: code removal
|
|
321
|
+
|
|
322
|
+
**Format:**
|
|
323
|
+
- With scope: <type>(<scope>): <description>
|
|
324
|
+
- Without scope: <type>: <description>
|
|
325
|
+
|
|
326
|
+
**Rules:**
|
|
327
|
+
- Maximum 72 characters for the subject line
|
|
328
|
+
- Description in English
|
|
329
|
+
- No period at the end
|
|
330
|
+
- Use imperative mood ("add" not "added")
|
|
331
|
+
- Be specific but concise
|
|
332
|
+
|
|
333
|
+
If this is a monorepo and you can identify the module, include the scope.
|
|
334
|
+
|
|
335
|
+
Return ONLY the commit message, nothing else.`;
|
|
336
|
+
}
|
|
337
|
+
getSplitSystemPrompt() {
|
|
338
|
+
return `You are a Git commit organization expert. Analyze the changes and divide them into logical commits.
|
|
339
|
+
|
|
340
|
+
**YOUR TASK:**
|
|
341
|
+
Group changes into logical commits based on:
|
|
342
|
+
1. **Functional cohesion**: Changes that make sense together
|
|
343
|
+
2. **Change type**: features, fixes, docs, refactorings separated
|
|
344
|
+
3. **Related files**: Files that work together
|
|
345
|
+
|
|
346
|
+
**RETURN FORMAT (JSON):**
|
|
347
|
+
Return ONLY valid JSON in this format:
|
|
348
|
+
\`\`\`json
|
|
349
|
+
{
|
|
350
|
+
"commits": [
|
|
351
|
+
{
|
|
352
|
+
"type": "feat",
|
|
353
|
+
"files": ["src/auth.ts", "src/models/user.ts"],
|
|
354
|
+
"description": "add user authentication"
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"type": "docs",
|
|
358
|
+
"files": ["README.md"],
|
|
359
|
+
"description": "update documentation"
|
|
360
|
+
}
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
\`\`\`
|
|
364
|
+
|
|
365
|
+
**AVAILABLE TYPES:**
|
|
366
|
+
feat, fix, docs, style, refactor, perf, test, build, ci, chore
|
|
367
|
+
|
|
368
|
+
**RULES:**
|
|
369
|
+
- Each commit should have a clear purpose
|
|
370
|
+
- Group functionally related files
|
|
371
|
+
- Separate features from fixes from documentation
|
|
372
|
+
- Maximum 5 files per commit (ideally fewer)
|
|
373
|
+
- If diff is small (<3 files), can be 1 commit only
|
|
374
|
+
- Description must ALWAYS be in English
|
|
375
|
+
- Include ALL files in the result
|
|
376
|
+
|
|
377
|
+
**IMPORTANT:** Return ONLY the JSON, no additional text.`;
|
|
378
|
+
}
|
|
379
|
+
getRefineSystemPrompt() {
|
|
380
|
+
return `You are refining a commit message based on user feedback.
|
|
381
|
+
|
|
382
|
+
**Instructions:**
|
|
383
|
+
- Keep the message concise (max 72 characters)
|
|
384
|
+
- Follow Conventional Commits format
|
|
385
|
+
- Incorporate the user's suggestion
|
|
386
|
+
- Return ONLY the new commit message, without explanations
|
|
387
|
+
- Message MUST be in English`;
|
|
388
|
+
}
|
|
389
|
+
constructor(multiLlmService, monorepoDetector){
|
|
390
|
+
this.multiLlmService = multiLlmService;
|
|
391
|
+
this.monorepoDetector = monorepoDetector;
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
CommitGeneratorService = _ts_decorate([
|
|
395
|
+
(0, _common.Injectable)(),
|
|
396
|
+
_ts_metadata("design:type", Function),
|
|
397
|
+
_ts_metadata("design:paramtypes", [
|
|
398
|
+
typeof _multillmservice.MultiLlmService === "undefined" ? Object : _multillmservice.MultiLlmService,
|
|
399
|
+
typeof _monorepodetectorservice.MonorepoDetectorService === "undefined" ? Object : _monorepodetectorservice.MonorepoDetectorService
|
|
400
|
+
])
|
|
401
|
+
], CommitGeneratorService);
|
|
402
|
+
|
|
403
|
+
//# sourceMappingURL=commit-generator.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/git/services/commit-generator.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { execSync } from 'child_process';\nimport { HumanMessage, SystemMessage } from '@langchain/core/messages';\nimport { MultiLlmService } from '../../../common/services/multi-llm.service';\nimport { MonorepoDetectorService } from './monorepo-detector.service';\nimport { GitDiffInfo, SplitCommit, CommitGroup, MonorepoInfo } from '../types/git.types';\n\n@Injectable()\nexport class CommitGeneratorService {\n constructor(\n private readonly multiLlmService: MultiLlmService,\n private readonly monorepoDetector: MonorepoDetectorService,\n ) {}\n\n getDiffInfo(): GitDiffInfo | null {\n try {\n const cwd = process.cwd();\n const staged = execSync('git diff --cached', { cwd, encoding: 'utf-8' });\n const unstaged = execSync('git diff', { cwd, encoding: 'utf-8' });\n const stats = execSync('git diff --stat', { cwd, encoding: 'utf-8' });\n\n return {\n staged,\n unstaged,\n stagedFiles: this.extractFiles(staged),\n unstagedFiles: this.extractFiles(unstaged),\n stats,\n };\n } catch {\n return null;\n }\n }\n\n hasChanges(): boolean {\n try {\n const output = execSync('git status --porcelain', { cwd: process.cwd(), encoding: 'utf-8' });\n return output.trim().length > 0;\n } catch {\n return false;\n }\n }\n\n async generateCommitMessage(): Promise<string | null> {\n const diffInfo = this.getDiffInfo();\n if (!diffInfo) return null;\n\n const monorepoInfo = this.monorepoDetector.detectMonorepo(process.cwd());\n const allFiles = [...diffInfo.stagedFiles, ...diffInfo.unstagedFiles];\n const scope = this.monorepoDetector.determineScope(allFiles, monorepoInfo);\n\n const llm = this.multiLlmService.createModel('cheap');\n const prompt = this.buildCommitPrompt(diffInfo, scope);\n\n const response = await llm.invoke([\n new SystemMessage(this.getCommitSystemPrompt()),\n new HumanMessage(prompt),\n ]);\n\n const message = this.extractContent(response.content);\n return this.cleanCommitMessage(message);\n }\n\n async splitCommits(): Promise<SplitCommit[] | null> {\n const diffInfo = this.getDiffInfo();\n if (!diffInfo) return null;\n\n const monorepoInfo = this.monorepoDetector.detectMonorepo(process.cwd());\n const allFiles = [...diffInfo.stagedFiles, ...diffInfo.unstagedFiles];\n\n const llm = this.multiLlmService.createModel('cheap');\n const splitPrompt = this.buildSplitPrompt(diffInfo, allFiles);\n\n const splitResponse = await llm.invoke([\n new SystemMessage(this.getSplitSystemPrompt()),\n new HumanMessage(splitPrompt),\n ]);\n\n const splitContent = this.extractContent(splitResponse.content);\n const commitGroups = this.parseCommitGroups(splitContent);\n\n if (!commitGroups?.length) return null;\n\n const validGroups = commitGroups.filter((group) => Array.isArray(group.files) && group.files.length > 0);\n if (validGroups.length === 0) return null;\n\n for (const group of validGroups) {\n if (!group.scope) {\n group.scope = this.monorepoDetector.determineScope(group.files, monorepoInfo);\n }\n }\n\n const splitCommits: SplitCommit[] = [];\n for (const group of validGroups) {\n const message = await this.generateMessageForGroup(group, diffInfo);\n splitCommits.push({ ...group, message });\n }\n\n return splitCommits;\n }\n\n executeCommit(message: string, autoStage = true): boolean {\n try {\n const cwd = process.cwd();\n if (autoStage) {\n execSync('git add -A', { cwd });\n }\n execSync('git commit -F -', { cwd, input: `${message}\\n`, encoding: 'utf-8' });\n return true;\n } catch {\n return false;\n }\n }\n\n executePush(): { success: boolean; error?: string } {\n try {\n const cwd = process.cwd();\n const branch = execSync('git branch --show-current', { cwd, encoding: 'utf-8' }).trim();\n execSync(`git push origin ${branch}`, { cwd, encoding: 'utf-8' });\n return { success: true };\n } catch (error: any) {\n const message = error.message || 'Push failed';\n if (message.includes('rejected') || message.includes('diverged')) {\n return { success: false, error: 'Push rejected. Run \"git pull --rebase\" first.' };\n }\n return { success: false, error: message };\n }\n }\n\n executeSplitCommits(commits: SplitCommit[]): { success: boolean; committed: number; error?: string; originalHead?: string } {\n const cwd = process.cwd();\n let committedCount = 0;\n let originalHead: string | undefined;\n\n try {\n originalHead = execSync('git rev-parse HEAD', { cwd, encoding: 'utf-8' }).trim();\n\n for (const commit of commits) {\n execSync('git reset', { cwd });\n\n for (const file of commit.files) {\n try {\n execSync(`git add \"${file}\"`, { cwd });\n } catch {}\n }\n\n const staged = execSync('git diff --cached --name-only', { cwd, encoding: 'utf-8' });\n if (!staged.trim()) continue;\n\n execSync('git commit -F -', { cwd, input: `${commit.message}\\n`, encoding: 'utf-8' });\n committedCount++;\n }\n\n return { success: true, committed: committedCount };\n } catch (error: any) {\n return {\n success: false,\n committed: committedCount,\n error: error.message || 'Failed to execute commits',\n originalHead\n };\n }\n }\n\n async refineCommitMessage(\n currentMessage: string,\n userSuggestion: string,\n diffInfo: GitDiffInfo,\n ): Promise<string> {\n const llm = this.multiLlmService.createModel('cheap');\n\n const prompt = `Current commit message: ${currentMessage}\\n\\nUser suggestion: ${userSuggestion}\\n\\nDiff:\\n${diffInfo.staged.slice(0, 3000)}`;\n\n const response = await llm.invoke([\n new SystemMessage(this.getRefineSystemPrompt()),\n new HumanMessage(prompt),\n ]);\n\n const message = this.extractContent(response.content);\n return this.cleanCommitMessage(message);\n }\n\n private extractFiles(diff: string): string[] {\n const files = new Set<string>();\n const lines = diff.split('\\n');\n\n for (const line of lines) {\n if (line.startsWith('diff --git')) {\n const match = line.match(/diff --git a\\/(.+?) b\\/(.+?)$/);\n if (match) {\n files.add(match[2]);\n }\n }\n }\n\n return Array.from(files);\n }\n\n private extractContent(content: unknown): string {\n if (typeof content === 'string') return content;\n if (Array.isArray(content) && content.length > 0) {\n const first = content[0];\n if (typeof first === 'object' && first !== null && 'text' in first) {\n return String(first.text);\n }\n }\n return String(content);\n }\n\n private cleanCommitMessage(message: string): string {\n return message\n .trim()\n .replace(/^[\"']|[\"']$/g, '')\n .replace(/\\n/g, ' ')\n .trim();\n }\n\n private buildCommitPrompt(diffInfo: GitDiffInfo, scope?: string): string {\n const scopeHint = scope ? `\\n\\nThis is a monorepo. The changes are primarily in the \"${scope}\" module.` : '';\n\n let fullDiff = '';\n if (diffInfo.staged) {\n fullDiff += `=== Staged changes ===\\n${diffInfo.staged}\\n\\n`;\n }\n if (diffInfo.unstaged) {\n fullDiff += `=== Unstaged changes ===\\n${diffInfo.unstaged}\\n\\n`;\n }\n\n const maxLength = 10000;\n if (fullDiff.length > maxLength) {\n fullDiff = fullDiff.slice(0, maxLength) + '\\n\\n... (truncated)';\n }\n\n return `Generate a conventional commit message for the following changes.${scopeHint}\\n\\nFiles changed:\\n${diffInfo.stats}\\n\\n${fullDiff}`;\n }\n\n private buildSplitPrompt(diffInfo: GitDiffInfo, files: string[]): string {\n let fullDiff = '';\n if (diffInfo.staged) {\n fullDiff += `=== Staged changes ===\\n${diffInfo.staged}\\n\\n`;\n }\n if (diffInfo.unstaged) {\n fullDiff += `=== Unstaged changes ===\\n${diffInfo.unstaged}\\n\\n`;\n }\n\n const maxLength = 8000;\n if (fullDiff.length > maxLength) {\n fullDiff = fullDiff.slice(0, maxLength) + '\\n\\n... (truncated)';\n }\n\n return `Analyze all the files below and group them into logical commits.\\n\\nFiles: ${files.join(', ')}\\n\\nStats:\\n${diffInfo.stats}\\n\\n${fullDiff}`;\n }\n\n private async generateMessageForGroup(group: CommitGroup, diffInfo: GitDiffInfo): Promise<string> {\n const llm = this.multiLlmService.createModel('cheap');\n\n const scopePart = group.scope ? `(${group.scope})` : '';\n\n const prompt = `Generate a conventional commit message (max 72 chars) for:\\n\\nType: ${group.type}${scopePart}\\nFiles: ${group.files.join(', ')}\\nDescription: ${group.description}\\n\\nIMPORTANT: Return ONLY the commit message in format: \"type(scope): description\" or \"type: description\"\\nThe message MUST be in English.`;\n\n const response = await llm.invoke([\n new SystemMessage(this.getCommitSystemPrompt()),\n new HumanMessage(prompt),\n ]);\n\n let message = this.extractContent(response.content);\n message = this.cleanCommitMessage(message);\n\n if (!message.includes(':')) {\n const scope = group.scope ? `(${group.scope})` : '';\n message = `${group.type}${scope}: ${message}`;\n }\n\n return message;\n }\n\n private parseCommitGroups(content: string): CommitGroup[] | null {\n const jsonMatch = content.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n if (jsonMatch) {\n try {\n const parsed = JSON.parse(jsonMatch[1]);\n if (parsed.commits && Array.isArray(parsed.commits)) {\n return parsed.commits;\n }\n } catch {}\n }\n\n try {\n const parsed = JSON.parse(content);\n if (parsed.commits && Array.isArray(parsed.commits)) {\n return parsed.commits;\n }\n } catch {}\n\n return null;\n }\n\n private getCommitSystemPrompt(): string {\n return `You are a Git commit message expert. Generate concise commit messages following Conventional Commits.\n\n**Available types:**\n- feat: new feature\n- fix: bug fix\n- docs: documentation\n- style: formatting (no logic change)\n- refactor: refactoring (no functionality change)\n- perf: performance improvement\n- test: tests\n- build: build/dependencies\n- ci: continuous integration\n- chore: general tasks\n- cleanup: code cleanup\n- remove: code removal\n\n**Format:**\n- With scope: <type>(<scope>): <description>\n- Without scope: <type>: <description>\n\n**Rules:**\n- Maximum 72 characters for the subject line\n- Description in English\n- No period at the end\n- Use imperative mood (\"add\" not \"added\")\n- Be specific but concise\n\nIf this is a monorepo and you can identify the module, include the scope.\n\nReturn ONLY the commit message, nothing else.`;\n }\n\n private getSplitSystemPrompt(): string {\n return `You are a Git commit organization expert. Analyze the changes and divide them into logical commits.\n\n**YOUR TASK:**\nGroup changes into logical commits based on:\n1. **Functional cohesion**: Changes that make sense together\n2. **Change type**: features, fixes, docs, refactorings separated\n3. **Related files**: Files that work together\n\n**RETURN FORMAT (JSON):**\nReturn ONLY valid JSON in this format:\n\\`\\`\\`json\n{\n \"commits\": [\n {\n \"type\": \"feat\",\n \"files\": [\"src/auth.ts\", \"src/models/user.ts\"],\n \"description\": \"add user authentication\"\n },\n {\n \"type\": \"docs\",\n \"files\": [\"README.md\"],\n \"description\": \"update documentation\"\n }\n ]\n}\n\\`\\`\\`\n\n**AVAILABLE TYPES:**\nfeat, fix, docs, style, refactor, perf, test, build, ci, chore\n\n**RULES:**\n- Each commit should have a clear purpose\n- Group functionally related files\n- Separate features from fixes from documentation\n- Maximum 5 files per commit (ideally fewer)\n- If diff is small (<3 files), can be 1 commit only\n- Description must ALWAYS be in English\n- Include ALL files in the result\n\n**IMPORTANT:** Return ONLY the JSON, no additional text.`;\n }\n\n private getRefineSystemPrompt(): string {\n return `You are refining a commit message based on user feedback.\n\n**Instructions:**\n- Keep the message concise (max 72 characters)\n- Follow Conventional Commits format\n- Incorporate the user's suggestion\n- Return ONLY the new commit message, without explanations\n- Message MUST be in English`;\n }\n}\n"],"names":["CommitGeneratorService","getDiffInfo","cwd","process","staged","execSync","encoding","unstaged","stats","stagedFiles","extractFiles","unstagedFiles","hasChanges","output","trim","length","generateCommitMessage","diffInfo","monorepoInfo","monorepoDetector","detectMonorepo","allFiles","scope","determineScope","llm","multiLlmService","createModel","prompt","buildCommitPrompt","response","invoke","SystemMessage","getCommitSystemPrompt","HumanMessage","message","extractContent","content","cleanCommitMessage","splitCommits","splitPrompt","buildSplitPrompt","splitResponse","getSplitSystemPrompt","splitContent","commitGroups","parseCommitGroups","validGroups","filter","group","Array","isArray","files","generateMessageForGroup","push","executeCommit","autoStage","input","executePush","branch","success","error","includes","executeSplitCommits","commits","committedCount","originalHead","commit","file","committed","refineCommitMessage","currentMessage","userSuggestion","slice","getRefineSystemPrompt","diff","Set","lines","split","line","startsWith","match","add","from","first","String","text","replace","scopeHint","fullDiff","maxLength","join","scopePart","type","description","jsonMatch","parsed","JSON","parse"],"mappings":";;;;+BAQaA;;;eAAAA;;;wBARc;+BACF;0BACmB;iCACZ;yCACQ;;;;;;;;;;AAIjC,IAAA,AAAMA,yBAAN,MAAMA;IAMXC,cAAkC;QAChC,IAAI;YACF,MAAMC,MAAMC,QAAQD,GAAG;YACvB,MAAME,SAASC,IAAAA,uBAAQ,EAAC,qBAAqB;gBAAEH;gBAAKI,UAAU;YAAQ;YACtE,MAAMC,WAAWF,IAAAA,uBAAQ,EAAC,YAAY;gBAAEH;gBAAKI,UAAU;YAAQ;YAC/D,MAAME,QAAQH,IAAAA,uBAAQ,EAAC,mBAAmB;gBAAEH;gBAAKI,UAAU;YAAQ;YAEnE,OAAO;gBACLF;gBACAG;gBACAE,aAAa,IAAI,CAACC,YAAY,CAACN;gBAC/BO,eAAe,IAAI,CAACD,YAAY,CAACH;gBACjCC;YACF;QACF,EAAE,OAAM;YACN,OAAO;QACT;IACF;IAEAI,aAAsB;QACpB,IAAI;YACF,MAAMC,SAASR,IAAAA,uBAAQ,EAAC,0BAA0B;gBAAEH,KAAKC,QAAQD,GAAG;gBAAII,UAAU;YAAQ;YAC1F,OAAOO,OAAOC,IAAI,GAAGC,MAAM,GAAG;QAChC,EAAE,OAAM;YACN,OAAO;QACT;IACF;IAEA,MAAMC,wBAAgD;QACpD,MAAMC,WAAW,IAAI,CAAChB,WAAW;QACjC,IAAI,CAACgB,UAAU,OAAO;QAEtB,MAAMC,eAAe,IAAI,CAACC,gBAAgB,CAACC,cAAc,CAACjB,QAAQD,GAAG;QACrE,MAAMmB,WAAW;eAAIJ,SAASR,WAAW;eAAKQ,SAASN,aAAa;SAAC;QACrE,MAAMW,QAAQ,IAAI,CAACH,gBAAgB,CAACI,cAAc,CAACF,UAAUH;QAE7D,MAAMM,MAAM,IAAI,CAACC,eAAe,CAACC,WAAW,CAAC;QAC7C,MAAMC,SAAS,IAAI,CAACC,iBAAiB,CAACX,UAAUK;QAEhD,MAAMO,WAAW,MAAML,IAAIM,MAAM,CAAC;YAChC,IAAIC,uBAAa,CAAC,IAAI,CAACC,qBAAqB;YAC5C,IAAIC,sBAAY,CAACN;SAClB;QAED,MAAMO,UAAU,IAAI,CAACC,cAAc,CAACN,SAASO,OAAO;QACpD,OAAO,IAAI,CAACC,kBAAkB,CAACH;IACjC;IAEA,MAAMI,eAA8C;QAClD,MAAMrB,WAAW,IAAI,CAAChB,WAAW;QACjC,IAAI,CAACgB,UAAU,OAAO;QAEtB,MAAMC,eAAe,IAAI,CAACC,gBAAgB,CAACC,cAAc,CAACjB,QAAQD,GAAG;QACrE,MAAMmB,WAAW;eAAIJ,SAASR,WAAW;eAAKQ,SAASN,aAAa;SAAC;QAErE,MAAMa,MAAM,IAAI,CAACC,eAAe,CAACC,WAAW,CAAC;QAC7C,MAAMa,cAAc,IAAI,CAACC,gBAAgB,CAACvB,UAAUI;QAEpD,MAAMoB,gBAAgB,MAAMjB,IAAIM,MAAM,CAAC;YACrC,IAAIC,uBAAa,CAAC,IAAI,CAACW,oBAAoB;YAC3C,IAAIT,sBAAY,CAACM;SAClB;QAED,MAAMI,eAAe,IAAI,CAACR,cAAc,CAACM,cAAcL,OAAO;QAC9D,MAAMQ,eAAe,IAAI,CAACC,iBAAiB,CAACF;QAE5C,IAAI,CAACC,cAAc7B,QAAQ,OAAO;QAElC,MAAM+B,cAAcF,aAAaG,MAAM,CAAC,CAACC,QAAUC,MAAMC,OAAO,CAACF,MAAMG,KAAK,KAAKH,MAAMG,KAAK,CAACpC,MAAM,GAAG;QACtG,IAAI+B,YAAY/B,MAAM,KAAK,GAAG,OAAO;QAErC,KAAK,MAAMiC,SAASF,YAAa;YAC/B,IAAI,CAACE,MAAM1B,KAAK,EAAE;gBAChB0B,MAAM1B,KAAK,GAAG,IAAI,CAACH,gBAAgB,CAACI,cAAc,CAACyB,MAAMG,KAAK,EAAEjC;YAClE;QACF;QAEA,MAAMoB,eAA8B,EAAE;QACtC,KAAK,MAAMU,SAASF,YAAa;YAC/B,MAAMZ,UAAU,MAAM,IAAI,CAACkB,uBAAuB,CAACJ,OAAO/B;YAC1DqB,aAAae,IAAI,CAAC;gBAAE,GAAGL,KAAK;gBAAEd;YAAQ;QACxC;QAEA,OAAOI;IACT;IAEAgB,cAAcpB,OAAe,EAAEqB,YAAY,IAAI,EAAW;QACxD,IAAI;YACF,MAAMrD,MAAMC,QAAQD,GAAG;YACvB,IAAIqD,WAAW;gBACblD,IAAAA,uBAAQ,EAAC,cAAc;oBAAEH;gBAAI;YAC/B;YACAG,IAAAA,uBAAQ,EAAC,mBAAmB;gBAAEH;gBAAKsD,OAAO,GAAGtB,QAAQ,EAAE,CAAC;gBAAE5B,UAAU;YAAQ;YAC5E,OAAO;QACT,EAAE,OAAM;YACN,OAAO;QACT;IACF;IAEAmD,cAAoD;QAClD,IAAI;YACF,MAAMvD,MAAMC,QAAQD,GAAG;YACvB,MAAMwD,SAASrD,IAAAA,uBAAQ,EAAC,6BAA6B;gBAAEH;gBAAKI,UAAU;YAAQ,GAAGQ,IAAI;YACrFT,IAAAA,uBAAQ,EAAC,CAAC,gBAAgB,EAAEqD,QAAQ,EAAE;gBAAExD;gBAAKI,UAAU;YAAQ;YAC/D,OAAO;gBAAEqD,SAAS;YAAK;QACzB,EAAE,OAAOC,OAAY;YACnB,MAAM1B,UAAU0B,MAAM1B,OAAO,IAAI;YACjC,IAAIA,QAAQ2B,QAAQ,CAAC,eAAe3B,QAAQ2B,QAAQ,CAAC,aAAa;gBAChE,OAAO;oBAAEF,SAAS;oBAAOC,OAAO;gBAAgD;YAClF;YACA,OAAO;gBAAED,SAAS;gBAAOC,OAAO1B;YAAQ;QAC1C;IACF;IAEA4B,oBAAoBC,OAAsB,EAAkF;QAC1H,MAAM7D,MAAMC,QAAQD,GAAG;QACvB,IAAI8D,iBAAiB;QACrB,IAAIC;QAEJ,IAAI;YACFA,eAAe5D,IAAAA,uBAAQ,EAAC,sBAAsB;gBAAEH;gBAAKI,UAAU;YAAQ,GAAGQ,IAAI;YAE9E,KAAK,MAAMoD,UAAUH,QAAS;gBAC5B1D,IAAAA,uBAAQ,EAAC,aAAa;oBAAEH;gBAAI;gBAE5B,KAAK,MAAMiE,QAAQD,OAAOf,KAAK,CAAE;oBAC/B,IAAI;wBACF9C,IAAAA,uBAAQ,EAAC,CAAC,SAAS,EAAE8D,KAAK,CAAC,CAAC,EAAE;4BAAEjE;wBAAI;oBACtC,EAAE,OAAM,CAAC;gBACX;gBAEA,MAAME,SAASC,IAAAA,uBAAQ,EAAC,iCAAiC;oBAAEH;oBAAKI,UAAU;gBAAQ;gBAClF,IAAI,CAACF,OAAOU,IAAI,IAAI;gBAEpBT,IAAAA,uBAAQ,EAAC,mBAAmB;oBAAEH;oBAAKsD,OAAO,GAAGU,OAAOhC,OAAO,CAAC,EAAE,CAAC;oBAAE5B,UAAU;gBAAQ;gBACnF0D;YACF;YAEA,OAAO;gBAAEL,SAAS;gBAAMS,WAAWJ;YAAe;QACpD,EAAE,OAAOJ,OAAY;YACnB,OAAO;gBACLD,SAAS;gBACTS,WAAWJ;gBACXJ,OAAOA,MAAM1B,OAAO,IAAI;gBACxB+B;YACF;QACF;IACF;IAEA,MAAMI,oBACJC,cAAsB,EACtBC,cAAsB,EACtBtD,QAAqB,EACJ;QACjB,MAAMO,MAAM,IAAI,CAACC,eAAe,CAACC,WAAW,CAAC;QAE7C,MAAMC,SAAS,CAAC,wBAAwB,EAAE2C,eAAe,qBAAqB,EAAEC,eAAe,WAAW,EAAEtD,SAASb,MAAM,CAACoE,KAAK,CAAC,GAAG,OAAO;QAE5I,MAAM3C,WAAW,MAAML,IAAIM,MAAM,CAAC;YAChC,IAAIC,uBAAa,CAAC,IAAI,CAAC0C,qBAAqB;YAC5C,IAAIxC,sBAAY,CAACN;SAClB;QAED,MAAMO,UAAU,IAAI,CAACC,cAAc,CAACN,SAASO,OAAO;QACpD,OAAO,IAAI,CAACC,kBAAkB,CAACH;IACjC;IAEQxB,aAAagE,IAAY,EAAY;QAC3C,MAAMvB,QAAQ,IAAIwB;QAClB,MAAMC,QAAQF,KAAKG,KAAK,CAAC;QAEzB,KAAK,MAAMC,QAAQF,MAAO;YACxB,IAAIE,KAAKC,UAAU,CAAC,eAAe;gBACjC,MAAMC,QAAQF,KAAKE,KAAK,CAAC;gBACzB,IAAIA,OAAO;oBACT7B,MAAM8B,GAAG,CAACD,KAAK,CAAC,EAAE;gBACpB;YACF;QACF;QAEA,OAAO/B,MAAMiC,IAAI,CAAC/B;IACpB;IAEQhB,eAAeC,OAAgB,EAAU;QAC/C,IAAI,OAAOA,YAAY,UAAU,OAAOA;QACxC,IAAIa,MAAMC,OAAO,CAACd,YAAYA,QAAQrB,MAAM,GAAG,GAAG;YAChD,MAAMoE,QAAQ/C,OAAO,CAAC,EAAE;YACxB,IAAI,OAAO+C,UAAU,YAAYA,UAAU,QAAQ,UAAUA,OAAO;gBAClE,OAAOC,OAAOD,MAAME,IAAI;YAC1B;QACF;QACA,OAAOD,OAAOhD;IAChB;IAEQC,mBAAmBH,OAAe,EAAU;QAClD,OAAOA,QACJpB,IAAI,GACJwE,OAAO,CAAC,gBAAgB,IACxBA,OAAO,CAAC,OAAO,KACfxE,IAAI;IACT;IAEQc,kBAAkBX,QAAqB,EAAEK,KAAc,EAAU;QACvE,MAAMiE,YAAYjE,QAAQ,CAAC,0DAA0D,EAAEA,MAAM,SAAS,CAAC,GAAG;QAE1G,IAAIkE,WAAW;QACf,IAAIvE,SAASb,MAAM,EAAE;YACnBoF,YAAY,CAAC,wBAAwB,EAAEvE,SAASb,MAAM,CAAC,IAAI,CAAC;QAC9D;QACA,IAAIa,SAASV,QAAQ,EAAE;YACrBiF,YAAY,CAAC,0BAA0B,EAAEvE,SAASV,QAAQ,CAAC,IAAI,CAAC;QAClE;QAEA,MAAMkF,YAAY;QAClB,IAAID,SAASzE,MAAM,GAAG0E,WAAW;YAC/BD,WAAWA,SAAShB,KAAK,CAAC,GAAGiB,aAAa;QAC5C;QAEA,OAAO,CAAC,iEAAiE,EAAEF,UAAU,oBAAoB,EAAEtE,SAAST,KAAK,CAAC,IAAI,EAAEgF,UAAU;IAC5I;IAEQhD,iBAAiBvB,QAAqB,EAAEkC,KAAe,EAAU;QACvE,IAAIqC,WAAW;QACf,IAAIvE,SAASb,MAAM,EAAE;YACnBoF,YAAY,CAAC,wBAAwB,EAAEvE,SAASb,MAAM,CAAC,IAAI,CAAC;QAC9D;QACA,IAAIa,SAASV,QAAQ,EAAE;YACrBiF,YAAY,CAAC,0BAA0B,EAAEvE,SAASV,QAAQ,CAAC,IAAI,CAAC;QAClE;QAEA,MAAMkF,YAAY;QAClB,IAAID,SAASzE,MAAM,GAAG0E,WAAW;YAC/BD,WAAWA,SAAShB,KAAK,CAAC,GAAGiB,aAAa;QAC5C;QAEA,OAAO,CAAC,2EAA2E,EAAEtC,MAAMuC,IAAI,CAAC,MAAM,YAAY,EAAEzE,SAAST,KAAK,CAAC,IAAI,EAAEgF,UAAU;IACrJ;IAEA,MAAcpC,wBAAwBJ,KAAkB,EAAE/B,QAAqB,EAAmB;QAChG,MAAMO,MAAM,IAAI,CAACC,eAAe,CAACC,WAAW,CAAC;QAE7C,MAAMiE,YAAY3C,MAAM1B,KAAK,GAAG,CAAC,CAAC,EAAE0B,MAAM1B,KAAK,CAAC,CAAC,CAAC,GAAG;QAErD,MAAMK,SAAS,CAAC,oEAAoE,EAAEqB,MAAM4C,IAAI,GAAGD,UAAU,SAAS,EAAE3C,MAAMG,KAAK,CAACuC,IAAI,CAAC,MAAM,eAAe,EAAE1C,MAAM6C,WAAW,CAAC,2IAA2I,CAAC;QAE9T,MAAMhE,WAAW,MAAML,IAAIM,MAAM,CAAC;YAChC,IAAIC,uBAAa,CAAC,IAAI,CAACC,qBAAqB;YAC5C,IAAIC,sBAAY,CAACN;SAClB;QAED,IAAIO,UAAU,IAAI,CAACC,cAAc,CAACN,SAASO,OAAO;QAClDF,UAAU,IAAI,CAACG,kBAAkB,CAACH;QAElC,IAAI,CAACA,QAAQ2B,QAAQ,CAAC,MAAM;YAC1B,MAAMvC,QAAQ0B,MAAM1B,KAAK,GAAG,CAAC,CAAC,EAAE0B,MAAM1B,KAAK,CAAC,CAAC,CAAC,GAAG;YACjDY,UAAU,GAAGc,MAAM4C,IAAI,GAAGtE,MAAM,EAAE,EAAEY,SAAS;QAC/C;QAEA,OAAOA;IACT;IAEQW,kBAAkBT,OAAe,EAAwB;QAC/D,MAAM0D,YAAY1D,QAAQ4C,KAAK,CAAC;QAChC,IAAIc,WAAW;YACb,IAAI;gBACF,MAAMC,SAASC,KAAKC,KAAK,CAACH,SAAS,CAAC,EAAE;gBACtC,IAAIC,OAAOhC,OAAO,IAAId,MAAMC,OAAO,CAAC6C,OAAOhC,OAAO,GAAG;oBACnD,OAAOgC,OAAOhC,OAAO;gBACvB;YACF,EAAE,OAAM,CAAC;QACX;QAEA,IAAI;YACF,MAAMgC,SAASC,KAAKC,KAAK,CAAC7D;YAC1B,IAAI2D,OAAOhC,OAAO,IAAId,MAAMC,OAAO,CAAC6C,OAAOhC,OAAO,GAAG;gBACnD,OAAOgC,OAAOhC,OAAO;YACvB;QACF,EAAE,OAAM,CAAC;QAET,OAAO;IACT;IAEQ/B,wBAAgC;QACtC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CA6BiC,CAAC;IAC5C;IAEQU,uBAA+B;QACrC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAuC4C,CAAC;IACvD;IAEQ+B,wBAAgC;QACtC,OAAO,CAAC;;;;;;;4BAOgB,CAAC;IAC3B;IApXA,YACE,AAAiBhD,eAAgC,EACjD,AAAiBN,gBAAyC,CAC1D;aAFiBM,kBAAAA;aACAN,mBAAAA;IAChB;AAkXL"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./commit-generator.service"), exports);
|
|
6
|
+
_export_star(require("./monorepo-detector.service"), exports);
|
|
7
|
+
function _export_star(from, to) {
|
|
8
|
+
Object.keys(from).forEach(function(k) {
|
|
9
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
10
|
+
Object.defineProperty(to, k, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function() {
|
|
13
|
+
return from[k];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return from;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/git/services/index.ts"],"sourcesContent":["export * from './commit-generator.service';\nexport * from './monorepo-detector.service';\n"],"names":[],"mappings":";;;;qBAAc;qBACA"}
|