pi-git-status-line 0.1.0 → 0.1.2
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 +4 -0
- package/extensions/git-status-line.ts +35 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,10 @@ A standalone [Pi](https://github.com/badlogic/pi-mono) package that extends Pi's
|
|
|
9
9
|
|
|
10
10
|
It keeps Pi's existing footer/status line and adds a git summary via `ctx.ui.setStatus(...)`.
|
|
11
11
|
|
|
12
|
+
## Preview
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
12
16
|
## Install
|
|
13
17
|
|
|
14
18
|
### From npm
|
|
@@ -20,20 +20,51 @@ type RepoState = {
|
|
|
20
20
|
|
|
21
21
|
const STATUS_KEY = "git-status-line";
|
|
22
22
|
const REFRESH_TOOL_NAMES = new Set(["bash", "write", "edit"]);
|
|
23
|
+
/** How often the status line is refreshed while a session is active (git state can change outside Pi). */
|
|
24
|
+
const REFRESH_INTERVAL_MS = 15_000;
|
|
23
25
|
|
|
24
26
|
export default function gitStatusLineExtension(pi: ExtensionAPI) {
|
|
27
|
+
let refreshInterval: ReturnType<typeof setInterval> | undefined;
|
|
28
|
+
let latestCtx: ExtensionContext | undefined;
|
|
29
|
+
let periodicRefreshInFlight = false;
|
|
30
|
+
|
|
31
|
+
const stopPeriodicRefresh = () => {
|
|
32
|
+
if (refreshInterval !== undefined) {
|
|
33
|
+
clearInterval(refreshInterval);
|
|
34
|
+
refreshInterval = undefined;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const startPeriodicRefresh = () => {
|
|
39
|
+
stopPeriodicRefresh();
|
|
40
|
+
refreshInterval = setInterval(() => {
|
|
41
|
+
const ctx = latestCtx;
|
|
42
|
+
if (!ctx?.hasUI || periodicRefreshInFlight) return;
|
|
43
|
+
periodicRefreshInFlight = true;
|
|
44
|
+
void updateStatusLine(pi, ctx).finally(() => {
|
|
45
|
+
periodicRefreshInFlight = false;
|
|
46
|
+
});
|
|
47
|
+
}, REFRESH_INTERVAL_MS);
|
|
48
|
+
};
|
|
49
|
+
|
|
25
50
|
const refresh = async (ctx: ExtensionContext) => {
|
|
51
|
+
latestCtx = ctx;
|
|
26
52
|
await updateStatusLine(pi, ctx);
|
|
27
53
|
};
|
|
28
54
|
|
|
29
55
|
pi.on("session_start", async (_event, ctx) => {
|
|
30
56
|
await refresh(ctx);
|
|
57
|
+
startPeriodicRefresh();
|
|
31
58
|
});
|
|
32
59
|
|
|
33
60
|
pi.on("turn_end", async (_event, ctx) => {
|
|
34
61
|
await refresh(ctx);
|
|
35
62
|
});
|
|
36
63
|
|
|
64
|
+
pi.on("agent_end", async (_event, ctx) => {
|
|
65
|
+
await refresh(ctx);
|
|
66
|
+
});
|
|
67
|
+
|
|
37
68
|
pi.on("tool_execution_end", async (event, ctx) => {
|
|
38
69
|
if (REFRESH_TOOL_NAMES.has(event.toolName)) {
|
|
39
70
|
await refresh(ctx);
|
|
@@ -41,6 +72,8 @@ export default function gitStatusLineExtension(pi: ExtensionAPI) {
|
|
|
41
72
|
});
|
|
42
73
|
|
|
43
74
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
75
|
+
stopPeriodicRefresh();
|
|
76
|
+
latestCtx = undefined;
|
|
44
77
|
if (ctx.hasUI) ctx.ui.setStatus(STATUS_KEY, "");
|
|
45
78
|
});
|
|
46
79
|
}
|
|
@@ -181,7 +214,8 @@ function formatGitStatusLine(repo: RepoState, theme: { fg(color: string, text: s
|
|
|
181
214
|
? formatAheadBehind(repo.aheadCount, repo.behindCount, theme)
|
|
182
215
|
: theme.fg("dim", "no upstream");
|
|
183
216
|
|
|
184
|
-
|
|
217
|
+
const segments = [branch, workingTree, sync].join(theme.fg("dim", " · "));
|
|
218
|
+
return ` ${segments}`;
|
|
185
219
|
}
|
|
186
220
|
|
|
187
221
|
function formatAheadBehind(aheadCount: number, behindCount: number, theme: { fg(color: string, text: string): string }) {
|
package/package.json
CHANGED