mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 16:01:05 +00:00
feat(coding-agent): watch .git/HEAD for branch changes (#79)
Auto-updates footer when git branch changes externally (e.g., git checkout in another terminal)
This commit is contained in:
parent
532bb69ed6
commit
832273d4d6
2 changed files with 52 additions and 1 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import type { AgentState } from "@mariozechner/pi-agent-core";
|
import type { AgentState } from "@mariozechner/pi-agent-core";
|
||||||
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
||||||
import { type Component, visibleWidth } from "@mariozechner/pi-tui";
|
import { type Component, visibleWidth } from "@mariozechner/pi-tui";
|
||||||
import { readFileSync } from "fs";
|
import { existsSync, type FSWatcher, readFileSync, watch } from "fs";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { theme } from "../theme/theme.js";
|
import { theme } from "../theme/theme.js";
|
||||||
|
|
||||||
|
|
@ -11,11 +11,56 @@ import { theme } from "../theme/theme.js";
|
||||||
export class FooterComponent implements Component {
|
export class FooterComponent implements Component {
|
||||||
private state: AgentState;
|
private state: AgentState;
|
||||||
private cachedBranch: string | null | undefined = undefined; // undefined = not checked yet, null = not in git repo, string = branch name
|
private cachedBranch: string | null | undefined = undefined; // undefined = not checked yet, null = not in git repo, string = branch name
|
||||||
|
private gitWatcher: FSWatcher | null = null;
|
||||||
|
private onBranchChange: (() => void) | null = null;
|
||||||
|
|
||||||
constructor(state: AgentState) {
|
constructor(state: AgentState) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up a file watcher on .git/HEAD to detect branch changes.
|
||||||
|
* Call the provided callback when branch changes.
|
||||||
|
*/
|
||||||
|
watchBranch(onBranchChange: () => void): void {
|
||||||
|
this.onBranchChange = onBranchChange;
|
||||||
|
this.setupGitWatcher();
|
||||||
|
}
|
||||||
|
|
||||||
|
private setupGitWatcher(): void {
|
||||||
|
// Clean up existing watcher
|
||||||
|
if (this.gitWatcher) {
|
||||||
|
this.gitWatcher.close();
|
||||||
|
this.gitWatcher = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gitHeadPath = join(process.cwd(), ".git", "HEAD");
|
||||||
|
if (!existsSync(gitHeadPath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.gitWatcher = watch(gitHeadPath, () => {
|
||||||
|
this.cachedBranch = undefined; // Invalidate cache
|
||||||
|
if (this.onBranchChange) {
|
||||||
|
this.onBranchChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// Silently fail if we can't watch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up the file watcher
|
||||||
|
*/
|
||||||
|
dispose(): void {
|
||||||
|
if (this.gitWatcher) {
|
||||||
|
this.gitWatcher.close();
|
||||||
|
this.gitWatcher = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateState(state: AgentState): void {
|
updateState(state: AgentState): void {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -464,6 +464,11 @@ export class TuiRenderer {
|
||||||
this.updateEditorBorderColor();
|
this.updateEditorBorderColor();
|
||||||
this.ui.requestRender();
|
this.ui.requestRender();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set up git branch watcher
|
||||||
|
this.footer.watchBranch(() => {
|
||||||
|
this.ui.requestRender();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private subscribeToAgent(): void {
|
private subscribeToAgent(): void {
|
||||||
|
|
@ -1523,6 +1528,7 @@ export class TuiRenderer {
|
||||||
this.loadingAnimation.stop();
|
this.loadingAnimation.stop();
|
||||||
this.loadingAnimation = null;
|
this.loadingAnimation = null;
|
||||||
}
|
}
|
||||||
|
this.footer.dispose();
|
||||||
if (this.isInitialized) {
|
if (this.isInitialized) {
|
||||||
this.ui.stop();
|
this.ui.stop();
|
||||||
this.isInitialized = false;
|
this.isInitialized = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue