<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1100" role="img"
  aria-labelledby="title description">
  <title id="title">Logician package architecture</title>
  <desc id="description">Four TypeScript packages in one Node.js process. The terminal UI composes the coding agent, agent capabilities, and agent core. The coding agent and capabilities both build on agent core. External access flows through the tool bus.</desc>

  <defs>
    <linearGradient id="background" x1="0" y1="0" x2="1" y2="1">
      <stop offset="0" stop-color="#0b1018"/>
      <stop offset="0.55" stop-color="#0d1117"/>
      <stop offset="1" stop-color="#111827"/>
    </linearGradient>
    <radialGradient id="aura" cx="50%" cy="42%" r="52%">
      <stop offset="0" stop-color="#2563eb" stop-opacity=".14"/>
      <stop offset=".55" stop-color="#06b6d4" stop-opacity=".04"/>
      <stop offset="1" stop-color="#0d1117" stop-opacity="0"/>
    </radialGradient>
    <pattern id="grid" width="28" height="28" patternUnits="userSpaceOnUse">
      <path d="M28 0H0V28" fill="none" stroke="#94a3b8" stroke-opacity=".045"/>
    </pattern>
    <filter id="shadow" x="-20%" y="-30%" width="140%" height="170%">
      <feDropShadow dx="0" dy="8" stdDeviation="12" flood-color="#000" flood-opacity=".38"/>
    </filter>
    <filter id="glow" x="-30%" y="-40%" width="160%" height="180%">
      <feGaussianBlur stdDeviation="8" result="blur"/>
      <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
    </filter>
    <marker id="arrow-blue" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
      <path d="M0 0 10 5 0 10Z" fill="#58a6ff"/>
    </marker>
    <marker id="arrow-muted" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
      <path d="M0 0 10 5 0 10Z" fill="#64748b"/>
    </marker>
    <style>
      text { font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace; }
      .eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 2.5px; }
      .title { font-size: 38px; font-weight: 800; letter-spacing: 7px; }
      .subtitle { font-size: 13px; font-weight: 600; letter-spacing: 3px; }
      .package { font-size: 11px; font-weight: 700; letter-spacing: .5px; }
      .card-title { fill: #f8fafc; font-size: 20px; font-weight: 750; }
      .body { fill: #94a3b8; font-size: 12px; }
      .chip { fill: #cbd5e1; font-size: 11px; font-weight: 600; }
      .link-label { fill: #64748b; font-size: 10px; font-style: italic; }
      .external-title { fill: #e2e8f0; font-size: 14px; font-weight: 700; }
      .external-sub { fill: #64748b; font-size: 10px; }
    </style>
  </defs>

  <rect width="1400" height="1100" rx="18" fill="url(#background)"/>
  <rect width="1400" height="1100" rx="18" fill="url(#grid)"/>
  <rect width="1400" height="1100" rx="18" fill="url(#aura)"/>

  <g aria-label="Diagram heading">
    <text x="700" y="55" text-anchor="middle" class="title" fill="#60a5fa">LOGICIAN</text>
    <text x="700" y="82" text-anchor="middle" class="subtitle" fill="#94a3b8">PACKAGE ARCHITECTURE</text>
    <g transform="translate(526 100)">
      <rect width="104" height="25" rx="12.5" fill="#58a6ff" fill-opacity=".1" stroke="#58a6ff" stroke-opacity=".75"/>
      <text x="52" y="17" text-anchor="middle" class="chip" fill="#60a5fa">TypeScript</text>
      <rect x="116" width="142" height="25" rx="12.5" fill="#56d364" fill-opacity=".1" stroke="#56d364" stroke-opacity=".75"/>
      <text x="187" y="17" text-anchor="middle" class="chip" fill="#56d364">Node.js ≥22.19</text>
      <rect x="270" width="78" height="25" rx="12.5" fill="#94a3b8" fill-opacity=".08" stroke="#64748b"/>
      <text x="309" y="17" text-anchor="middle" class="chip">4 packages</text>
    </g>
  </g>

  <g aria-label="User session">
    <rect x="500" y="148" width="400" height="55" rx="13" fill="#161d28" stroke="#334155"/>
    <circle cx="530" cy="175" r="5" fill="#22d3ee" filter="url(#glow)"/>
    <text x="700" y="171" text-anchor="middle" fill="#e2e8f0" font-size="15" font-weight="700">User · Terminal Session</text>
    <text x="700" y="189" text-anchor="middle" class="body">local · SSH · tmux · VT100</text>
    <path d="M700 203V230" stroke="#a78bfa" stroke-width="2" marker-end="url(#arrow-blue)"/>
  </g>

  <g id="package-tui" filter="url(#shadow)">
    <rect x="150" y="230" width="1100" height="105" rx="16" fill="#171c26" stroke="#a78bfa" stroke-width="2"/>
    <rect x="150" y="230" width="7" height="105" rx="3.5" fill="#a78bfa"/>
    <text x="184" y="258" class="package" fill="#a78bfa">packages/tui</text>
    <text x="184" y="288" class="card-title">Terminal UI</text>
    <text x="184" y="310" class="body">Streaming presentation and runtime controls</text>
    <g transform="translate(620 253)">
      <rect width="130" height="34" rx="17" fill="#a78bfa" fill-opacity=".08" stroke="#a78bfa" stroke-opacity=".55"/>
      <text x="65" y="22" text-anchor="middle" class="chip">Rendering</text>
      <rect x="146" width="130" height="34" rx="17" fill="#a78bfa" fill-opacity=".08" stroke="#a78bfa" stroke-opacity=".55"/>
      <text x="211" y="22" text-anchor="middle" class="chip">Input</text>
      <rect x="292" width="130" height="34" rx="17" fill="#a78bfa" fill-opacity=".08" stroke="#a78bfa" stroke-opacity=".55"/>
      <text x="357" y="22" text-anchor="middle" class="chip">Themes</text>
      <rect x="438" width="130" height="34" rx="17" fill="#a78bfa" fill-opacity=".08" stroke="#a78bfa" stroke-opacity=".55"/>
      <text x="503" y="22" text-anchor="middle" class="chip">Overlays</text>
    </g>
  </g>

  <g aria-label="Package dependency links" fill="none" stroke-linecap="round">
    <path d="M700 335V366H430V395" stroke="#58a6ff" stroke-width="2" marker-end="url(#arrow-blue)"/>
    <path d="M700 335V395" stroke="#58a6ff" stroke-width="2" marker-end="url(#arrow-blue)"/>
    <path d="M700 335V366H970V395" stroke="#58a6ff" stroke-width="2" marker-end="url(#arrow-blue)"/>
    <text x="713" y="360" class="link-label">direct dependencies</text>
  </g>

  <g id="package-capabilities" filter="url(#shadow)">
    <rect x="150" y="395" width="390" height="175" rx="16" fill="#151d26" stroke="#22d3ee" stroke-width="2"/>
    <rect x="150" y="395" width="7" height="175" rx="3.5" fill="#22d3ee"/>
    <text x="184" y="424" class="package" fill="#22d3ee">packages/agent-capabilities</text>
    <text x="184" y="453" class="card-title">Agent Capabilities</text>
    <text x="184" y="482" class="body">todo · ask-user · subagents</text>
    <text x="184" y="506" class="body">reasoners · EOH optimization</text>
    <rect x="184" y="528" width="190" height="25" rx="12.5" fill="#22d3ee" fill-opacity=".08" stroke="#22d3ee" stroke-opacity=".45"/>
    <text x="279" y="545" text-anchor="middle" class="chip">behavior modules</text>
  </g>

  <g id="package-coding-agent" filter="url(#shadow)">
    <rect x="590" y="395" width="390" height="175" rx="16" fill="#151d26" stroke="#56d364" stroke-width="2"/>
    <rect x="590" y="395" width="7" height="175" rx="3.5" fill="#56d364"/>
    <text x="624" y="424" class="package" fill="#56d364">packages/coding-agent</text>
    <text x="624" y="453" class="card-title">Coding Agent</text>
    <text x="624" y="482" class="body">sessions · config · skills · prompts</text>
    <text x="624" y="506" class="body">tools · MCP · trust · context files</text>
    <rect x="624" y="528" width="190" height="25" rx="12.5" fill="#56d364" fill-opacity=".08" stroke="#56d364" stroke-opacity=".45"/>
    <text x="719" y="545" text-anchor="middle" class="chip">orchestration layer</text>
  </g>

  <g id="package-core" filter="url(#shadow)">
    <rect x="1030" y="395" width="220" height="175" rx="16" fill="#151d26" stroke="#58a6ff" stroke-width="2"/>
    <rect x="1030" y="395" width="7" height="175" rx="3.5" fill="#58a6ff"/>
    <text x="1064" y="424" class="package" fill="#58a6ff">packages/agent-core</text>
    <text x="1064" y="453" class="card-title">Agent Core</text>
    <text x="1064" y="482" class="body">loop · harness</text>
    <text x="1064" y="506" class="body">hooks · compaction</text>
    <text x="1064" y="530" class="body">queue · tool registry</text>
  </g>

  <g aria-label="Internal dependency links" fill="none" stroke-linecap="round">
    <path d="M540 510H565V585H1010V510H1030" stroke="#22d3ee" stroke-width="2" marker-end="url(#arrow-blue)"/>
    <path d="M980 482H1030" stroke="#56d364" stroke-width="2" marker-end="url(#arrow-blue)"/>
    <text x="765" y="602" text-anchor="middle" class="link-label">capabilities and coding-agent build on agent-core</text>
  </g>

  <g id="harness-detail" aria-label="Agent core harness loop" filter="url(#shadow)">
    <path d="M1140 570V610H700V630" fill="none" stroke="#58a6ff" stroke-width="1.5" stroke-dasharray="5 4"/>
    <rect x="150" y="630" width="1100" height="155" rx="18" fill="#111925" stroke="#58a6ff" stroke-width="1.5"/>
    <text x="182" y="658" class="package" fill="#58a6ff">AGENT-CORE · HARNESS LOOP</text>
    <text x="1218" y="658" text-anchor="end" class="link-label">each turn follows the same controlled path</text>

    <g transform="translate(182 680)">
      <rect width="155" height="55" rx="11" fill="#172033" stroke="#38bdf8"/>
      <text x="77.5" y="23" text-anchor="middle" class="chip">Message Intake</text>
      <text x="77.5" y="41" text-anchor="middle" class="external-sub">steering · follow-ups</text>

      <path d="M155 27H190" stroke="#58a6ff" stroke-width="1.7" marker-end="url(#arrow-blue)"/>
      <rect x="190" width="155" height="55" rx="11" fill="#172033" stroke="#a78bfa"/>
      <text x="267.5" y="23" text-anchor="middle" class="chip">Model Call</text>
      <text x="267.5" y="41" text-anchor="middle" class="external-sub">stream · parse</text>

      <path d="M345 27H380" stroke="#58a6ff" stroke-width="1.7" marker-end="url(#arrow-blue)"/>
      <rect x="380" width="155" height="55" rx="11" fill="#172033" stroke="#22d3ee"/>
      <text x="457.5" y="23" text-anchor="middle" class="chip">Pre-tool Hooks</text>
      <text x="457.5" y="41" text-anchor="middle" class="external-sub">inspect · veto · rewrite</text>

      <path d="M535 27H570" stroke="#58a6ff" stroke-width="1.7" marker-end="url(#arrow-blue)"/>
      <rect x="570" width="155" height="55" rx="11" fill="#172033" stroke="#56d364"/>
      <text x="647.5" y="23" text-anchor="middle" class="chip">Tool Execution</text>
      <text x="647.5" y="41" text-anchor="middle" class="external-sub">permission-gated</text>

      <path d="M725 27H760" stroke="#58a6ff" stroke-width="1.7" marker-end="url(#arrow-blue)"/>
      <rect x="760" width="155" height="55" rx="11" fill="#172033" stroke="#22d3ee"/>
      <text x="837.5" y="23" text-anchor="middle" class="chip">Post-tool Hooks</text>
      <text x="837.5" y="41" text-anchor="middle" class="external-sub">format · diagnostics</text>

      <path d="M915 27H950" stroke="#58a6ff" stroke-width="1.7" marker-end="url(#arrow-blue)"/>
      <rect x="950" width="118" height="55" rx="11" fill="#172033" stroke="#f59e0b"/>
      <text x="1009" y="23" text-anchor="middle" class="chip">Loop Gate</text>
      <text x="1009" y="41" text-anchor="middle" class="external-sub">compact · finish</text>
    </g>
    <path d="M1191 747V763H259V739" fill="none" stroke="#64748b" stroke-width="1.2" stroke-dasharray="5 4" marker-end="url(#arrow-muted)"/>
    <rect x="505" y="754" width="440" height="22" rx="11" fill="#111925"/>
    <text x="725" y="770" text-anchor="middle" class="link-label">tool result → context assembly → next model turn</text>
  </g>

  <g aria-label="Tool bus">
    <path d="M700 785V815" fill="none" stroke="#64748b" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-muted)"/>
    <rect x="500" y="815" width="400" height="40" rx="20" fill="#111827" stroke="#475569"/>
    <text x="700" y="840" text-anchor="middle" class="eyebrow" fill="#94a3b8">GATED TOOL BUS</text>
    <path d="M700 855V880M205 880H1195M205 880V900M535 880V900M865 880V900M1195 880V900"
      fill="none" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5 5" marker-end="url(#arrow-muted)"/>
  </g>

  <g aria-label="External systems">
    <g>
      <rect x="85" y="900" width="240" height="100" rx="14" fill="#141a23" stroke="#475569" stroke-dasharray="6 4"/>
      <text x="205" y="940" text-anchor="middle" class="external-title">LLM Backend</text>
      <text x="205" y="965" text-anchor="middle" class="external-sub">OpenAI-compatible API</text>
    </g>
    <g>
      <rect x="415" y="900" width="240" height="100" rx="14" fill="#141a23" stroke="#475569" stroke-dasharray="6 4"/>
      <text x="535" y="940" text-anchor="middle" class="external-title">MCP Servers</text>
      <text x="535" y="965" text-anchor="middle" class="external-sub">stdio · streamable HTTP</text>
    </g>
    <g>
      <rect x="745" y="900" width="240" height="100" rx="14" fill="#141a23" stroke="#475569" stroke-dasharray="6 4"/>
      <text x="865" y="940" text-anchor="middle" class="external-title">SearXNG</text>
      <text x="865" y="965" text-anchor="middle" class="external-sub">web search · web fetch</text>
    </g>
    <g>
      <rect x="1075" y="900" width="240" height="100" rx="14" fill="#141a23" stroke="#475569" stroke-dasharray="6 4"/>
      <text x="1195" y="940" text-anchor="middle" class="external-title">Filesystem · Git</text>
      <text x="1195" y="965" text-anchor="middle" class="external-sub">files · shell · repository</text>
    </g>
  </g>

  <g aria-label="Footer">
    <text x="85" y="1060" class="body">local-first · SSH-ready · thinking-visible</text>
    <text x="1315" y="1060" text-anchor="end" class="body">github.com/lseman/logician</text>
    <circle cx="680" cy="1056" r="3" fill="#58a6ff"/>
    <circle cx="700" cy="1056" r="3" fill="#22d3ee"/>
    <circle cx="720" cy="1056" r="3" fill="#56d364"/>
  </g>
</svg>
