refactor(athena): rename session_handoff to switch_agent to avoid confusion with /handoff command

Rename across all layers to eliminate naming ambiguity:
- Tool: session_handoff → switch_agent
- Hook: agent-handoff → agent-switch
- Feature: agent-handoff/ → agent-switch/
- Types: SessionHandoffArgs → SwitchAgentArgs, PendingHandoff → PendingSwitch
- Functions: setPendingHandoff → setPendingSwitch, consumePendingHandoff → consumePendingSwitch

/handoff = inter-session context summary (existing command)
switch_agent = intra-session active agent change (our new tool)
This commit is contained in:
ismeth
2026-02-13 13:18:07 +01:00
committed by YeonGyu-Kim
parent 7db0f110ee
commit 84185490f9
22 changed files with 139 additions and 139 deletions
-2
View File
@@ -1,2 +0,0 @@
export { setPendingHandoff, consumePendingHandoff, _resetForTesting } from "./state"
export type { PendingHandoff } from "./state"
-50
View File
@@ -1,50 +0,0 @@
import { describe, test, expect, beforeEach } from "bun:test"
import { setPendingHandoff, consumePendingHandoff, _resetForTesting } from "./state"
describe("agent-handoff state", () => {
beforeEach(() => {
_resetForTesting()
})
//#given a pending handoff is set
//#when consumePendingHandoff is called
//#then it returns the handoff and removes it
test("should store and consume a pending handoff", () => {
setPendingHandoff("session-1", "atlas", "Fix these findings")
const handoff = consumePendingHandoff("session-1")
expect(handoff).toEqual({ agent: "atlas", context: "Fix these findings" })
expect(consumePendingHandoff("session-1")).toBeUndefined()
})
//#given no pending handoff exists
//#when consumePendingHandoff is called
//#then it returns undefined
test("should return undefined when no handoff is pending", () => {
expect(consumePendingHandoff("session-1")).toBeUndefined()
})
//#given a pending handoff is set
//#when a new handoff is set for the same session
//#then the latest handoff wins
test("should overwrite previous handoff for same session", () => {
setPendingHandoff("session-1", "atlas", "Fix A")
setPendingHandoff("session-1", "prometheus", "Plan B")
const handoff = consumePendingHandoff("session-1")
expect(handoff).toEqual({ agent: "prometheus", context: "Plan B" })
})
//#given handoffs for different sessions
//#when consumed separately
//#then each session gets its own handoff
test("should isolate handoffs by session", () => {
setPendingHandoff("session-1", "atlas", "Fix A")
setPendingHandoff("session-2", "prometheus", "Plan B")
expect(consumePendingHandoff("session-1")).toEqual({ agent: "atlas", context: "Fix A" })
expect(consumePendingHandoff("session-2")).toEqual({ agent: "prometheus", context: "Plan B" })
})
})
-23
View File
@@ -1,23 +0,0 @@
export interface PendingHandoff {
agent: string
context: string
}
const pendingHandoffs = new Map<string, PendingHandoff>()
export function setPendingHandoff(sessionID: string, agent: string, context: string): void {
pendingHandoffs.set(sessionID, { agent, context })
}
export function consumePendingHandoff(sessionID: string): PendingHandoff | undefined {
const handoff = pendingHandoffs.get(sessionID)
if (handoff) {
pendingHandoffs.delete(sessionID)
}
return handoff
}
/** @internal For testing only */
export function _resetForTesting(): void {
pendingHandoffs.clear()
}
+2
View File
@@ -0,0 +1,2 @@
export { setPendingSwitch, consumePendingSwitch, _resetForTesting } from "./state"
export type { PendingSwitch } from "./state"
+50
View File
@@ -0,0 +1,50 @@
import { describe, test, expect, beforeEach } from "bun:test"
import { setPendingSwitch, consumePendingSwitch, _resetForTesting } from "./state"
describe("agent-switch state", () => {
beforeEach(() => {
_resetForTesting()
})
//#given a pending switch is set
//#when consumePendingSwitch is called
//#then it returns the switch and removes it
test("should store and consume a pending switch", () => {
setPendingSwitch("session-1", "atlas", "Fix these findings")
const entry = consumePendingSwitch("session-1")
expect(entry).toEqual({ agent: "atlas", context: "Fix these findings" })
expect(consumePendingSwitch("session-1")).toBeUndefined()
})
//#given no pending switch exists
//#when consumePendingSwitch is called
//#then it returns undefined
test("should return undefined when no switch is pending", () => {
expect(consumePendingSwitch("session-1")).toBeUndefined()
})
//#given a pending switch is set
//#when a new switch is set for the same session
//#then the latest switch wins
test("should overwrite previous switch for same session", () => {
setPendingSwitch("session-1", "atlas", "Fix A")
setPendingSwitch("session-1", "prometheus", "Plan B")
const entry = consumePendingSwitch("session-1")
expect(entry).toEqual({ agent: "prometheus", context: "Plan B" })
})
//#given switches for different sessions
//#when consumed separately
//#then each session gets its own switch
test("should isolate switches by session", () => {
setPendingSwitch("session-1", "atlas", "Fix A")
setPendingSwitch("session-2", "prometheus", "Plan B")
expect(consumePendingSwitch("session-1")).toEqual({ agent: "atlas", context: "Fix A" })
expect(consumePendingSwitch("session-2")).toEqual({ agent: "prometheus", context: "Plan B" })
})
})
+23
View File
@@ -0,0 +1,23 @@
export interface PendingSwitch {
agent: string
context: string
}
const pendingSwitches = new Map<string, PendingSwitch>()
export function setPendingSwitch(sessionID: string, agent: string, context: string): void {
pendingSwitches.set(sessionID, { agent, context })
}
export function consumePendingSwitch(sessionID: string): PendingSwitch | undefined {
const entry = pendingSwitches.get(sessionID)
if (entry) {
pendingSwitches.delete(sessionID)
}
return entry
}
/** @internal For testing only */
export function _resetForTesting(): void {
pendingSwitches.clear()
}