#!/usr/bin/env runts -- --allow-all import {parseArgs} from "jsr:@std/cli/parse-args"; import {execCommandShell, exit, log, ProcessBar, term,} from "https://script.hatter.ink/@67/deno-commons-mod.ts"; import {howto} from "https://script.hatter.ink/@3/deno-ai-mod.ts"; async function main() { const flags = parseArgs(Deno.args, { boolean: ["help", "no-exec"], alias: { h: "help", N: "no-exec", }, }); if (flags.help) { console.log(`howto.ts - 🚀 AI-powered Natural Language to CLI conversion e.g. howto.ts get disk usage for current dir howto.ts --help - show help howto.ts [-N|--no-exec] 'MESSAGE' - generate command line for MESSAGE `); exit(0); } const noExec = flags["no-exec"]; const message = (flags._) ? flags._.join(" ") : prompt("Input your message: "); if (!message) { throw new Error("Message is required"); } const summary = await new ProcessBar("AI thinking").call( async (): Promise => { return await howto(message); }, ); log.success(`AI howto command line message: \n${summary}`); if (!noExec) { try { const commandLines = extractCommand(summary); if (commandLines.length == 1) { log.success( "Found command line: ", term.auto(`[green][[[${commandLines}]]][/]`), ); } else { log.success(`Found ${commandLines.length} commands`); } if (commandLines.length == 1) { if (confirm("Execute this command?")) { exit( await execCommandShell("sh", [ "-c", commandLines[0], ]), ); } } else { const colors = ["red", "green", "blue"]; for (const [i, command] of commandLines.entries()) { console.log(term.auto( `[${colors[i % 3]}][[[# ${i}: ${command}]]][/]`, )); } const selectCommandLineIndex = parseInt( prompt( "Please select the command line: ", ), 10, ); if ( isNaN(selectCommandLineIndex) || selectCommandLineIndex < 0 || selectCommandLineIndex >= commandLines.length ) { log.error( `Bad command line index: ${selectCommandLineIndex}`, ); } else { exit( await execCommandShell("sh", [ "-c", commandLines[0], ]), ); } } } catch (e) { log.error("Extract command line failed", e); } } } function extractCommand(summary: string): string[] { const lines = summary.split(/\r?\n/); const codeBlocks: string[] = []; let codeBlock: string[] = []; let inCode = false; for (const line of lines) { if (inCode) { if (line.startsWith("```")) { codeBlocks.push(codeBlock.join("\n")); codeBlock = []; inCode = false; } else { codeBlock.push(line); } } else if (line.startsWith("```")) { inCode = true; } } if (codeBlocks.length > 0) { return codeBlocks; } throw new Error("Command line not found"); } main().catch((err) => { log.error(err); process.exit(0); }).then(() => process.exit(0)); // @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260415T232646+08:00.MEUCIEw1GSf+P9+9GnxdehpK // 1jUaC3A4NI73i5fK+CHlxauGAiEAgo47/bat/+T2xPc2OCiy38yo157pxSNBjUoRp2pBvKM=