TASK: Smart Absorb — Auto-sort files to virtual branches
Context
GitButler already has absorb (assigns hunks to existing commits/branches).
This task makes it smart: agent analyzes changed files, groups them by semantic context, and assigns each group to the correct virtual branch — or creates a new one.
PHI LOOP: edit spec → seal hash → gen → test → verdict → experience → skill commit → git commit
Tool spec
// Tool: gitbutler_absorb_smart
// Input:
interface AbsorbSmartInput {
strategy: 'auto' | 'by-directory' | 'by-type' | 'by-feature';
// auto: LLM decides grouping
// by-directory: group by top-level dir (src/, tests/, docs/)
// by-type: group by file extension (.rs, .ts, .md)
// by-feature: LLM reads file content, infers feature context
dryRun?: boolean; // default false — if true, return plan without executing
}
// Output:
interface AbsorbSmartResult {
ok: boolean;
plan: AbsorbGroup[]; // always returned (even if dryRun: false)
executed: boolean;
summary: string; // human-readable: "Sorted 7 files into 3 branches"
}
interface AbsorbGroup {
branch: string; // target virtual branch name
files: string[]; // file paths assigned to this branch
action: 'existing' | 'create-new'; // use existing GB branch or create
rationale: string; // why these files go here
}
Algorithm
1. gitbutler_workspace_status() → get all changed files
2. IF strategy === 'auto' or 'by-feature':
├─ Read first 50 lines of each changed file
└─ LLM prompt: "Group these files by feature/concern. Return JSON."
ELSE:
└─ Apply deterministic grouping (dir or extension)
3. Get existing GB virtual branches (but branch list)
4. Match groups to branches (fuzzy name match or LLM decision)
5. IF dryRun: return plan only
6. ELSE: for each group:
├─ if branch exists: gitbutler_stage(files) on that branch
└─ if new branch needed: gitbutler_create_branch() then stage
7. Return AbsorbSmartResult
Example usage
# Dry run first (see the plan)
curl -X POST http://127.0.0.1:9200/mcp/tools/call \
-H 'Content-Type: application/json' \
-d '{"name":"gitbutler_absorb_smart","arguments":{"strategy":"auto","dryRun":true}}'
# Expected:
# {
# "ok": true,
# "plan": [
# {"branch": "feat-auth", "files": ["src/auth.rs", "tests/auth_test.rs"], "action": "existing"},
# {"branch": "fix-ui", "files": ["src/ui/button.ts", "src/ui/modal.ts"], "action": "create-new"}
# ],
# "executed": false,
# "summary": "Plan: 4 files into 2 branches"
# }
# Execute
curl -X POST http://127.0.0.1:9200/mcp/tools/call \
-H 'Content-Type: application/json' \
-d '{"name":"gitbutler_absorb_smart","arguments":{"strategy":"auto"}}'
Chat usage example
User: "Sort my changes into branches automatically"
Agent:
1. gitbutler_absorb_smart({strategy: "auto", dryRun: true})
2. "I'll sort 7 files into 3 branches. Shall I proceed?"
3. User: "yes"
4. gitbutler_absorb_smart({strategy: "auto"})
5. ✅ Sorted 7 files: auth (3), ui (2), docs (2)
Tests required
// src/__tests__/absorb-smart.test.ts
describe('gitbutler_absorb_smart', () => {
it('groups files by-directory correctly', ...)
it('groups files by-type correctly', ...)
it('dry-run returns plan without side effects', ...)
it('creates new branch when no match exists', ...)
it('returns structured error when workspace is clean', ...)
})
Laws
- L1:
Closes #6
- L4: 5+ tests
- L7: NO
.sh
Success criteria
φ² + 1/φ² = 3 | TRINITY | GO.
TASK: Smart Absorb — Auto-sort files to virtual branches
Context
GitButler already has
absorb(assigns hunks to existing commits/branches).This task makes it smart: agent analyzes changed files, groups them by semantic context, and assigns each group to the correct virtual branch — or creates a new one.
PHI LOOP: edit spec → seal hash → gen → test → verdict → experience → skill commit → git commit
Tool spec
Algorithm
Example usage
Chat usage example
Tests required
Laws
Closes #6.shSuccess criteria
gitbutler_absorb_smarttool live on port 9200dryRun: truereturns plan without executingauto,by-directory,by-typebun testgreenφ² + 1/φ² = 3 | TRINITY | GO.