desktop AI fix: a claude CLI without a sign-in ("Not logged in · Please run /login", seen in a real headless run) shows 'not signed in' with the copy-for-AI fallback instead of a bare failure; the flags were checked against a real claude run (it edited the file)
This commit is contained in:
parent
c95f2af8ff
commit
5ed787a8ca
4 changed files with 19 additions and 1 deletions
|
|
@ -453,6 +453,7 @@ export const en = {
|
|||
'ai.dirty': 'Uncommitted files in the app folder ({count}): commit or stash them first, so Undo can restore exactly what the AI changes.',
|
||||
'ai.noGit': 'The app folder is not in a git repository: Fix with AI needs git for the diff and Undo.',
|
||||
'ai.cancelled': 'Cancelled',
|
||||
'ai.signedOut': 'Claude Code is not signed in: run claude once in a terminal and sign in with /login, or copy the prompt for your AI agent',
|
||||
'ai.timedOut': 'Stopped after 10 minutes',
|
||||
'ai.noChanges': 'No files changed',
|
||||
'ai.changed': 'Changed files: {count}',
|
||||
|
|
|
|||
|
|
@ -455,6 +455,7 @@ export const tr: Record<keyof typeof en, string> = {
|
|||
'ai.dirty': 'Uygulama klasöründe commit edilmemiş {count} dosya var: önce commit et ya da stash yap ki Geri al tam olarak yapay zekânın değiştirdiğini geri yüklesin.',
|
||||
'ai.noGit': 'Uygulama klasörü bir git deposunda değil: Yapay zekâyla düzelt fark ve Geri al için git ister.',
|
||||
'ai.cancelled': 'İptal edildi',
|
||||
'ai.signedOut': 'Claude Code oturum açmamış: bir terminalde claude çalıştırıp /login ile giriş yapın ya da istemi yapay zekâ ajanınız için kopyalayın',
|
||||
'ai.timedOut': '10 dakika sonra durduruldu',
|
||||
'ai.noChanges': 'Hiçbir dosya değişmedi',
|
||||
'ai.changed': 'Değişen dosya: {count}',
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@ export function AiFix({ projectId, f, claude, busy, setBusy, rescan, stillThere,
|
|||
);
|
||||
else if (p.kind === 'done') {
|
||||
const o = p.run.outcome;
|
||||
const head = o.cancelled ? t('ai.cancelled') : o.timed_out ? t('ai.timedOut') : !p.run.changes.length ? t('ai.noChanges') : t('ai.changed', { count: p.run.changes.length });
|
||||
// a claude CLI that is not signed in answers at once ("Not logged in · Please run /login"): say so, offer the copy
|
||||
const signedOut = !p.run.changes.length && signedOutText(o.summary);
|
||||
const head = o.cancelled ? t('ai.cancelled') : o.timed_out ? t('ai.timedOut') : signedOut ? t('ai.signedOut') : !p.run.changes.length ? t('ai.noChanges') : t('ai.changed', { count: p.run.changes.length });
|
||||
panel = (
|
||||
<div className="ai-panel" role="status">
|
||||
<span className="li-sub">{head}{p.run.changes.length > 0 && !p.undone ? ` · ${stillThere ? t('ai.stillThere') : t('ai.gone')}` : ''}</span>
|
||||
|
|
@ -100,6 +102,7 @@ export function AiFix({ projectId, f, claude, busy, setBusy, rescan, stillThere,
|
|||
<div className="row">
|
||||
{p.run.changes.length > 0 && <button className="btn btn-sm btn-primary" onClick={() => setP({ kind: 'idle' })}><Icon name="check" />{t('ai.keep')}</button>}
|
||||
{p.run.changes.length > 0 && <button className="btn btn-sm" onClick={() => undo(p.run)}><Icon name="rotate" />{t('ai.undo')}</button>}
|
||||
{signedOut && <button className="btn btn-sm" onClick={copy}><Icon name="copy" />{t('ai.copy')}</button>}
|
||||
{!p.run.changes.length && <button className="btn btn-sm" onClick={() => setP({ kind: 'idle' })}>{t('common.close')}</button>}
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -113,3 +116,6 @@ export function AiFix({ projectId, f, claude, busy, setBusy, rescan, stillThere,
|
|||
);
|
||||
return <>{p.kind === 'idle' || p.kind === 'running' ? <div className="ai-actions">{button}</div> : null}{panel}</>;
|
||||
}
|
||||
|
||||
/** The claude CLI's answer when it has no sign-in (it exits at once, nothing changed). */
|
||||
export const signedOutText = (s: string): boolean => /not logged in|please run \/login|invalid api key|authentication/i.test(s);
|
||||
|
|
|
|||
10
apps/desktop/tests/ai-signed-out.test.ts
Normal file
10
apps/desktop/tests/ai-signed-out.test.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// The claude CLI without a sign-in exits at once with this result text (seen with a real run): the AI fix panel says
|
||||
// "not signed in" and offers the copy instead of a bare failure.
|
||||
import { expect, test } from 'bun:test';
|
||||
import { signedOutText } from '../src/ui/AiFix';
|
||||
|
||||
test('signed-out claude answers are recognised', () => {
|
||||
expect(signedOutText('Not logged in · Please run /login')).toBe(true);
|
||||
expect(signedOutText('Invalid API key · Fix external API key')).toBe(true);
|
||||
expect(signedOutText('Removed NSAllowsArbitraryLoads; no http URLs are loaded.')).toBe(false);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue