mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 18:18:43 +00:00
feat(kiro): add UI toggle and auth hint for --no-incognito option
- Add "Kiro: Use normal browser" toggle in config dashboard (Proxy section) - Add --no-incognito documentation to ccs --help output - Show hint after successful Kiro auth about saving AWS credentials
This commit is contained in:
@@ -202,7 +202,7 @@ export async function triggerOAuth(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute OAuth process
|
// Execute OAuth process
|
||||||
return executeOAuthProcess({
|
const account = await executeOAuthProcess({
|
||||||
provider,
|
provider,
|
||||||
binaryPath,
|
binaryPath,
|
||||||
args,
|
args,
|
||||||
@@ -214,6 +214,16 @@ export async function triggerOAuth(
|
|||||||
isCLI,
|
isCLI,
|
||||||
nickname,
|
nickname,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show hint for Kiro users about --no-incognito option (first-time auth only)
|
||||||
|
if (account && provider === 'kiro' && !noIncognito) {
|
||||||
|
console.log('');
|
||||||
|
console.log(info('Tip: To save your AWS login credentials for future sessions:'));
|
||||||
|
console.log(' Use: ccs kiro --no-incognito');
|
||||||
|
console.log(' Or enable "Kiro: Use normal browser" in: ccs config');
|
||||||
|
}
|
||||||
|
|
||||||
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ Run ${color('ccs config', 'command')} for web dashboard`.trim();
|
|||||||
['ccs <provider> --config', 'Change model (agy, gemini)'],
|
['ccs <provider> --config', 'Change model (agy, gemini)'],
|
||||||
['ccs <provider> --logout', 'Clear authentication'],
|
['ccs <provider> --logout', 'Clear authentication'],
|
||||||
['ccs <provider> --headless', 'Headless auth (for SSH)'],
|
['ccs <provider> --headless', 'Headless auth (for SSH)'],
|
||||||
|
['ccs kiro --no-incognito', 'Use normal browser (saves AWS login)'],
|
||||||
['ccs codex "explain code"', 'Use with prompt'],
|
['ccs codex "explain code"', 'Use with prompt'],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Settings section for CLIProxyAPI configuration (local/remote)
|
* Settings section for CLIProxyAPI configuration (local/remote)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Alert, AlertDescription } from '@/components/ui/alert';
|
import { Alert, AlertDescription } from '@/components/ui/alert';
|
||||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||||
@@ -12,6 +12,7 @@ import { RefreshCw, CheckCircle2, AlertCircle, Laptop, Cloud } from 'lucide-reac
|
|||||||
import { useProxyConfig, useRawConfig } from '../../hooks';
|
import { useProxyConfig, useRawConfig } from '../../hooks';
|
||||||
import { LocalProxyCard } from './local-proxy-card';
|
import { LocalProxyCard } from './local-proxy-card';
|
||||||
import { RemoteProxyCard } from './remote-proxy-card';
|
import { RemoteProxyCard } from './remote-proxy-card';
|
||||||
|
import { api } from '@/lib/api-client';
|
||||||
|
|
||||||
export default function ProxySection() {
|
export default function ProxySection() {
|
||||||
const {
|
const {
|
||||||
@@ -37,11 +38,54 @@ export default function ProxySection() {
|
|||||||
|
|
||||||
const { fetchRawConfig } = useRawConfig();
|
const { fetchRawConfig } = useRawConfig();
|
||||||
|
|
||||||
|
// Kiro provider settings state
|
||||||
|
const [kiroNoIncognito, setKiroNoIncognito] = useState(false);
|
||||||
|
const [kiroSettingsLoading, setKiroSettingsLoading] = useState(true);
|
||||||
|
const [kiroSaving, setKiroSaving] = useState(false);
|
||||||
|
|
||||||
|
// Fetch Kiro settings from unified config
|
||||||
|
const fetchKiroSettings = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
setKiroSettingsLoading(true);
|
||||||
|
const unifiedConfig = await api.config.get();
|
||||||
|
const cliproxyConfig = unifiedConfig.cliproxy as { kiro_no_incognito?: boolean } | undefined;
|
||||||
|
setKiroNoIncognito(cliproxyConfig?.kiro_no_incognito ?? false);
|
||||||
|
} catch {
|
||||||
|
// Config may not exist yet, use default
|
||||||
|
setKiroNoIncognito(false);
|
||||||
|
} finally {
|
||||||
|
setKiroSettingsLoading(false);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Save Kiro no-incognito setting
|
||||||
|
const saveKiroNoIncognito = useCallback(async (enabled: boolean) => {
|
||||||
|
setKiroNoIncognito(enabled); // Optimistic update
|
||||||
|
setKiroSaving(true);
|
||||||
|
try {
|
||||||
|
const unifiedConfig = await api.config.get();
|
||||||
|
const existingCliproxy = (unifiedConfig.cliproxy ?? {}) as Record<string, unknown>;
|
||||||
|
await api.config.update({
|
||||||
|
...unifiedConfig,
|
||||||
|
cliproxy: {
|
||||||
|
...existingCliproxy,
|
||||||
|
kiro_no_incognito: enabled,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// Revert on error
|
||||||
|
setKiroNoIncognito(!enabled);
|
||||||
|
} finally {
|
||||||
|
setKiroSaving(false);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Load data on mount
|
// Load data on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchConfig();
|
fetchConfig();
|
||||||
fetchRawConfig();
|
fetchRawConfig();
|
||||||
}, [fetchConfig, fetchRawConfig]);
|
fetchKiroSettings();
|
||||||
|
}, [fetchConfig, fetchRawConfig, fetchKiroSettings]);
|
||||||
|
|
||||||
if (loading || !config) {
|
if (loading || !config) {
|
||||||
return (
|
return (
|
||||||
@@ -265,6 +309,27 @@ export default function ProxySection() {
|
|||||||
onSaveConfig={saveConfig}
|
onSaveConfig={saveConfig}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Provider Settings */}
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-base font-medium">Provider Settings</h3>
|
||||||
|
<div className="space-y-3 p-4 rounded-lg border bg-muted/30">
|
||||||
|
{/* Kiro: Use normal browser */}
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="font-medium text-sm">Kiro: Use normal browser</p>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
Save AWS login credentials (disable incognito mode)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Switch
|
||||||
|
checked={kiroNoIncognito}
|
||||||
|
onCheckedChange={saveKiroNoIncognito}
|
||||||
|
disabled={kiroSaving || kiroSettingsLoading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|
||||||
@@ -276,6 +341,7 @@ export default function ProxySection() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
fetchConfig();
|
fetchConfig();
|
||||||
fetchRawConfig();
|
fetchRawConfig();
|
||||||
|
fetchKiroSettings();
|
||||||
}}
|
}}
|
||||||
disabled={loading || saving}
|
disabled={loading || saving}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
|||||||
Reference in New Issue
Block a user