diff --git a/.github/workflows/rabbit-retrigger.yml b/.github/workflows/rabbit-retrigger.yml deleted file mode 100644 index 9115c618c..000000000 --- a/.github/workflows/rabbit-retrigger.yml +++ /dev/null @@ -1,59 +0,0 @@ ---- -name: CodeRabbit Retrigger -# Periodically scans open PRs and posts `@coderabbitai review` on any whose -# rate-limit window has elapsed. CodeRabbit ignores comments authored by a -# GitHub App, so this workflow uses a personal access token (`RABBIT_PAT`) -# scoped to the `Review` environment. -on: - schedule: - # Every 20 minutes. CodeRabbit Pro reviews 5 PRs/hr, so this gives - # ~3 ticks per hour — enough to catch elapsed windows without thrashing. - - cron: "*/20 * * * *" - workflow_dispatch: - inputs: - max: - description: "Max retriggers this run (CR Pro = 5/hr)" - required: false - default: "5" - dry_run: - description: "Print what would be done; post nothing" - type: boolean - required: false - default: false -permissions: - contents: read - pull-requests: write - issues: write -concurrency: - group: rabbit-retrigger - cancel-in-progress: false -jobs: - retrigger: - name: Retrigger CodeRabbit - runs-on: ubuntu-22.04 - # CodeRabbit ignores `@coderabbitai review` comments posted under a - # GitHub App identity, so this workflow uses a personal access token - # scoped to the `Review` environment instead. Set `RABBIT_PAT` on the - # `Review` environment in repo settings — a fine-grained PAT with - # `pull-requests: write` and `issues: write` on this repo is enough. - environment: Review - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 24.x - - name: Run rabbit - env: - GH_TOKEN: ${{ secrets.RABBIT_PAT }} - RABBIT_REPO: ${{ github.repository }} - run: | - set -e - ARGS=(run --max "${{ inputs.max || '5' }}") - if [ "${{ inputs.dry_run }}" = "true" ]; then - ARGS+=(--dry-run) - fi - node scripts/rabbit/cli.mjs "${ARGS[@]}" diff --git a/app/src-tauri/Cargo.lock b/app/src-tauri/Cargo.lock index 65f7833f3..7f9bb576e 100644 --- a/app/src-tauri/Cargo.lock +++ b/app/src-tauri/Cargo.lock @@ -50,6 +50,7 @@ dependencies = [ "tokio-util", "toml 0.8.2", "url", + "windows-sys 0.59.0", ] [[package]] diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 6187406cf..070c4fc39 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -141,6 +141,13 @@ objc2-web-kit = { version = "0.3.2", features = ["block2"] } [target.'cfg(target_os = "linux")'.dependencies] notify-rust = { version = "4", default-features = false, features = ["dbus"] } +[target.'cfg(target_os = "windows")'.dependencies] +# AttachConsole — re-attach to the parent shell when the binary runs as a CLI +# (the `core` subcommand). The main binary itself is windows-subsystem so +# launching the Tauri app from Explorer does not pop a console; the helper +# CEF subprocess re-execs inherit that same subsystem. +windows-sys = { version = "0.59", features = ["Win32_System_Console", "Win32_Foundation"] } + [features] default = [] # `custom-protocol` switches Tauri from `devUrl` (vite dev server) to the diff --git a/app/src-tauri/src/main.rs b/app/src-tauri/src/main.rs index 65de8596a..8d1838928 100644 --- a/app/src-tauri/src/main.rs +++ b/app/src-tauri/src/main.rs @@ -1,5 +1,10 @@ -// Prevents additional console window on Windows in release, DO NOT REMOVE!! -#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +// Always run as the Windows GUI subsystem so launching the Tauri app — and +// every CEF helper subprocess re-exec'd from this binary — does not pop a +// console window. Without this, debug builds default to console-subsystem +// and each CEF role (renderer / GPU / utility) opens its own terminal. +// The `core` CLI subcommand path below re-attaches to the parent shell's +// console at runtime via AttachConsole, so command-line output still works. +#![cfg_attr(target_os = "windows", windows_subsystem = "windows")] // On the CEF runtime, the main binary is re-exec'd as the renderer / GPU / // utility helper subprocesses. The `cef_entry_point` macro short-circuits @@ -11,6 +16,13 @@ fn main() { let args: Vec = std::env::args().collect(); if args.get(1).map(String::as_str) == Some("core") { + // CLI path: re-attach to the parent shell's console so eprintln! + // output lands in the cmd/PowerShell window the user invoked us + // from. No-op (and harmless) when launched without a parent + // console, e.g. from Explorer. + #[cfg(target_os = "windows")] + attach_parent_console(); + if let Err(err) = openhuman::run_core_from_args(&args[2..]) { eprintln!("core process failed: {err}"); std::process::exit(1); @@ -20,3 +32,15 @@ fn main() { openhuman::run() } + +#[cfg(target_os = "windows")] +fn attach_parent_console() { + use windows_sys::Win32::System::Console::{AttachConsole, ATTACH_PARENT_PROCESS}; + // SAFETY: AttachConsole has no preconditions beyond a valid PID constant. + // It returns 0 on failure (no parent console / already attached); both + // outcomes are fine for our use — we just won't print anything in that + // case, matching the GUI-launch behavior. + unsafe { + AttachConsole(ATTACH_PARENT_PROCESS); + } +}