MCPcopy Create free account
hub / github.com/backnotprop/plannotator / execute

Function execute

apps/opencode-plugin/index.ts:588–703  ·  view source on GitHub ↗
(args, context)

Source from the content-addressed store, hash-verified

586 },
587
588 async execute(args, context) {
589 const invokingAgent = (context as { agent?: string }).agent;
590 if (shouldRejectSubmitPlanForAgent(invokingAgent, workflowOptions)) {
591 return `Plannotator is configured for plan-agent mode. submit_plan can only be called by: ${workflowOptions.planningAgents.join(", ")}.
592
593Use /plannotator-last or /plannotator-annotate for manual review, or set workflow to all-agents to allow broader submit_plan access.`;
594 }
595
596 if (!args.edits || args.edits.length === 0) {
597 return "Error: No edits provided. Pass at least one edit with start and content.";
598 }
599
600 // Read existing backing file (empty on first call)
601 const project = sanitizeTag(path.basename(ctx.directory)) || "_unknown";
602 const backingPath = getPlanBackingPath(project);
603 const backingDir = path.dirname(backingPath);
604 mkdirSync(backingDir, { recursive: true });
605
606 let existingContent = "";
607 if (existsSync(backingPath)) {
608 existingContent = readFileSync(backingPath, "utf-8");
609 }
610
611 // Validate and apply edits
612 const existingLines = existingContent ? existingContent.split("\n") : [];
613
614 const validationError = validateEdits(existingLines, args.edits);
615 if (validationError) {
616 return `Error: ${validationError}`;
617 }
618
619 let resultLines: string[];
620 try {
621 resultLines = applyEdits(existingLines, args.edits);
622 } catch (err) {
623 return `Error applying edits: ${err instanceof Error ? err.message : String(err)}`;
624 }
625
626 const planContent = resultLines.join("\n");
627 if (planContent.length > MAX_PLAN_SIZE) {
628 return `Error: Plan content exceeds the maximum size of ${MAX_PLAN_SIZE / (1024 * 1024)}MB.`;
629 }
630 if (!planContent.trim()) {
631 return "Error: Plan content is empty after applying edits.";
632 }
633
634 // Write backing file
635 writeFileSync(backingPath, planContent, "utf-8");
636
637 const timeoutSeconds = getPlanTimeoutSeconds();
638 let result: OpenCodePlanReviewResult;
639 try {
640 result = await runPlanReview({
641 client: ctx.client,
642 runtime: workflowOptions.runtime,
643 planContent,
644 sharingEnabled: await getSharingEnabled(),
645 shareBaseUrl: getShareBaseUrl(),

Callers

nothing calls this directly

Calls 15

sanitizeTagFunction · 0.90
getPlanBackingPathFunction · 0.90
validateEditsFunction · 0.90
applyEditsFunction · 0.90
getPlanApprovedPromptFunction · 0.90
formatWithLineNumbersFunction · 0.90
getPlanDeniedPromptFunction · 0.90
getPlanToolNameFunction · 0.90
getPlanTimeoutSecondsFunction · 0.85
runPlanReviewFunction · 0.85

Tested by

no test coverage detected