File size: 2,253 Bytes
275f68e
 
b89c27d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275f68e
 
 
b89c27d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { CodeBlock } from './CodeBlock.jsx'

const KIND_STYLES = {
  draft:        'text-accent border-accent',
  run_baseline: 'text-[#7ecfc5] border-[#5a9c94]',
  inspect:      'text-[#b5a5e0] border-[#7e6ea8]',
  commit:       'text-[#7ab68c] border-[#4e7c5c]',
}

export function TurnCard({ turn, kind, action_str, output, duration_s,
                           budget_remaining, code }) {
  const chipClass = KIND_STYLES[kind] || 'text-ink border-border'

  return (
    <div className="rounded-lg border border-border bg-surface p-4 shadow-card">
      <div className="flex items-center gap-3 pb-2.5 mb-2.5
                      border-b border-dashed border-border/60">
        <span className="font-serif font-semibold text-[0.98rem] tracking-tight">
          Turn {turn}
        </span>
        <span className={`chip ${chipClass}`}>{kind}</span>
        <span className="ml-auto font-mono text-xs text-subtle">
          {duration_s.toFixed(1)}s · budget <strong className="text-ink">{budget_remaining}</strong>
        </span>
      </div>

      <Row label="Action">{action_str}</Row>
      <Row label="Output">
        {output.length === 0 ? 'ok' : output.map((o, i) => (
          <StatusChip key={i} {...o} />
        ))}
      </Row>

      {code && (
        <div className="mt-3">
          <CodeBlock code={code.trim()} language="python" />
        </div>
      )}
    </div>
  )
}

function Row({ label, children }) {
  return (
    <div className="grid grid-cols-[70px_1fr] gap-3 items-baseline py-1">
      <div className="text-[0.68rem] font-semibold uppercase tracking-[0.1em]
                      text-subtle pt-0.5">{label}</div>
      <div className="text-[0.9rem] leading-[1.55] flex flex-wrap gap-2 items-center">
        {children}
      </div>
    </div>
  )
}

function StatusChip({ kind, text }) {
  const cls = {
    good: 'text-good border-good/40 bg-good/10',
    warn: 'text-warn border-warn/40 bg-warn/10',
    bad:  'text-bad  border-bad/40  bg-bad/10',
    info: 'text-ink  border-border  bg-transparent',
  }[kind] || 'text-ink border-border'
  return (
    <span className={`inline-block px-1.5 py-0.5 rounded border text-xs font-medium ${cls}`}
          dangerouslySetInnerHTML={{ __html: text }} />
  )
}