Last active
June 21, 2025 14:52
-
-
Save sigmaSd/8a08b2f4dfe971c804a969b482965cb4 to your computer and use it in GitHub Desktop.
random script to make deno permission dialog apper as a gui popup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* GUI Permission Dialog for Deno | |
* | |
* Runs a Deno script and shows permission prompts as GUI dialogs | |
* instead of CLI prompts. | |
* | |
* Usage: | |
* deno run -A gui-permissions.ts my-script.ts | |
*/ | |
import { Pty } from "jsr:@sigma/[email protected]"; | |
import { stripAnsiCode } from "jsr:@std/[email protected]/colors"; | |
async function showDialog(message: string): Promise<boolean> { | |
const os = Deno.build.os; | |
try { | |
let command: string[]; | |
switch (os) { | |
case "linux": | |
// Try zenity first, then kdialog as fallback | |
command = [ | |
"zenity", | |
"--question", | |
"--text", | |
message, | |
"--title", | |
"Deno Permission Request", | |
"--width", | |
"400", | |
"--height", | |
"200", | |
]; | |
break; | |
case "darwin": { | |
// macOS using osascript with better formatting | |
const script = `display dialog "${ | |
message.replace(/"/g, '\\"').replace(/\n/g, "\\n") | |
}" with title "Deno Permission Request" buttons {"Deny", "Allow"} default button "Allow" with icon caution`; | |
command = ["osascript", "-e", script]; | |
break; | |
} | |
case "windows": { | |
// Windows using PowerShell with better formatting | |
const psScript = | |
`Add-Type -AssemblyName PresentationFramework; [System.Windows.MessageBox]::Show('${ | |
message.replace(/'/g, "''").replace(/\n/g, "`n") | |
}', 'Deno Permission Request', 'YesNo', 'Question') -eq 'Yes'`; | |
command = ["powershell", "-Command", psScript]; | |
break; | |
} | |
default: | |
console.error(`Unsupported OS: ${os}`); | |
return false; | |
} | |
const process = new Deno.Command(command[0], { | |
args: command.slice(1), | |
stdout: "piped", | |
stderr: "piped", | |
}); | |
const { code, stdout } = await process.output(); | |
if (os === "windows") { | |
const output = new TextDecoder().decode(stdout).trim(); | |
return output === "True"; | |
} else if (os === "darwin") { | |
// osascript returns 0 for "Allow", 1 for "Deny" | |
return code === 0; | |
} else { | |
// zenity returns 0 for "Yes", 1 for "No" | |
return code === 0; | |
} | |
} catch (error) { | |
console.error("Failed to show dialog:", error); | |
// Fallback to console prompt | |
return await showConsolePrompt(message); | |
} | |
} | |
async function showConsolePrompt(message: string): Promise<boolean> { | |
console.log("\n" + message); | |
console.log("Allow? (y/N): "); | |
const buf = new Uint8Array(1024); | |
const n = await Deno.stdin.read(buf); | |
if (n === null) return false; | |
const input = new TextDecoder().decode(buf.subarray(0, n)).trim() | |
.toLowerCase(); | |
return input === "y" || input === "yes"; | |
} | |
function extractPermissionMessage(lines: string): string | null { | |
// Look for the most detailed permission request patterns | |
const fullPattern = | |
/┏ ⚠️\s+Deno requests (.*?)\n┠─ Requested by `(.*?)` API\.(.*?)┗/s; | |
const fullMatch = lines.match(fullPattern); | |
if (fullMatch) { | |
const permission = fullMatch[1].trim(); | |
const api = fullMatch[2].trim(); | |
const additionalInfo = fullMatch[3].trim(); | |
let message = `🔒 DENO PERMISSION REQUEST\n\n`; | |
message += `Permission: ${permission}\n`; | |
message += `API: ${api}\n`; | |
if (additionalInfo) { | |
// Clean up additional info | |
const cleanInfo = additionalInfo | |
.replace(/┠─/g, "") | |
.replace(/│/g, "") | |
.replace(/\s+/g, " ") | |
.trim(); | |
if (cleanInfo) { | |
// too verbose | |
// message += `Details: ${cleanInfo}\n`; | |
} | |
} | |
message += `\nAllow this permission?`; | |
return message; | |
} | |
// Look for detailed permission request patterns (without additional info) | |
const detailedPattern = | |
/┏ ⚠️\s+Deno requests (.*?)\n┠─ Requested by `(.*?)` API\./s; | |
const match = lines.match(detailedPattern); | |
if (match) { | |
const permission = match[1].trim(); | |
const api = match[2].trim(); | |
return `🔒 DENO PERMISSION REQUEST\n\nPermission: ${permission}\nAPI: ${api}\n\nAllow this permission?`; | |
} | |
// Look for simpler permission patterns with box drawing | |
const simplePattern = /┏ ⚠️.*?Deno requests (.*?)\./s; | |
const simpleMatch = lines.match(simplePattern); | |
if (simpleMatch) { | |
const permission = simpleMatch[1].trim(); | |
return `🔒 DENO PERMISSION REQUEST\n\nPermission: ${permission}\n\nAllow this permission?`; | |
} | |
// Legacy pattern fallback | |
const legacyPattern = /┌ ⚠️.*?\n│\s*(.*?)\n│.*?Allow\?/s; | |
const legacyMatch = lines.match(legacyPattern); | |
if (legacyMatch) { | |
return `🔒 DENO PERMISSION REQUEST\n\n${ | |
legacyMatch[1].trim() | |
}\n\nAllow this permission?`; | |
} | |
return null; | |
} | |
if (import.meta.main) { | |
if (Deno.args.length === 0) { | |
console.error( | |
"Usage: deno run -A gui-permissions.ts <script.ts> [args...]", | |
); | |
Deno.exit(1); | |
} | |
console.log("Starting Deno script with GUI permission dialog..."); | |
const pty = new Pty(Deno.execPath(), { | |
args: ["run", ...Deno.args], | |
env: { NO_COLOR: "1" }, | |
}); | |
let buffer = ""; | |
pty.setPollingInterval(100); | |
for await (const chunk of pty.readable) { | |
const cleaned = stripAnsiCode(chunk); | |
buffer += cleaned; | |
// Print output to console (except permission prompts) | |
if (!cleaned.includes("Allow?")) { | |
await Deno.stdout.write(new TextEncoder().encode(cleaned)); | |
} | |
// Check for permission prompts | |
if (buffer.includes("Allow?")) { | |
console.log("\n🔍 DEBUG: Raw buffer content:"); | |
console.log("=" + "=".repeat(50)); | |
console.log(buffer); | |
console.log("=" + "=".repeat(50)); | |
const message = extractPermissionMessage(buffer); | |
if (message) { | |
console.log("\n🔒 Permission request detected..."); | |
console.log("📋 Extracted message:", message); | |
const allowed = await showDialog(message); | |
if (allowed) { | |
console.log("✅ Permission granted"); | |
pty.write("y\n"); | |
} else { | |
console.log("❌ Permission denied"); | |
pty.write("n\n"); | |
} | |
} else { | |
throw new Error( | |
"Could not extract permission message from Deno output", | |
); | |
} | |
// Clear buffer after handling prompt | |
buffer = ""; | |
} | |
// Keep buffer manageable | |
if (buffer.length > 10000) { | |
buffer = buffer.slice(-5000); | |
} | |
} | |
console.log("\nScript execution completed."); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment