Compare commits

..

No commits in common. "main" and "feature/demo-experience" have entirely different histories.

2 changed files with 42 additions and 58 deletions

View file

@ -9,62 +9,6 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
---
## [0.9.0] — 2026-04-20
### Added
- **Messaging tab** (#74) — per-job communication timeline replacing `/contacts`.
Unified view of IMAP emails (`job_contacts`) and manually logged entries (`messages`).
Log calls and in-person notes with timestamp. Message template library with 4 built-in
templates (follow-up, thank-you, accommodation request, withdrawal) and user-created
templates with `{{token}}` substitution. LLM draft reply for inbound emails (BYOK-unlockable,
BSL 1.1). Draft approval flow with inline editing and one-click clipboard copy. Osprey
IVR stub button (Phase 2 placeholder with easter egg). `migrations/008_messaging.sql`.
- **Public demo experience** (#103) — full read-only demo mode at `demo.circuitforge.tech/peregrine`.
`IS_DEMO=true` write-blocks all mutating API endpoints with a toast notification.
Ephemeral seed data via tmpfs + `demo/seed.sql` (resets on container start). WelcomeModal
on first visit (localStorage-gated). Per-view HintChips guiding new users through the
job search flow (localStorage-dismissed). DemoBanner with accessible CTA buttons
(WCAG-compliant contrast in light and dark themes). `migrations/006_missing_columns.sql`.
- **References tracker and recommendation letter system** (#96) — track professional
references and generate LLM-drafted recommendation request letters.
- **Shadow listing detector** — flags duplicate or aggregator-reposted job listings.
- **Hired feedback widget** — capture post-hire notes and retrospective feedback on jobs.
- **Interview prep Q&A** — LLM-generated practice questions for the selected job.
- **Resume library ↔ profile sync**`POST /api/resumes/{id}/apply-to-profile` pushes
a library resume into the active profile; `PUT /api/settings/resume` syncs edits back
to the default library entry. `ResumeSyncConfirmModal` shows a before/after diff.
`ResumeProfileView` extended with career summary, education, and achievements sections.
`migrations/007_resume_sync.sql` adds `synced_at` to `resumes`.
- **Plausible analytics** — lightweight privacy-preserving analytics in Vue SPA and docs.
- **cf_text / cf_voice LLM backends** — wire trunk service backends in `llm.yaml`.
- **Mission alignment domains** — load preferred company domains from
`config/mission_domains.yaml` rather than hardcoded values.
- **GitHub Actions CI** — workflow for public credibility badge (`ci.yml`).
- **`CF_APP_NAME` cloud annotation** — coordinator pipeline attribution for multi-product
cloud deployments.
### Changed
- `/contacts` route now redirects to `/messages`; nav item renamed "Messages" → "Contacts"
label removed. `ContactsView.vue` preserved for reference, router points to `MessagingView`.
- Survey `/analyze` endpoint is now fully async via the task queue (no blocking LLM call
on the request thread).
- nginx config adds `/peregrine/` base-path routing for subdirectory deployments.
- `compose.demo.yml` updated for Vue/FastAPI architecture with tmpfs demo volume.
### Fixed
- Tier bypass and draft body persistence after page navigation.
- `canDraftLlm` cleanup and message list `limit` cap.
- DemoBanner button contrast — semantic surface token instead of hardcoded white.
- Period split in `profile_to_library` now handles ISO date strings containing hyphens.
- Cloud startup sweeps all user DBs for pending migrations on deploy.
- Resume import strips CID glyph references via `resume_parser` extractors.
- Survey and interview tests updated for `hired_feedback` column and async analyze flow.
---
## [0.8.6] — 2026-04-12
### Added

View file

@ -1,7 +1,48 @@
# compose.yml — Peregrine by Circuit Forge LLC
# Streamlit (app service) removed — Vue+FastAPI is the only frontend (#104)
# Profiles: remote | cpu | single-gpu | dual-gpu-ollama
services:
app:
build:
context: ..
dockerfile: peregrine/Dockerfile.cfcore
command: >
bash -c "streamlit run app/app.py
--server.port=8501
--server.headless=true
--server.fileWatcherType=none
2>&1 | tee /app/data/.streamlit.log"
ports:
- "${STREAMLIT_PORT:-8501}:8501"
volumes:
- ./config:/app/config
- ./data:/app/data
- ${DOCS_DIR:-~/Documents/JobSearch}:/docs
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker:ro
environment:
- STAGING_DB=/app/data/staging.db
- DOCS_DIR=/docs
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- OPENAI_COMPAT_URL=${OPENAI_COMPAT_URL:-}
- OPENAI_COMPAT_KEY=${OPENAI_COMPAT_KEY:-}
- PEREGRINE_GPU_COUNT=${PEREGRINE_GPU_COUNT:-0}
- PEREGRINE_GPU_NAMES=${PEREGRINE_GPU_NAMES:-}
- RECOMMENDED_PROFILE=${RECOMMENDED_PROFILE:-remote}
- STREAMLIT_SERVER_BASE_URL_PATH=${STREAMLIT_BASE_URL_PATH:-}
- FORGEJO_API_TOKEN=${FORGEJO_API_TOKEN:-}
- FORGEJO_REPO=${FORGEJO_REPO:-}
- FORGEJO_API_URL=${FORGEJO_API_URL:-}
- PYTHONUNBUFFERED=1
- PYTHONLOGGING=WARNING
- PEREGRINE_CADDY_PROXY=1
depends_on:
searxng:
condition: service_healthy
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
api:
build:
context: ..
@ -21,7 +62,6 @@ services:
- PEREGRINE_GPU_COUNT=${PEREGRINE_GPU_COUNT:-0}
- PEREGRINE_GPU_NAMES=${PEREGRINE_GPU_NAMES:-}
- CF_ORCH_URL=${CF_ORCH_URL:-http://host.docker.internal:7700}
- CF_APP_NAME=peregrine
- PYTHONUNBUFFERED=1
extra_hosts:
- "host.docker.internal:host-gateway"