skillmux 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1529,26 +1529,78 @@ function updateTuiState(state, event) {
1529
1529
  return readyState;
1530
1530
  }
1531
1531
 
1532
- // src/tui/components/AgentList.tsx
1533
- import { Box, Text } from "ink";
1534
- import { jsx, jsxs } from "react/jsx-runtime";
1535
- function statusMarker(agent) {
1536
- if (!agent.supported) {
1537
- return "!";
1532
+ // src/tui/theme.ts
1533
+ import React from "react";
1534
+ var nord0 = "#2e3440";
1535
+ var nord1 = "#3b4252";
1536
+ var nord3 = "#4c566a";
1537
+ var nord4 = "#d8dee9";
1538
+ var nord6 = "#eceff4";
1539
+ var nord8 = "#88c0d0";
1540
+ var nord9 = "#81a1c1";
1541
+ var nord11 = "#bf616a";
1542
+ var nord13 = "#ebcb8b";
1543
+ var nord14 = "#a3be8c";
1544
+ var nord15 = "#b48ead";
1545
+ var nordTheme = {
1546
+ fg: { default: nord4, muted: nord3, emphasis: nord6 },
1547
+ bg: { base: nord0, surface: nord1, overlay: nord1, selection: nord9 },
1548
+ accent: { primary: nord9, secondary: nord15 },
1549
+ status: { success: nord14, warning: nord13, error: nord11, info: nord8 },
1550
+ border: { default: nord3, focused: nord9 }
1551
+ };
1552
+ var fallbackTheme = {
1553
+ fg: { default: "white", muted: "gray", emphasis: "white" },
1554
+ bg: {
1555
+ base: "black",
1556
+ surface: "black",
1557
+ overlay: "black",
1558
+ selection: "cyan"
1559
+ },
1560
+ accent: { primary: "cyan", secondary: "magenta" },
1561
+ status: { success: "green", warning: "yellow", error: "red", info: "cyan" },
1562
+ border: { default: "gray", focused: "cyan" }
1563
+ };
1564
+ function detectColorLevel() {
1565
+ if (process.env.NO_COLOR !== void 0) {
1566
+ return "none";
1538
1567
  }
1539
- if (!agent.exists) {
1540
- return "?";
1568
+ const colorTerm = process.env.COLORTERM;
1569
+ if (colorTerm === "truecolor" || colorTerm === "24bit") {
1570
+ return "truecolor";
1541
1571
  }
1542
- return "*";
1543
- }
1544
- function statusColor(agent) {
1545
- if (!agent.supported) {
1546
- return "red";
1572
+ const term = process.env.TERM ?? "";
1573
+ if (term.includes("256color")) {
1574
+ return "256";
1547
1575
  }
1548
- if (!agent.exists || agent.issueCount > 0) {
1549
- return "yellow";
1576
+ return "16";
1577
+ }
1578
+ function resolveTheme() {
1579
+ const colorLevel = detectColorLevel();
1580
+ if (colorLevel === "none" || colorLevel === "16") {
1581
+ return fallbackTheme;
1550
1582
  }
1551
- return "green";
1583
+ return nordTheme;
1584
+ }
1585
+ var ThemeContext = React.createContext(nordTheme);
1586
+ function useTheme() {
1587
+ return React.useContext(ThemeContext);
1588
+ }
1589
+ var ThemeProvider = ThemeContext.Provider;
1590
+
1591
+ // src/tui/components/AgentList.tsx
1592
+ import { Box, Text } from "ink";
1593
+ import { jsx, jsxs } from "react/jsx-runtime";
1594
+ function statusColor(agent, theme) {
1595
+ if (!agent.supported) return theme.status.error;
1596
+ if (!agent.exists || agent.issueCount > 0) return theme.status.warning;
1597
+ return theme.status.success;
1598
+ }
1599
+ function statusLabel(agent) {
1600
+ if (!agent.supported) return "!";
1601
+ if (!agent.exists) return "?";
1602
+ if (agent.issueCount > 0) return "*";
1603
+ return "*";
1552
1604
  }
1553
1605
  function AgentList({
1554
1606
  agents,
@@ -1558,20 +1610,23 @@ function AgentList({
1558
1610
  width = 24,
1559
1611
  height = 18
1560
1612
  }) {
1613
+ const theme = useTheme();
1561
1614
  const emptyMessage = searchQuery !== void 0 && searchQuery.trim().length > 0 ? "No matching agents" : "No agents found";
1562
1615
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width, height, children: [
1563
- /* @__PURE__ */ jsx(Text, { bold: true, color: focused ? "cyan" : void 0, children: "Agents" }),
1616
+ /* @__PURE__ */ jsx(Text, { bold: true, color: focused ? theme.fg.emphasis : theme.fg.muted, children: "Agents" }),
1564
1617
  agents.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: emptyMessage }) : agents.map((agent) => {
1565
- const selected = agent.id === selectedAgentId;
1566
- const selectionPrefix = selected ? ">" : " ";
1567
- return /* @__PURE__ */ jsxs(Text, { inverse: selected, children: [
1568
- /* @__PURE__ */ jsx(Text, { color: statusColor(agent), children: statusMarker(agent) }),
1569
- /* @__PURE__ */ jsxs(Text, { children: [
1570
- selectionPrefix,
1618
+ const isSelected = agent.id === selectedAgentId;
1619
+ const isActive = isSelected && focused;
1620
+ const prefix = isActive ? ">" : " ";
1621
+ return /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsxs(Text, { backgroundColor: isSelected ? theme.bg.selection : void 0, children: [
1622
+ /* @__PURE__ */ jsx(Text, { color: statusColor(agent, theme), children: statusLabel(agent) }),
1623
+ /* @__PURE__ */ jsxs(Text, { color: isSelected ? theme.fg.emphasis : theme.fg.default, children: [
1624
+ " ",
1625
+ prefix,
1571
1626
  " ",
1572
1627
  agent.name
1573
1628
  ] })
1574
- ] }, agent.id);
1629
+ ] }) }, agent.id);
1575
1630
  })
1576
1631
  ] });
1577
1632
  }
@@ -1608,18 +1663,17 @@ function confirmationDetails(modal) {
1608
1663
  return `${modal.unmanagedCount} unmanaged skills will be moved under SkillMux management.`;
1609
1664
  }
1610
1665
  function ConfirmDialog({ modal }) {
1666
+ const theme = useTheme();
1667
+ const isRemove = modal.kind === "confirm-remove" || modal.kind === "confirm-remove-agent";
1668
+ const titleColor = isRemove ? theme.status.warning : theme.status.info;
1611
1669
  return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", height: confirmDialogHeight, children: [
1612
- /* @__PURE__ */ jsx2(
1613
- Text2,
1614
- {
1615
- bold: true,
1616
- color: modal.kind === "confirm-remove" || modal.kind === "confirm-remove-agent" ? "yellow" : "cyan",
1617
- children: "Confirm"
1618
- }
1619
- ),
1620
- /* @__PURE__ */ jsx2(Text2, { children: confirmationText(modal) }),
1621
- confirmationDetails(modal) === null ? null : /* @__PURE__ */ jsx2(Text2, { children: confirmationDetails(modal) }),
1622
- /* @__PURE__ */ jsx2(Text2, { children: "[y] confirm [Esc] cancel" })
1670
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: titleColor, children: "Confirm" }),
1671
+ /* @__PURE__ */ jsx2(Text2, { color: theme.fg.default, children: confirmationText(modal) }),
1672
+ confirmationDetails(modal) === null ? null : /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: confirmationDetails(modal) }),
1673
+ /* @__PURE__ */ jsxs2(Text2, { children: [
1674
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.status.success, children: "[y] confirm" }),
1675
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " [Esc] cancel" })
1676
+ ] })
1623
1677
  ] });
1624
1678
  }
1625
1679
 
@@ -1641,17 +1695,18 @@ function DoctorDialog({
1641
1695
  width = 72,
1642
1696
  height = 14
1643
1697
  }) {
1698
+ const theme = useTheme();
1644
1699
  if (modal.status === "loading") {
1645
1700
  return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", width, height, children: [
1646
- /* @__PURE__ */ jsx3(Text3, { bold: true, children: "Doctor" }),
1647
- /* @__PURE__ */ jsx3(Text3, { children: "Loading doctor diagnostics..." }),
1701
+ /* @__PURE__ */ jsx3(Text3, { bold: true, color: theme.fg.emphasis, children: "Doctor" }),
1702
+ /* @__PURE__ */ jsx3(Text3, { color: theme.fg.muted, children: "Loading doctor diagnostics..." }),
1648
1703
  /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "[Esc] close" })
1649
1704
  ] });
1650
1705
  }
1651
1706
  if (modal.status === "error") {
1652
1707
  return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", width, height, children: [
1653
- /* @__PURE__ */ jsx3(Text3, { bold: true, children: "Doctor" }),
1654
- /* @__PURE__ */ jsx3(Text3, { color: "red", children: modal.errorMessage }),
1708
+ /* @__PURE__ */ jsx3(Text3, { bold: true, color: theme.fg.emphasis, children: "Doctor" }),
1709
+ /* @__PURE__ */ jsx3(Text3, { color: theme.status.error, children: modal.errorMessage }),
1655
1710
  /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "[Esc] close" })
1656
1711
  ] });
1657
1712
  }
@@ -1661,12 +1716,12 @@ function DoctorDialog({
1661
1716
  const clampedOffset = Math.min(Math.max(scrollOffset, 0), maxOffset);
1662
1717
  const visibleIssues = issues.slice(clampedOffset, clampedOffset + maxIssues);
1663
1718
  return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", width, height, children: [
1664
- /* @__PURE__ */ jsx3(Text3, { bold: true, children: "Doctor" }),
1719
+ /* @__PURE__ */ jsx3(Text3, { bold: true, color: theme.fg.emphasis, children: "Doctor" }),
1665
1720
  /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: issues.length === 0 ? "No doctor issues found." : `${issues.length} issue(s) found` }),
1666
1721
  issues.length === 0 ? null : /* @__PURE__ */ jsxs3(Fragment, { children: [
1667
1722
  visibleIssues.map((issue) => /* @__PURE__ */ jsxs3(Text3, { children: [
1668
- /* @__PURE__ */ jsx3(Text3, { color: issue.severity === "error" ? "red" : "yellow", children: "! " }),
1669
- /* @__PURE__ */ jsxs3(Text3, { children: [
1723
+ /* @__PURE__ */ jsx3(Text3, { color: issue.severity === "error" ? theme.status.error : theme.status.warning, children: "! " }),
1724
+ /* @__PURE__ */ jsxs3(Text3, { color: theme.fg.default, children: [
1670
1725
  issueLabel(issue),
1671
1726
  " - ",
1672
1727
  issue.message,
@@ -1690,26 +1745,18 @@ function DoctorDialog({
1690
1745
  import { Box as Box4, Text as Text4 } from "ink";
1691
1746
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1692
1747
  function compactPath(value, maxLength) {
1693
- if (value.length <= maxLength) {
1694
- return value;
1695
- }
1748
+ if (value.length <= maxLength) return value;
1696
1749
  const separator = value.includes("\\") ? "\\" : "/";
1697
1750
  const parts = value.split(/[\\/]+/).filter((part) => part.length > 0);
1698
1751
  let suffix = parts.at(-1) ?? value;
1699
1752
  for (let index = parts.length - 2; index >= 0; index -= 1) {
1700
1753
  const candidate = `${parts[index]}${separator}${suffix}`;
1701
- if (`...${separator}${candidate}`.length > maxLength) {
1702
- break;
1703
- }
1754
+ if (`...${separator}${candidate}`.length > maxLength) break;
1704
1755
  suffix = candidate;
1705
1756
  }
1706
1757
  const shortened = `...${separator}${suffix}`;
1707
- if (shortened.length <= maxLength) {
1708
- return shortened;
1709
- }
1710
- if (maxLength <= 3) {
1711
- return ".".repeat(maxLength);
1712
- }
1758
+ if (shortened.length <= maxLength) return shortened;
1759
+ if (maxLength <= 3) return ".".repeat(maxLength);
1713
1760
  return `...${suffix.slice(-(maxLength - 3))}`;
1714
1761
  }
1715
1762
  function detailLines(skill) {
@@ -1757,9 +1804,10 @@ function DetailPane({
1757
1804
  width = 28,
1758
1805
  height = 18
1759
1806
  }) {
1807
+ const theme = useTheme();
1760
1808
  return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", width, height, children: [
1761
- /* @__PURE__ */ jsx4(Text4, { bold: true, children: "Detail" }),
1762
- selectedAgent === null ? /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Select an agent" }) : /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
1809
+ /* @__PURE__ */ jsx4(Text4, { bold: true, color: theme.fg.emphasis, children: "Detail" }),
1810
+ selectedAgent === null ? /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Select an agent" }) : /* @__PURE__ */ jsxs4(Text4, { color: theme.fg.muted, children: [
1763
1811
  "Agent: ",
1764
1812
  selectedAgent.name
1765
1813
  ] }),
@@ -1771,11 +1819,12 @@ function DetailPane({
1771
1819
  const valueWidth = Math.max(width - (label.length + 2), 8);
1772
1820
  const renderedValue = compact ? compactPath(value, valueWidth) : value;
1773
1821
  return /* @__PURE__ */ jsxs4(Text4, { children: [
1774
- /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
1822
+ /* @__PURE__ */ jsxs4(Text4, { bold: true, color: theme.accent.primary, children: [
1775
1823
  label,
1776
- ": "
1824
+ ":",
1825
+ " "
1777
1826
  ] }),
1778
- /* @__PURE__ */ jsx4(Text4, { children: renderedValue })
1827
+ /* @__PURE__ */ jsx4(Text4, { color: theme.fg.default, children: renderedValue })
1779
1828
  ] }, label);
1780
1829
  })
1781
1830
  ] });
@@ -1783,17 +1832,16 @@ function DetailPane({
1783
1832
 
1784
1833
  // src/tui/components/Footer.tsx
1785
1834
  import { Box as Box5, Text as Text5 } from "ink";
1786
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1787
- var agentLegend = "Agent icons: * ready yellow * issues ? missing ! unsupported";
1788
- var skillLegend = "Skill markers: \u25CF enabled \u25CB disabled ? unmanaged ! issue";
1835
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1789
1836
  function Footer({ actions, search }) {
1837
+ const theme = useTheme();
1790
1838
  const shortcuts = [
1791
1839
  actions.addAgent ? "[n]add agent" : null,
1792
1840
  actions.editAgent ? "[e]edit agent" : null,
1793
1841
  actions.removeAgent ? "[X]remove agent" : null,
1794
1842
  actions.importSkill ? "[i]import" : null,
1795
1843
  actions.doctor ? "[d]doctor" : null,
1796
- "[Left/Right]focus",
1844
+ "\u2190\u2192 focus",
1797
1845
  actions.toggle ? "[Space]toggle" : null,
1798
1846
  actions.adopt ? "[a]adopt" : null,
1799
1847
  actions.adoptAll ? "[Shift+A]adopt all" : null,
@@ -1802,46 +1850,90 @@ function Footer({ actions, search }) {
1802
1850
  actions.help ? "[?]help" : null,
1803
1851
  "[q]quit"
1804
1852
  ].filter((shortcut) => shortcut !== null);
1805
- return /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", height: 3, children: search === null ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
1806
- /* @__PURE__ */ jsx5(Text5, { children: shortcuts.join(" ") }),
1807
- /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: agentLegend }),
1808
- /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: skillLegend })
1809
- ] }) : /* @__PURE__ */ jsxs5(Text5, { children: [
1810
- /* @__PURE__ */ jsx5(Text5, { color: "cyan", children: "/" }),
1811
- /* @__PURE__ */ jsx5(Text5, { children: search.query }),
1812
- /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " [Enter]keep [Esc]cancel" })
1813
- ] }) });
1853
+ const legendParts = [
1854
+ { symbol: "\u25CF", label: "enabled", color: theme.status.success },
1855
+ { symbol: "\u25CB", label: "disabled", color: theme.fg.muted },
1856
+ { symbol: "?", label: "unmanaged", color: theme.status.warning },
1857
+ { symbol: "!", label: "issue", color: theme.status.error }
1858
+ ];
1859
+ if (search !== null) {
1860
+ return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", height: 3, children: [
1861
+ /* @__PURE__ */ jsxs5(Text5, { children: [
1862
+ /* @__PURE__ */ jsx5(Text5, { color: theme.accent.primary, children: "/" }),
1863
+ /* @__PURE__ */ jsx5(Text5, { color: theme.fg.default, children: search.query }),
1864
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " [Enter]keep [Esc]cancel" })
1865
+ ] }),
1866
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: legendParts.map((p, i) => /* @__PURE__ */ jsxs5(Text5, { children: [
1867
+ /* @__PURE__ */ jsxs5(Text5, { color: p.color, children: [
1868
+ p.symbol,
1869
+ " ",
1870
+ p.label
1871
+ ] }),
1872
+ i < legendParts.length - 1 ? " " : ""
1873
+ ] }, p.label)) })
1874
+ ] });
1875
+ }
1876
+ return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", height: 3, children: [
1877
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: shortcuts.join(" ") }),
1878
+ /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
1879
+ "SkillMux ",
1880
+ "\xB7",
1881
+ " [j/k]move ",
1882
+ "\xB7",
1883
+ " [g/G]top/bottom ",
1884
+ "\xB7",
1885
+ " [/]search"
1886
+ ] }),
1887
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: legendParts.map((p, i) => /* @__PURE__ */ jsxs5(Text5, { children: [
1888
+ /* @__PURE__ */ jsxs5(Text5, { color: p.color, children: [
1889
+ p.symbol,
1890
+ " ",
1891
+ p.label
1892
+ ] }),
1893
+ i < legendParts.length - 1 ? " \xB7 " : ""
1894
+ ] }, p.label)) })
1895
+ ] });
1814
1896
  }
1815
1897
 
1816
1898
  // src/tui/components/HelpOverlay.tsx
1817
1899
  import { Box as Box6, Text as Text6 } from "ink";
1818
1900
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1819
1901
  function HelpOverlay() {
1902
+ const theme = useTheme();
1820
1903
  return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", height: 8, children: [
1821
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Help" }),
1822
- /* @__PURE__ */ jsxs6(Text6, { children: [
1823
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Navigation" }),
1824
- /* @__PURE__ */ jsx6(Text6, { children: ": Left/Right switch panels, j/k or Up/Down move, g/G jump." })
1825
- ] }),
1904
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.fg.emphasis, children: "Help" }),
1826
1905
  /* @__PURE__ */ jsxs6(Text6, { children: [
1827
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Actions" }),
1828
- /* @__PURE__ */ jsx6(Text6, { children: ": Space toggles, a adopts, Shift+A current-agent bulk adopt, r removes, s scans, n add agent, e edit selected override, X remove selected override, i import, d doctor." })
1906
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.accent.primary, children: "Navigation" }),
1907
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: ": Left/Right switch panels, j/k or Up/Down move, g/G jump." })
1829
1908
  ] }),
1830
1909
  /* @__PURE__ */ jsxs6(Text6, { children: [
1831
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Search" }),
1832
- /* @__PURE__ */ jsx6(Text6, { children: ": / filters the focused list, Enter keeps the result, Esc cancels." })
1910
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.accent.primary, children: "Actions" }),
1911
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: ": Space toggles, a adopts, Shift+A current-agent bulk adopt, r removes, s scans, n add agent, e edit selected override, X remove selected override, i import, d doctor." })
1833
1912
  ] }),
1834
1913
  /* @__PURE__ */ jsxs6(Text6, { children: [
1835
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Agent icons" }),
1836
- /* @__PURE__ */ jsx6(Text6, { children: ": * ready, yellow * issues, ? missing, ! unsupported." })
1914
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.accent.primary, children: "Search" }),
1915
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: ": / filters the focused list, Enter keeps the result, Esc cancels." })
1837
1916
  ] }),
1838
1917
  /* @__PURE__ */ jsxs6(Text6, { children: [
1839
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Skill markers" }),
1840
- /* @__PURE__ */ jsx6(Text6, { children: ": \u25CF enabled, \u25CB disabled, ? unmanaged, ! issue." })
1918
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.accent.primary, children: "Skill markers" }),
1919
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: ": " }),
1920
+ /* @__PURE__ */ jsxs6(Text6, { color: theme.status.success, children: [
1921
+ "\u25CF",
1922
+ " enabled"
1923
+ ] }),
1924
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: " " }),
1925
+ /* @__PURE__ */ jsxs6(Text6, { color: theme.fg.muted, children: [
1926
+ "\u25CB",
1927
+ " disabled"
1928
+ ] }),
1929
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: " " }),
1930
+ /* @__PURE__ */ jsx6(Text6, { color: theme.status.warning, children: "? unmanaged" }),
1931
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: " " }),
1932
+ /* @__PURE__ */ jsx6(Text6, { color: theme.status.error, children: "! issue" })
1841
1933
  ] }),
1842
1934
  /* @__PURE__ */ jsxs6(Text6, { children: [
1843
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Safety" }),
1844
- /* @__PURE__ */ jsx6(Text6, { children: ": Toggle, adopt, remove, and scan can update SkillMux state and agent links." })
1935
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.accent.primary, children: "Safety" }),
1936
+ /* @__PURE__ */ jsx6(Text6, { color: theme.fg.default, children: ": Toggle, adopt, remove, and scan can update SkillMux state and agent links." })
1845
1937
  ] })
1846
1938
  ] });
1847
1939
  }
@@ -1853,36 +1945,60 @@ var platformOptions = ["win32", "linux", "darwin"];
1853
1945
  function checkbox(value) {
1854
1946
  return value ? "[x]" : "[ ]";
1855
1947
  }
1856
- function renderTextField(label, value, active) {
1857
- return /* @__PURE__ */ jsxs7(Text7, { inverse: active, children: [
1858
- /* @__PURE__ */ jsxs7(Text7, { bold: true, children: [
1948
+ function renderTextField(label, value, active, theme) {
1949
+ if (active) {
1950
+ return /* @__PURE__ */ jsxs7(Text7, { backgroundColor: theme.bg.selection, children: [
1951
+ /* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.fg.emphasis, children: [
1952
+ label,
1953
+ ": "
1954
+ ] }),
1955
+ /* @__PURE__ */ jsx7(Text7, { color: theme.fg.emphasis, children: value.length > 0 ? value : " " })
1956
+ ] }, label);
1957
+ }
1958
+ return /* @__PURE__ */ jsxs7(Text7, { children: [
1959
+ /* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accent.primary, children: [
1859
1960
  label,
1860
1961
  ": "
1861
1962
  ] }),
1862
- /* @__PURE__ */ jsx7(Text7, { children: value.length > 0 ? value : " " })
1963
+ /* @__PURE__ */ jsx7(Text7, { color: theme.fg.default, children: value.length > 0 ? value : " " })
1863
1964
  ] }, label);
1864
1965
  }
1865
- function renderBooleanField(label, value, active) {
1866
- return /* @__PURE__ */ jsxs7(Text7, { inverse: active, children: [
1867
- /* @__PURE__ */ jsxs7(Text7, { bold: true, children: [
1966
+ function renderBooleanField(label, value, active, theme) {
1967
+ if (active) {
1968
+ return /* @__PURE__ */ jsxs7(Text7, { backgroundColor: theme.bg.selection, children: [
1969
+ /* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.fg.emphasis, children: [
1970
+ label,
1971
+ ": "
1972
+ ] }),
1973
+ /* @__PURE__ */ jsx7(Text7, { color: theme.fg.emphasis, children: checkbox(value) })
1974
+ ] }, label);
1975
+ }
1976
+ return /* @__PURE__ */ jsxs7(Text7, { children: [
1977
+ /* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accent.primary, children: [
1868
1978
  label,
1869
1979
  ": "
1870
1980
  ] }),
1871
- /* @__PURE__ */ jsx7(Text7, { children: checkbox(value) })
1981
+ /* @__PURE__ */ jsx7(Text7, { color: theme.fg.default, children: checkbox(value) })
1872
1982
  ] }, label);
1873
1983
  }
1874
- function renderPlatformField(selectedPlatforms, activePlatformIndex, active) {
1984
+ function renderPlatformField(selectedPlatforms, activePlatformIndex, active, theme) {
1875
1985
  return platformOptions.map((platform, index) => {
1876
1986
  const selected = selectedPlatforms.includes(platform);
1877
1987
  const isCurrent = active && index === activePlatformIndex;
1878
- return /* @__PURE__ */ jsxs7(Text7, { inverse: isCurrent, children: [
1879
- /* @__PURE__ */ jsx7(Text7, { children: isCurrent ? "> " : " " }),
1880
- /* @__PURE__ */ jsxs7(Text7, { children: [
1988
+ if (isCurrent) {
1989
+ return /* @__PURE__ */ jsx7(Text7, { backgroundColor: theme.bg.selection, children: /* @__PURE__ */ jsxs7(Text7, { color: theme.fg.emphasis, children: [
1990
+ "> ",
1881
1991
  checkbox(selected),
1882
- " "
1883
- ] }),
1884
- /* @__PURE__ */ jsx7(Text7, { children: platform })
1885
- ] }, platform);
1992
+ " ",
1993
+ platform
1994
+ ] }) }, platform);
1995
+ }
1996
+ return /* @__PURE__ */ jsx7(Text7, { children: /* @__PURE__ */ jsxs7(Text7, { color: selected ? theme.status.success : theme.fg.muted, children: [
1997
+ " ",
1998
+ checkbox(selected),
1999
+ " ",
2000
+ platform
2001
+ ] }) }, platform);
1886
2002
  });
1887
2003
  }
1888
2004
  function FormDialog({
@@ -1892,89 +2008,94 @@ function FormDialog({
1892
2008
  width = 72,
1893
2009
  height = 14
1894
2010
  }) {
2011
+ const theme = useTheme();
1895
2012
  const activeField = fieldIndex;
1896
- const submitFieldIndex = modal.kind === "import" ? 2 : 6;
1897
2013
  if (modal.kind === "import") {
2014
+ const submitFieldIndex2 = 2;
1898
2015
  return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", width, height, children: [
1899
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: "Import skill" }),
1900
- modal.form.error === null ? null : /* @__PURE__ */ jsx7(Text7, { color: "red", children: modal.form.error }),
2016
+ /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.fg.emphasis, children: "Import skill" }),
2017
+ modal.form.error === null ? null : /* @__PURE__ */ jsx7(Text7, { color: theme.status.error, children: modal.form.error }),
1901
2018
  renderTextField(
1902
2019
  "Source path",
1903
2020
  modal.form.values.sourcePath,
1904
- activeField === 0
2021
+ activeField === 0,
2022
+ theme
1905
2023
  ),
1906
2024
  renderTextField(
1907
2025
  "Skill name",
1908
2026
  modal.form.values.skillName,
1909
- activeField === 1
2027
+ activeField === 1,
2028
+ theme
1910
2029
  ),
1911
- /* @__PURE__ */ jsx7(Text7, { inverse: activeField === submitFieldIndex, children: "Submit" }),
2030
+ /* @__PURE__ */ jsx7(Text7, { children: activeField === submitFieldIndex2 ? /* @__PURE__ */ jsx7(Text7, { backgroundColor: theme.bg.selection, children: /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.fg.emphasis, children: "Submit" }) }) : /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.accent.primary, children: "Submit" }) }),
1912
2031
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "[Up/Down] move [Enter] submit selected row [Esc] cancel" })
1913
2032
  ] });
1914
2033
  }
1915
2034
  const title = modal.kind === "add-agent" ? "Add agent" : `Edit agent ${modal.agentId}`;
1916
2035
  const fields = modal.kind === "add-agent" ? [
1917
- renderTextField("Agent id", modal.form.values.id, activeField === 0),
1918
- renderTextField("Root path", modal.form.values.root, activeField === 1),
1919
- renderTextField("Skills path", modal.form.values.skills, activeField === 2),
1920
- renderTextField("Display name", modal.form.values.name, activeField === 3)
2036
+ renderTextField("Agent id", modal.form.values.id, activeField === 0, theme),
2037
+ renderTextField("Root path", modal.form.values.root, activeField === 1, theme),
2038
+ renderTextField("Skills path", modal.form.values.skills, activeField === 2, theme),
2039
+ renderTextField("Display name", modal.form.values.name, activeField === 3, theme)
1921
2040
  ] : [
1922
- renderTextField("Root path", modal.form.values.root, activeField === 0),
1923
- renderTextField("Skills path", modal.form.values.skills, activeField === 1),
1924
- renderTextField("Display name", modal.form.values.name, activeField === 2)
2041
+ renderTextField("Root path", modal.form.values.root, activeField === 0, theme),
2042
+ renderTextField("Skills path", modal.form.values.skills, activeField === 1, theme),
2043
+ renderTextField("Display name", modal.form.values.name, activeField === 2, theme)
1925
2044
  ];
1926
2045
  const platformFieldIndex = modal.kind === "add-agent" ? 4 : 3;
1927
2046
  const booleanFieldIndex = modal.kind === "add-agent" ? 5 : 4;
2047
+ const submitFieldIndex = 6;
1928
2048
  const platformLines = renderPlatformField(
1929
2049
  modal.form.values.platforms,
1930
2050
  platformIndex,
1931
- activeField === platformFieldIndex
2051
+ activeField === platformFieldIndex,
2052
+ theme
1932
2053
  );
1933
2054
  const booleanLabel = modal.kind === "add-agent" ? "Disabled by default" : "Enabled by default";
1934
2055
  const booleanValue = modal.kind === "add-agent" ? modal.form.values.disabledByDefault : modal.form.values.enabledByDefault;
1935
2056
  const secondaryBooleanLabel = modal.kind === "add-agent" ? null : "Disabled by default";
1936
2057
  return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", width, height, children: [
1937
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: title }),
1938
- modal.form.error === null ? null : /* @__PURE__ */ jsx7(Text7, { color: "red", children: modal.form.error }),
2058
+ /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.fg.emphasis, children: title }),
2059
+ modal.form.error === null ? null : /* @__PURE__ */ jsx7(Text7, { color: theme.status.error, children: modal.form.error }),
1939
2060
  fields,
1940
- /* @__PURE__ */ jsx7(Text7, { bold: true, inverse: activeField === platformFieldIndex, children: "Platforms" }),
2061
+ /* @__PURE__ */ jsx7(Text7, { children: activeField === platformFieldIndex ? /* @__PURE__ */ jsx7(Text7, { backgroundColor: theme.bg.selection, children: /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.fg.emphasis, children: "Platforms" }) }) : /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.accent.primary, children: "Platforms" }) }),
1941
2062
  platformLines,
1942
2063
  renderBooleanField(
1943
2064
  booleanLabel,
1944
2065
  booleanValue,
1945
- activeField === booleanFieldIndex
2066
+ activeField === booleanFieldIndex,
2067
+ theme
1946
2068
  ),
1947
2069
  secondaryBooleanLabel === null ? null : renderBooleanField(
1948
2070
  secondaryBooleanLabel,
1949
2071
  modal.form.values.disabledByDefault,
1950
- activeField === booleanFieldIndex + 1
2072
+ activeField === booleanFieldIndex + 1,
2073
+ theme
1951
2074
  ),
1952
- /* @__PURE__ */ jsx7(Text7, { inverse: activeField === submitFieldIndex, children: "Submit" }),
2075
+ /* @__PURE__ */ jsx7(Text7, { children: activeField === submitFieldIndex ? /* @__PURE__ */ jsx7(Text7, { backgroundColor: theme.bg.selection, children: /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.fg.emphasis, children: "Submit" }) }) : /* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.accent.primary, children: "Submit" }) }),
1953
2076
  modal.kind === "edit-agent" ? /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Leaving both defaults unchecked preserves the current setting." }) : null,
1954
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "[Up/Down] move [Enter] submit selected row [Esc] cancel" })
2077
+ /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "[Up/Down] move [Enter] submit [Esc] cancel" })
1955
2078
  ] });
1956
2079
  }
1957
2080
 
1958
2081
  // src/tui/components/SkillList.tsx
1959
2082
  import { Box as Box8, Text as Text8 } from "ink";
1960
2083
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1961
- function markerColor(skill) {
1962
- if (skill.kind === "enabled") {
1963
- return "green";
1964
- }
1965
- if (skill.kind === "issue") {
1966
- return skill.severity === "error" ? "red" : "yellow";
1967
- }
1968
- if (skill.kind === "unmanaged") {
1969
- return "yellow";
1970
- }
1971
- return "gray";
2084
+ function statusLabel2(skill) {
2085
+ if (skill.kind === "enabled") return "\u25CF";
2086
+ if (skill.kind === "disabled") return "\u25CB";
2087
+ if (skill.kind === "unmanaged") return "?";
2088
+ if (skill.severity === "error") return "!";
2089
+ return "*";
1972
2090
  }
1973
- function skillLabel(skill) {
1974
- if (skill.kind === "issue") {
1975
- return skill.issueCode;
1976
- }
1977
- return skill.name;
2091
+ function statusColor2(skill, theme) {
2092
+ if (skill.kind === "enabled") return theme.status.success;
2093
+ if (skill.kind === "disabled") return theme.fg.muted;
2094
+ if (skill.kind === "unmanaged") return theme.status.warning;
2095
+ return skill.severity === "error" ? theme.status.error : theme.status.warning;
2096
+ }
2097
+ function rowLabel(skill) {
2098
+ return skill.kind === "issue" ? skill.issueCode : skill.name;
1978
2099
  }
1979
2100
  function SkillList({
1980
2101
  agentId,
@@ -1986,40 +2107,111 @@ function SkillList({
1986
2107
  width = 28,
1987
2108
  height = 18
1988
2109
  }) {
2110
+ const theme = useTheme();
1989
2111
  const emptyMessage = loadingAgentName !== null ? `Loading skills for ${loadingAgentName}...` : agentId === null ? "Select an agent" : searchQuery !== void 0 && searchQuery.trim().length > 0 ? "No matching skills" : "No skills for this agent";
1990
2112
  return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", width, height, children: [
1991
- /* @__PURE__ */ jsxs8(Text8, { bold: true, color: focused ? "cyan" : void 0, children: [
2113
+ /* @__PURE__ */ jsxs8(Text8, { bold: true, color: focused ? theme.fg.emphasis : theme.fg.muted, children: [
1992
2114
  "Skills for ",
1993
2115
  agentId ?? "none"
1994
2116
  ] }),
1995
2117
  skills.length === 0 ? /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: emptyMessage }) : skills.map((skill) => {
1996
2118
  const selected = skill.id === selectedSkillId;
1997
- return /* @__PURE__ */ jsxs8(Text8, { inverse: focused && selected, children: [
1998
- /* @__PURE__ */ jsx8(Text8, { color: markerColor(skill), children: skill.marker }),
1999
- /* @__PURE__ */ jsxs8(Text8, { children: [
2000
- " ",
2001
- skillLabel(skill)
2002
- ] })
2003
- ] }, skill.id);
2119
+ return /* @__PURE__ */ jsx8(Text8, { children: /* @__PURE__ */ jsxs8(
2120
+ Text8,
2121
+ {
2122
+ backgroundColor: focused && selected ? theme.bg.selection : void 0,
2123
+ children: [
2124
+ /* @__PURE__ */ jsx8(Text8, { bold: true, color: statusColor2(skill, theme), children: statusLabel2(skill) }),
2125
+ /* @__PURE__ */ jsxs8(
2126
+ Text8,
2127
+ {
2128
+ color: focused && selected ? theme.fg.emphasis : theme.fg.default,
2129
+ children: [
2130
+ " ",
2131
+ rowLabel(skill)
2132
+ ]
2133
+ }
2134
+ )
2135
+ ]
2136
+ }
2137
+ ) }, skill.id);
2004
2138
  })
2005
2139
  ] });
2006
2140
  }
2007
2141
 
2008
2142
  // src/tui/components/StatusLine.tsx
2009
2143
  import { Box as Box9, Text as Text9 } from "ink";
2010
- import { jsx as jsx9 } from "react/jsx-runtime";
2011
- function StatusLine({
2012
- busy,
2013
- statusMessage,
2014
- lastScanAt,
2015
- issueCount
2016
- }) {
2017
- const message = statusMessage ?? (busy ? "scanning..." : `Last scan: ${lastScanAt ?? "never"} | issues: ${issueCount}`);
2018
- return /* @__PURE__ */ jsx9(Box9, { height: 1, children: /* @__PURE__ */ jsx9(Text9, { color: busy ? "cyan" : void 0, children: message }) });
2144
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
2145
+ function StatusLine({ busy, statusMessage, model }) {
2146
+ const theme = useTheme();
2147
+ if (busy) {
2148
+ return /* @__PURE__ */ jsxs9(Box9, { height: 1, children: [
2149
+ /* @__PURE__ */ jsx9(Text9, { bold: true, color: theme.status.info, children: "\u26A1 SkillMux" }),
2150
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \xB7 " }),
2151
+ /* @__PURE__ */ jsx9(Text9, { color: theme.status.info, children: statusMessage ?? "scanning..." })
2152
+ ] });
2153
+ }
2154
+ const agentCount = model.agents.length;
2155
+ let enabled = 0;
2156
+ let disabled = 0;
2157
+ let unmanaged = 0;
2158
+ let issueCount = 0;
2159
+ for (const agent of model.agents) {
2160
+ enabled += agent.enabledCount;
2161
+ disabled += agent.disabledCount;
2162
+ unmanaged += agent.unmanagedCount;
2163
+ issueCount += agent.issueCount;
2164
+ }
2165
+ if (statusMessage !== null) {
2166
+ return /* @__PURE__ */ jsxs9(Box9, { height: 1, children: [
2167
+ /* @__PURE__ */ jsx9(Text9, { bold: true, color: theme.fg.emphasis, children: "\u26A1 SkillMux" }),
2168
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \xB7 " }),
2169
+ /* @__PURE__ */ jsx9(Text9, { color: theme.status.warning, children: statusMessage })
2170
+ ] });
2171
+ }
2172
+ return /* @__PURE__ */ jsxs9(Box9, { height: 1, children: [
2173
+ /* @__PURE__ */ jsx9(Text9, { bold: true, color: theme.fg.emphasis, children: "\u26A1 SkillMux" }),
2174
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \xB7 " }),
2175
+ /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
2176
+ agentCount,
2177
+ " agent",
2178
+ agentCount !== 1 ? "s" : ""
2179
+ ] }),
2180
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \u2502 " }),
2181
+ /* @__PURE__ */ jsxs9(Text9, { color: theme.status.success, children: [
2182
+ enabled,
2183
+ " enabled"
2184
+ ] }),
2185
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \u2502 " }),
2186
+ /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
2187
+ disabled,
2188
+ " disabled"
2189
+ ] }),
2190
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \u2502 " }),
2191
+ /* @__PURE__ */ jsxs9(Text9, { color: theme.status.warning, children: [
2192
+ unmanaged,
2193
+ " unmanaged"
2194
+ ] }),
2195
+ issueCount > 0 ? /* @__PURE__ */ jsxs9(Fragment2, { children: [
2196
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \u2502 " }),
2197
+ /* @__PURE__ */ jsxs9(Text9, { color: theme.status.error, children: [
2198
+ issueCount,
2199
+ " issue",
2200
+ issueCount !== 1 ? "s" : ""
2201
+ ] })
2202
+ ] }) : null,
2203
+ model.lastScanAt ? /* @__PURE__ */ jsxs9(Fragment2, { children: [
2204
+ /* @__PURE__ */ jsx9(Text9, { color: theme.fg.muted, children: " \u2502 " }),
2205
+ /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
2206
+ "Last scan: ",
2207
+ model.lastScanAt
2208
+ ] })
2209
+ ] }) : null
2210
+ ] });
2019
2211
  }
2020
2212
 
2021
2213
  // src/tui/components/Dashboard.tsx
2022
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2214
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
2023
2215
  var minimumWidth = 80;
2024
2216
  var minimumHeight = 24;
2025
2217
  var agentRatio = 0.26;
@@ -2030,6 +2222,18 @@ var skillMinimumWidth = 24;
2030
2222
  var detailMinimumWidth = 28;
2031
2223
  var largeModalWidth = 72;
2032
2224
  var largeModalHeight = 14;
2225
+ function horizontalBorder(left, mid, right, ...widths) {
2226
+ const h = "\u2500";
2227
+ let result = left;
2228
+ for (let i = 0; i < widths.length; i++) {
2229
+ result += h.repeat(widths[i]);
2230
+ if (i < widths.length - 1) {
2231
+ result += mid;
2232
+ }
2233
+ }
2234
+ result += right;
2235
+ return result;
2236
+ }
2033
2237
  function paneWidths(width) {
2034
2238
  const agentWidth = Math.max(agentMinimumWidth, Math.round(width * agentRatio));
2035
2239
  const skillWidth = Math.max(skillMinimumWidth, Math.round(width * skillRatio));
@@ -2053,6 +2257,7 @@ function Dashboard({
2053
2257
  height,
2054
2258
  modalInteraction
2055
2259
  }) {
2260
+ const theme = useTheme();
2056
2261
  const interaction = modalInteraction ?? {
2057
2262
  fieldIndex: 0,
2058
2263
  platformIndex: 0,
@@ -2086,16 +2291,19 @@ function Dashboard({
2086
2291
  const { agentWidth, skillWidth, detailWidth } = paneWidths(width);
2087
2292
  const modalWidth = Math.min(width - 4, largeModalWidth);
2088
2293
  const modalHeight = Math.min(bodyHeight, largeModalHeight);
2089
- return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", width, height, children: [
2090
- /* @__PURE__ */ jsx10(
2294
+ const adjustedDetailWidth = Math.max(0, detailWidth - 2);
2295
+ const contentHeight = Math.max(0, bodyHeight - 2);
2296
+ const separatorBorder1 = state.focus === "agents" ? theme.border.focused : theme.border.default;
2297
+ const separatorBorder2 = state.focus === "skills" ? theme.border.focused : theme.border.default;
2298
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", width, height, children: [
2299
+ /* @__PURE__ */ jsx10(Box10, { height: 1, children: /* @__PURE__ */ jsx10(
2091
2300
  StatusLine,
2092
2301
  {
2093
2302
  busy: state.busy,
2094
2303
  statusMessage: state.statusMessage,
2095
- lastScanAt: state.model.lastScanAt,
2096
- issueCount: state.model.issueCount
2304
+ model: state.model
2097
2305
  }
2098
- ),
2306
+ ) }),
2099
2307
  largeModal ? /* @__PURE__ */ jsx10(
2100
2308
  Box10,
2101
2309
  {
@@ -2123,42 +2331,47 @@ function Dashboard({
2123
2331
  }
2124
2332
  ) : state.modal?.kind === "confirm-remove-agent" ? /* @__PURE__ */ jsx10(ConfirmDialog, { modal: state.modal }) : null })
2125
2333
  }
2126
- ) : /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", width, height: bodyHeight, children: [
2127
- /* @__PURE__ */ jsx10(
2128
- AgentList,
2129
- {
2130
- agents: visibleAgents,
2131
- selectedAgentId: state.model.selectedAgentId,
2132
- focused: state.focus === "agents",
2133
- searchQuery: state.search?.panel === "agents" ? state.search.query : void 0,
2134
- width: agentWidth,
2135
- height: bodyHeight
2136
- }
2137
- ),
2138
- /* @__PURE__ */ jsx10(
2139
- SkillList,
2140
- {
2141
- agentId: state.model.selectedAgentId,
2142
- skills: visibleSkills,
2143
- selectedSkillId: state.model.selectedSkillId,
2144
- focused: state.focus === "skills",
2145
- searchQuery: state.search?.panel === "skills" ? state.search.query : void 0,
2146
- loadingAgentName: loadingAgent?.name ?? null,
2147
- width: skillWidth,
2148
- height: bodyHeight
2149
- }
2150
- ),
2151
- /* @__PURE__ */ jsx10(
2152
- DetailPane,
2153
- {
2154
- selectedAgent,
2155
- selectedSkill,
2156
- focused: state.focus === "detail",
2157
- loadingAgentName: loadingAgent?.name ?? null,
2158
- width: detailWidth,
2159
- height: bodyHeight
2160
- }
2161
- )
2334
+ ) : /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
2335
+ /* @__PURE__ */ jsx10(Text10, { color: theme.border.default, children: horizontalBorder("\u251C", "\u252C", "\u2524", agentWidth, skillWidth, detailWidth) }),
2336
+ /* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", width, height: contentHeight, children: [
2337
+ /* @__PURE__ */ jsx10(
2338
+ AgentList,
2339
+ {
2340
+ agents: visibleAgents,
2341
+ selectedAgentId: state.model.selectedAgentId,
2342
+ focused: state.focus === "agents",
2343
+ searchQuery: state.search?.panel === "agents" ? state.search.query : void 0,
2344
+ width: agentWidth,
2345
+ height: contentHeight
2346
+ }
2347
+ ),
2348
+ /* @__PURE__ */ jsx10(Text10, { color: separatorBorder1, children: "\u2502" }),
2349
+ /* @__PURE__ */ jsx10(
2350
+ SkillList,
2351
+ {
2352
+ agentId: state.model.selectedAgentId,
2353
+ skills: visibleSkills,
2354
+ selectedSkillId: state.model.selectedSkillId,
2355
+ focused: state.focus === "skills",
2356
+ searchQuery: state.search?.panel === "skills" ? state.search.query : void 0,
2357
+ loadingAgentName: loadingAgent?.name ?? null,
2358
+ width: skillWidth,
2359
+ height: contentHeight
2360
+ }
2361
+ ),
2362
+ /* @__PURE__ */ jsx10(Text10, { color: separatorBorder2, children: "\u2502" }),
2363
+ /* @__PURE__ */ jsx10(
2364
+ DetailPane,
2365
+ {
2366
+ selectedAgent,
2367
+ selectedSkill,
2368
+ focused: state.focus === "detail",
2369
+ loadingAgentName: loadingAgent?.name ?? null,
2370
+ width: adjustedDetailWidth,
2371
+ height: contentHeight
2372
+ }
2373
+ )
2374
+ ] })
2162
2375
  ] }),
2163
2376
  state.modal?.kind === "help" ? /* @__PURE__ */ jsx10(HelpOverlay, {}) : null,
2164
2377
  state.modal?.kind === "confirm-adopt" || state.modal?.kind === "confirm-adopt-all" || state.modal?.kind === "confirm-remove" || state.modal?.kind === "confirm-discard-dirty-form" ? /* @__PURE__ */ jsx10(ConfirmDialog, { modal: state.modal }) : null,
@@ -3100,13 +3313,14 @@ function App({
3100
3313
  setState(updateTuiState(state, { type: "request-scan" }));
3101
3314
  }
3102
3315
  });
3316
+ const theme = useMemo(() => resolveTheme(), []);
3103
3317
  if (loadError !== null) {
3104
3318
  return /* @__PURE__ */ jsx11(Text11, { color: "red", children: loadError });
3105
3319
  }
3106
3320
  if (state === null) {
3107
3321
  return /* @__PURE__ */ jsx11(Text11, { children: "loading dashboard..." });
3108
3322
  }
3109
- return sizeBridgeEnabled ? /* @__PURE__ */ jsx11(
3323
+ return /* @__PURE__ */ jsx11(ThemeProvider, { value: theme, children: sizeBridgeEnabled ? /* @__PURE__ */ jsx11(
3110
3324
  BridgedDashboardViewport,
3111
3325
  {
3112
3326
  state,
@@ -3123,7 +3337,7 @@ function App({
3123
3337
  terminalHeight,
3124
3338
  modalInteraction
3125
3339
  }
3126
- );
3340
+ ) });
3127
3341
  }
3128
3342
 
3129
3343
  // src/tui/launch-tui.tsx
@@ -3186,4 +3400,4 @@ function sleep(ms) {
3186
3400
  export {
3187
3401
  launchTui
3188
3402
  };
3189
- //# sourceMappingURL=launch-tui-4TJFQA3L.js.map
3403
+ //# sourceMappingURL=launch-tui-JD4F62FS.js.map