Files
backnotprop__plannotator/apps/opencode-plugin/embedded.ts
T
Michael Ramos b19505efd3 chore: remove the redundant /plannotator-status and /plannotator-archive commands (#873)
Two agent command-surface cleanups. Both remove only the command entry points; all underlying infrastructure stays.

1. /plannotator-status (Pi): removed — it echoed phase/plan-file/progress on
   demand, but that state is already shown ambiently (status bar + live
   checklist widget). The phase/checklist state machine is untouched.

2. /plannotator-archive (all agents): removed the command/skill entry points
   across every surface — Claude/Codex/Kiro skills, Pi, OpenCode (handler +
   dispatch + cli-bridge + embedded + stub), Droid, the Kiro agent prompt, all
   three installers, docs, marketing, and the CI deprecated-command guard. The
   installers also gained a stale-skill cleanup so upgraders drop a previously
   installed plannotator-archive skill.

Kept (infrastructure) — archive browsing stays available in-review via the
sidebar: the `plannotator archive` CLI subcommand (apps/hook/server), the
mode:"archive" server path + /api/archive endpoints, ArchiveBrowser/useArchive,
the sidebar Archive tab, sessions.ts "archive" mode, and ~/.plannotator/plans
storage.

Verified: bun test scripts/install.test.ts → 72 pass; pi-extension typecheck +
build:opencode pass; repo-wide residual scan clean; KEEP-set integrity
confirmed; one orphaned import (opencode commands.ts) caught in self-review and
removed.
2026-06-08 11:08:11 -07:00

108 lines
2.9 KiB
TypeScript

import { recoverNativeFetchConstructors } from "./fetch-shim";
export interface EmbeddedPlanReviewInput {
client: any;
planContent: string;
sharingEnabled: boolean;
shareBaseUrl?: string;
pasteApiUrl?: string;
htmlContent: string;
timeoutSeconds: number | null;
logReady: (url: string, isRemote: boolean, port: number) => void;
}
export interface EmbeddedPlanReviewResult {
approved: boolean;
feedback?: string;
savedPath?: string;
agentSwitch?: string;
}
async function loadPlanServer() {
recoverNativeFetchConstructors();
return await import("@plannotator/server");
}
async function loadCommandHandlers() {
recoverNativeFetchConstructors();
return await import("./commands");
}
export async function runEmbeddedPlanReview(
input: EmbeddedPlanReviewInput,
): Promise<EmbeddedPlanReviewResult> {
const { startPlannotatorServer, handleServerReady } = await loadPlanServer();
const server = await startPlannotatorServer({
plan: input.planContent,
origin: "opencode",
sharingEnabled: input.sharingEnabled,
shareBaseUrl: input.shareBaseUrl,
pasteApiUrl: input.pasteApiUrl,
htmlContent: input.htmlContent,
opencodeClient: input.client,
onReady: async (url, isRemote, port) => {
await handleServerReady(url, isRemote, port);
input.logReady(url, isRemote, port);
},
});
const timeoutMs = input.timeoutSeconds === null ? null : input.timeoutSeconds * 1000;
const result = timeoutMs === null
? await server.waitForDecision()
: await new Promise<Awaited<ReturnType<typeof server.waitForDecision>>>((resolve) => {
const timeoutId = setTimeout(
() =>
resolve({
approved: false,
feedback: `[Plannotator] No response within ${input.timeoutSeconds} seconds. Port released automatically. Please call submit_plan again.`,
}),
timeoutMs,
);
server.waitForDecision().then((decision) => {
clearTimeout(timeoutId);
resolve(decision);
});
});
await Bun.sleep(1500);
server.stop();
return result;
}
export async function handleEmbeddedCommand(
command: string,
event: any,
deps: {
client: any;
htmlContent: string;
reviewHtmlContent: string;
getSharingEnabled: () => Promise<boolean>;
getShareBaseUrl: () => string | undefined;
getPasteApiUrl: () => string | undefined;
directory?: string;
},
): Promise<{ feedback?: string | null }> {
const {
handleReviewCommand,
handleAnnotateCommand,
handleAnnotateLastCommand,
} = await loadCommandHandlers();
if (command === "plannotator-last") {
return { feedback: await handleAnnotateLastCommand(event, deps) };
}
if (command === "plannotator-annotate") {
await handleAnnotateCommand(event, deps);
return {};
}
if (command === "plannotator-review") {
await handleReviewCommand(event, deps);
return {};
}
return {};
}