chore: Archive all pending OpenSpec proposals

Force archive the following proposals:
- add-audio-device-selector (complete)
- add-embedded-backend-packaging (19/26 tasks)
- add-flexible-deployment-options (20/21 tasks)

New specs created:
- audio-device-management (7 requirements)
- embedded-backend (8 requirements)

Updated specs:
- transcription (+2 requirements for model download progress)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-22 08:44:04 +08:00
parent c36f4167f2
commit e7a06e2b8f
19 changed files with 1551 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
## ADDED Requirements
### Requirement: Embedded Backend Packaging
The FastAPI backend SHALL be packaged as a standalone executable using PyInstaller for all-in-one deployment.
#### Scenario: Backend executable creation
- **WHEN** build script runs with embedded backend flag
- **THEN** PyInstaller SHALL create `backend/dist/backend/backend.exe` containing FastAPI, uvicorn, and all dependencies
#### Scenario: Backend executable startup
- **WHEN** backend executable is launched
- **THEN** it SHALL read configuration from `config.json` in the same directory
- **AND** start uvicorn server on configured host and port
### Requirement: Electron Backend Sidecar Management
The Electron main process SHALL manage the embedded backend as a sidecar process.
#### Scenario: Start backend on app launch
- **WHEN** Electron app launches with `backend.embedded: true` in config
- **THEN** main process SHALL spawn backend executable as child process
- **AND** pass configuration via environment variables
#### Scenario: Skip backend when disabled
- **WHEN** Electron app launches with `backend.embedded: false` in config
- **THEN** main process SHALL NOT spawn backend executable
- **AND** frontend SHALL connect to remote backend via `apiBaseUrl`
#### Scenario: Terminate backend on app close
- **WHEN** user closes Electron app
- **THEN** main process SHALL send SIGTERM to backend process
- **AND** force kill after 5 seconds if still running
### Requirement: Backend Health Check
The Electron main process SHALL verify backend readiness before showing the main window.
#### Scenario: Health check success
- **WHEN** backend `/api/health` returns HTTP 200
- **THEN** main process SHALL proceed to create main window
- **AND** set `backendReady` state to true
#### Scenario: Health check timeout
- **WHEN** backend does not respond within 30 seconds (30 attempts, 1s interval)
- **THEN** main process SHALL display error dialog
- **AND** log detailed error for debugging
#### Scenario: Health check polling
- **WHEN** health check attempt fails
- **THEN** main process SHALL retry after 1 second
- **AND** log attempt number for debugging
### Requirement: Unified Configuration Schema
All configuration for frontend, backend, and whisper SHALL be in a single `config.json` file.
#### Scenario: Backend configuration loading
- **WHEN** backend sidecar starts
- **THEN** it SHALL read database credentials from `config.json` backend.database section
- **AND** read API keys from `config.json` backend.externalApis section
- **AND** read auth settings from `config.json` backend.auth section
#### Scenario: Configuration priority
- **WHEN** both environment variable and config.json value exist
- **THEN** environment variable SHALL take precedence
#### Scenario: Default values
- **WHEN** configuration value is not specified
- **THEN** system SHALL use sensible defaults (host: 127.0.0.1, port: 8000)
### Requirement: Backend Status API
The Electron app SHALL expose backend status to the renderer process.
#### Scenario: Get backend status
- **WHEN** renderer calls `window.electronAPI.getBackendStatus()`
- **THEN** it SHALL return object with `ready` boolean and `url` string
#### Scenario: Backend status in UI
- **WHEN** backend is starting
- **THEN** UI MAY display loading indicator
### Requirement: Backward Compatibility
The embedded backend feature SHALL NOT break existing separate-deployment mode.
#### Scenario: Separate deployment unchanged
- **WHEN** `backend.embedded` is false or undefined
- **THEN** system SHALL behave exactly as before this change
- **AND** frontend connects to `apiBaseUrl` without spawning local backend
#### Scenario: Existing scripts work
- **WHEN** user runs `./start.sh start` or `./scripts/setup-backend.sh`
- **THEN** backend SHALL start normally as standalone server

View File

@@ -0,0 +1,40 @@
## ADDED Requirements
### Requirement: Model Download Progress Display
The sidecar SHALL report Whisper model download progress to enable UI feedback.
#### Scenario: Emit download start
- **WHEN** Whisper model download begins
- **THEN** sidecar SHALL emit JSON to stdout: `{"status": "downloading_model", "model": "<size>", "progress": 0, "total_mb": <size>}`
#### Scenario: Emit download progress
- **WHEN** download progress updates
- **THEN** sidecar SHALL emit JSON: `{"status": "downloading_model", "progress": <percent>, "downloaded_mb": <current>, "total_mb": <total>}`
- **AND** progress updates SHALL occur at least every 5% or every 5 seconds
#### Scenario: Emit download complete
- **WHEN** model download completes
- **THEN** sidecar SHALL emit JSON: `{"status": "model_downloaded", "model": "<size>"}`
- **AND** proceed to model loading
#### Scenario: Skip download for cached model
- **WHEN** model already exists in huggingface cache
- **THEN** sidecar SHALL NOT emit download progress messages
- **AND** proceed directly to loading
### Requirement: Frontend Model Download Progress Display
The Electron frontend SHALL display model download progress to users.
#### Scenario: Show download progress in transcript panel
- **WHEN** sidecar emits download progress
- **THEN** whisper status element SHALL display download percentage and size
- **AND** format: "Downloading: XX% (YYY MB / ZZZ MB)"
#### Scenario: Show download complete
- **WHEN** sidecar emits model_downloaded status
- **THEN** whisper status element SHALL briefly show "Model downloaded"
- **AND** transition to loading state
#### Scenario: Forward progress events via IPC
- **WHEN** main process receives download progress from sidecar
- **THEN** it SHALL forward to renderer via `model-download-progress` IPC channel