// dev-agent-workspace.jsx
// §05 Develop · Agent + IDE workspace (the "hero" Develop view)
// JetBrains Air–style task / agent / editor co-existence, but with Ghast's
// mono+Liquid-Glass tone, no green highlights, no IDE chrome theatrics.

// ────────── shared data ──────────

const DAW_TASKS = [
  { id: 't-canvas-png',   label: '完成 画布导出 PNG 功能',                      done: true,  plus: 445, minus: 9,  age: 'Today' },
  { id: 't-settings',     label: '打开设置窗口，窗口位置要在原来窗口右侧',     done: true,  plus: 445, minus: 9,  age: 'Today' },
  { id: 't-canvas-drag',  label: 'canvas 里 node 拖动碰撞检测有问题',          done: true,  plus: 75,  minus: 8,  age: 'Today' },
  { id: 't-canvas-mode',  label: 'canvas 模式下，Note Library 从右侧弹出',      done: true,  plus: 45,  minus: 0,  age: 'Today', active: true },
  { id: 't-export-md',    label: 'Markdown export · 包含 frontmatter',          done: false, plus: 0,   minus: 0,  age: 'Pending' },
  { id: 't-tests-vitest', label: 'vitest watch · re-run on save flake',         done: false, plus: 0,   minus: 0,  age: 'Pending' },
];

const DAW_AGENT_STREAM = [
  { kind: 'summary',   text: '定位完成: 右侧弹出和新建逻辑都在 DetachedNotesSidebar; 标题栏高度适配需要从根标题栏暴露 CSS 变量。' },
  { kind: 'processed', text: 'Results Retrieved' },
  { kind: 'summary',   text: '交互和位置已经改完；现在补测试覆盖"剩余关闭按钮"和标题栏高度变量。' },
  { kind: 'processed', text: 'Processed' },
  { kind: 'summary',   text: '测试已补；我先跑受影响的组件和路由测试，确认没有回归。' },
  { kind: 'processed', text: 'Processed' },
  { kind: 'summary',   text: '受影响测试通过。按项目要求再跑全量单测，确保整体行为稳定。' },
  { kind: 'processed', text: 'Processed' },
  { kind: 'summary',   text: '全量单测也通过；最后跑类型检查，避免 TS 细节漏掉。' },
  { kind: 'processed', text: 'Processed' },
  { kind: 'summary',   text: '类型检查卡在 node_modules/electrobun 的既有声明问题；我再跑项目 lint/check 看本次改动是否干净。' },
  { kind: 'processed', text: 'Processed' },
  { kind: 'summary',   text: '项目级 check 也被既有 .agents 文件拦住；我对本次改动文件单独跑一次格式/规则检查。' },
  { kind: 'processed', text: 'Processed' },
  { kind: 'summary',   text: '本次改动文件单独 check 通过。最后看下 diff，确认没有多余变更。' },
  { kind: 'processed', text: 'Processed' },
];

const DAW_PLAN = [
  { label: '定位 Note Library 组件', done: true },
  { label: '调整画布模式交互',         done: true },
  { label: '适配标题栏高度',            done: true },
  { label: '补充或更新测试',            done: true },
  { label: '运行针对性验证',            done: true },
];

const DAW_FILES = [
  { name: 'dist',           kind: 'dir',  level: 0 },
  { name: 'docs',           kind: 'dir',  level: 0 },
  { name: 'icon.iconset',   kind: 'dir',  level: 0 },
  { name: 'messages',       kind: 'dir',  level: 0 },
  { name: 'node_modules',   kind: 'dir',  level: 0 },
  { name: 'project.inlang', kind: 'dir',  level: 0 },
  { name: 'src',            kind: 'dir',  level: 0, open: true },
  { name: 'bun',            kind: 'dir',  level: 1 },
  { name: 'mainview',       kind: 'dir',  level: 1, open: true },
  { name: 'components',     kind: 'dir',  level: 2 },
  { name: 'data',           kind: 'dir',  level: 2 },
  { name: 'hooks',          kind: 'dir',  level: 2, open: true },
  { name: 'useCanvasKeyboard.test.tsx', kind: 'tsx', level: 3, dirty: false },
  { name: 'useCanvasKeyboard.ts',       kind: 'ts',  level: 3 },
  { name: 'useCanvasPersistence.test.tsx', kind: 'tsx', level: 3 },
  { name: 'useCanvasPersistence.ts',    kind: 'ts',  level: 3 },
  { name: 'useContextMenu.test.tsx',    kind: 'tsx', level: 3 },
  { name: 'useContextMenu.ts',          kind: 'ts',  level: 3 },
  { name: 'useDocumentKeyboard.ts',     kind: 'ts',  level: 3 },
  { name: 'useHelperLines.test.tsx',    kind: 'tsx', level: 3 },
  { name: 'useHelperLines.ts',          kind: 'ts',  level: 3 },
  { name: 'useNodeCreation.test.tsx',   kind: 'tsx', level: 3 },
  { name: 'useNodeCreation.ts',         kind: 'ts',  level: 3 },
  { name: 'useNodeDrag.test.tsx',       kind: 'tsx', level: 3, dirty: true },
  { name: 'useNodeDrag.ts',             kind: 'ts',  level: 3, dirty: true },
  { name: 'useNoteSaver.test.tsx',      kind: 'tsx', level: 3 },
  { name: 'useNoteSaver.ts',            kind: 'ts',  level: 3 },
  { name: 'useSearch.ts',               kind: 'ts',  level: 3 },
  { name: 'lib',            kind: 'dir',  level: 2 },
  { name: 'routes',         kind: 'dir',  level: 2 },
  { name: 'store',          kind: 'dir',  level: 2 },
  { name: 'index.css',      kind: 'css',  level: 2 },
  { name: 'index.html',     kind: 'html', level: 2 },
  { name: 'main.tsx',       kind: 'tsx',  level: 2 },
  { name: 'router.test.tsx',kind: 'tsx',  level: 2 },
  { name: 'router.tsx',     kind: 'tsx',  level: 2, active: true },
];

const DAW_EDITOR_TABS = [
  { name: 'useNodeDrag.ts',     dirty: true },
  { name: 'useNodeCreation.ts', dirty: false },
  { name: 'router.tsx',         dirty: false, active: true },
  { name: 'router.test.tsx',    dirty: false },
];

// router.tsx — annotated lines so we can render line numbers + token spans
// without a real syntax highlighter
const DAW_CODE_LINES = [
  { n: 1,  s: [['kw','import'],[' { '],['id','QueryClientProvider'],[' } '],['kw','from'],[' '],['str',"'@tanstack/react-query'"],[';']] },
  { n: 2,  s: [['kw','import'],[' {']] },
  { n: 3,  s: [['  '],['id','createHashHistory'],[',']] },
  { n: 4,  s: [['  '],['id','createRouter'],[' '],['kw','as'],[' '],['id','createTanStackRouter'],[',']] },
  { n: 5,  s: [['} '],['kw','from'],[' '],['str',"'@tanstack/react-router'"],[';']] },
  { n: 6,  s: [] },
  { n: 7,  s: [['kw','import'],[' { '],['id','ErrorBoundaryFallback'],[' } '],['kw','from'],[' '],['str',"'@/components/layout/ErrorBoundaryFallback'"],[';']] },
  { n: 8,  s: [['kw','import'],[' { '],['id','Loader'],[' } '],['kw','from'],[' '],['str',"'@/components/layout/Loader'"],[';']] },
  { n: 9,  s: [['kw','import'],[' { '],['id','queryClient'],[' } '],['kw','from'],[' '],['str',"'@/lib/queryClient'"],[';']] },
  { n: 10, s: [] },
  { n: 11, s: [['kw','import'],[' '],['id','routeTree'],[' '],['kw','from'],[' '],['str',"'./routeTree.gen'"],[';']] },
  { n: 12, s: [] },
  { n: 13, s: [['kw','const'],[' '],['id','isHttpProtocol'],[' = ['],['str',"'http:'"],[', '],['str',"'https:'"],[']'],['.'],['fn','includes'],['(']] },
  { n: 14, s: [['  '],['id','globalThis'],['.'],['id','location'],['.'],['id','protocol'],[',']] },
  { n: 15, s: [[');']] },
  { n: 16, s: [] },
  { n: 17, s: [['kw','export'],[' '],['kw','const'],[' '],['id','router'],[' = '],['fn','createTanStackRouter'],['('],['id','options'],[': {']] },
  { n: 18, s: [['  '],['id','routeTree'],[',']] },
  { n: 19, s: [['  '],['id','history'],[': '],['id','isHttpProtocol'],[' ? '],['kw','undefined'],[' : '],['fn','createHashHistory'],['(),']] },
  { n: 20, s: [['  '],['id','scrollRestoration'],[': '],['kw','true'],[',']] },
  { n: 21, s: [['  '],['id','defaultPreloadStaleTime'],[': '],['num','0'],[',']] },
  { n: 22, s: [['  '],['id','context'],[': { '],['id','queryClient'],[' },']] },
  { n: 23, s: [['  '],['id','defaultPendingComponent'],[': () : '],['id','Element'],[' => <'],['tag','Loader'],[' />,']] },
  { n: 24, s: [['  '],['id','defaultErrorComponent'],[': '],['id','ErrorBoundaryFallback'],[',']] },
  { n: 25, s: [['  '],['id','defaultNotFoundComponent'],[': () : '],['id','Element'],[' => <'],['tag','div'],['>Not Found</'],['tag','div'],['>,']] },
  { n: 26, s: [['  '],['id','Wrap'],[': ({ '],['id','children'],[' }: { '],['id','children'],[': '],['id','any'],[' }) : '],['id','Element'],[' => (']] },
  { n: 27, s: [['    <'],['tag','QueryClientProvider'],[' '],['attr','client'],['={'],['id','queryClient'],['}>{'],['id','children'],['}</'],['tag','QueryClientProvider'],['>']] },
  { n: 28, s: [['  ),']] },
  { n: 29, s: [['});']], cursor: true },
  { n: 30, s: [] },
];

const DAW_TERMINAL_LINES = [
  { kind: 'cmd',     text: '/exit' },
  { kind: 'comment', text: 'Exit the CLI' },
  { kind: 'cmd',     text: '/context' },
  { kind: 'comment', text: 'Visualize current context usage as a colored grid' },
  { kind: 'cmd',     text: '/impeccable' },
  { kind: 'comment', text: 'Create distinctive, production-grade frontend interfaces with high design quality. Generates' },
  { kind: 'comment', text: 'creative, polished code that avoids generic AI aesthetics. Use when the user asks to build web' },
  { kind: 'comment', text: 'components, pages, artifacts, posters.' },
  { kind: 'cmd',     text: '/distill' },
  { kind: 'comment', text: 'Strip designs to their essence by removing unnecessary complexity. Great design is simple,' },
  { kind: 'comment', text: 'powerful, and clean. Use when the user asks to simplify, declutter, reduce noise, remove elements,' },
  { kind: 'comment', text: 'or make a UI cleaner and more focused.' },
  { kind: 'spacer' },
  { kind: 'banner',  ts: '33s', tag: 'claude' },
  { kind: 'gitstatus', repo: 'electrobun-starter-tanstack', branch: 'main', mods: 4, untrack: 15, summary: 'pkg ★ 1.0  node ◆ 24.15.0  14:32' },
  { kind: 'spacer' },
  { kind: 'prompt',  text: 'try "fix lint errors"' },
  { kind: 'hint',    text: '? for shortcuts' },
];

// ────────── leaf renderers ──────────

function DawTaskList({ t, dark, tasks = DAW_TASKS, activeId = 't-canvas-mode', compact = false }) {
  return (
    <div style={{
      width: compact ? 220 : 250, flexShrink: 0,
      borderRight: `0.5px solid ${t.border}`,
      display: 'flex', flexDirection: 'column',
      paddingTop: 36,
      background: t.bg,
    }}>
      <div style={{ padding: '10px 12px', display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{
          height: 28, padding: '0 10px', flex: 1,
          display: 'flex', alignItems: 'center', gap: 8,
          background: t.surface, border: `1px solid ${t.border}`, borderRadius: 8,
          fontSize: 12, color: t.fg3,
        }}>
          <Icon name="search" size={11} />
          <span>Search tasks</span>
          <span style={{ flex: 1 }} />
          <span style={{ fontSize: 10, fontFamily: G.mono }}>⌥T</span>
        </div>
      </div>
      <div style={{ padding: '4px 12px 12px' }}>
        <Button variant="ghost" size="sm" full icon={<Icon name="plus" size={11} />} style={{ justifyContent: 'flex-start' }}>
          New Task
        </Button>
      </div>

      <div className="gh-scroll" style={{ flex: 1, overflow: 'auto', padding: '4px 8px 12px' }}>
        <div style={{ fontSize: 10, fontWeight: 600, color: t.fg3, letterSpacing: 0.6, padding: '6px 6px 4px', textTransform: 'uppercase' }}>Today</div>
        {tasks.map((task) => {
          const active = task.id === activeId;
          return (
            <div key={task.id} style={{
              padding: '8px 10px', borderRadius: 8, marginBottom: 2, cursor: 'pointer',
              background: active ? t.surface2 : 'transparent',
              border: active ? `1px solid ${t.border}` : '1px solid transparent',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: task.done ? 4 : 0 }}>
                {task.done
                  ? <span style={{
                      width: 13, height: 13, borderRadius: 7,
                      background: t.fg, color: t.bg,
                      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                    }}><Icon name="check" size={9} /></span>
                  : <span style={{ width: 13, height: 13, borderRadius: 7, border: `1.5px solid ${t.fg3}`, flexShrink: 0 }} />}
                <span style={{ fontSize: 12.5, color: active ? t.fg : t.fg2, lineHeight: 1.35, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{task.label}</span>
              </div>
              {task.done && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, paddingLeft: 21, fontSize: 10.5, fontFamily: G.mono, color: t.fg3 }}>
                  <span>Done</span>
                  <span style={{ color: t.fg2 }}>+{task.plus}</span>
                  <span>−{task.minus}</span>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function DawAgentStream({ t, stream = DAW_AGENT_STREAM, plan = DAW_PLAN, planLabel = '5/5', showScrollHint = true }) {
  return (
    <div className="gh-scroll" style={{ flex: 1, overflow: 'auto', padding: '24px 28px 12px' }}>
      {stream.map((node, i) => (
        node.kind === 'summary' ? (
          <div key={i} style={{ fontSize: 13, lineHeight: 1.65, color: t.fg, marginBottom: 12 }}>{node.text}</div>
        ) : (
          <div key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, marginBottom: 16, fontSize: 11.5, color: t.fg3 }}>
            <span style={{
              width: 13, height: 13, borderRadius: 7,
              background: t.fg, color: t.bg,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            }}><Icon name="check" size={8} /></span>
            <span>{node.text}</span>
          </div>
        )
      ))}

      {showScrollHint && (
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 6, padding: '4px 0 14px', fontSize: 11, color: t.fg3 }}>
          <Icon name="chevron-down" size={11} />
          Scroll to bottom
        </div>
      )}

      {plan && (
        <div style={{
          marginTop: 4, padding: 14,
          border: `1px solid ${t.border}`, borderRadius: 12, background: t.surface,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
            <span style={{ fontSize: 10, fontWeight: 600, letterSpacing: 0.6, color: t.fg3, textTransform: 'uppercase' }}>Plan</span>
            <span style={{ fontFamily: G.mono, fontSize: 11, color: t.fg2 }}>{planLabel}</span>
          </div>
          {plan.map((p, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 0', fontSize: 13 }}>
              {p.done
                ? <span style={{
                    width: 14, height: 14, borderRadius: 7,
                    background: t.fg, color: t.bg,
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                  }}><Icon name="check" size={9} /></span>
                : <span style={{ width: 14, height: 14, borderRadius: 7, border: `1.5px solid ${t.fg3}`, flexShrink: 0 }} />}
              <span style={{ color: p.done ? t.fg : t.fg2 }}>{p.label}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}


function DawFileTree({ t, files = DAW_FILES, width = 240 }) {
  const iconForKind = (k) => ({
    dir: 'folder', tsx: 'code', ts: 'code', css: 'file', html: 'file', js: 'code',
  }[k] || 'file');
  return (
    <div style={{
      width, flexShrink: 0,
      borderLeft: `0.5px solid ${t.border}`,
      display: 'flex', flexDirection: 'column',
      paddingTop: 0,
      background: t.bg,
    }}>
      <div style={{ padding: '14px 14px 8px', display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ fontSize: 12, fontWeight: 600 }}>Files</div>
        <span style={{ flex: 1 }} />
        <Icon name="search" size={12} color={t.fg3} />
      </div>
      <div className="gh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 8px 12px' }}>
        {files.map((f, i) => {
          const Indent = f.level * 12;
          return (
            <div key={i} style={{
              display: 'flex', alignItems: 'center', gap: 6,
              padding: '4px 8px',
              paddingLeft: 8 + Indent,
              borderRadius: 6,
              background: f.active ? t.surface2 : 'transparent',
              fontSize: 12.5, color: f.active ? t.fg : t.fg2,
              cursor: 'pointer',
            }}>
              {f.kind === 'dir' ? (
                <Icon name={f.open ? 'chevron-down' : 'chevron-right'} size={10} color={t.fg3} />
              ) : (
                <span style={{ width: 10 }} />
              )}
              <Icon name={iconForKind(f.kind)} size={12} color={t.fg3} />
              <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.name}</span>
              {f.dirty && <span style={{ width: 6, height: 6, borderRadius: 3, background: t.fg2 }} />}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function DawEditor({ t, dark, tabs = DAW_EDITOR_TABS, lines = DAW_CODE_LINES, height }) {
  const tokenColor = (k) => {
    const map = dark
      ? { kw: '#c792ea', str: '#c3e88d', num: '#f78c6c', fn: '#82aaff', id: '#eeffff', tag: '#f07178', attr: '#ffcb6b' }
      : { kw: '#7c3aed', str: '#0e7c39', num: '#b91c1c', fn: '#1d4ed8', id: t.fg, tag: '#b91c1c', attr: '#a16207' };
    return map[k] || t.fg2;
  };
  return (
    <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', background: t.bg, height }}>
      {/* Tab bar */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 0, height: 36, borderBottom: `1px solid ${t.border}`, padding: '0 8px', overflow: 'hidden' }}>
        {tabs.map((tab, i) => {
          const active = tab.active;
          return (
            <div key={i} style={{
              display: 'flex', alignItems: 'center', gap: 8,
              height: '100%', padding: '0 12px',
              borderRight: `1px solid ${t.border2 || t.border}`,
              background: active ? t.surface : 'transparent',
              borderBottom: active ? `2px solid ${t.fg}` : '2px solid transparent',
              cursor: 'pointer', minWidth: 0,
            }}>
              <Icon name={tab.name.endsWith('.tsx') || tab.name.endsWith('.ts') ? 'code' : 'file'} size={12} color={t.fg3} />
              <span style={{ fontSize: 12, color: active ? t.fg : t.fg2, fontFamily: G.mono, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{tab.name}</span>
              {tab.dirty && <span style={{ width: 6, height: 6, borderRadius: 3, background: t.fg2 }} />}
              <Icon name="close" size={11} color={t.fg3} />
            </div>
          );
        })}
        <span style={{ flex: 1 }} />
        <Icon name="check" size={12} color={t.fg2} style={{ marginRight: 8 }} />
      </div>
      {/* Code area */}
      <div className="gh-scroll" style={{ flex: 1, overflow: 'auto', padding: '12px 0 16px' }}>
        {lines.map((l) => (
          <div key={l.n} style={{
            display: 'flex',
            background: l.cursor ? t.surface2 : 'transparent',
            paddingLeft: 8,
          }}>
            <span style={{
              width: 36, textAlign: 'right', paddingRight: 12,
              fontFamily: G.mono, fontSize: 11, color: l.cursor ? t.fg2 : t.fg3,
              userSelect: 'none', flexShrink: 0,
            }}>{l.n}</span>
            <span style={{ fontFamily: G.mono, fontSize: 12.5, lineHeight: 1.7, whiteSpace: 'pre' }}>
              {l.s.length === 0 ? ' ' : l.s.map((tok, i) => {
                const text = Array.isArray(tok) ? (tok.length === 2 ? tok[1] : tok[0]) : '';
                const kind = Array.isArray(tok) && tok.length === 2 ? tok[0] : null;
                return (
                  <span key={i} style={{ color: kind ? tokenColor(kind) : t.fg }}>{text}</span>
                );
              })}
              {l.cursor && <span style={{ display: 'inline-block', width: 1, height: 14, background: t.fg, marginLeft: 1, verticalAlign: 'middle', animation: 'gh-blink 1s infinite' }} />}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
}

function DawTerminal({ t, dark, lines = DAW_TERMINAL_LINES, height = 220 }) {
  return (
    <div style={{ height, borderTop: `1px solid ${t.border}`, display: 'flex', flexDirection: 'column', background: t.bg }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 0, height: 32, borderBottom: `1px solid ${t.border}`, padding: '0 8px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 12px', height: '100%', borderBottom: `2px solid ${t.fg}` }}>
          <Icon name="terminal" size={12} color={t.fg2} />
          <span style={{ fontSize: 12, fontFamily: G.mono }}>Terminal</span>
          <Icon name="close" size={11} color={t.fg3} />
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 12px', height: '100%', color: t.fg3 }}>
          <Icon name="terminal" size={12} />
          <span style={{ fontSize: 12, fontFamily: G.mono }}>Terminal (3)</span>
          <Icon name="close" size={11} />
        </div>
        <Icon name="plus" size={12} color={t.fg3} style={{ marginLeft: 4 }} />
      </div>
      <div className="gh-scroll" style={{ flex: 1, overflow: 'auto', padding: '10px 16px', fontFamily: G.mono, fontSize: 11.5, lineHeight: 1.7 }}>
        {lines.map((l, i) => {
          if (l.kind === 'spacer') return <div key={i} style={{ height: 8 }} />;
          if (l.kind === 'cmd')      return <div key={i} style={{ color: t.fg, fontWeight: 600 }}>{l.text}</div>;
          if (l.kind === 'comment')  return <div key={i} style={{ color: t.fg3, paddingLeft: 24 }}>{l.text}</div>;
          if (l.kind === 'banner')   return (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, color: t.fg3, padding: '6px 0' }}>
              <span style={{ color: t.fg2 }}>{l.ts}</span>
              <span style={{ color: t.fg }}>{l.tag}</span>
              <span style={{ flex: 1 }} />
            </div>
          );
          if (l.kind === 'gitstatus') return (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 14, color: t.fg2 }}>
              <span style={{ color: t.fg }}>Claude Code</span>
              <span>v2.1.126</span>
              <span>·</span>
              <span>Sonnet 4.6</span>
              <span>·</span>
              <span>API Usage Billing</span>
              <span style={{ flex: 1 }} />
              <span style={{ color: t.fg3 }}>~/Projects/{l.repo}</span>
              <span>{l.branch}</span>
              <span>{l.mods}|{l.untrack}</span>
              <span>{l.summary}</span>
            </div>
          );
          if (l.kind === 'prompt') return (
            <div key={i} style={{ color: t.fg, padding: '8px 0' }}>
              <span style={{ color: t.fg3, marginRight: 8 }}>&gt;</span>
              {l.text}
            </div>
          );
          if (l.kind === 'hint') return <div key={i} style={{ color: t.fg3, fontStyle: 'italic' }}>{l.text}</div>;
          return null;
        })}
      </div>
    </div>
  );
}

function DawTopBar({ t, dark, repo = 'electrobun-starter-tanstack', branch = 'main', task = 'canvas 模式下，Note Library 从右边弹出，去掉新建...', expanded = false }) {
  return (
    <div style={{
      height: 38, flexShrink: 0,
      borderBottom: `0.5px solid ${t.border}`,
      display: 'flex', alignItems: 'center', gap: 12,
      padding: '0 14px',
      background: dark ? 'rgba(20,20,20,0.6)' : 'rgba(255,255,255,0.65)',
      backdropFilter: 'blur(20px) saturate(180%)',
    }}>
      <Icon name="grid" size={13} color={t.fg3} />
      <Icon name="chat" size={13} color={t.fg3} />
      <Icon name="plus" size={13} color={t.fg3} />
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 12, color: t.fg2 }}>
        <span style={{ fontWeight: 500, color: t.fg }}>{repo}</span>
        <Icon name="git" size={11} />
        <span>{branch}</span>
        <span>/</span>
        <span style={{ color: t.fg3 }}>●</span>
        <span style={{ color: t.fg, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 380 }}>{task}</span>
      </div>
      <span style={{ flex: 1 }} />
      <Icon name="ext" size={13} color={t.fg3} />
    </div>
  );
}


// ────────── main component ──────────
//
// variant:
//   'agent-led'      — left task list, agent stream + composer (main), file tree right
//   'code-led'       — left task list narrow, editor full, file tree right
//   'terminal-split' — code-led + bottom terminal split
//   'plan-focus'     — agent + plan checklist big, no editor
//   'followup'       — composer focused, autocomplete dropdown

function DevAgentWorkspace({ dark, variant = 'agent-led' }) {
  const t = dark ? G.d : G.l;
  const compact = variant === 'code-led' || variant === 'terminal-split';
  const showAgent = variant === 'agent-led' || variant === 'plan-focus' || variant === 'followup' || variant === 'perm-menu';
  const showEditorMain = variant === 'code-led' || variant === 'terminal-split';
  const showTerminal = variant === 'terminal-split';

  return (
    <AppShell
      dark={dark}
      active="code"
      sidebar={<DawTaskList t={t} dark={dark} compact={compact} />}
      topBar={<DawTopBar t={t} dark={dark} />}
    >
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
        <div style={{ flex: 1, display: 'flex', minHeight: 0 }}>
          {/* Middle column — agent stream OR editor (depends on variant) */}
          <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }}>
            {showAgent && (
              <>
                <DawAgentStream t={t} showScrollHint={variant !== 'plan-focus'} />
                <Composer
                  dark={dark}
                  placeholder="Follow-up on this task, @ for mentions, / for commands"
                  value={variant === 'followup' ? 'Re-run vitest on changed files only' : ''}
                  permissionMode={variant === 'perm-menu' ? 'auto' : 'full'}
                  model="Ghast 2 Pro"
                  skillCount={0}
                  contextFile="router.tsx"
                  contextUsed={42}
                  contextLimit={200}
                />
              </>
            )}
            {showEditorMain && (
              <>
                <DawEditor t={t} dark={dark} />
                {showTerminal && <DawTerminal t={t} dark={dark} height={260} />}
              </>
            )}
          </div>

          {/* Right column — agent-led shows editor + tree; others just tree */}
          {variant === 'agent-led' ? (
            <>
              <div style={{ width: 540, flexShrink: 0, display: 'flex', flexDirection: 'column', borderLeft: `0.5px solid ${t.border}` }}>
                <DawEditor t={t} dark={dark} />
              </div>
              <DawFileTree t={t} dark={dark} width={220} />
            </>
          ) : variant === 'plan-focus' || variant === 'followup' || variant === 'perm-menu' ? (
            <DawFileTree t={t} dark={dark} width={220} />
          ) : (
            <DawFileTree t={t} dark={dark} width={240} />
          )}
        </div>
      </div>
    </AppShell>
  );
}

// Export
Object.assign(window, {
  DevAgentWorkspace,
  DAW_TASKS, DAW_AGENT_STREAM, DAW_PLAN, DAW_FILES, DAW_EDITOR_TABS,
});
