Commit graph

329 commits

Author SHA1 Message Date
931a07d4e0 chore(merge): merge main into feature/vue-spa — resolve ApplyWorkspace conflict
ApplyWorkspace.vue: kept HEAD (vue-spa) version for resume optimizer panel,
cl-error__actions wrapper, and ResumeOptimizerPanel import. main's older
version lacked these additions.
2026-03-31 21:25:15 -07:00
faf0a7c4dc feat(apply): ATS resume optimizer — gap report + LLM rewrite (paid tier)
- scripts/resume_optimizer.py: extract_jd_signals, prioritize_gaps,
  rewrite_for_ats, hallucination_check, render_resume_text
- dev_api.py: GET/POST /api/jobs/{id}/resume_optimizer + /task endpoints
- web/src/components/ResumeOptimizerPanel.vue: gap report (all tiers),
  per-section LLM rewrite + hallucination badge (paid+)
- ApplyWorkspace.vue: ResumeOptimizerPanel wired in below cover letter

Closes #29
2026-03-31 21:24:49 -07:00
818e46c17e feat: migrate to circuitforge-core for db, llm router, and tiers
Some checks failed
CI / test (push) Failing after 24s
2026-03-25 11:44:19 -07:00
608e0fa922 fix(demo): block Vue navigation in demo mode; fix wizard gate ui sync
- ui_switcher.py: add explicit guard that forces pref=streamlit when
  DEMO_MODE=true, before the tier-downgrade check. Demo Vue SPA (#46)
  is not yet implemented, so navigating there produced a blank screen.
- app.py: call sync_ui_cookie inside wizard gate block before st.stop()
  so that cloud users with ui_preference=vue are redirected correctly
  even when the first-run wizard is still active. Previous behaviour
  called sync_ui_cookie after pg.run() which was never reached.
- demo/config/user.yaml: reset ui_preference to streamlit (belt-and-
  suspenders alongside the code guard).

Closes: demo blank-screen regression reported 2026-03-24.
2026-03-24 12:31:37 -07:00
e9c3c45612 fix(app): pass yaml_path and tier args to render_banner and sync_ui_cookie
Both functions require (yaml_path, tier) — calling them with no args was
silently failing inside the try/except, causing the banner to never render.
2026-03-22 19:28:25 -07:00
e95272c92f fix(app): show ui switcher banner in demo mode
render_banner() was incorrectly guarded by 'if not IS_DEMO' — the spec
says the banner is open to all demo visitors. render_banner() already
handles its own eligibility check internally (_DEMO_MODE or can_use).
2026-03-22 19:18:58 -07:00
c42ba318cf chore(release): v0.7.0
UI switcher (vue_ui_beta paid tier gate), demo toolbar (tier simulation),
Vue SPA merged from feature/vue-spa, nginx Docker web service, Caddy
cookie routing prgn_ui → :8506/:8507/:8508
2026-03-22 18:58:48 -07:00
8208731064 feat(docker): add web service for Vue SPA (nginx, multi-stage build)
Ports: dev=8506, demo=8507, cloud=8508
manage.sh build now includes web service
2026-03-22 18:47:46 -07:00
49e3265132 feat(web): merge Vue SPA from feature/vue-spa; add ClassicUIButton + useFeatureFlag
- Import web/ directory (Vue 3 + Vite + UnoCSS SPA) from feature/vue-spa branch
- Add web/src/components/ClassicUIButton.vue: switch-back to Streamlit via
  cookie (prgn_ui=streamlit) + ?prgn_switch=streamlit query param bridge
- Add web/src/composables/useFeatureFlag.ts: reads prgn_demo_tier cookie for
  demo toolbar visual consistency (not an authoritative gate, see issue #8)
- Update .gitignore: add .superpowers/, pytest-output.txt, docs/superpowers/
2026-03-22 18:46:11 -07:00
86de5d2f3f feat(settings): add ui_switcher toggle to Deployment expander 2026-03-22 16:50:17 -07:00
c94a9d5b30 chore(settings): remove old SettingsView placeholder — new shell at views/settings/SettingsView.vue
Full test suite: 71 frontend (14 files) + 583 backend tests passing.
2026-03-22 16:40:37 -07:00
17eed400f8 feat(app): wire ui_switcher and demo_toolbar into app.py render pass
- Initialize simulated_tier session state for demo mode after resolve_session/init_db
- Render demo toolbar before pg.run() when IS_DEMO is set
- Render ui_switcher banner before pg.run() for non-demo paid-tier users (guarded with try/except)
- Sync ui_preference cookie after pg.run() (guarded with try/except)
- All imports are local (inside if-blocks) to avoid Streamlit circular import issues
2026-03-22 16:30:52 -07:00
3e41dbf030 test(settings): settingsGuard unit tests — tab gating scenarios
Extract guard logic to settingsGuard.ts for testability.
Router beforeEach keeps async config.load() wrapper, delegates to sync guard.
14 test cases cover system/fine-tune/developer gates across cloud/self-hosted/tier/GPU profile combos.
2026-03-22 16:27:45 -07:00
35e8f7513c fix(demo): remove reload antipattern, fix label consistency in demo_toolbar tests 2026-03-22 16:27:20 -07:00
feea057463 test(settings): backend tests for all settings API endpoints 2026-03-22 16:25:37 -07:00
c7a785da4c test(demo): add render_demo_toolbar test (94% coverage) 2026-03-22 16:20:16 -07:00
88e870df5c feat(demo): add demo_toolbar component (tier simulation for DEMO_MODE) 2026-03-22 16:11:58 -07:00
d748081a53 refactor(ui-switcher): narrow exception handling, remove duplicate profile loads, fix test isolation
- Add explanatory comments to all 5 bare except Exception blocks clarifying that UI components must not crash the app
- Refactor sync_ui_cookie() to load UserProfile once instead of up to 3 times in normal path
- Store profile reference and reuse it in tier downgrade protection block
- Replace importlib.reload() pattern in tests with unittest.mock.patch for _DEMO_MODE
- Improves test isolation and eliminates module state contamination across test runs
- All 5 tests pass (100%)
2026-03-22 16:05:53 -07:00
fa2569c7e4 feat(settings): License, Data, Privacy, Developer tabs — stores, views, endpoints
- useLicenseStore: load/activate/deactivate with tier badge and key input
- useDataStore: createBackup with file count and size display
- usePrivacyStore: BYOK panel logic (dismissal snapshot tracks new backends),
  telemetry toggle (self-hosted) and master-off/usage/content controls (cloud)
- Views: LicenseView (cloud/self-hosted split), LicenseSelfHosted,
  LicenseCloud, DataView, PrivacyView, DeveloperView
- dev-api.py: /api/settings/license, /activate, /deactivate;
  /api/settings/data/backup/create; /api/settings/privacy GET+PUT;
  /api/settings/developer GET, /tier PUT, /hf-token PUT+test, /wizard-reset,
  /export-classifier; _load_user_config/_save_user_config helpers; CONFIG_DIR
- TDD: 10/10 store tests passing (license×3, data×2, privacy×5)
2026-03-22 16:01:29 -07:00
5f7e7ee912 feat(ui-switcher): add ui_switcher component (sync_ui_cookie, switch_ui, render_banner, render_settings_toggle) 2026-03-22 16:01:07 -07:00
0acde6d199 feat(profile): add ui_preference field (streamlit|vue, default: streamlit) 2026-03-22 15:55:38 -07:00
eb72776e9f feat(settings): Fine-Tune tab — wizard, polling, step lifecycle
Add useFineTuneStore (Pinia setup-function) with step state, polling via
setInterval, loadStatus, startPolling/stopPolling, and submitJob. Add
FineTuneView.vue with a 3-step wizard (upload → extract → train), mode-aware
train step (self-hosted shows make finetune + model check; cloud shows
submit job + quota). Add fine-tune endpoints to dev-api.py: status, extract,
upload, submit, and local-status. All 4 store unit tests pass.
2026-03-22 15:52:53 -07:00
bd24275455 refactor(tiers): replace importlib.reload with mock.patch in demo_tier tests
- Replace fragile reload pattern with unittest.mock.patch('app.wizard.tiers._DEMO_MODE', ...)
- Eliminates parallel test run failures (pytest-xdist) and improves test isolation
- All 4 demo_tier tests now use context managers for clean setup/teardown
- Add explanatory comment to _DEMO_MODE definition about immutability and env-based init
2026-03-22 15:52:03 -07:00
a380ec33ec fix(settings): task 6 review fixes — credential paths, email security, integrationResults in store
- Anchor CRED_DIR/KEY_PATH to __file__ (not CWD) in credential_store.py
- Fix email PUT: separate password pop from sentinel discard (was fragile or-chain)
- Fix email test: always use stored credential, remove password override path
- Move integrationResults into system store (was view-local — spec violation)
- saveFilePaths/saveDeployConfig write to dedicated error refs, not saveError
2026-03-22 15:46:47 -07:00
1c7a093125 feat(tiers): add vue_ui_beta feature key and demo_tier kwarg to can_use 2026-03-22 15:31:54 -07:00
f6ddaca14f feat(settings): credential store + fix Task 6 blocking review issues
- add scripts/credential_store.py (keyring/file/env-ref backends, Fernet encryption)
- email password stored via credential store, never returned in GET
- email GET returns password_set flag; PUT accepts new password or ${ENV_VAR} ref
- move integration actions to store (connectIntegration, testIntegration, disconnectIntegration)
- add tier-gating UI with locked state and upgrade prompt
- move subprocess/socket/imaplib/ssl imports to top level
2026-03-22 15:31:45 -07:00
bce997e596 feat(settings): System tab — services, email, integrations, paths, deployment 2026-03-22 13:25:38 -07:00
5afb752be6 fix(settings): system tab review fixes
- guard confirmByok() against byok-ack POST failure (leave modal open on error)
- fix drag reorder to use ID-based index lookup (not filtered-list index)
- guard cancelByok() against empty snapshot
- add LlmConfigPayload Pydantic model for PUT endpoint
- add test for confirmByok() failure path
2026-03-22 12:01:55 -07:00
7af0366330 feat(settings): System tab — LLM backends, BYOK gate, store + view 2026-03-22 07:26:07 -07:00
a38d9e5663 fix(settings): search prefs review fixes
- add try/except to suggest endpoint
- use immutable spread/filter in addTag, removeTag, acceptSuggestion
- add toggleBoard store action, remove direct v-model on board.enabled
2026-03-22 07:21:10 -07:00
2200d05b5c feat(settings): Search Prefs tab — store, view, API endpoints, remote preference filter 2026-03-21 03:09:51 -07:00
92bd82b4c9 fix(settings): address resume tab review issues
- add loadError ref (separated from empty-state path)
- add stable id to WorkEntry, use as v-for key
- move addExperience/removeExperience/addTag/removeTag to store actions
- strip id from save payload
- fix uploadError type handling in handleUpload
- add outer try/except to upload_resume endpoint
- gate syncFromProfile to non-loaded resume only
- add date_of_birth input to personal info section
- add loadError test
2026-03-21 03:04:29 -07:00
56857dc989 feat(settings): Resume Profile tab — store, view, API endpoints, identity sync 2026-03-21 02:57:49 -07:00
6093275549 fix(settings): final code quality fixes for My Profile tab
- add try/except to sync_identity endpoint
- strip id field from mission_preferences save body
- fix NDA v-for key to use company string (not index), add dedup guard
- move imports out of save_user_profile function body
2026-03-21 02:53:29 -07:00
3bcc08c080 fix(settings): spec compliance gaps in My Profile tab
- add POST /api/settings/resume/sync-identity endpoint (IdentitySyncPayload)
- fix loadError destructuring to use storeToRefs for reactivity
2026-03-21 02:40:17 -07:00
d3b4ed74bb fix(settings): address profile tab code quality issues
- add loadError ref to useProfileStore, rendered in MyProfileView
- replace raw fetch with useApiFetch in generateSummary/generateMissions
- remove await from sync-identity call (fire-and-forget)
- add stable id field to MissionPref, use as v-for key
- add test for load() error path
2026-03-21 02:37:53 -07:00
da7d305588 fix(settings): profile tests assert sync-identity; add load/save_user_profile helpers 2026-03-21 02:31:39 -07:00
1ef418ba00 feat(settings): My Profile tab — store, view, API endpoints
- Add useProfileStore (settings/profile) with load/save, all profile fields,
  loading/saving/saveError state, and graceful resume sync-identity call
- Add MyProfileView.vue: Identity, Mission & Values, NDA Companies, and
  Research Brief Preferences sections; autosave on NDA add/remove and
  debounced autosave (400ms) on research checkbox changes
- Add GET/PUT /api/settings/profile endpoints to dev-api.py with YAML
  field mapping (linkedin ↔ linkedin_url, candidate_*_focus ↔ *_focus,
  mission_preferences dict ↔ list of {industry, note})
- 3 new store tests pass; full suite 26/26 green
2026-03-21 02:28:14 -07:00
32a83d6ff4 fix(settings): async guard awaits config load, reactive devTierOverride, validate APP_TIER 2026-03-21 02:23:10 -07:00
05a737572e feat(settings): foundation — appConfig store, settings shell, nested router
- Add useAppConfigStore (isCloud, isDevMode, tier, contractedClient, inferenceProfile)
- Add GET /api/config/app endpoint to dev-api.py (reads env vars)
- Replace flat /settings route with nested children (9 tabs) + redirect to my-profile
- Add global router.beforeEach guard for system/fine-tune/developer tab access control
- Add SettingsView.vue shell: desktop sidebar with group labels, mobile chip bar, RouterView
- Tab visibility driven reactively by store state (cloud mode hides system, GPU profile gates fine-tune, devMode gates developer)
- Tests: 3 store tests + 3 component tests, all passing
2026-03-21 02:19:43 -07:00
4ac9cea5a6 chore: ignore .superpowers/, docs/superpowers/, pytest-output.txt; untrack plan/spec files 2026-03-21 00:55:17 -07:00
3bfce5e6ef feat(survey): show job picker when navigating to /survey with no id 2026-03-21 00:49:55 -07:00
80999b9e7b fix: SurveyView history reactivity, timer cleanup, accessibility
- Reassign expandedHistory.value to a new Set on toggle so Vue tracks
  the change and template expressions re-evaluate correctly
- Capture saveSuccess setTimeout in a module-level variable; clear it
  on unmount to prevent state mutation after component teardown
- Add role="region" + aria-label to screenshot drop zone div
- Add box-sizing: border-box to .save-input to match .survey-textarea
2026-03-21 00:31:31 -07:00
4bea0899db feat(survey): implement SurveyView with navigation wiring 2026-03-21 00:27:57 -07:00
ea23845c23 fix: survey store quality issues — loading in fetchFor, source guard, saveResponse failure test 2026-03-21 00:21:21 -07:00
80ed7a470a feat(survey): add survey Pinia store with tests
Setup-store pattern (setup function style) with fetchFor, analyze,
saveResponse, and clear. analysis ref stores mode + rawInput so
saveResponse can build the full POST body without re-passing them.
6/6 unit tests pass; full suite 15/15.
2026-03-21 00:17:13 -07:00
595035e02d fix(survey): validate mode input and handle malformed base64 in save endpoint 2026-03-21 00:14:39 -07:00
75163b8e48 feat(survey): add 4 backend survey endpoints with tests
Add GET /api/vision/health, POST /api/jobs/{id}/survey/analyze,
POST /api/jobs/{id}/survey/responses, and GET /api/jobs/{id}/survey/responses
to dev-api.py. All 10 TDD tests pass; 549 total suite tests pass (0 regressions).
2026-03-21 00:09:02 -07:00
b1a32ab207 fix: contacts fetch error degrades partially, not full panel blank
Contacts 5xx no longer early-returns from fetchFor, leaving the entire
right panel blank. A new contactsError ref surfaces the failure message
in the Email tab only; JD tab, Cover Letter tab, and match score all
render normally. Adds test asserting partial degradation behavior.
2026-03-20 19:16:03 -07:00
8479f79701 fix: aria-label binding, dead import, guardAndLoad network error handling
- Fix 1: Add missing `:` binding prefix to aria-label on score badge
  (was emitting literal backtick template string to DOM)
- Fix 2: Remove unused `watch` import from InterviewPrepView.vue
- Fix 3: guardAndLoad now checks interviewsStore.error after fetchAll;
  shows pageError banner instead of silently redirecting to /interviews
  on network failure; job is now a ref set explicitly in the guard
- Fix 4: Remove unconditional research-badge from InterviewCard.vue
  (added in this branch; card has no access to prep store so badge
  always showed regardless of whether research exists)
2026-03-20 18:57:41 -07:00