Skip to content

Commit 35900e6

Browse files
committed
Add visual feedback to the handoff lifecycle via TUI status indicator
1 parent 5eb71fe commit 35900e6

4 files changed

Lines changed: 25 additions & 2 deletions

File tree

handoff/command.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
99
import type { AgenticodingState } from "../state.js";
10+
import { STATUS_KEY_HANDOFF } from "../tui.js";
1011

1112
export function registerHandoffCommand(pi: ExtensionAPI, state: AgenticodingState): void {
1213
pi.registerCommand("handoff", {
@@ -27,6 +28,14 @@ export function registerHandoffCommand(pi: ExtensionAPI, state: AgenticodingStat
2728
toolCalled: false,
2829
};
2930

31+
// Show live progress indicator in footer
32+
if (ctx.hasUI && ctx.ui.theme) {
33+
ctx.ui.setStatus(
34+
STATUS_KEY_HANDOFF,
35+
ctx.ui.theme.fg("accent", "\uD83E\uDD1D Handoff in progress"),
36+
);
37+
}
38+
3039
pi.sendUserMessage(
3140
`Handoff direction: ${direction}\n\nPrepare a real handoff in the current session and current context. Before calling the handoff tool, capture any reusable state in the ledger if needed. Then complete the picture in a concise but sufficiently detailed handoff brief and call the handoff tool in this turn. Preserve the important knowledge that is still only present in the current context so the next clean context can start well without re-deriving it. Use any structure that makes the next work unambiguous. Include findings, current state, unresolved questions, failed paths worth avoiding, next steps, refs, constraints, and spawn ideas when useful. Reference ledger entries by name when relevant.`,
3241
ctx.isIdle() ? undefined : { deliverAs: "followUp" },

handoff/compact.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
* pre-handoff messages in LLM context.
66
*/
77

8-
import type { ExtensionAPI, SessionEntry } from "@earendil-works/pi-coding-agent";
8+
import type { ExtensionAPI, ExtensionContext, SessionEntry } from "@earendil-works/pi-coding-agent";
99
import type { AgenticodingState } from "../state.js";
10+
import { STATUS_KEY_HANDOFF } from "../tui.js";
1011

1112
function getImpossibleKeptId(branchEntries: SessionEntry[]): string {
1213
const leaf = branchEntries[branchEntries.length - 1];
1314
return `${leaf?.id ?? "handoff"}-handoff-cut`;
1415
}
1516

1617
export function registerHandoffCompaction(pi: ExtensionAPI, state: AgenticodingState): void {
17-
pi.on("session_before_compact", async (event) => {
18+
pi.on("session_before_compact", async (event, ctx: ExtensionContext) => {
1819
const pending = state.pendingHandoff;
1920
if (!pending) {
2021
return;
@@ -23,6 +24,11 @@ export function registerHandoffCompaction(pi: ExtensionAPI, state: AgenticodingS
2324
state.pendingHandoff = null;
2425
state.pendingRequestedHandoff = null;
2526

27+
// Clear the handoff progress indicator now that compaction is consuming it
28+
if (ctx.hasUI) {
29+
ctx.ui.setStatus(STATUS_KEY_HANDOFF, undefined);
30+
}
31+
2632
return {
2733
compaction: {
2834
summary: pending.task,

handoff/tool.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
1313
import { Type } from "typebox";
1414
import type { AgenticodingState } from "../state.js";
15+
import { STATUS_KEY_HANDOFF } from "../tui.js";
1516

1617
const MAX_INLINE_ENTRIES = 3;
1718
const MAX_INLINE_CHARS = 4000;
@@ -137,6 +138,9 @@ export function registerHandoffTool(
137138
if (state.pendingRequestedHandoff) {
138139
state.pendingRequestedHandoff.toolCalled = false;
139140
}
141+
if (ctx.hasUI) {
142+
ctx.ui.setStatus(STATUS_KEY_HANDOFF, undefined);
143+
}
140144
},
141145
});
142146

watchdog.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
1212
import type { AgenticodingState } from "./state.js";
13+
import { STATUS_KEY_HANDOFF } from "./tui.js";
1314

1415
/** Build a nudge string with the exact percent interpolated. */
1516
export function buildNudge(percent: number): string {
@@ -47,6 +48,9 @@ export function registerWatchdog(pi: ExtensionAPI, state: AgenticodingState): vo
4748
requestedHandoff.enforcementAttempts += 1;
4849
if (!requestedHandoff.toolCalled) {
4950
state.pendingRequestedHandoff = null;
51+
if (ctx.hasUI) {
52+
ctx.ui.setStatus(STATUS_KEY_HANDOFF, undefined);
53+
}
5054
}
5155
}
5256

0 commit comments

Comments
 (0)