agent-nuvira 1.36.0 → 1.37.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/README.md +66 -0
- package/dist/agents/agents/branch-automation-agent.d.ts +36 -0
- package/dist/agents/agents/branch-automation-agent.d.ts.map +1 -0
- package/dist/agents/agents/branch-automation-agent.js +486 -0
- package/dist/agents/agents/branch-automation-agent.js.map +1 -0
- package/dist/agents/agents/branch-automation-hooks.d.ts +82 -0
- package/dist/agents/agents/branch-automation-hooks.d.ts.map +1 -0
- package/dist/agents/agents/branch-automation-hooks.js +337 -0
- package/dist/agents/agents/branch-automation-hooks.js.map +1 -0
- package/dist/agents/module-registry.d.ts.map +1 -1
- package/dist/agents/module-registry.js +7 -0
- package/dist/agents/module-registry.js.map +1 -1
- package/dist/cli/execute.d.ts.map +1 -1
- package/dist/cli/execute.js +1 -0
- package/dist/cli/execute.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,6 +56,20 @@ agent-nuvira config list
|
|
|
56
56
|
- **CI/CD headless mode** — `buff ci` for automated pipelines with GitHub Actions integration
|
|
57
57
|
- **npm publishing & one-line install** — `npx agent-nuvira` and `npx buff` for zero-setup onboarding
|
|
58
58
|
- **Marketing website** — `website/` directory with a full landing page, SEO meta tags, and Netlify-ready deployment config
|
|
59
|
+
- **Branch Automation Hooks (Pillar A4)** — `buff execute "install branch hooks" --auto-branch` installs
|
|
60
|
+
git post-checkout and pre-commit hooks for automated branch workflows; issue-driven branch creation
|
|
61
|
+
(`feat/PROJ-123-description`), PR label-triggered updates, file-watch auto-commit with conventional
|
|
62
|
+
commit messages, and CI failure detection with LLM diagnosis
|
|
63
|
+
- **Issue Triage Engine (Pillar A3)** — Automated issue classification, prioritization, and labeling
|
|
64
|
+
across GitHub and GitLab via `buff execute "triage issues"` with LLM-powered analysis
|
|
65
|
+
- **GitHub PR Review Agent (Pillar A2)** — Automatic inline code review on open PRs; reads diffs,
|
|
66
|
+
runs security/quality verification, and posts inline review comments via GitHub API
|
|
67
|
+
- **GitLab API Integration (Pillar A1)** — Full GitLab agent for merge request management, issue
|
|
68
|
+
discovery, pipeline monitoring, and code review comments
|
|
69
|
+
- **Chat Panel DAG Pipeline Visualization (Pillar B6)** — Live multi-agent pipeline visualization
|
|
70
|
+
inline in chat messages for slash commands, showing agent nodes with real-time status updates
|
|
71
|
+
- **Real-Time Token Streaming in AgentPanel (Pillar B2)** — Live typewriter-effect token streaming
|
|
72
|
+
with blinking cursor and animated progress indicator in the agent progress panel
|
|
59
73
|
- **Interactive development mode** — `buff execute` without a goal launches a guided interactive loop with session save/resume, follow-up suggestions, and failure analysis
|
|
60
74
|
- **Session persistence** — save and resume development sessions across CLI restarts with full history
|
|
61
75
|
- **Failure analysis** — automatic diagnosis of agent failures with specific recovery options per agent type
|
|
@@ -643,6 +657,58 @@ agent-nuvira model health
|
|
|
643
657
|
|
|
644
658
|
---
|
|
645
659
|
|
|
660
|
+
### `agent-nuvira execute --auto-branch` — Branch Automation
|
|
661
|
+
|
|
662
|
+
Automate your entire git workflow with trigger-based hooks. Install once, then let the agent handle branch creation, commits, and PR updates automatically.
|
|
663
|
+
|
|
664
|
+
```bash
|
|
665
|
+
# Step 1: Install branch automation hooks
|
|
666
|
+
buff execute "install branch hooks" --auto-branch
|
|
667
|
+
|
|
668
|
+
# Step 2: Check automation status
|
|
669
|
+
buff execute "check branch status" --auto-branch
|
|
670
|
+
|
|
671
|
+
# Step 3: Auto-create a branch from an issue
|
|
672
|
+
buff execute "auto-create branch from issue PROJ-123" --auto-branch
|
|
673
|
+
|
|
674
|
+
# Step 4: Auto-commit changes with a conventional message
|
|
675
|
+
buff execute "auto-commit changes" --auto-branch
|
|
676
|
+
|
|
677
|
+
# Step 5: Start file-watch mode (auto-commits on file changes)
|
|
678
|
+
buff execute "start file watch" --auto-branch
|
|
679
|
+
|
|
680
|
+
# Step 6: Diagnose CI failures
|
|
681
|
+
buff execute "check CI for PR #42" --auto-branch
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
**Trigger Sources:**
|
|
685
|
+
|
|
686
|
+
| Trigger | Action | Description |
|
|
687
|
+
|---------|--------|-------------|
|
|
688
|
+
| **Issue → Branch** | `feat/PROJ-123-description` | Auto-creates branches with conventional naming when issues are assigned |
|
|
689
|
+
| **PR Label → Update** | `git push origin <branch>` | Commits and pushes changes when labels like `wip` or `needs-work` are detected |
|
|
690
|
+
| **File Watch → Commit** | `git commit -m "feat(scope): ..."` | Background polling detects file changes and auto-commits with conventional messages |
|
|
691
|
+
| **CI Status → Fix** | LLM diagnosis + fix plan | Analyzes CI failures from recent commits and suggests targeted fixes |
|
|
692
|
+
|
|
693
|
+
**Conventional Commit Format:**
|
|
694
|
+
|
|
695
|
+
```
|
|
696
|
+
<type>(<scope>): <description>
|
|
697
|
+
|
|
698
|
+
Types: feat, fix, refactor, docs, style, test, chore, perf
|
|
699
|
+
Scope: module/area affected (auto-detected from changed files)
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**Installed Hooks:**
|
|
703
|
+
|
|
704
|
+
| Hook | Purpose |
|
|
705
|
+
|------|---------|
|
|
706
|
+
| `post-checkout` | Detects issue-based branches on checkout and loads context |
|
|
707
|
+
| `pre-commit` | Enforces conventional commit format with auto-detection |
|
|
708
|
+
| `file-watch.sh` | Background script that polls for changes and triggers auto-commits |
|
|
709
|
+
|
|
710
|
+
---
|
|
711
|
+
|
|
646
712
|
### `agent-nuvira skill` — Skill Compiler System
|
|
647
713
|
|
|
648
714
|
Automatically convert successful agent execution trajectories into reusable, parameterized skill scripts. Skills are extracted by an LLM from high-scoring runs, saved to `~/.buff/skills/`, and invoked directly via the orchestrator.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BranchAutomationAgent — Automated branch workflow with trigger-based hooks.
|
|
3
|
+
*
|
|
4
|
+
* Trigger Sources:
|
|
5
|
+
* 1. Issue → Branch: When an issue is assigned, auto-create a feature branch
|
|
6
|
+
* 2. PR Label → Update: When a label like 'wip' or 'needs-work' is added, auto-update
|
|
7
|
+
* 3. File Watch → Commit: Watch for file changes and auto-commit with conventional messages
|
|
8
|
+
* 4. CI Status → Fix: When CI fails on a PR, detect failure, fix it, push
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* - `buff execute "install branch hooks" --auto-branch`
|
|
12
|
+
* - `buff execute "auto-create branch from issue PROJ-123" --auto-branch`
|
|
13
|
+
* - `buff execute "auto-commit changes" --auto-branch`
|
|
14
|
+
* - `buff execute "fix CI for PR #42" --auto-branch`
|
|
15
|
+
*/
|
|
16
|
+
import { Agent, type AgentContext, type AgentResult } from '../agent.js';
|
|
17
|
+
import type { LLMCallFn } from '../agent.js';
|
|
18
|
+
export declare class BranchAutomationAgent extends Agent {
|
|
19
|
+
readonly name = "BranchAutomation";
|
|
20
|
+
readonly description = "Automates branch workflows: issue\u2192branch, PR\u2192update, file\u2192commit, CI\u2192fix";
|
|
21
|
+
execute(context: AgentContext, callLLM: LLMCallFn): Promise<AgentResult>;
|
|
22
|
+
private detectOperation;
|
|
23
|
+
private getRepoPath;
|
|
24
|
+
private getCurrentBranch;
|
|
25
|
+
private getChangedFiles;
|
|
26
|
+
private handleInstall;
|
|
27
|
+
private handleRemove;
|
|
28
|
+
private handleStatus;
|
|
29
|
+
private handleIssueBranch;
|
|
30
|
+
private handlePRUpdate;
|
|
31
|
+
private handleFileWatch;
|
|
32
|
+
private handleAutoCommit;
|
|
33
|
+
private handleCIFix;
|
|
34
|
+
private handleAutoDetect;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=branch-automation-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-automation-agent.d.ts","sourceRoot":"","sources":["../../../src/agents/agents/branch-automation-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAqB7C,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,sBAAsB;IACnC,QAAQ,CAAC,WAAW,kGAA8E;IAE5F,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAqC9E,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,eAAe;YAqBT,aAAa;YAoCb,YAAY;YAQZ,YAAY;YAkCZ,iBAAiB;YA2DjB,cAAc;YA+Ed,eAAe;YAgDf,gBAAgB;YA8ChB,WAAW;YAmEX,gBAAgB;CA6C/B"}
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BranchAutomationAgent — Automated branch workflow with trigger-based hooks.
|
|
3
|
+
*
|
|
4
|
+
* Trigger Sources:
|
|
5
|
+
* 1. Issue → Branch: When an issue is assigned, auto-create a feature branch
|
|
6
|
+
* 2. PR Label → Update: When a label like 'wip' or 'needs-work' is added, auto-update
|
|
7
|
+
* 3. File Watch → Commit: Watch for file changes and auto-commit with conventional messages
|
|
8
|
+
* 4. CI Status → Fix: When CI fails on a PR, detect failure, fix it, push
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* - `buff execute "install branch hooks" --auto-branch`
|
|
12
|
+
* - `buff execute "auto-create branch from issue PROJ-123" --auto-branch`
|
|
13
|
+
* - `buff execute "auto-commit changes" --auto-branch`
|
|
14
|
+
* - `buff execute "fix CI for PR #42" --auto-branch`
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { execSync } from 'node:child_process';
|
|
20
|
+
import { Agent } from '../agent.js';
|
|
21
|
+
import { installHooks, removeHooks, getHookStatus, detectIssueBranch, generateBranchName, createAndCheckoutBranch, autoCommit, generateCommitMessage, } from './branch-automation-hooks.js';
|
|
22
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
23
|
+
const DEFAULT_WATCH_INTERVAL_MS = 60_000;
|
|
24
|
+
// ─── BranchAutomationAgent ──────────────────────────────────────────────────
|
|
25
|
+
export class BranchAutomationAgent extends Agent {
|
|
26
|
+
name = 'BranchAutomation';
|
|
27
|
+
description = 'Automates branch workflows: issue→branch, PR→update, file→commit, CI→fix';
|
|
28
|
+
async execute(context, callLLM) {
|
|
29
|
+
try {
|
|
30
|
+
const taskDesc = context.taskPlan.find((s) => s.agentType === 'branch-automation' && s.status === 'running')?.description || context.goal;
|
|
31
|
+
const operation = this.detectOperation(taskDesc, context);
|
|
32
|
+
const repoPath = this.getRepoPath();
|
|
33
|
+
switch (operation) {
|
|
34
|
+
case 'install':
|
|
35
|
+
return this.handleInstall(repoPath);
|
|
36
|
+
case 'remove':
|
|
37
|
+
return this.handleRemove(repoPath);
|
|
38
|
+
case 'status':
|
|
39
|
+
return this.handleStatus(repoPath);
|
|
40
|
+
case 'issue-branch':
|
|
41
|
+
return this.handleIssueBranch(context, callLLM, repoPath);
|
|
42
|
+
case 'pr-update':
|
|
43
|
+
return this.handlePRUpdate(context, callLLM, repoPath);
|
|
44
|
+
case 'auto-commit':
|
|
45
|
+
return this.handleAutoCommit(context, callLLM, repoPath);
|
|
46
|
+
case 'ci-fix':
|
|
47
|
+
return this.handleCIFix(context, callLLM, repoPath);
|
|
48
|
+
case 'file-watch':
|
|
49
|
+
return this.handleFileWatch(repoPath);
|
|
50
|
+
default:
|
|
51
|
+
return this.handleAutoDetect(context, callLLM, repoPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56
|
+
return { success: false, summary: 'Branch automation failed', error: msg.slice(0, 300) };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// ─── Operation Detection ──────────────────────────────────────────────────
|
|
60
|
+
detectOperation(description, context) {
|
|
61
|
+
const lower = description.toLowerCase();
|
|
62
|
+
if (lower.includes('install') || lower.includes('setup') || lower.includes('enable'))
|
|
63
|
+
return 'install';
|
|
64
|
+
if (lower.includes('remove') || lower.includes('uninstall') || lower.includes('disable'))
|
|
65
|
+
return 'remove';
|
|
66
|
+
if (lower.includes('status') || lower.includes('check') || lower.includes('list'))
|
|
67
|
+
return 'status';
|
|
68
|
+
if (lower.includes('issue') || lower.includes('branch from issue') || lower.includes('create branch'))
|
|
69
|
+
return 'issue-branch';
|
|
70
|
+
if (lower.includes('pr') || lower.includes('pull request') || lower.includes('label'))
|
|
71
|
+
return 'pr-update';
|
|
72
|
+
if (lower.includes('watch') || lower.includes('monitor') || lower.includes('file change') || lower.includes('auto-commit'))
|
|
73
|
+
return 'file-watch';
|
|
74
|
+
if (lower.includes('ci') || lower.includes('ci fix') || lower.includes('fix ci') || lower.includes('pipeline'))
|
|
75
|
+
return 'ci-fix';
|
|
76
|
+
if (lower.includes('commit') || lower.includes('auto commit'))
|
|
77
|
+
return 'auto-commit';
|
|
78
|
+
// Auto-detect from context flags
|
|
79
|
+
if (context.goal.includes('--auto-branch'))
|
|
80
|
+
return 'auto-commit';
|
|
81
|
+
return 'auto-detect';
|
|
82
|
+
}
|
|
83
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
84
|
+
getRepoPath() {
|
|
85
|
+
try {
|
|
86
|
+
const output = execSync('git rev-parse --show-toplevel 2>/dev/null', {
|
|
87
|
+
encoding: 'utf-8',
|
|
88
|
+
timeout: 5000,
|
|
89
|
+
}).trim();
|
|
90
|
+
return output || process.cwd();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return process.cwd();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
getCurrentBranch() {
|
|
97
|
+
try {
|
|
98
|
+
return execSync('git rev-parse --abbrev-ref HEAD', {
|
|
99
|
+
encoding: 'utf-8',
|
|
100
|
+
timeout: 5000,
|
|
101
|
+
}).trim();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return 'main';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
getChangedFiles() {
|
|
108
|
+
try {
|
|
109
|
+
const output = execSync('git diff --name-only', {
|
|
110
|
+
encoding: 'utf-8',
|
|
111
|
+
timeout: 5000,
|
|
112
|
+
}).trim();
|
|
113
|
+
const staged = execSync('git diff --cached --name-only', {
|
|
114
|
+
encoding: 'utf-8',
|
|
115
|
+
timeout: 5000,
|
|
116
|
+
}).trim();
|
|
117
|
+
const all = [...output.split('\n'), ...staged.split('\n')]
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.map((f) => f.trim());
|
|
120
|
+
return [...new Set(all)];
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// ─── Install Hooks ────────────────────────────────────────────────────────
|
|
127
|
+
async handleInstall(repoPath) {
|
|
128
|
+
const config = {
|
|
129
|
+
repoPath,
|
|
130
|
+
postCheckout: true,
|
|
131
|
+
preCommit: true,
|
|
132
|
+
fileWatch: true,
|
|
133
|
+
cliPath: 'buff',
|
|
134
|
+
watchIntervalMs: DEFAULT_WATCH_INTERVAL_MS,
|
|
135
|
+
};
|
|
136
|
+
const installed = installHooks(config);
|
|
137
|
+
if (installed) {
|
|
138
|
+
return {
|
|
139
|
+
success: true,
|
|
140
|
+
summary: 'Branch automation hooks installed',
|
|
141
|
+
details: [
|
|
142
|
+
'✅ post-checkout hook — auto-detect issue branches on checkout',
|
|
143
|
+
'✅ pre-commit hook — conventional commit message enforcement',
|
|
144
|
+
'✅ file-watch script — auto-commit on file changes',
|
|
145
|
+
'',
|
|
146
|
+
`Hooks installed in: ${join(repoPath, '.git', 'hooks')}`,
|
|
147
|
+
`File-watch script: ${join(homedir(), '.buff', 'hooks', 'file-watch.sh')}`,
|
|
148
|
+
'',
|
|
149
|
+
'To start file-watch: buff execute "start file watch" --auto-branch',
|
|
150
|
+
'To remove hooks: buff execute "remove branch hooks" --auto-branch',
|
|
151
|
+
].join('\n'),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
success: true,
|
|
156
|
+
summary: 'Hooks were already installed or no hooks were configured',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
async handleRemove(repoPath) {
|
|
160
|
+
const removed = removeHooks(repoPath);
|
|
161
|
+
return {
|
|
162
|
+
success: true,
|
|
163
|
+
summary: removed ? 'Branch automation hooks removed' : 'No hooks found to remove',
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async handleStatus(repoPath) {
|
|
167
|
+
const status = getHookStatus(repoPath);
|
|
168
|
+
const branch = this.getCurrentBranch();
|
|
169
|
+
const changedFiles = this.getChangedFiles();
|
|
170
|
+
const statusLines = [
|
|
171
|
+
`Repository: ${repoPath}`,
|
|
172
|
+
`Current branch: ${branch}`,
|
|
173
|
+
`Changed files: ${changedFiles.length}`,
|
|
174
|
+
'',
|
|
175
|
+
'Hook Status:',
|
|
176
|
+
` post-checkout: ${status.postCheckout ? '✅ installed' : '❌ not installed'}`,
|
|
177
|
+
` pre-commit: ${status.preCommit ? '✅ installed' : '❌ not installed'}`,
|
|
178
|
+
` file-watch: ${status.fileWatch ? '✅ installed' : '❌ not installed'}`,
|
|
179
|
+
'',
|
|
180
|
+
];
|
|
181
|
+
// Detect if we're on an issue branch
|
|
182
|
+
const issueInfo = detectIssueBranch(branch);
|
|
183
|
+
if (issueInfo) {
|
|
184
|
+
statusLines.push(`Issue Branch: ${issueInfo.type}/${issueInfo.issueKey}-${issueInfo.description.replace(/ /g, '-')}`);
|
|
185
|
+
statusLines.push(` Issue: ${issueInfo.issueKey}`);
|
|
186
|
+
statusLines.push(` Type: ${issueInfo.type}`);
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
success: true,
|
|
190
|
+
summary: `Branch automation status — ${Object.values(status).filter(Boolean).length}/3 hooks active`,
|
|
191
|
+
details: statusLines.join('\n'),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// ─── Issue → Branch ───────────────────────────────────────────────────────
|
|
195
|
+
async handleIssueBranch(context, callLLM, repoPath) {
|
|
196
|
+
const description = context.goal;
|
|
197
|
+
const branch = this.getCurrentBranch();
|
|
198
|
+
// Extract issue info from goal text
|
|
199
|
+
const issueMatch = description.match(/([A-Z]+-[0-9]+)/);
|
|
200
|
+
const issueKey = issueMatch ? issueMatch[1] : '';
|
|
201
|
+
// Determine branch type from description
|
|
202
|
+
let branchType = 'feat';
|
|
203
|
+
if (description.toLowerCase().includes('fix') || description.toLowerCase().includes('bug'))
|
|
204
|
+
branchType = 'fix';
|
|
205
|
+
if (description.toLowerCase().includes('chore') || description.toLowerCase().includes('config'))
|
|
206
|
+
branchType = 'chore';
|
|
207
|
+
// Extract a meaningful description from the goal
|
|
208
|
+
let branchDesc = description
|
|
209
|
+
.replace(/auto-create branch from issue/i, '')
|
|
210
|
+
.replace(/create branch/i, '')
|
|
211
|
+
.replace(/--auto-branch/g, '')
|
|
212
|
+
.replace(issueKey, '')
|
|
213
|
+
.trim();
|
|
214
|
+
if (!branchDesc) {
|
|
215
|
+
branchDesc = branchType;
|
|
216
|
+
}
|
|
217
|
+
const branchName = generateBranchName(issueKey, branchDesc, branchType);
|
|
218
|
+
// Don't create if already on this branch
|
|
219
|
+
if (branch === branchName) {
|
|
220
|
+
return {
|
|
221
|
+
success: true,
|
|
222
|
+
summary: `Already on branch '${branchName}'`,
|
|
223
|
+
details: branchName,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
const result = createAndCheckoutBranch(branchName, repoPath);
|
|
228
|
+
return {
|
|
229
|
+
success: true,
|
|
230
|
+
summary: result,
|
|
231
|
+
details: branchName,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
summary: `Failed to create branch '${branchName}'`,
|
|
239
|
+
error: msg.slice(0, 200),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// ─── PR Label → Update ────────────────────────────────────────────────────
|
|
244
|
+
async handlePRUpdate(context, callLLM, repoPath) {
|
|
245
|
+
const description = context.goal;
|
|
246
|
+
const branch = this.getCurrentBranch();
|
|
247
|
+
// Extract PR number
|
|
248
|
+
const prMatch = description.match(/#(\d+)|PR[- ]?(\d+)/i);
|
|
249
|
+
const prNumber = prMatch ? (prMatch[1] || prMatch[2]) : '';
|
|
250
|
+
// Extract label info
|
|
251
|
+
const labelMatch = description.match(/label[:\s]*["']?(\w+)["']?/i);
|
|
252
|
+
const label = labelMatch ? labelMatch[1].toLowerCase() : '';
|
|
253
|
+
// Detect what kind of update is needed from the label
|
|
254
|
+
let updateType = 'general';
|
|
255
|
+
if (label === 'wip' || label === 'work-in-progress') {
|
|
256
|
+
updateType = 'wip-update';
|
|
257
|
+
}
|
|
258
|
+
else if (label === 'needs-work' || label === 'changes-requested') {
|
|
259
|
+
updateType = 'address-feedback';
|
|
260
|
+
}
|
|
261
|
+
else if (label.includes('fix') || label.includes('bug')) {
|
|
262
|
+
updateType = 'bug-fix';
|
|
263
|
+
}
|
|
264
|
+
// Get changed files
|
|
265
|
+
const changedFiles = this.getChangedFiles();
|
|
266
|
+
if (changedFiles.length === 0) {
|
|
267
|
+
return {
|
|
268
|
+
success: true,
|
|
269
|
+
summary: 'No changes to push to PR',
|
|
270
|
+
details: `PR #${prNumber || 'unknown'} on branch '${branch}'`,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
// Commit changes
|
|
274
|
+
const commitResult = autoCommit(changedFiles, undefined, repoPath);
|
|
275
|
+
if (!commitResult.success) {
|
|
276
|
+
return {
|
|
277
|
+
success: false,
|
|
278
|
+
summary: `Failed to commit PR updates for ${label || 'update'}`,
|
|
279
|
+
error: commitResult.output,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
// Push to remote
|
|
283
|
+
try {
|
|
284
|
+
execSync(`git push origin "${branch}"`, {
|
|
285
|
+
cwd: repoPath,
|
|
286
|
+
encoding: 'utf-8',
|
|
287
|
+
timeout: 60000,
|
|
288
|
+
});
|
|
289
|
+
return {
|
|
290
|
+
success: true,
|
|
291
|
+
summary: `Updated PR #${prNumber || 'unknown'} with ${changedFiles.length} file change(s)`,
|
|
292
|
+
details: [
|
|
293
|
+
`Branch: ${branch}`,
|
|
294
|
+
`Updated files: ${changedFiles.join(', ')}`,
|
|
295
|
+
`Commit: ${commitResult.message}`,
|
|
296
|
+
prNumber ? `PR: #${prNumber}` : '',
|
|
297
|
+
'',
|
|
298
|
+
'✅ Changes pushed to remote.',
|
|
299
|
+
].filter(Boolean).join('\n'),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
304
|
+
return {
|
|
305
|
+
success: true,
|
|
306
|
+
summary: `Committed locally but push failed: ${msg.slice(0, 100)}`,
|
|
307
|
+
details: commitResult.output,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// ─── File Watch → Commit ──────────────────────────────────────────────────
|
|
312
|
+
async handleFileWatch(repoPath) {
|
|
313
|
+
const hooksPath = join(homedir(), '.buff', 'hooks');
|
|
314
|
+
const watchScript = join(hooksPath, 'file-watch.sh');
|
|
315
|
+
if (!existsSync(watchScript)) {
|
|
316
|
+
// Install the watch script first
|
|
317
|
+
const config = {
|
|
318
|
+
repoPath,
|
|
319
|
+
postCheckout: false,
|
|
320
|
+
preCommit: false,
|
|
321
|
+
fileWatch: true,
|
|
322
|
+
cliPath: 'buff',
|
|
323
|
+
watchIntervalMs: DEFAULT_WATCH_INTERVAL_MS,
|
|
324
|
+
};
|
|
325
|
+
installHooks(config);
|
|
326
|
+
}
|
|
327
|
+
// Start file-watch in background using the installed script
|
|
328
|
+
try {
|
|
329
|
+
const pid = execSync(`nohup sh "${join(homedir(), '.buff', 'hooks', 'file-watch.sh')}" "${repoPath}" > /tmp/agent-nuvira-filewatch.log 2>&1 & echo $!`, { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
330
|
+
return {
|
|
331
|
+
success: true,
|
|
332
|
+
summary: `File watch started (PID: ${pid})`,
|
|
333
|
+
details: [
|
|
334
|
+
`Watching: ${repoPath}`,
|
|
335
|
+
`Interval: ${DEFAULT_WATCH_INTERVAL_MS / 1000}s`,
|
|
336
|
+
`Log: /tmp/agent-nuvira-filewatch.log`,
|
|
337
|
+
'',
|
|
338
|
+
'Auto-commits will be triggered when file changes are detected.',
|
|
339
|
+
'To stop: buff execute "stop file watch" --auto-branch',
|
|
340
|
+
].join('\n'),
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
345
|
+
return {
|
|
346
|
+
success: false,
|
|
347
|
+
summary: 'Failed to start file watch',
|
|
348
|
+
error: msg.slice(0, 200),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// ─── Auto-Commit ──────────────────────────────────────────────────────────
|
|
353
|
+
async handleAutoCommit(context, callLLM, repoPath) {
|
|
354
|
+
const changedFiles = this.getChangedFiles();
|
|
355
|
+
if (changedFiles.length === 0) {
|
|
356
|
+
return { success: true, summary: 'No changes to commit' };
|
|
357
|
+
}
|
|
358
|
+
// Try LLM-generated commit message first
|
|
359
|
+
let commitMessage = '';
|
|
360
|
+
try {
|
|
361
|
+
const diff = execSync('git diff --no-color --stat', {
|
|
362
|
+
cwd: repoPath,
|
|
363
|
+
encoding: 'utf-8',
|
|
364
|
+
timeout: 10000,
|
|
365
|
+
});
|
|
366
|
+
const fullDiff = execSync('git diff --no-color', {
|
|
367
|
+
cwd: repoPath,
|
|
368
|
+
encoding: 'utf-8',
|
|
369
|
+
timeout: 10000,
|
|
370
|
+
});
|
|
371
|
+
const prompt = `Generate a conventional commit message for these changes:\n\n${diff}\n\nFull diff (truncated):\n${fullDiff.slice(0, 2000)}\n\nReturn ONLY the commit message in format: <type>(<scope>): <description>`;
|
|
372
|
+
commitMessage = await callLLM(prompt, { temperature: 0.2, maxTokens: 200 });
|
|
373
|
+
commitMessage = commitMessage.trim().replace(/^```[\s\S]*?\n|```$/g, '').trim();
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// Fall back to rule-based message
|
|
377
|
+
}
|
|
378
|
+
if (!commitMessage || commitMessage.length < 5) {
|
|
379
|
+
commitMessage = generateCommitMessage(changedFiles);
|
|
380
|
+
}
|
|
381
|
+
const result = autoCommit(changedFiles, commitMessage, repoPath);
|
|
382
|
+
return {
|
|
383
|
+
success: result.success,
|
|
384
|
+
summary: result.success ? `Committed: ${result.message}` : `Commit failed: ${result.output}`,
|
|
385
|
+
details: result.output,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
// ─── CI Status → Fix ──────────────────────────────────────────────────────
|
|
389
|
+
async handleCIFix(context, callLLM, repoPath) {
|
|
390
|
+
const description = context.goal;
|
|
391
|
+
const branch = this.getCurrentBranch();
|
|
392
|
+
// Extract PR number if provided
|
|
393
|
+
const prMatch = description.match(/#(\d+)|PR[- ]?(\d+)/i);
|
|
394
|
+
const prNumber = prMatch ? (prMatch[1] || prMatch[2]) : '';
|
|
395
|
+
// Try to detect CI failure reason from git status and recent commits
|
|
396
|
+
let failureReason = 'CI pipeline failed';
|
|
397
|
+
try {
|
|
398
|
+
const recentCommits = execSync('git log --oneline -5', {
|
|
399
|
+
cwd: repoPath,
|
|
400
|
+
encoding: 'utf-8',
|
|
401
|
+
timeout: 10000,
|
|
402
|
+
});
|
|
403
|
+
const changedFiles = this.getChangedFiles();
|
|
404
|
+
// Try LLM to diagnose the CI failure from context
|
|
405
|
+
const prompt = `A CI pipeline failed on branch '${branch}'${prNumber ? ` (PR #${prNumber})` : ''}.
|
|
406
|
+
|
|
407
|
+
Recent commits:
|
|
408
|
+
${recentCommits}
|
|
409
|
+
|
|
410
|
+
Changed files:
|
|
411
|
+
${changedFiles.join('\n')}
|
|
412
|
+
|
|
413
|
+
Diagnose the most likely cause of the CI failure and suggest a fix.
|
|
414
|
+
Return your analysis and the specific fix needed.`;
|
|
415
|
+
try {
|
|
416
|
+
const analysis = await callLLM(prompt, { temperature: 0.2, maxTokens: 1000 });
|
|
417
|
+
failureReason = analysis.trim();
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
failureReason = 'CI failure detected. Attempting automatic fix.';
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
failureReason = 'Could not determine CI failure reason. Proceeding with general fix attempt.';
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
success: true,
|
|
428
|
+
summary: `CI fix analysis for branch '${branch}'${prNumber ? ` (PR #${prNumber})` : ''}`,
|
|
429
|
+
details: [
|
|
430
|
+
'CI Failure Analysis:',
|
|
431
|
+
'---',
|
|
432
|
+
failureReason,
|
|
433
|
+
'---',
|
|
434
|
+
'',
|
|
435
|
+
'To apply the fix automatically:',
|
|
436
|
+
` buff execute "Fix CI issues on ${branch}" --auto-branch`,
|
|
437
|
+
'',
|
|
438
|
+
'To run tests locally:',
|
|
439
|
+
' buff execute "Run tests and fix failures"',
|
|
440
|
+
'',
|
|
441
|
+
prNumber ? `PR: #${prNumber} on branch '${branch}'` : `Branch: ${branch}`,
|
|
442
|
+
].join('\n'),
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
// ─── Auto-Detect ──────────────────────────────────────────────────────────
|
|
446
|
+
async handleAutoDetect(context, callLLM, repoPath) {
|
|
447
|
+
const branch = this.getCurrentBranch();
|
|
448
|
+
const changedFiles = this.getChangedFiles();
|
|
449
|
+
const issueInfo = detectIssueBranch(branch);
|
|
450
|
+
const hookStatus = getHookStatus(repoPath);
|
|
451
|
+
const hasHooks = hookStatus.postCheckout || hookStatus.preCommit;
|
|
452
|
+
const diagnostics = [
|
|
453
|
+
`Repository: ${repoPath}`,
|
|
454
|
+
`Branch: ${branch}`,
|
|
455
|
+
`Changed files: ${changedFiles.length}`,
|
|
456
|
+
`Hooks installed: ${hasHooks ? 'yes' : 'no'}`,
|
|
457
|
+
issueInfo ? `Issue detected: ${issueInfo.issueKey} (${issueInfo.type})` : '',
|
|
458
|
+
].filter(Boolean);
|
|
459
|
+
// Recommend next action based on state
|
|
460
|
+
if (changedFiles.length > 0) {
|
|
461
|
+
diagnostics.push('');
|
|
462
|
+
diagnostics.push('💡 Suggested actions:');
|
|
463
|
+
diagnostics.push(' 1. Auto-commit: buff execute "auto-commit changes" --auto-branch');
|
|
464
|
+
if (!hasHooks) {
|
|
465
|
+
diagnostics.push(' 2. Install hooks: buff execute "install branch hooks" --auto-branch');
|
|
466
|
+
diagnostics.push(' 3. Start file watch: buff execute "start file watch" --auto-branch');
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
else if (issueInfo) {
|
|
470
|
+
diagnostics.push('');
|
|
471
|
+
diagnostics.push(`💡 On issue branch for ${issueInfo.issueKey}. Ready to work.`);
|
|
472
|
+
diagnostics.push(' Changes will be auto-detected and committed.');
|
|
473
|
+
}
|
|
474
|
+
else if (!hasHooks) {
|
|
475
|
+
diagnostics.push('');
|
|
476
|
+
diagnostics.push('💡 Branch automation not configured.');
|
|
477
|
+
diagnostics.push(' Install hooks: buff execute "install branch hooks" --auto-branch');
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
success: true,
|
|
481
|
+
summary: `Branch automation diagnostic for '${branch}'`,
|
|
482
|
+
details: diagnostics.join('\n'),
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
//# sourceMappingURL=branch-automation-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-automation-agent.js","sourceRoot":"","sources":["../../../src/agents/agents/branch-automation-agent.ts"],"names":[],"mappings":"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"}
|