/** * mission_complete tool * * Agent tool to mark a mission run as complete. * Sets run.json status to "done" and finish_at timestamp. * Clears active_run_id from state.json. * * Used by: mission-orchestrator skill */ import { readState, readRun, writeRun, updateState, getTimestamp, RunStatus } from "../state.js"; export interface MissionCompleteParams { run_id: string; } export interface MissionCompleteResult { success: boolean; message: string; runId: string | null; previousStatus: RunStatus | null; newStatus: RunStatus; finishAt: string; errors: string[]; } /** * Mark a mission run as complete * * @param params.run_id - ID of the run to complete * @returns Result with completion info */ export function missionComplete(params: MissionCompleteParams): MissionCompleteResult { const result: MissionCompleteResult = { success: false, message: "", runId: null, previousStatus: null, newStatus: "done", finishAt: "", errors: [] }; try { // Validate parameters if (!params.run_id || params.run_id.trim() === "") { result.errors.push("Run ID is required"); result.message = "Failed to complete mission: run_id is required"; return result; } const runId = params.run_id.trim(); result.runId = runId; // Read the run const run = readRun(runId); if (!run) { result.errors.push(`Run not found: ${runId}`); result.message = "Failed to complete mission: run not found"; return result; } result.previousStatus = run.status; // Check if run is already completed if (run.status === "done") { result.success = true; result.message = `Mission ${runId} is already complete`; result.finishAt = run.finish_at || getTimestamp(); return result; } // Check if run is in a state that can be completed if (run.status === "failed") { result.errors.push(`Run ${runId} has failed status and cannot be marked complete`); result.message = "Failed to complete mission: run has failed status"; return result; } const now = getTimestamp(); result.finishAt = now; // Update run.json const updatedRun = { ...run, status: "done" as RunStatus, finish_at: now }; writeRun(updatedRun); // Clear active_run_id from state.json if it matches const state = readState(); if (state.active_run_id === runId) { updateState({ active_run_id: null, current_phase: "idle", current_status_message: "Mission complete" }); } result.success = true; result.message = `Mission ${runId} marked as complete`; } catch (error) { result.success = false; result.message = `Error completing mission: ${error instanceof Error ? error.message : String(error)}`; result.errors.push(String(error)); } return result; }