import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent"; import { inspectNote, notes } from "./notebook"; type NotebookNote = (typeof notes)[number]; type NotebookDetails = | { operations: string[]; ids: NotebookNote["id"][]; persistence: "factory-local" } | { note: NotebookNote; selected: string | null; changed: boolean } | { selected: string | null }; export default function notebookPackage(pi: ExtensionAPI): void { const { Type } = pi.typebox; // Factory-local state belongs to one binding, not Bun's cached module. let selected: string | null = null; const parameters = Type.Object({ op: Type.Union([Type.Literal("discover"), Type.Literal("inspect"), Type.Literal("query"), Type.Literal("act")]), id: Type.Optional(Type.String()), }); pi.registerTool({ name: "notebook", label: "Notebook", description: "Discover fictional notes, inspect an id, query the current selection, or act to select an id. Selection lives in this extension binding, including across /new and session switches; it is not persisted.", parameters, async execute(_callId, params) { if (params.op === "discover") { const details: NotebookDetails = { operations: ["discover", "inspect", "query", "act"], ids: notes.map(note => note.id), persistence: "factory-local" }; return { content: [{ type: "text", text: JSON.stringify(details) }], details }; } if (params.op === "inspect" || params.op === "act") { const note = inspectNote(params.id ?? ""); if (params.op === "act") selected = note.id; const details = { note, selected, changed: params.op === "act" }; return { content: [{ type: "text", text: JSON.stringify(details) }], details }; } return { content: [{ type: "text", text: selected ?? "No note selected." }], details: { selected } }; }, }); pi.registerCommand("notebook", { description: "Inspect or select a fictional note: /notebook [reed|fern]", getArgumentCompletions(prefix) { const hits = notes.filter(note => note.id.startsWith(prefix)); if (!hits.length || (hits.length === 1 && hits[0]?.id === prefix)) return null; return hits.map(note => ({ value: `${note.id} `, label: note.id, description: note.text })); }, async handler(args, ctx) { if (!args.trim()) { ctx.ui.notify(selected ? `Selected: ${selected}.` : "No selection. Try /notebook reed.", "info"); return; } try { selected = inspectNote(args.trim()).id; ctx.ui.notify(`Selected ${selected} for this extension binding; /new and session switches keep it. Verify with /notebook.`, "info"); } catch (error) { ctx.ui.notify(`Nothing changed. ${error instanceof Error ? error.message : String(error)}`, "warning"); } }, }); }