feat(aiturk): one-click sign-in for AITURK IDE (1.0.0-beta.14)

The onboarding and provider settings get a Sign in button: the IDE shows a
short code, opens the turkservis.online approval page, and after approval
saves the TurkServis provider itself and hands a separate member key to the
AITURK CLI over stdin (aiturk login --key-stdin --keep-other-account).
Keys never reach the renderer, logs, process arguments or URLs. Pasting an
API key remains as the fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B8ppceaR5s6cvMnm7uGRnf
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-03 15:13:23 +03:00
1 parent fe0a45a84f
commit 25d8c18c10
13 files changed
+1938 -15

No files matched your search

@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { AiturkLogin } from '@/components/aiturk-login'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Input } from '@/components/ui/input'
@@ -80,7 +81,10 @@ function toPayload(form: EndpointForm, models?: string[]): CustomEndpointUpdate
export function CustomEndpointsSettings({ onConfigSaved, onMainModelChanged }: CustomEndpointsSettingsProps) {
const { t } = useI18n()
const c = useAiturkCopy().custom
const aiturkCopy = useAiturkCopy()
const c = aiturkCopy.custom
const loginCopy = aiturkCopy.login
const loginLabel = loginCopy.settingsSignIn
const [loading, setLoading] = useState(true)
const [saving, setSaving] = useState(false)
const [testing, setTesting] = useState(false)
@@ -129,6 +133,31 @@ export function CustomEndpointsSettings({ onConfigSaved, onMainModelChanged }: C
}
}, [])
// One-click sign-in saved the TurkServis provider in the main process:
// reload the list and tell the app its default model changed.
async function handleAiturkConnected() {
try {
const data = await getCustomEndpoints()
setEndpoints(data.endpoints)
const current = data.endpoints.find(endpoint => endpoint.id === 'turkservis')
if (current) {
setForm(formFromEndpoint(current))
setDiscoveredModels(current.models)
if (current.is_current) {
onMainModelChanged?.(current.id, current.model)
}
}
triggerHaptic('success')
onConfigSaved?.()
notify({ kind: 'success', message: loginCopy.connected })
} catch (err) {
notifyError(err, c.loadFailed)
}
}
async function handleSave() {
try {
setSaving(true)
@@ -298,10 +327,13 @@ export function CustomEndpointsSettings({ onConfigSaved, onMainModelChanged }: C
</section>
<section>
<Button className="mb-3" onClick={() => {
setForm({ ...EMPTY_FORM, name: 'TurkServis · AITURK', baseUrl: AITURK_API_BASE_URL })
setDiscoveredModels([])
}} variant="outline">{c.preset}</Button>
<div className="mb-3 flex flex-wrap items-start gap-2">
<AiturkLogin label={loginLabel} onConnected={handleAiturkConnected} />
<Button onClick={() => {
setForm({ ...EMPTY_FORM, name: 'TurkServis · AITURK', baseUrl: AITURK_API_BASE_URL })
setDiscoveredModels([])
}} variant="outline">{c.preset}</Button>
</div>
<SectionHeading icon={Plus} title={form.id ? c.edit : c.add} />
<div className="grid gap-3 rounded-md border border-border/50 p-3">
<div className="grid gap-3 sm:grid-cols-2">