Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2aaeade
feat(desktop): add cross-platform local setup, curated model flow, an…
sammargolis Mar 10, 2026
1a9d4f4
ci: add desktop release matrix and quality gate workflows
sammargolis Mar 10, 2026
bea5eac
test(backend): cover config defaults/model policy and ignore runtime …
sammargolis Mar 10, 2026
7ecc704
build(release): add artifact checksums and smoke checks to desktop pi…
sammargolis Mar 10, 2026
a16fcb0
test(release): add cross-platform desktop e2e gates and GA evidence v…
sammargolis Mar 10, 2026
261914a
test(update): add platform/arch release-link regression coverage
sammargolis Mar 10, 2026
bfd0f8d
release: publish downloadable desktop assets and improve install flow
sammargolis Mar 10, 2026
26c860c
test(e2e): stabilize desktop smoke and lifecycle on mac
sammargolis Mar 11, 2026
64c3f5f
fix(desktop): guard renderer IPC sends after window teardown
sammargolis Mar 11, 2026
2115561
fix(note-gen): fail fast on missing placeholder Anthropic keys
sammargolis Mar 11, 2026
2c27586
feat(settings): prompt for Anthropic key when mixed mode requires it
sammargolis Mar 11, 2026
e13b3bf
test(assemble): unref session cleanup timer to prevent hanging tests
sammargolis Mar 11, 2026
f2a7ccb
Gate local mode by runtime readiness and make system audio optional
sammargolis Mar 11, 2026
8bcf64e
Make mixed onboarding key-first with background whisper readiness
sammargolis Mar 11, 2026
1a083dc
Handle blank audio explicitly in transcription flows
sammargolis Mar 11, 2026
f3d18a3
Loosen silence gate for quiet microphone input
sammargolis Mar 11, 2026
482aa72
Harden mixed auth status and microphone readiness gating
sammargolis Mar 12, 2026
273b08e
Fallback to default mic when preferred device is unavailable
sammargolis Mar 12, 2026
80390ec
Add mac audio-input entitlement for microphone permission prompts
sammargolis Mar 12, 2026
b9d7983
Bump app version to 0.1.1 for release
sammargolis Mar 12, 2026
9c248f8
chore: normalize next env route types import
sammargolis Mar 12, 2026
24a2625
Merge origin/main into codex/stablize-electron-build: resolve desktop…
sammargolis Mar 12, 2026
e44b545
ci: fix lint/test workflow scope and stabilize test runner
sammargolis Mar 12, 2026
a22ba36
ci: remove pnpm version pin from quality gates
sammargolis Mar 12, 2026
f94d4a7
ci: fetch full history and robust base sha in quality gates
sammargolis Mar 13, 2026
644ab50
test(eval): remove forced process exit from e2e-basic
sammargolis Mar 13, 2026
fe32447
test(ci): run compiled test files one-at-a-time for stability
sammargolis Mar 13, 2026
6686471
ci: fix pnpm setup order in quality gates and opt into node24 action …
sammargolis Mar 13, 2026
7f525eb
test(ipc): remove Electron runtime dependency from desktop IPC contra…
sammargolis Mar 13, 2026
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
21 changes: 10 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
name: CI
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"

on:
pull_request:
Expand All @@ -20,29 +22,26 @@ jobs:
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint:structure
- name: Detect lint targets
id: lint-targets
- name: Run ESLint on changed files
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
BASE_SHA="${{ github.event.pull_request.base.sha }}"
else
BASE_SHA="${{ github.event.before }}"
fi
CHANGED_FILES="$(git diff --name-only "$BASE_SHA" "${{ github.sha }}" -- \
git diff --name-only "$BASE_SHA" "${{ github.sha }}" -- \
apps/web/src \
packages/storage/src \
packages/pipeline/transcribe/src \
packages/pipeline/assemble/src \
scripts/check-no-phi-logs.mjs \
config/scripts/check-structure.mjs \
| tr '\n' ' ')"
echo "files=${CHANGED_FILES}" >> "$GITHUB_OUTPUT"
- name: Run ESLint on changed files
if: steps.lint-targets.outputs.files != ''
run: pnpm exec eslint --config config/eslint.config.mjs ${{ steps.lint-targets.outputs.files }}
- name: Skip ESLint when no tracked files changed
if: steps.lint-targets.outputs.files == ''
run: echo "No lint-tracked files changed; skipping eslint."
> /tmp/lint-targets.txt
if [[ -s /tmp/lint-targets.txt ]]; then
xargs pnpm exec eslint --config config/eslint.config.mjs < /tmp/lint-targets.txt
else
echo "No lint-tracked files changed; skipping eslint."
fi

typecheck:
runs-on: ubuntu-latest
Expand Down
202 changes: 202 additions & 0 deletions .github/workflows/desktop-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
name: Desktop Release

on:
workflow_dispatch:
inputs:
release_version:
description: "Release version (e.g. 0.2.0)"
required: true
release_base_url:
description: "Base download URL for manifest entries"
required: false
push:
tags:
- "v*"

permissions:
contents: write

jobs:
build-desktop:
name: Build ${{ matrix.target }}-${{ matrix.arch }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
target: mac
arch: x64
platform_id: darwin
- os: macos-latest
target: mac
arch: arm64
platform_id: darwin
- os: windows-latest
target: win
arch: x64
platform_id: win32
- os: ubuntu-latest
target: linux
arch: x64
platform_id: linux
- os: ubuntu-latest
target: linux
arch: arm64
platform_id: linux
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
WIN_CSC_LINK: ${{ secrets.WIN_CSC_LINK }}
WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CSC_KEY_PASSWORD }}
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: Install Dependencies
run: pnpm install --frozen-lockfile

- name: Backend Unit Tests
shell: bash
run: |
cd local-only/openscribe-backend
PYTHONPATH=. python -m unittest discover -s tests -p "test*_unittest.py"

- name: Provision Clean Environment
run: pnpm test:e2e:desktop:provision

- name: Generate E2E Fixtures
run: pnpm test:e2e:desktop:fixtures

- name: Build Desktop Installer
run: node scripts/build-desktop.mjs ${{ matrix.target }} ${{ matrix.arch }} installer

- name: Build Desktop Unpacked Dir
run: node scripts/build-desktop.mjs ${{ matrix.target }} ${{ matrix.arch }} dir

- name: Smoke Check Artifacts
run: pnpm test:desktop:artifacts

- name: Runtime Launch Smoke
run: pnpm test:e2e:desktop:launch

- name: Install Lifecycle Smoke
run: pnpm test:e2e:desktop:lifecycle

- name: IPC Contract Regression
run: pnpm test:e2e:desktop:ipc

- name: Signing/Notarization Gate
run: pnpm test:e2e:desktop:signing
env:
CI_PLATFORM: ${{ matrix.platform_id }}

- name: Generate Release Manifest
run: pnpm build:release:manifest
env:
RELEASE_VERSION: ${{ github.ref_name }}
RELEASE_BASE_URL: ${{ inputs.release_base_url }}
SIGNATURE_STATUS: VERIFIED

- name: Generate Checksums
run: pnpm build:release:checksums

- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: desktop-${{ matrix.target }}-${{ matrix.arch }}
path: |
build/dist/**

validate-release-evidence:
name: Validate Release Evidence
runs-on: ubuntu-latest
needs: build-desktop
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download All Desktop Artifacts
uses: actions/download-artifact@v4
with:
path: build/evidence
pattern: desktop-*

- name: Validate 5-target evidence and integrity files
run: node scripts/e2e/validate-release-evidence.mjs

publish-github-release:
name: Publish GitHub Release
runs-on: ubuntu-latest
needs: validate-release-evidence
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: Download All Desktop Artifacts
uses: actions/download-artifact@v4
with:
path: build/release-artifacts
pattern: desktop-*

- name: Resolve release tag
id: release_tag
shell: bash
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
tag="${{ inputs.release_version }}"
if [[ ! "$tag" =~ ^v ]]; then
tag="v$tag"
fi
else
tag="${{ github.ref_name }}"
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"

- name: Collect installer assets
run: pnpm build:release:collect

- name: Generate consolidated manifest/checksums
run: |
DIST_DIR=build/publish RELEASE_VERSION=${{ steps.release_tag.outputs.tag }} RELEASE_BASE_URL=https://github.com/${{ github.repository }}/releases/download/${{ steps.release_tag.outputs.tag }} SIGNATURE_STATUS=VERIFIED pnpm build:release:manifest
DIST_DIR=build/publish pnpm build:release:checksums

- name: Publish Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.release_tag.outputs.tag }}
draft: false
prerelease: false
generate_release_notes: true
files: |
build/publish/*
90 changes: 90 additions & 0 deletions .github/workflows/quality-gates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Quality Gates
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"

on:
pull_request:
push:
branches:
- main

jobs:
checks:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install pnpm
uses: pnpm/action-setup@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: pnpm

- name: Install Dependencies
run: pnpm install --frozen-lockfile

- name: Lint structure
run: pnpm lint:structure

- name: Run ESLint on changed files
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
BASE_SHA="${{ github.event.pull_request.base.sha }}"
else
BASE_SHA="${{ github.event.before }}"
fi
git diff --name-only "$BASE_SHA" "${{ github.sha }}" -- \
apps/web/src \
packages/storage/src \
packages/pipeline/transcribe/src \
packages/pipeline/assemble/src \
scripts/check-no-phi-logs.mjs \
config/scripts/check-structure.mjs \
> /tmp/lint-targets.txt
if [[ -s /tmp/lint-targets.txt ]]; then
xargs pnpm exec eslint --config config/eslint.config.mjs < /tmp/lint-targets.txt
else
echo "No lint-tracked files changed; skipping eslint."
fi

- name: Build Tests
run: pnpm build:test

- name: Unit Tests
run: pnpm test:llm

- name: Desktop IPC Contract Test
run: pnpm test:e2e:desktop:ipc

- name: Detect dependency manifest changes
id: dep-scope
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
BASE_SHA="${{ github.event.pull_request.base.sha }}"
else
BASE_SHA="${{ github.event.before }}"
fi
if git diff --name-only "$BASE_SHA" "${{ github.sha }}" -- pnpm-lock.yaml | grep -q .; then
echo "run_audit=true" >> "$GITHUB_OUTPUT"
else
echo "run_audit=false" >> "$GITHUB_OUTPUT"
fi

- name: Dependency Audit
if: steps.dep-scope.outputs.run_audit == 'true'
run: pnpm audit --audit-level high

- name: Skip dependency audit when manifests are unchanged
if: steps.dep-scope.outputs.run_audit != 'true'
run: echo "No dependency manifest changes; skipping audit."
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ yarn-debug.log*
yarn-error.log*
*.tsbuildinfo
.idea
local-only/openscribe-backend/ollama_startup_report.json
local-only/openscribe-backend/recorder_state.json
local-only/openscribe-backend/config.json
Loading
Loading