import { z } from 'zod'; import { apiGetJson } from '../api/client.js'; import { parseUWP } from '../parsers/uwp.js'; export const name = 'find_route'; export const description = 'Finds a jump route between two worlds and returns the sequence of intermediate worlds. ' + 'Locations are specified as "Sector XXYY" (e.g. "Spinward Marches 1910"). ' + 'Returns 404/no-route if no path exists within the jump rating. ' + 'Options: avoid Red zones, require Imperial membership, require wilderness refueling stops.'; export const inputSchema = z.object({ start: z .string() .describe('Starting world as "Sector XXYY" (e.g. "Spinward Marches 1910") or T5SS abbreviation format'), end: z .string() .describe('Destination world in the same format (e.g. "Core 2118" for Capital)'), jump: z .number() .min(1) .max(12) .optional() .default(2) .describe('Maximum jump distance per leg (1-12, default 2)'), avoid_red_zones: z .boolean() .optional() .default(false) .describe('If true, the route will not pass through TAS Red Zone worlds'), imperial_only: z .boolean() .optional() .default(false) .describe('If true, only stop at Third Imperium member worlds'), wilderness_refueling: z .boolean() .optional() .default(false) .describe('If true, stops must have wilderness refueling available (gas giant or ocean)'), milieu: z.string().optional().describe('Campaign era (default: M1105)'), }); const ZONE_LABELS = { R: 'Red', A: 'Amber', G: 'Green', '': 'Green' }; export async function handler(args) { const { start, end, jump, avoid_red_zones, imperial_only, wilderness_refueling, milieu } = args; let rawData; try { rawData = await apiGetJson('/api/route', { start, end, jump, nored: avoid_red_zones ? 1 : undefined, im: imperial_only ? 1 : undefined, wild: wilderness_refueling ? 1 : undefined, milieu, }); } catch (err) { const message = err instanceof Error ? err.message : String(err); if (message.includes('404')) { return { content: [ { type: 'text', text: JSON.stringify({ found: false, start, end, jump_rating: jump, message: `No jump-${jump} route found between "${start}" and "${end}". Try increasing the jump rating or relaxing constraints.`, }, null, 2), }, ], }; } throw err; } // The API returns an array of worlds directly (not wrapped in {Worlds: [...]}) const worldArray = Array.isArray(rawData) ? rawData : (rawData.Worlds ?? []); const worlds = worldArray.map((w) => { const zoneCode = (w.Zone ?? '').trim(); const uwpRaw = w.UWP ?? ''; const sectorName = typeof w.Sector === 'string' ? w.Sector : w.Sector?.Name; let starport = ''; if (uwpRaw && uwpRaw !== '?000000-0') { try { starport = parseUWP(uwpRaw).starport.code; } catch { starport = uwpRaw[0] ?? ''; } } return { name: w.Name, sector: sectorName, hex: w.Hex, location: sectorName && w.Hex ? `${sectorName} ${w.Hex}` : undefined, uwp: uwpRaw, starport, zone: (ZONE_LABELS[zoneCode] ?? zoneCode) || 'Green', bases: w.Bases, allegiance: w.AllegianceName ?? w.Allegiance, }; }); const result = { found: true, start, end, jump_rating: jump, total_jumps: Math.max(0, worlds.length - 1), route: worlds, }; return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } //# sourceMappingURL=find_route.js.map