import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent"; const channel = "workbook:field-notes:selection"; export default function fieldNoteEvents(pi: ExtensionAPI): void { let selected: string | null = null; const unsubscribe = pi.events.on(channel, data => { if (data === "reed" || data === "fern") selected = data; }); pi.on("session_shutdown", () => unsubscribe()); const { Type } = pi.typebox; pi.registerTool({ name: "field_events", label: "Field events", description: "Discover or inspect the field-notes channel, query last selection, or act to publish reed/fern. In-process extension-runtime bus; selection survives /new and session switches within this binding, without durable delivery.", parameters: Type.Object({ op: Type.Union([Type.Literal("discover"), Type.Literal("inspect"), Type.Literal("query"), Type.Literal("act")]), id: Type.Optional(Type.Union([Type.Literal("reed"), Type.Literal("fern")])), }), async execute(_id, params) { if (params.op === "act") { if (!params.id) throw new Error("act requires a note id; nothing published."); pi.events.emit(channel, params.id); } const details = { channel, selected, operations: ["discover", "inspect", "query", "act"], delivery: "synchronous emit; asynchronous listeners are not awaited" }; return { content: [{ type: "text", text: JSON.stringify(details) }], details }; }, }); }