diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ddb22fa --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + +jobs: + rust: + name: Rust checks + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Linux dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + pkg-config \ + libdbus-1-dev \ + libxdo-dev \ + libx11-dev \ + libxi-dev \ + libxtst-dev + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Cache cargo + uses: Swatinem/rust-cache@v2 + + - name: Check formatting + run: cargo fmt --check + + - name: Clippy + run: cargo clippy --all-targets -- -D warnings + + - name: Test + run: cargo test + + - name: Build + run: cargo build + + python: + name: Python PoC syntax + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Compile Wayland listener + run: python -m py_compile scripts/wayland_listener.py diff --git a/.github/workflows/release-builds.yml b/.github/workflows/release-builds.yml new file mode 100644 index 0000000..665f2b0 --- /dev/null +++ b/.github/workflows/release-builds.yml @@ -0,0 +1,80 @@ +name: Release Builds + +on: + workflow_dispatch: + push: + tags: + - "v*" + +jobs: + build: + name: Build ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: linux-x86_64 + os: ubuntu-latest + binary: stringcast + archive: stringcast-linux-x86_64.tar.gz + - name: macos + os: macos-latest + binary: stringcast + archive: stringcast-macos.tar.gz + - name: windows-x86_64 + os: windows-latest + binary: stringcast.exe + archive: stringcast-windows-x86_64.zip + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + pkg-config \ + libdbus-1-dev \ + libxdo-dev \ + libx11-dev \ + libxi-dev \ + libxtst-dev + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache cargo + uses: Swatinem/rust-cache@v2 + + - name: Build release binary + run: cargo build --release + + - name: Prepare Unix artifact + if: runner.os != 'Windows' + run: | + mkdir -p dist/stringcast + cp "target/release/${{ matrix.binary }}" dist/stringcast/ + cp README.md RUNNING.md SPEC.md dist/stringcast/ + cp -R docs dist/stringcast/ + tar -czf "dist/${{ matrix.archive }}" -C dist stringcast + + - name: Prepare Windows artifact + if: runner.os == 'Windows' + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path dist/stringcast | Out-Null + Copy-Item "target/release/${{ matrix.binary }}" dist/stringcast/ + Copy-Item README.md,RUNNING.md,SPEC.md dist/stringcast/ + Copy-Item docs dist/stringcast/docs -Recurse + Compress-Archive -Path dist/stringcast -DestinationPath "dist/${{ matrix.archive }}" -Force + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.archive }} + path: dist/${{ matrix.archive }} + if-no-files-found: error diff --git a/README.md b/README.md new file mode 100644 index 0000000..3722903 --- /dev/null +++ b/README.md @@ -0,0 +1,125 @@ +# Stringcast + +Stringcast is a system-wide AI text transformation tool. Type text in a field, end it with a trigger such as `?fix`, and Stringcast sends the selected text to your configured AI provider, shows a short working marker, then replaces the field with the result. + +The current app is a Rust CLI/runtime MVP. It works from a terminal today; packaged desktop apps and installers are planned next. + +## Status + +- Primary runtime: Rust. +- macOS: actively tested during development. +- Windows: runtime scaffolding exists, needs real user testing. +- Linux X11: intended to use the Rust runtime. +- Linux Wayland: separate experimental Python fallback exists in [docs/WAYLAND_POC.md](docs/WAYLAND_POC.md). + +For macOS and Windows users, the preferred direction is downloadable Rust binaries/apps, not a separate Python implementation. + +## Features + +- System-wide trigger detection. +- Clipboard-based text extraction and replacement. +- Inline working marker while the API request is in flight. +- API key metadata in config and secrets in OS key storage. +- Provider support for Gemini, OpenAI, Anthropic, and custom OpenAI-compatible APIs. +- Built-in commands for grammar, tone, summary, translation, and more. + +## Commands + +Static commands: + +```text +?fix Fix grammar, spelling, and punctuation +?improve Improve clarity and readability +?shorten Shorten text +?expand Expand with more detail +?formal Rewrite formally +?casual Rewrite casually +?emoji Add tasteful emojis +?reply Generate a reply +?bullets Convert to bullet points +?summarize Summarize in 1-3 sentences +``` + +Dynamic commands: + +```text +?translate: +?ask: +``` + +Examples: + +```text +i dont knwo whats happening ?fix +hello, how are you ?translate:hi +This paragraph is too long. ?ask:make it sound more confident +``` + +## Quick Start From Source + +Install Rust, then run: + +```bash +cargo run -- init +cargo run -- check-permissions +``` + +Add an API key: + +```bash +STRINGCAST_API_KEY="your-key-here" cargo run -- add-key gemini main "Gemini" +cargo run -- set-provider gemini +cargo run -- api-test +``` + +Run Stringcast: + +```bash +cargo run -- run +``` + +Type in a normal text field: + +```text +i dont knwo whats happening ?fix +``` + +For detailed local setup, see [RUNNING.md](RUNNING.md). + +## Downloadable Builds + +Release workflows build downloadable binaries for: + +- macOS +- Windows +- Linux + +Download artifacts from the GitHub Actions release workflow or from GitHub Releases once release publishing is enabled. + +## Development + +Run the local checks: + +```bash +cargo fmt --check +cargo test +cargo build +python3 -m py_compile scripts/wayland_listener.py +``` + +Linux builds may need native packages: + +```bash +sudo apt update +sudo apt install build-essential pkg-config libdbus-1-dev libxdo-dev libx11-dev libxi-dev libxtst-dev +``` + +## Documentation + +- [RUNNING.md](RUNNING.md): developer/local run instructions. +- [SPEC.md](SPEC.md): product and architecture spec. +- [docs/WAYLAND_POC.md](docs/WAYLAND_POC.md): experimental Linux Wayland listener notes. + +## Security Notes + +Stringcast handles API keys and text from active fields. Avoid using it in password managers, secure input fields, or sensitive apps. The Linux Wayland Python PoC requires keyboard device access and should be treated as experimental.