feat(flight-finder): implement milestone M2 - report workflow and delivery gates
This commit is contained in:
86
skills/flight-finder/src/cli.ts
Normal file
86
skills/flight-finder/src/cli.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import fs from "node:fs/promises";
|
||||
import minimist from "minimist";
|
||||
|
||||
import {
|
||||
DFW_BLQ_2026_PROMPT_DRAFT,
|
||||
normalizeFlightReportRequest
|
||||
} from "./request-normalizer.js";
|
||||
import { getFlightReportStatus } from "./report-status.js";
|
||||
import { renderFlightReportPdf } from "./report-pdf.js";
|
||||
import { buildLukeDeliveryPlan } from "./report-delivery.js";
|
||||
import type { FlightReportPayload, FlightReportRequestDraft } from "./types.js";
|
||||
|
||||
function usage(): never {
|
||||
throw new Error(`Usage:
|
||||
flight-finder normalize-request --input "<request.json>"
|
||||
flight-finder normalize-request --legacy-dfw-blq
|
||||
flight-finder report-status --input "<report-payload.json>"
|
||||
flight-finder render-report --input "<report-payload.json>" --output "<report.pdf>"
|
||||
flight-finder delivery-plan --to "<recipient@example.com>" --subject "<subject>" --body "<body>" --attach "<report.pdf>"`);
|
||||
}
|
||||
|
||||
async function readJsonFile<T>(filePath: string): Promise<T> {
|
||||
return JSON.parse(await fs.readFile(filePath, "utf8")) as T;
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const argv = minimist(process.argv.slice(2), {
|
||||
string: ["input", "output", "to", "subject", "body", "attach"],
|
||||
boolean: ["legacy-dfw-blq"]
|
||||
});
|
||||
|
||||
const command = argv._[0];
|
||||
if (!command) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if (command === "normalize-request") {
|
||||
const draft = argv["legacy-dfw-blq"]
|
||||
? DFW_BLQ_2026_PROMPT_DRAFT
|
||||
: await readJsonFile<FlightReportRequestDraft>(argv.input || usage());
|
||||
console.log(JSON.stringify(normalizeFlightReportRequest(draft), null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (command === "report-status") {
|
||||
const payload = await readJsonFile<FlightReportPayload>(argv.input || usage());
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
getFlightReportStatus(normalizeFlightReportRequest(payload.request), payload),
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command === "render-report") {
|
||||
const payload = await readJsonFile<FlightReportPayload>(argv.input || usage());
|
||||
const rendered = await renderFlightReportPdf(payload, argv.output || usage());
|
||||
console.log(rendered);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command === "delivery-plan") {
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
buildLukeDeliveryPlan({
|
||||
recipientEmail: argv.to,
|
||||
subject: argv.subject || "",
|
||||
body: argv.body || "",
|
||||
attachmentPath: argv.attach || usage()
|
||||
}),
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
usage();
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error instanceof Error ? error.message : String(error));
|
||||
process.exitCode = 1;
|
||||
});
|
||||
Reference in New Issue
Block a user