import { Type } from "@sinclair/typebox"; import type { ExtensionAPI } from "../_shared/pi-api.js"; import { errorResult, getCommandText, setTextWidget } from "../_shared/pi-api.js"; import { validateParams } from "../_shared/validation.js"; const PlanModeParams = Type.Object({ action: Type.Union([Type.Literal("on"), Type.Literal("off"), Type.Literal("status"), Type.Literal("execute")], { description: "Plan mode action" }), planText: Type.Optional(Type.String({ description: "Plan text to extract todos from", maxLength: 20_000 })), }); export default function plan(pi: ExtensionAPI): void { pi.registerTool({ name: "planMode", description: "Legacy alias for local plan mode. Fails closed until OMP plan mode is ported.", parameters: PlanModeParams, async execute(_toolCallId, params) { const valid = validateParams(PlanModeParams, params); if (!valid.ok) return valid.result; return planModeNotPorted(valid.value.action, "planMode"); }, }); pi.registerCommand("plan", { description: "Show fail-closed OMP plan mode status until the native runtime is ported.", handler: async (args, ctx) => { const [action = "status"] = getCommandText(args).trim().split(/\s+/); const result = planModeNotPorted(asPlanAction(action), "plan-command"); setTextWidget(ctx, "plan", result.content[0]?.type === "text" ? result.content[0].text : "plan mode is not available"); }, }); pi.registerCommand("todos", { description: "Show fail-closed OMP plan todo status until the native runtime is ported.", handler: async (_args, ctx) => { const result = planModeNotPorted("status", "todos-command"); setTextWidget(ctx, "todos", result.content[0]?.type === "text" ? result.content[0].text : "plan todos are not available"); }, }); } function asPlanAction(action: string): "on" | "off" | "status" | "execute" { if (action === "on" || action === "off" || action === "execute") return action; return "status"; } function planModeNotPorted(action: "on" | "off" | "status" | "execute", requestedSurface: "planMode" | "plan-command" | "todos-command" = "planMode") { return errorResult( [ "Plan mode is disabled in miloc-pi.", "OMP plan mode is the source truth for read-only planning, plan-file writes, hidden `resolve` approval, model/tool restoration, status-line state, and session resume.", "This extension does not block tools or inject hidden plan context until OMP plan mode is ported here.", ].join("\n"), { owner: "omp-plan-mode", ported: false, requestedSurface, action, ompSources: [ "packages/coding-agent/src/modes/interactive-mode.ts", "packages/coding-agent/src/plan-mode/state.ts", "packages/coding-agent/src/plan-mode/approved-plan.ts", "packages/coding-agent/src/tools/plan-mode-guard.ts", "packages/coding-agent/src/prompts/system/plan-mode-active.md", "packages/coding-agent/src/prompts/system/plan-mode-approved.md", "packages/coding-agent/src/prompts/tools/resolve.md", "packages/coding-agent/src/slash-commands/builtin-registry.ts", ], }, ); }