diff --git a/src-tauri/crates/commit_ai/src/lib.rs b/src-tauri/crates/commit_ai/src/lib.rs index c82cecc..19a20ae 100644 --- a/src-tauri/crates/commit_ai/src/lib.rs +++ b/src-tauri/crates/commit_ai/src/lib.rs @@ -413,20 +413,27 @@ do not include lines starting with 'diff --git', '@@', '+', '-', 'index ', 'Stag or 'Diff stat:' anywhere in your answer. \ Format: a Conventional Commits header ((): ) in imperative mood, \ max. 72 characters, then a blank line, then a body. \ -The body is required: one short paragraph explaining what changed and why, \ -then bullet points (- ...) of the key changes grouped by affected area/file. \ +The body is required: a short, general paragraph (2-4 sentences) summarizing what changed \ +and why at a high level — do NOT enumerate every changed file individually. \ +You may optionally add up to 3 bullet points (- ...) afterward, but only for the most \ +significant changes overall, never one bullet or heading per file. \ +Never use bold text, backticks, or markdown headings for file names. \ Lines in the body max. 72 characters. \ -No preamble, no explanation, no code fences, no markdown headings, answer in English.\n\n\ +No preamble, no explanation, no code fences, answer in English.\n\n\ Example:\n\ Diff:\n\ diff --git a/src/auth.py b/src/auth.py\n\ +def hash_password(pw):\n\ -+ return bcrypt.hash(pw)\n\n\ ++ return bcrypt.hash(pw)\n\ +diff --git a/src/routes.py b/src/routes.py\n\ +-if password == stored_password:\n\ ++if bcrypt.check(password, stored_password):\n\n\ Commit message:\n\ -feat(auth): add password hashing helper\n\n\ -Add a bcrypt-based helper so passwords are never stored or compared in\n\ -plain text.\n\n\ -- auth.py: add hash_password() using bcrypt" +feat(auth): hash and verify passwords with bcrypt\n\n\ +Passwords were previously compared as plain text. This adds a bcrypt-based\n\ +hashing helper and updates the login check to verify against the hash\n\ +instead of a direct string comparison.\n\n\ +- Hash passwords on write, verify with bcrypt on login" .to_string(); let mut user = String::new(); diff --git a/src/App.svelte b/src/App.svelte index 44b93b9..5f6b11d 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -543,7 +543,7 @@ function defaultAiSettings(): AiSettings { return { - provider: "local", + provider: "openai", localModelId: "qwen2.5-0.5b", localProfile: "fast", openaiModel: "gpt-4o-mini", @@ -557,7 +557,11 @@ try { const stored = JSON.parse(localStorage.getItem(AI_SETTINGS_KEY) ?? "null") as unknown; if (stored && typeof stored === "object") { - return { ...defaultAiSettings(), ...(stored as Partial) }; + const merged = { ...defaultAiSettings(), ...(stored as Partial) }; + // Local AI is still in development and disabled in the settings UI — migrate any + // previously saved selection away from it so nobody gets stuck on a dead option. + if (merged.provider === "local") merged.provider = "openai"; + return merged; } } catch { // Fall through to defaults below. diff --git a/src/app.css b/src/app.css index 99b89e5..334ce75 100644 --- a/src/app.css +++ b/src/app.css @@ -1721,6 +1721,19 @@ color: #f5f7ff; background: linear-gradient(180deg, rgba(100,108,255,0.22), rgba(65,209,255,0.1)); } + .ai-provider-option-local { + flex-wrap: wrap; + row-gap: 2px; + } + .ai-provider-badge { + flex-basis: 100%; + text-align: center; + font-size: 9.5px; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + color: var(--color-ink-faint); + } .ai-local-profile-options { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); diff --git a/src/lib/components/AiSettingsDialog.svelte b/src/lib/components/AiSettingsDialog.svelte index d647239..b74efc2 100644 --- a/src/lib/components/AiSettingsDialog.svelte +++ b/src/lib/components/AiSettingsDialog.svelte @@ -141,9 +141,16 @@
{ e.preventDefault(); void handleSave(); }}>
- {/each}