Checks: findings with a skill get Open guide (context menu and a link on the card) to the shipped skills/<name>/SKILL.md; known-skill list kept equal to skills/ by a test
This commit is contained in:
parent
4a74989a95
commit
a656240bfb
7 changed files with 53 additions and 1 deletions
|
|
@ -2045,6 +2045,8 @@ export const en = {
|
|||
'acct.noDevId': 'no Play developer id',
|
||||
'acct.devIdLabel': 'Play developer account id',
|
||||
'acct.devIdHint': "The digits in play.google.com/console/u/0/developers/<id>. With it, Play Console links open each app's own page; the CLI uses it too.",
|
||||
'checks.openGuide': 'Open guide',
|
||||
'checks.openGuideHint': 'Open the {skill} guide (SKILL.md)',
|
||||
'cm.more': "More actions",
|
||||
'cm.showIgnored': "Show ignored apps",
|
||||
'cm.copyVersion': "Copy version",
|
||||
|
|
|
|||
|
|
@ -2047,6 +2047,8 @@ export const tr: Record<keyof typeof en, string> = {
|
|||
'acct.noDevId': 'Play geliştirici kimliği yok',
|
||||
'acct.devIdLabel': 'Play geliştirici hesabı kimliği',
|
||||
'acct.devIdHint': 'play.google.com/console/u/0/developers/<id> içindeki rakamlar. Girilince Play Console bağlantıları her uygulamanın kendi sayfasını açar; CLI de kullanır.',
|
||||
'checks.openGuide': 'Kılavuzu aç',
|
||||
'checks.openGuideHint': '{skill} kılavuzunu aç (SKILL.md)',
|
||||
'cm.more': "Diğer işlemler",
|
||||
'cm.showIgnored': "Yok sayılanları göster",
|
||||
'cm.copyVersion': "Sürümü kopyala",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { OpenLink } from '../../ui/OpenLink';
|
|||
import { Bar, ErrorNotice, ReadControl, Skeleton } from '../../ui/kit';
|
||||
import { EmptyState, Section, StatusPill } from '../../ui/ds';
|
||||
import '../../styles/checks.css';
|
||||
import { skillGuideUrl } from '../../../../../cli/lib/skill-guide';
|
||||
import { exportName, validateMd } from '../../lib/exports';
|
||||
import { useExports } from '../../ui/Exports';
|
||||
|
||||
|
|
@ -90,11 +91,13 @@ function ScanCard({ project }: { project: Project }) {
|
|||
const card = ({ f, k }: { f: ScanFinding; k: string }) => {
|
||||
const [tone, icon] = f.accepted ? ['ok', 'check'] as const : SEV[f.severity] ?? SEV.low;
|
||||
const ev = Array.isArray(f.evidence) ? f.evidence : [];
|
||||
const guide = skillGuideUrl(f.skill);
|
||||
return (
|
||||
<CheckCard key={k} tone={tone} icon={icon} title={<><span className="ck-gl">{f.guideline}</span>{f.title}</>}
|
||||
menu={() => [
|
||||
!f.accepted && fixable(f.action) && fixItem(w, f.action, f.title),
|
||||
!f.accepted && f.url && /^https:\/\//.test(f.url) && { label: t('link.open'), icon: 'external', onSelect: () => openUrl(d, f.url!) },
|
||||
guide && { label: t('checks.openGuide'), icon: 'sparkle', shortcut: f.skill, onSelect: () => openUrl(d, guide) },
|
||||
ev[0] && { label: t('cm.revealEvidence'), icon: 'folder', shortcut: `${ev[0].file.split('/').pop()}:${ev[0].line}`, onSelect: () => { api.reveal(project.id, ev[0]!.file).catch(() => {}); } },
|
||||
'sep',
|
||||
{ label: t('cm.copy'), icon: 'copy', submenu: [
|
||||
|
|
@ -108,7 +111,7 @@ function ScanCard({ project }: { project: Project }) {
|
|||
actions={<>{!f.accepted && <OpenLink url={f.url} />}{!f.accepted && fixable(f.action) && <FixButton action={f.action} what={f.title} w={w} />}</>}>
|
||||
{ev.slice(0, 2).map((e, j) => <span className="ck-sub selectable" key={j}><code>{e.file}:{e.line}</code>{e.text ? ` ${e.text}` : ''}</span>)}
|
||||
{f.accepted ? <span className="ck-sub">{t('checks.accepted', { reason: f.accepted })}</span>
|
||||
: <span className="ck-fix"><Icon name="wand" /><span className="selectable">{f.fix} <code>{f.skill}</code></span></span>}
|
||||
: <span className="ck-fix"><Icon name="wand" /><span className="selectable">{f.fix} {guide ? <button type="button" className="ck-guide" onClick={() => openUrl(d, guide)} title={t('checks.openGuideHint', { skill: f.skill })}><code>{f.skill}</code><Icon name="external" /></button> : f.skill && <code>{f.skill}</code>}</span></span>}
|
||||
{!f.accepted && f.aiFix && !fixable(f.action) && <div className="ck-ai"><AiFix projectId={project.id} f={f} claude={claude} busy={aiBusy} setBusy={setAiBusy} rescan={() => { s.refresh(); }}
|
||||
stillThere={findings.some(x => same(x, f))} onActive={on => setAiActive(on ? f : null)} /></div>}
|
||||
</CheckCard>
|
||||
|
|
|
|||
|
|
@ -74,3 +74,7 @@
|
|||
.scr-checks .ck-report { display: flex; align-items: center; gap: 16px; padding: 14px 18px; border-radius: var(--ds-r-lg); background: var(--ds-surface); border: 1px solid var(--ds-stroke); }
|
||||
.scr-checks .ck-report-t { display: grid; gap: 2px; flex: 1; min-width: 0; font-size: var(--ds-t-meta); color: var(--muted); }
|
||||
.scr-checks .ck-report-t b { color: var(--ink); font-size: var(--ds-t-body); }
|
||||
.scr-checks .ck-guide { all: unset; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; border-radius: var(--ds-r-xs); }
|
||||
.scr-checks .ck-guide:hover code { text-decoration: underline; }
|
||||
.scr-checks .ck-guide:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
|
||||
.scr-checks .ck-guide svg { width: 12px; height: 12px; margin: 0; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue