Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed .devin/workflows/accept-edits.md
Empty file.
19 changes: 15 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@ on:
pull_request:
branches: [main]

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
quality-gate:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
steps:
- uses: actions/checkout@v7.0.0
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Install Rust
uses: dtolnay/rust-toolchain@1.97.0
uses: dtolnay/rust-toolchain@889fac408b4da0905346410f253f0c55fbcb6613 # 1.97.0
with:
components: rustfmt, clippy

Expand All @@ -23,12 +33,13 @@ jobs:
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev librsvg2-dev ripgrep

- name: Setup Node.js
uses: actions/setup-node@v6.4.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: npm

- name: Cache Rust build
uses: Swatinem/rust-cache@v2.9.1
uses: Swatinem/rust-cache@23869a5bd66c73db3c0ac40331f3206eb23791dc # v2.9.1

- name: Install cargo-audit
run: cargo install cargo-audit --locked
Expand Down
36 changes: 24 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,32 @@ env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}

permissions:
contents: write
contents: read

concurrency:
group: release-${{ github.ref }}

jobs:
quality:
runs-on: ubuntu-22.04
timeout-minutes: 45
permissions:
contents: read
outputs:
release_sha: ${{ steps.resolve_tag.outputs.release_sha }}
steps:
- uses: actions/checkout@v7.0.0
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: refs/tags/${{ env.RELEASE_TAG }}
fetch-depth: 0
- uses: actions/setup-node@v6.4.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: npm
- uses: dtolnay/rust-toolchain@1.97.0
- uses: dtolnay/rust-toolchain@889fac408b4da0905346410f253f0c55fbcb6613 # 1.97.0
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2.9.1
- uses: Swatinem/rust-cache@23869a5bd66c73db3c0ac40331f3206eb23791dc # v2.9.1
- name: Resolve release tag to immutable commit
id: resolve_tag
shell: bash
Expand All @@ -61,6 +67,9 @@ jobs:

build:
needs: quality
timeout-minutes: 60
permissions:
contents: write
strategy:
fail-fast: false
matrix:
Expand All @@ -84,25 +93,25 @@ jobs:

runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v7.0.0
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ needs.quality.outputs.release_sha }}
fetch-depth: 0
fetch-tags: true

- uses: actions/setup-node@v6.4.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: npm

- name: Install Rust
uses: dtolnay/rust-toolchain@1.97.0
uses: dtolnay/rust-toolchain@889fac408b4da0905346410f253f0c55fbcb6613 # 1.97.0
with:
components: rustfmt, clippy
targets: ${{ matrix.target }}

- name: Cache Rust build
uses: Swatinem/rust-cache@v2.9.1
uses: Swatinem/rust-cache@23869a5bd66c73db3c0ac40331f3206eb23791dc # v2.9.1

- name: Install Linux dependencies
if: matrix.platform == 'ubuntu-22.04'
Expand All @@ -126,7 +135,7 @@ jobs:
test "$(git rev-parse HEAD)" = "${RELEASE_SHA}"

- name: Build and publish release assets
uses: tauri-apps/tauri-action@v1
uses: tauri-apps/tauri-action@1deb371b0cd8bd54025b384f1cd735e725c4060f # v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_SIGNING_IDENTITY: ${{ matrix.signing_identity }}
Expand All @@ -141,13 +150,16 @@ jobs:
checksums:
needs: [quality, build]
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
steps:
- uses: actions/checkout@v7.0.0
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ needs.quality.outputs.release_sha }}
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-node@v6.4.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: npm
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ target/

# Internal audit
docs/FULL_AUDIT_REPORT.md

# CI / local artifacts
.privacy-gate-check-*
release-assets/
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed
- Fixed a process-aborting stack overflow when importing OpenAPI documents with self-referencing schemas by adding a depth limit and cycle handling to schema sampling.
- Made the pre-request/test script engine functional: `console.log/info/warn/error` output and `test(name, condition)` assertions are now captured and reported, with caps on log and result volume.
- Stopped reporting every failed gRPC call as a success: responses with an empty or malformed body now surface `UNKNOWN` or an HTTP-derived gRPC status instead of a hardcoded `0`, with request timeouts and 50 MB response caps.
- Fixed silent authentication degradation: invalid URLs, missing credentials, and malformed header values now surface errors instead of sending unauthenticated or unsigned requests.
- Corrected AWS SigV4 canonical path and query encoding (percent-decoding before canonical re-encoding, sorted parameters) and OAuth 1.0 signing (HMAC-SHA1 per spec, query parameters included, order-independent base string), with golden-value regression tests.
- Fixed WebSocket and SSE connection hangs with 30-second connect timeouts, and closed the check-then-act race that let concurrent connects with the same id clobber each other.
- WebSocket now notifies the UI when a stream ends without a Close frame (for example after an idle TCP reset), and outbound messages use a bounded buffer that errors when the peer stops consuming.
- SSE decoder now rejects streams that send more than 1 MB without a line break instead of growing memory without limit.
- Numeric assertions (`greater than`/`less than`) now fail with an explanatory message when the compared value is not a number instead of silently comparing against `0`.
- Export, import, and write commands no longer block the UI thread; blocking file, database, and Git work runs on background tasks, and Postman/OpenAPI imports commit atomically so failures leave no partial collections.
- Export and import commands validate paths with the same safeguards as file writes (absolute, inside the home directory, no traversal, no symlinks).
- Git sync stages only exported `*.json` files instead of `git add -A`, so unrelated or untrusted files in the sync directory are never committed.
- Database serialization failures now surface as serialization errors instead of misleading "not found" messages.
- Mock server request counter uses an atomic counter.
- Mock server view no longer leaks a polling timer after unmount and re-syncs running state from the backend on mount.
- Unhandled promise rejections in team unshare, Git sync, API docs export, and clipboard copy paths now surface errors in the UI.

### Security
- Removed `'unsafe-inline'` from the Content Security Policy `script-src` directive.
- Scoped GitHub Actions workflows to least privilege: `ci.yml` now declares read-only permissions, release workflows grant write access only to jobs that publish, all actions are pinned to commit SHAs, and jobs run with concurrency groups and timeouts.

### Changed
- Enforced TypeScript strict mode for the Vite config type-check and added a Node `>=22` engine requirement.

## [0.2.1] - 2026-07-11

### Added
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading