@ra3orblade/swarm 0.4.1 → 0.6.0

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.
package/web/icons.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // generated by tools/build.ts — pixelarticons (MIT), 24x24 grid
2
- const ICON_PATHS = {"squares-four":"<path d=\"M4 2h16v2H4zM2 4h2v16H2zm2 7h16v2H4zm16-7h2v16h-2z\"/>\n <path d=\"M11 4h2v18h-2z\"/>\n <path d=\"M4 20h16v2H4z\"/>","timer":"<path d=\"M6 2h12v2H6zM2 6h2v12H2zm18 0h2v12h-2zm-2-2h2v2h-2zM4 4h2v2H4zm2 18h12v-2H6zm12-2h2v-2h-2zM4 20h2v-2H4zm7-14h2v7h-2zm2 7h2v2h-2zm2 2h2v2h-2z\"/>","coins":"<path d=\"M6 2h6v2H6zM4 4h2v2H4zm8 0h2v2h-2zm-8 8h2v2H4zm8 0h2v2h-2zm-6 2h6v2H6zM2 6h2v6H2zm12 0h2v6h-2z\"/>\n <path d=\"M14 8h4v2h-4zm-4 10h2v2h-2zm8-8h2v2h-2zm-6 10h2v2h-2zm6-2h2v2h-2z\"/>\n <path d=\"M12 20h6v2h-6zm-4-6h2v4H8zm12-2h2v6h-2zM7 6h4v2H7z\"/>\n <path d=\"M9 6h2v6H9zm6 8h2v4h-2zm-1-2h3v2h-3z\"/>","pulse":"<path d=\"M22 22H4v-2h18v2ZM4 20H2V2h2v18Zm4-6H6v-2h2v2Zm8 0h-2v-2h2v2Zm-6-2H8v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2Zm-6-2h-2V8h2v2Zm8 0h-2V8h2v2Zm2-2h-2V6h2v2Z\"/>","folder-simple":"<path d=\"M4 4h6v2H4zm0 14h16v2H4zM20 8h2v10h-2zM2 6h2v12H2zm8 0h10v2H10z\"/>","folders":"<path d=\"M9 3H7v14h2zM5 7H3v14h2zm12-6H9v2h8zm4 4h-2v12h2zm-2 12H9v2h10zm-4 4H5v2h10zm2-18h2v2h-2zm-4 0h2v6h-2z\"/>\n <path d=\"M13 7h6v2h-6zM5 5h2v2H5zm10 14h2v2h-2z\"/>","push-pin":"<path d=\"M7 2h10v2H7zM5 4h2v2H5zm14 0h-2v2h2zM7 17h2v2H7zm2 2h2v2H9zm6-2h2v2h-2zm-2 2h2v2h-2zm-2 2h2v2h-2zm-6-7h2v3H5zm12 0h2v3h-2zM3 6h2v8H3zm18 0h-2v8h2zM10 6h4v2h-4zM8 8h2v4H8zm2 4h4v2h-4zm4-4h2v4h-2z\"/>","push-pin-slash":"<path d=\"M7 2h10v2H7zM5 4h2v2H5zm14 0h-2v2h2zM7 17h2v2H7zm2 2h2v2H9zm6-2h2v2h-2zm-2 2h2v2h-2zm-2 2h2v2h-2zm-6-7h2v3H5zm12 0h2v3h-2zM3 6h2v8H3zm18 0h-2v8h2zM10 6h4v2h-4zM8 8h2v4H8zm2 4h4v2h-4zm4-4h2v4h-2z\"/>","x":"<path d=\"M7 19H5V17H7V19ZM19 19H17V17H19V19ZM9 15V17H7V15H9ZM17 17H15V15H17V17ZM11 15H9V13H11V15ZM15 15H13V13H15V15ZM13 13H11V11H13V13ZM11 11H9V9H11V11ZM15 11H13V9H15V11ZM9 9H7V7H9V9ZM17 9H15V7H17V9ZM7 7H5V5H7V7ZM19 7H17V5H19V7Z\"/>","plus":"<path d=\"M13 11h7v2h-7v7h-2v-7H4v-2h7V4h2v7Z\"/>","dots-three":"<path d=\"M3 9h2v2H3zm8 0h2v2h-2zm8 0h2v2h-2zM1 11h2v2H1zm8 0h2v2H9zm8 0h2v2h-2zM3 13h2v2H3zm8 0h2v2h-2zm8 0h2v2h-2zM5 11h2v2H5zm8 0h2v2h-2zm8 0h2v2h-2z\"/>","dots-three-vertical":"<path d=\"M15 3v2h-2V3zm0 8v2h-2v-2zm0 8v2h-2v-2zM13 1v2h-2V1zm0 8v2h-2V9zm0 8v2h-2v-2zM11 3v2H9V3zm0 8v2H9v-2zm0 8v2H9v-2zm2-14v2h-2V5zm0 8v2h-2v-2zm0 8v2h-2v-2z\"/>","keyboard":"<path d=\"M21 21H3v-2h18v2ZM3 19H1V5h2v14Zm20 0h-2V5h2v14Zm-5-2H6v-2h12v2Zm-9-4H7v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2ZM7 9H5V7h2v2Zm4 0H9V7h2v2Zm4 0h-2V7h2v2Zm4 0h-2V7h2v2Zm2-4H3V3h18v2Z\"/>","play":"<path d=\"M15 11h-2V9h2zm0 4h-2v-2h2zm-2 2h-2v-2h2zm0-8h-2V7h2zm-2-2H9V5h2zM9 21H7V3h2zm6-8h2v-2h-2zm-6 4h2v2H9z\"/>","tree-structure":"<path d=\"M6 4h2v2H6zm2-2h8v2H8zm10 4h2v4h-2zm2 4h2v6h-2zm-2 6h2v2h-2zM4 16h2v2H4zm-2-6h2v6H2zm4 8h12v2H6zM4 6h2v4H4z\"/>\n <path d=\"M11 18h2v4h-2zm5-14h2v2h-2z\"/>","robot":"<path d=\"M5 7h14v2H5zm0 12h14v2H5zM3 9h2v10H3zm16 0h2v10h-2zM1 13h2v2H1zm20 0h2v2h-2zM11 5h2v2h-2zM7 3h4v2H7zm1 9h2v4H8zm6 0h2v4h-2z\"/>","coin":"<path d=\"M6 2h6v2H6zM4 4h2v2H4zm8 0h2v2h-2zm-8 8h2v2H4zm8 0h2v2h-2zm-6 2h6v2H6zM2 6h2v6H2zm12 0h2v6h-2z\"/>\n <path d=\"M14 8h4v2h-4zm-4 10h2v2h-2zm8-8h2v2h-2zm-6 10h2v2h-2zm6-2h2v2h-2z\"/>\n <path d=\"M12 20h6v2h-6zm-4-6h2v4H8zm12-2h2v6h-2zM7 6h4v2H7z\"/>\n <path d=\"M9 6h2v6H9zm6 8h2v4h-2zm-1-2h3v2h-3z\"/>","cpu":"<path d=\"M5 3h14v2H5zm0 16h14v2H5zM3 5h2v14H3zm16 0h2v14h-2zM9 7h6v2H9zm0 8h6v2H9zM7 9h2v6H7zm8 0h2v6h-2zm-4-8h2v2h-2zm0 20h2v2h-2zM1 11h2v2H1zm20 0h2v2h-2zm0-4h2v2h-2zm0 8h2v2h-2zM1 15h2v2H1zm0-8h2v2H1zm6-6h2v2H7zm8 0h2v2h-2zm0 20h2v2h-2zm-8 0h2v2H7z\"/>","arrows-clockwise":"<path d=\"M13 22H11V15H13V22ZM5 21H3V19H5V21ZM21 19V21H19V19H21ZM7 19H5V17H7V19ZM19 19H17V17H19V19ZM9 17H7V15H9V17ZM17 17H15V15H17V17ZM9 13H2V11H9V13ZM22 13H15V11H22V13ZM9 9H7V7H9V9ZM13 9H11V2H13V9ZM17 9H15V7H17V9ZM7 7H5V5H7V7ZM19 7H17V5H19V7ZM5 5H3V3H5V5ZM21 5H19V3H21V5Z\"/>","lightning":"<path d=\"M4 20h16v2H4zM4 2h16v2H4zM2 4h2v16H2zm18 0h2v16h-2zM9 15h6v2H9zM7 9h2v6H7zm8 0h2v6h-2zm-4-2h2v5h-2z\"/>","clock":"<path d=\"M6 2h12v2H6zM2 6h2v12H2zm18 0h2v12h-2zm-2-2h2v2h-2zM4 4h2v2H4zm2 18h12v-2H6zm12-2h2v-2h-2zM4 20h2v-2H4zm7-14h2v7h-2zm2 7h2v2h-2zm2 2h2v2h-2z\"/>","wrench":"<path d=\"M18 22H13V24H11V22H6V20H18V22ZM4 22H2V20H4V22ZM22 22H20V20H22V22ZM6 20H4V18H6V20ZM20 20H18V18H20V20ZM4 18H2V13H0V11H2V6H4V18ZM8 18H6V16H8V18ZM22 11H24V13H22V18H20V13H16V16H8V8H16V11H20V6H22V11ZM10 10V14H14V10H10ZM8 8H6V6H8V8ZM6 6H4V4H6V6ZM20 6H18V4H20V6ZM4 4H2V2H4V4ZM13 2H18V4H6V2H11V0H13V2ZM22 4H20V2H22V4Z\"/>","file-text":"<path d=\"M6 4H4v16h2zm10-2H6v2h10zm4 4h-2v14h2zm-2 14H6v2h12zM16 4h2v2h-2zm-4 0h2v6h-2z\"/>\n <path d=\"M12 8h6v2h-6zm-4 8h8v2H8zm0-4h8v2H8zm0-4h2v2H8z\"/>","git-branch":"<path d=\"M2 14h8v2H2zm0 6h8v2H2zm0-4h2v4H2zm6 0h2v4H8zm6-14h8v2h-8zm0 6h8v2h-8zm0-4h2v4h-2zm6 0h2v4h-2zm-8 13h7v2h-7zm5-5h2v5h-2zM5 2h2v10H5z\"/>","git-commit":"<path d=\"M7 7h10v2H7zm0 2h2v6H7zm0 6h10v2H7zm8-6h2v6h-2zM0 11h5v2H0zm19 0h5v2h-5z\"/>","arrow-left":"<path d=\"M20 11v2H4v-2zM8 13v2H6v-2zm2 2v2H8v-2zm2 2v2h-2v-2zm-4-6V9H6v2z\"/>\n <path d=\"M10 15V7H8v8zm2 2V5h-2v12z\"/>","warning":"<path d=\"M4 2h16v2H4zm0 18h16v2H4zM20 4h2v16h-2zM2 4h2v16H2zm9 2h2v8h-2zm0 10h2v2h-2z\"/>","check":"<path d=\"M10 18H8v-2h2v2Zm-2-2H6v-2h2v2Zm4-2v2h-2v-2h2Zm-6 0H4v-2h2v2Zm8 0h-2v-2h2v2Zm2-2h-2v-2h2v2Zm2-2h-2V8h2v2Zm2-2h-2V6h2v2Z\"/>","copy":"<path d=\"M8 6h12v2H8zM4 2h12v2H4zm2 6h2v12H6zM2 4h2v12H2zm6 16h12v2H8zM20 8h2v12h-2zm-4-4h2v2h-2zM4 16h2v2H4z\"/>","arrow-square-out":"<path d=\"M11 5H5v2h6V5ZM5 7H3v12h2V7Zm12 12H5v2h12v-2Zm2-6h-2v6h2v-6Zm-8 0H9v2h2v-2Zm2-2h-2v2h2v-2Zm2-2h-2v2h2V9Zm2-2h-2v2h2V7Zm2-2h-2v2h2V5Zm2-2h-2v8h2V3Z\"/>\n <path d=\"M21 3h-8v2h8V3Z\"/>","moon":"<path d=\"M18 22H8v-2h10v2ZM8 20H6v-2h2v2Zm12 0h-2v-2h2v2ZM6 18H4v-2h2v2Zm16 0h-2v-4h-2v-2h2v-2h2v8ZM4 16H2V6h2v10Zm14 0h-6v-2h6v2Zm-6-2h-2v-2h2v2Zm-2-2H8V6h2v6ZM6 6H4V4h2v2Zm8-2h-2v2h-2V4H6V2h8v2Z\"/>","sun":"<path d=\"M13 22h-2v-3h2v3Zm-6-3H5v-2h2v2Zm12 0h-2v-2h2v2Zm-4-2H9v-2h6v2Zm-6-2H7V9h2v6Zm8 0h-2V9h2v6ZM5 13H2v-2h3v2Zm17 0h-3v-2h3v2Zm-7-4H9V7h6v2ZM7 7H5V5h2v2Zm12 0h-2V5h2v2Zm-6-2h-2V2h2v3Z\"/>","monitor":"<path d=\"M4 2h16v2H4zm0 14h16v2H4zM2 4h2v12H2zm18 0h2v12h-2zm-9 14h2v2h-2zm-3 2h8v2H8z\"/>","gear":"<path d=\"M18 22H13V24H11V22H6V20H18V22ZM4 22H2V20H4V22ZM22 22H20V20H22V22ZM6 20H4V18H6V20ZM20 20H18V18H20V20ZM4 18H2V13H0V11H2V6H4V18ZM8 18H6V16H8V18ZM22 11H24V13H22V18H20V13H16V16H8V8H16V11H20V6H22V11ZM10 10V14H14V10H10ZM8 8H6V6H8V8ZM6 6H4V4H6V6ZM20 6H18V4H20V6ZM4 4H2V2H4V4ZM13 2H18V4H6V2H11V0H13V2ZM22 4H20V2H22V4Z\"/>","book-open":"<path d=\"M2 3h9v2H2zM0 19h11v2H0zM13 3h9v2h-9zm0 16h11v2H13zM11 5h2v18h-2zM0 5h2v14H0zm22 0h2v14h-2zm-7 2h5v2h-5zm0 4h5v2h-5zm0 4h2v2h-2z\"/>","trash":"<path d=\"M18 22H6V20H18V22ZM9 6H15V4H17V6H22V8H20V20H18V8H6V20H4V8H2V6H7V4H9V6ZM15 4H9V2H15V4Z\"/>","magnifying-glass":"<path d=\"M22 22h-2v-2h2v2Zm-2-2h-2v-2h2v2Zm-6-2H6v-2h8v2Zm4 0h-2v-2h2v2ZM6 16H4v-2h2v2Zm10 0h-2v-2h2v2ZM4 14H2V6h2v8Zm14 0h-2V6h2v8ZM6 6H4V4h2v2Zm10 0h-2V4h2v2Zm-2-2H6V2h8v2Z\"/>","terminal-window":"<path d=\"M4 2h16v2H4zm0 18h16v2H4zM2 4h2v16H2zm18 0h2v16h-2zM6 16h2v2H6zm2-2h2v2H8zm-2-2h2v2H6z\"/>","stack":"<path d=\"M9 3H7v14h2zM5 7H3v14h2zm12-6H9v2h8zm4 4h-2v12h2zm-2 12H9v2h10zm-4 4H5v2h10zm2-18h2v2h-2zm-4 0h2v6h-2z\"/>\n <path d=\"M13 7h6v2h-6zM5 5h2v2H5zm10 14h2v2h-2z\"/>","chart-bar":"<path d=\"M4 20h18v2H4zM2 2h2v18H2zm16 11v3h-2v-3zM8 13v3H6v-3zm8-2v2H8v-2zm0 5v2H8v-2zm4-12v3h-2V4zM8 4v3H6V4zm10-2v2H8V2zm0 5v2H8V7z\"/>","clock-counter-clockwise":"<path d=\"M6 2h12v2H6zM2 6h2v12H2zm18 0h2v12h-2zm-2-2h2v2h-2zM4 4h2v2H4zm2 18h12v-2H6zm12-2h2v-2h-2zM4 20h2v-2H4zm7-14h2v7h-2zm2 7h2v2h-2zm2 2h2v2h-2z\"/>","brain":"<path d=\"M4 6h16v2H4zm0 14h16v2H4zM2 8h2v12H2zm18 0h2v12h-2z\"/>\n <path d=\"M11 4h2v4h-2zm-3 6h2v2H8zm6 0h4v2h-4zm-1-8h4v2h-4zM0 12h2v2H0zm22 0h2v2h-2zm-12 4h4v2h-4zm-2-2h2v2H8zm6 0h2v2h-2z\"/>","eye":"<path d=\"M16 20H8v-2h8v2Zm-8-2H4v-2h4v2Zm12 0h-4v-2h4v2ZM4 16H2v-2h2v2Zm10-6h-2v2h2v-2h2v4h-2v2h-4v-2H8v-4h2V8h4v2Zm8 6h-2v-2h2v2ZM2 14H0v-4h2v4Zm22 0h-2v-4h2v4ZM4 10H2V8h2v2Zm18 0h-2V8h2v2ZM8 8H4V6h4v2Zm12 0h-4V6h4v2Zm-4-2H8V4h8v2Z\"/>","pause":"<path d=\"M10 20H4V4h6v16Zm8-16v16h-6V4h6Zm-4 2v12h2V6h-2ZM6 18h2V6H6v12Z\"/>","stop":"<path d=\"M20 20H4V4H20V20ZM6 18H18V6H6V18ZM14 14H10V10H14V14Z\"/>","broadcast":"<path d=\"M4 2h16v2H4zm0 18h16v2H4zM20 4h2v16h-2zM2 4h2v16H2zm5 11h2v2H7zm0-4h4v2H7zm0-4h6v2H7zm4 6h2v4h-2zm4-2h2v6h-2zm-2-2h2v2h-2z\"/>","plugs-connected":"<path d=\"M16 18h-3v4h-2v-4H8v-2h8v2Zm-8-2H6v-2h2v2Zm10 0h-2v-2h2v2Zm-8-9h4V2h2v5h5v2h-1v5h-2V9H6v5H4V9H3V7h5V2h2v5Z\"/>","plugs":"<path d=\"M16 18h-3v4h-2v-4H8v-2h8v2Zm-8-2H6v-2h2v2Zm10 0h-2v-2h2v2Zm-8-9h4V2h2v5h5v2h-1v5h-2V9H6v5H4V9H3V7h5V2h2v5Z\"/>","currency-dollar":"<path d=\"M17 18h-4v4h-2v-4H7v-2h10v2Zm2-2h-2v-3h2v3Zm-2-3H7v-2h10v2ZM7 11H5V8h2v3Zm6-5h4v2H7V6h4V2h2v4Z\"/>","rows":"<path d=\"M10 5h12v2H10zm0 4h8v2h-8zm0 4h12v2H10zm0 4h8v2h-8zm-4-6H4V9h2v2ZM4 9H2V7h2v2Zm4 0H6V7h2v2ZM6 7H4V5h2v2Zm-2 6h2v2H4zm0 4h2v2H4zm-2 0v-2h2v2zm4 0v-2h2v2z\"/>","list-bullets":"<path d=\"M10 5h12v2H10zm0 4h8v2h-8zm0 4h12v2H10zm0 4h8v2h-8zm-4-6H4V9h2v2ZM4 9H2V7h2v2Zm4 0H6V7h2v2ZM6 7H4V5h2v2Zm-2 6h2v2H4zm0 4h2v2H4zm-2 0v-2h2v2zm4 0v-2h2v2z\"/>","sliders":"<path d=\"M8 14H7v6H5v-6H2v-2h6v2Zm5 6h-2V10h2v10Zm9-2h-3v2h-2v-2h-1v-2h6v2Zm-3-4h-2V4h2v10ZM7 10H5V4h2v6Zm6-4h2v2H9V6h2V4h2v2Z\"/>","comment-text":"<path d=\"M4 2h16v2H4zm0 14h14v2H4zm2-6h6v2H6zm0-4h12v2H6zM2 4h2v12H2zm18 0h2v18h-2zm-2 14h2v2h-2z\"/>","arrow-bar-left":"<path d=\"M4 4v16H2V4zm18 7v2H6v-2zm-12 2v2H8v-2zm2 2v2h-2v-2zm2 2v2h-2v-2zm-4-8v2H8V9zm2-2v2h-2V7zm2-2v2h-2V5z\"/>","arrow-bar-right":"<path d=\"M20 4v16h2V4zM2 11v2h16v-2zm12 2v2h2v-2zm-2 2v2h2v-2zm-2 2v2h2v-2zm4-8v2h2V9zm-2-2v2h2V7zm-2-2v2h2V5z\"/>","git-pull-request":"<path d=\"M2 10h8V8H2zm0-6h8V2H2zm0 4h2V4H2zm6 0h2V4H8zm6 14h8v-2h-8zm0-6h8v-2h-8zm0 4h2v-4h-2zm6 0h2v-4h-2zM12 7h5V5h-5zM5 22h2V12H5z\"/>","star":"<path d=\"M5 20H8V22H3V16H5V20ZM21 22H16V20H19V16H21V22ZM10 20H8V18H10V20ZM16 20H14V18H16V20ZM14 18H10V16H14V18ZM7 16H5V13H7V16ZM19 16H17V13H19V16ZM5 13H3V11H5V13ZM21 13H19V11H21V13ZM9 9H3V11H1V7H9V9ZM23 11H21V9H15V7H23V11ZM11 7H9V3H11V7ZM15 7H13V3H15V7ZM13 3H11V1H13V3Z\"/>"};
2
+ const ICON_PATHS = {"squares-four":"<path d=\"M4 2h16v2H4zM2 4h2v16H2zm2 7h16v2H4zm16-7h2v16h-2z\"/>\n <path d=\"M11 4h2v18h-2z\"/>\n <path d=\"M4 20h16v2H4z\"/>","timer":"<path d=\"M6 2h12v2H6zM2 6h2v12H2zm18 0h2v12h-2zm-2-2h2v2h-2zM4 4h2v2H4zm2 18h12v-2H6zm12-2h2v-2h-2zM4 20h2v-2H4zm7-14h2v7h-2zm2 7h2v2h-2zm2 2h2v2h-2z\"/>","coins":"<path d=\"M6 2h6v2H6zM4 4h2v2H4zm8 0h2v2h-2zm-8 8h2v2H4zm8 0h2v2h-2zm-6 2h6v2H6zM2 6h2v6H2zm12 0h2v6h-2z\"/>\n <path d=\"M14 8h4v2h-4zm-4 10h2v2h-2zm8-8h2v2h-2zm-6 10h2v2h-2zm6-2h2v2h-2z\"/>\n <path d=\"M12 20h6v2h-6zm-4-6h2v4H8zm12-2h2v6h-2zM7 6h4v2H7z\"/>\n <path d=\"M9 6h2v6H9zm6 8h2v4h-2zm-1-2h3v2h-3z\"/>","pulse":"<path d=\"M22 22H4v-2h18v2ZM4 20H2V2h2v18Zm4-6H6v-2h2v2Zm8 0h-2v-2h2v2Zm-6-2H8v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2Zm-6-2h-2V8h2v2Zm8 0h-2V8h2v2Zm2-2h-2V6h2v2Z\"/>","folder-simple":"<path d=\"M4 4h6v2H4zm0 14h16v2H4zM20 8h2v10h-2zM2 6h2v12H2zm8 0h10v2H10z\"/>","folders":"<path d=\"M9 3H7v14h2zM5 7H3v14h2zm12-6H9v2h8zm4 4h-2v12h2zm-2 12H9v2h10zm-4 4H5v2h10zm2-18h2v2h-2zm-4 0h2v6h-2z\"/>\n <path d=\"M13 7h6v2h-6zM5 5h2v2H5zm10 14h2v2h-2z\"/>","push-pin":"<path d=\"M7 2h10v2H7zM5 4h2v2H5zm14 0h-2v2h2zM7 17h2v2H7zm2 2h2v2H9zm6-2h2v2h-2zm-2 2h2v2h-2zm-2 2h2v2h-2zm-6-7h2v3H5zm12 0h2v3h-2zM3 6h2v8H3zm18 0h-2v8h2zM10 6h4v2h-4zM8 8h2v4H8zm2 4h4v2h-4zm4-4h2v4h-2z\"/>","push-pin-slash":"<path d=\"M7 2h10v2H7zM5 4h2v2H5zm14 0h-2v2h2zM7 17h2v2H7zm2 2h2v2H9zm6-2h2v2h-2zm-2 2h2v2h-2zm-2 2h2v2h-2zm-6-7h2v3H5zm12 0h2v3h-2zM3 6h2v8H3zm18 0h-2v8h2zM10 6h4v2h-4zM8 8h2v4H8zm2 4h4v2h-4zm4-4h2v4h-2z\"/>","x":"<path d=\"M7 19H5V17H7V19ZM19 19H17V17H19V19ZM9 15V17H7V15H9ZM17 17H15V15H17V17ZM11 15H9V13H11V15ZM15 15H13V13H15V15ZM13 13H11V11H13V13ZM11 11H9V9H11V11ZM15 11H13V9H15V11ZM9 9H7V7H9V9ZM17 9H15V7H17V9ZM7 7H5V5H7V7ZM19 7H17V5H19V7Z\"/>","plus":"<path d=\"M13 11h7v2h-7v7h-2v-7H4v-2h7V4h2v7Z\"/>","dots-three":"<path d=\"M3 9h2v2H3zm8 0h2v2h-2zm8 0h2v2h-2zM1 11h2v2H1zm8 0h2v2H9zm8 0h2v2h-2zM3 13h2v2H3zm8 0h2v2h-2zm8 0h2v2h-2zM5 11h2v2H5zm8 0h2v2h-2zm8 0h2v2h-2z\"/>","dots-three-vertical":"<path d=\"M15 3v2h-2V3zm0 8v2h-2v-2zm0 8v2h-2v-2zM13 1v2h-2V1zm0 8v2h-2V9zm0 8v2h-2v-2zM11 3v2H9V3zm0 8v2H9v-2zm0 8v2H9v-2zm2-14v2h-2V5zm0 8v2h-2v-2zm0 8v2h-2v-2z\"/>","keyboard":"<path d=\"M21 21H3v-2h18v2ZM3 19H1V5h2v14Zm20 0h-2V5h2v14Zm-5-2H6v-2h12v2Zm-9-4H7v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2ZM7 9H5V7h2v2Zm4 0H9V7h2v2Zm4 0h-2V7h2v2Zm4 0h-2V7h2v2Zm2-4H3V3h18v2Z\"/>","play":"<path d=\"M15 11h-2V9h2zm0 4h-2v-2h2zm-2 2h-2v-2h2zm0-8h-2V7h2zm-2-2H9V5h2zM9 21H7V3h2zm6-8h2v-2h-2zm-6 4h2v2H9z\"/>","tree-structure":"<path d=\"M6 4h2v2H6zm2-2h8v2H8zm10 4h2v4h-2zm2 4h2v6h-2zm-2 6h2v2h-2zM4 16h2v2H4zm-2-6h2v6H2zm4 8h12v2H6zM4 6h2v4H4z\"/>\n <path d=\"M11 18h2v4h-2zm5-14h2v2h-2z\"/>","robot":"<path d=\"M5 7h14v2H5zm0 12h14v2H5zM3 9h2v10H3zm16 0h2v10h-2zM1 13h2v2H1zm20 0h2v2h-2zM11 5h2v2h-2zM7 3h4v2H7zm1 9h2v4H8zm6 0h2v4h-2z\"/>","coin":"<path d=\"M6 2h6v2H6zM4 4h2v2H4zm8 0h2v2h-2zm-8 8h2v2H4zm8 0h2v2h-2zm-6 2h6v2H6zM2 6h2v6H2zm12 0h2v6h-2z\"/>\n <path d=\"M14 8h4v2h-4zm-4 10h2v2h-2zm8-8h2v2h-2zm-6 10h2v2h-2zm6-2h2v2h-2z\"/>\n <path d=\"M12 20h6v2h-6zm-4-6h2v4H8zm12-2h2v6h-2zM7 6h4v2H7z\"/>\n <path d=\"M9 6h2v6H9zm6 8h2v4h-2zm-1-2h3v2h-3z\"/>","cpu":"<path d=\"M5 3h14v2H5zm0 16h14v2H5zM3 5h2v14H3zm16 0h2v14h-2zM9 7h6v2H9zm0 8h6v2H9zM7 9h2v6H7zm8 0h2v6h-2zm-4-8h2v2h-2zm0 20h2v2h-2zM1 11h2v2H1zm20 0h2v2h-2zm0-4h2v2h-2zm0 8h2v2h-2zM1 15h2v2H1zm0-8h2v2H1zm6-6h2v2H7zm8 0h2v2h-2zm0 20h2v2h-2zm-8 0h2v2H7z\"/>","arrows-clockwise":"<path d=\"M13 22H11V15H13V22ZM5 21H3V19H5V21ZM21 19V21H19V19H21ZM7 19H5V17H7V19ZM19 19H17V17H19V19ZM9 17H7V15H9V17ZM17 17H15V15H17V17ZM9 13H2V11H9V13ZM22 13H15V11H22V13ZM9 9H7V7H9V9ZM13 9H11V2H13V9ZM17 9H15V7H17V9ZM7 7H5V5H7V7ZM19 7H17V5H19V7ZM5 5H3V3H5V5ZM21 5H19V3H21V5Z\"/>","lightning":"<path d=\"M4 20h16v2H4zM4 2h16v2H4zM2 4h2v16H2zm18 0h2v16h-2zM9 15h6v2H9zM7 9h2v6H7zm8 0h2v6h-2zm-4-2h2v5h-2z\"/>","clock":"<path d=\"M6 2h12v2H6zM2 6h2v12H2zm18 0h2v12h-2zm-2-2h2v2h-2zM4 4h2v2H4zm2 18h12v-2H6zm12-2h2v-2h-2zM4 20h2v-2H4zm7-14h2v7h-2zm2 7h2v2h-2zm2 2h2v2h-2z\"/>","wrench":"<path d=\"M18 22H13V24H11V22H6V20H18V22ZM4 22H2V20H4V22ZM22 22H20V20H22V22ZM6 20H4V18H6V20ZM20 20H18V18H20V20ZM4 18H2V13H0V11H2V6H4V18ZM8 18H6V16H8V18ZM22 11H24V13H22V18H20V13H16V16H8V8H16V11H20V6H22V11ZM10 10V14H14V10H10ZM8 8H6V6H8V8ZM6 6H4V4H6V6ZM20 6H18V4H20V6ZM4 4H2V2H4V4ZM13 2H18V4H6V2H11V0H13V2ZM22 4H20V2H22V4Z\"/>","file-text":"<path d=\"M6 4H4v16h2zm10-2H6v2h10zm4 4h-2v14h2zm-2 14H6v2h12zM16 4h2v2h-2zm-4 0h2v6h-2z\"/>\n <path d=\"M12 8h6v2h-6zm-4 8h8v2H8zm0-4h8v2H8zm0-4h2v2H8z\"/>","git-branch":"<path d=\"M2 14h8v2H2zm0 6h8v2H2zm0-4h2v4H2zm6 0h2v4H8zm6-14h8v2h-8zm0 6h8v2h-8zm0-4h2v4h-2zm6 0h2v4h-2zm-8 13h7v2h-7zm5-5h2v5h-2zM5 2h2v10H5z\"/>","git-commit":"<path d=\"M7 7h10v2H7zm0 2h2v6H7zm0 6h10v2H7zm8-6h2v6h-2zM0 11h5v2H0zm19 0h5v2h-5z\"/>","arrow-left":"<path d=\"M20 11v2H4v-2zM8 13v2H6v-2zm2 2v2H8v-2zm2 2v2h-2v-2zm-4-6V9H6v2z\"/>\n <path d=\"M10 15V7H8v8zm2 2V5h-2v12z\"/>","warning":"<path d=\"M4 2h16v2H4zm0 18h16v2H4zM20 4h2v16h-2zM2 4h2v16H2zm9 2h2v8h-2zm0 10h2v2h-2z\"/>","check":"<path d=\"M10 18H8v-2h2v2Zm-2-2H6v-2h2v2Zm4-2v2h-2v-2h2Zm-6 0H4v-2h2v2Zm8 0h-2v-2h2v2Zm2-2h-2v-2h2v2Zm2-2h-2V8h2v2Zm2-2h-2V6h2v2Z\"/>","copy":"<path d=\"M8 6h12v2H8zM4 2h12v2H4zm2 6h2v12H6zM2 4h2v12H2zm6 16h12v2H8zM20 8h2v12h-2zm-4-4h2v2h-2zM4 16h2v2H4z\"/>","arrow-square-out":"<path d=\"M11 5H5v2h6V5ZM5 7H3v12h2V7Zm12 12H5v2h12v-2Zm2-6h-2v6h2v-6Zm-8 0H9v2h2v-2Zm2-2h-2v2h2v-2Zm2-2h-2v2h2V9Zm2-2h-2v2h2V7Zm2-2h-2v2h2V5Zm2-2h-2v8h2V3Z\"/>\n <path d=\"M21 3h-8v2h8V3Z\"/>","moon":"<path d=\"M18 22H8v-2h10v2ZM8 20H6v-2h2v2Zm12 0h-2v-2h2v2ZM6 18H4v-2h2v2Zm16 0h-2v-4h-2v-2h2v-2h2v8ZM4 16H2V6h2v10Zm14 0h-6v-2h6v2Zm-6-2h-2v-2h2v2Zm-2-2H8V6h2v6ZM6 6H4V4h2v2Zm8-2h-2v2h-2V4H6V2h8v2Z\"/>","sun":"<path d=\"M13 22h-2v-3h2v3Zm-6-3H5v-2h2v2Zm12 0h-2v-2h2v2Zm-4-2H9v-2h6v2Zm-6-2H7V9h2v6Zm8 0h-2V9h2v6ZM5 13H2v-2h3v2Zm17 0h-3v-2h3v2Zm-7-4H9V7h6v2ZM7 7H5V5h2v2Zm12 0h-2V5h2v2Zm-6-2h-2V2h2v3Z\"/>","monitor":"<path d=\"M4 2h16v2H4zm0 14h16v2H4zM2 4h2v12H2zm18 0h2v12h-2zm-9 14h2v2h-2zm-3 2h8v2H8z\"/>","gear":"<path d=\"M18 22H13V24H11V22H6V20H18V22ZM4 22H2V20H4V22ZM22 22H20V20H22V22ZM6 20H4V18H6V20ZM20 20H18V18H20V20ZM4 18H2V13H0V11H2V6H4V18ZM8 18H6V16H8V18ZM22 11H24V13H22V18H20V13H16V16H8V8H16V11H20V6H22V11ZM10 10V14H14V10H10ZM8 8H6V6H8V8ZM6 6H4V4H6V6ZM20 6H18V4H20V6ZM4 4H2V2H4V4ZM13 2H18V4H6V2H11V0H13V2ZM22 4H20V2H22V4Z\"/>","book-open":"<path d=\"M2 3h9v2H2zM0 19h11v2H0zM13 3h9v2h-9zm0 16h11v2H13zM11 5h2v18h-2zM0 5h2v14H0zm22 0h2v14h-2zm-7 2h5v2h-5zm0 4h5v2h-5zm0 4h2v2h-2z\"/>","trash":"<path d=\"M18 22H6V20H18V22ZM9 6H15V4H17V6H22V8H20V20H18V8H6V20H4V8H2V6H7V4H9V6ZM15 4H9V2H15V4Z\"/>","magnifying-glass":"<path d=\"M22 22h-2v-2h2v2Zm-2-2h-2v-2h2v2Zm-6-2H6v-2h8v2Zm4 0h-2v-2h2v2ZM6 16H4v-2h2v2Zm10 0h-2v-2h2v2ZM4 14H2V6h2v8Zm14 0h-2V6h2v8ZM6 6H4V4h2v2Zm10 0h-2V4h2v2Zm-2-2H6V2h8v2Z\"/>","terminal-window":"<path d=\"M4 2h16v2H4zm0 18h16v2H4zM2 4h2v16H2zm18 0h2v16h-2zM6 16h2v2H6zm2-2h2v2H8zm-2-2h2v2H6z\"/>","stack":"<path d=\"M9 3H7v14h2zM5 7H3v14h2zm12-6H9v2h8zm4 4h-2v12h2zm-2 12H9v2h10zm-4 4H5v2h10zm2-18h2v2h-2zm-4 0h2v6h-2z\"/>\n <path d=\"M13 7h6v2h-6zM5 5h2v2H5zm10 14h2v2h-2z\"/>","chart-bar":"<path d=\"M4 20h18v2H4zM2 2h2v18H2zm16 11v3h-2v-3zM8 13v3H6v-3zm8-2v2H8v-2zm0 5v2H8v-2zm4-12v3h-2V4zM8 4v3H6V4zm10-2v2H8V2zm0 5v2H8V7z\"/>","clock-counter-clockwise":"<path d=\"M6 2h12v2H6zM2 6h2v12H2zm18 0h2v12h-2zm-2-2h2v2h-2zM4 4h2v2H4zm2 18h12v-2H6zm12-2h2v-2h-2zM4 20h2v-2H4zm7-14h2v7h-2zm2 7h2v2h-2zm2 2h2v2h-2z\"/>","brain":"<path d=\"M4 6h16v2H4zm0 14h16v2H4zM2 8h2v12H2zm18 0h2v12h-2z\"/>\n <path d=\"M11 4h2v4h-2zm-3 6h2v2H8zm6 0h4v2h-4zm-1-8h4v2h-4zM0 12h2v2H0zm22 0h2v2h-2zm-12 4h4v2h-4zm-2-2h2v2H8zm6 0h2v2h-2z\"/>","eye":"<path d=\"M16 20H8v-2h8v2Zm-8-2H4v-2h4v2Zm12 0h-4v-2h4v2ZM4 16H2v-2h2v2Zm10-6h-2v2h2v-2h2v4h-2v2h-4v-2H8v-4h2V8h4v2Zm8 6h-2v-2h2v2ZM2 14H0v-4h2v4Zm22 0h-2v-4h2v4ZM4 10H2V8h2v2Zm18 0h-2V8h2v2ZM8 8H4V6h4v2Zm12 0h-4V6h4v2Zm-4-2H8V4h8v2Z\"/>","pause":"<path d=\"M10 20H4V4h6v16Zm8-16v16h-6V4h6Zm-4 2v12h2V6h-2ZM6 18h2V6H6v12Z\"/>","stop":"<path d=\"M20 20H4V4H20V20ZM6 18H18V6H6V18ZM14 14H10V10H14V14Z\"/>","broadcast":"<path d=\"M4 2h16v2H4zm0 18h16v2H4zM20 4h2v16h-2zM2 4h2v16H2zm5 11h2v2H7zm0-4h4v2H7zm0-4h6v2H7zm4 6h2v4h-2zm4-2h2v6h-2zm-2-2h2v2h-2z\"/>","plugs-connected":"<path d=\"M16 18h-3v4h-2v-4H8v-2h8v2Zm-8-2H6v-2h2v2Zm10 0h-2v-2h2v2Zm-8-9h4V2h2v5h5v2h-1v5h-2V9H6v5H4V9H3V7h5V2h2v5Z\"/>","plugs":"<path d=\"M16 18h-3v4h-2v-4H8v-2h8v2Zm-8-2H6v-2h2v2Zm10 0h-2v-2h2v2Zm-8-9h4V2h2v5h5v2h-1v5h-2V9H6v5H4V9H3V7h5V2h2v5Z\"/>","currency-dollar":"<path d=\"M17 18h-4v4h-2v-4H7v-2h10v2Zm2-2h-2v-3h2v3Zm-2-3H7v-2h10v2ZM7 11H5V8h2v3Zm6-5h4v2H7V6h4V2h2v4Z\"/>","rows":"<path d=\"M10 5h12v2H10zm0 4h8v2h-8zm0 4h12v2H10zm0 4h8v2h-8zm-4-6H4V9h2v2ZM4 9H2V7h2v2Zm4 0H6V7h2v2ZM6 7H4V5h2v2Zm-2 6h2v2H4zm0 4h2v2H4zm-2 0v-2h2v2zm4 0v-2h2v2z\"/>","list-bullets":"<path d=\"M10 5h12v2H10zm0 4h8v2h-8zm0 4h12v2H10zm0 4h8v2h-8zm-4-6H4V9h2v2ZM4 9H2V7h2v2Zm4 0H6V7h2v2ZM6 7H4V5h2v2Zm-2 6h2v2H4zm0 4h2v2H4zm-2 0v-2h2v2zm4 0v-2h2v2z\"/>","sliders":"<path d=\"M8 14H7v6H5v-6H2v-2h6v2Zm5 6h-2V10h2v10Zm9-2h-3v2h-2v-2h-1v-2h6v2Zm-3-4h-2V4h2v10ZM7 10H5V4h2v6Zm6-4h2v2H9V6h2V4h2v2Z\"/>","comment-text":"<path d=\"M4 2h16v2H4zm0 14h14v2H4zm2-6h6v2H6zm0-4h12v2H6zM2 4h2v12H2zm18 0h2v18h-2zm-2 14h2v2h-2z\"/>","arrow-bar-left":"<path d=\"M4 4v16H2V4zm18 7v2H6v-2zm-12 2v2H8v-2zm2 2v2h-2v-2zm2 2v2h-2v-2zm-4-8v2H8V9zm2-2v2h-2V7zm2-2v2h-2V5z\"/>","arrow-bar-right":"<path d=\"M20 4v16h2V4zM2 11v2h16v-2zm12 2v2h2v-2zm-2 2v2h2v-2zm-2 2v2h2v-2zm4-8v2h2V9zm-2-2v2h2V7zm-2-2v2h2V5z\"/>","git-pull-request":"<path d=\"M2 10h8V8H2zm0-6h8V2H2zm0 4h2V4H2zm6 0h2V4H8zm6 14h8v-2h-8zm0-6h8v-2h-8zm0 4h2v-4h-2zm6 0h2v-4h-2zM12 7h5V5h-5zM5 22h2V12H5z\"/>","star":"<path d=\"M5 20H8V22H3V16H5V20ZM21 22H16V20H19V16H21V22ZM10 20H8V18H10V20ZM16 20H14V18H16V20ZM14 18H10V16H14V18ZM7 16H5V13H7V16ZM19 16H17V13H19V16ZM5 13H3V11H5V13ZM21 13H19V11H21V13ZM9 9H3V11H1V7H9V9ZM23 11H21V9H15V7H23V11ZM11 7H9V3H11V7ZM15 7H13V3H15V7ZM13 3H11V1H13V3Z\"/>","shield":"<path d=\"M4 2h16v2H4zM2 4h2v10H2zm18 0h2v10h-2zM4 14h2v2H4zm2 2h2v2H6zm4 4h4v2h-4zm10-6h-2v2h2zm-2 2h-2v2h2zm-2 2h-2v2h2zm-6 0H8v2h2z\"/>","bell":"<path d=\"M9 2h6v2H9zM7 4h2v2H7zm8 0h2v2h-2zM5 6h2v7H5zm12 0h2v7h-2zM3 13h2v4H3zm16 0h2v4h-2z\"/>\n <path d=\"M3 15h18v2H3zm5 3h2v2H8zm6 0h2v2h-2zm-4 2h4v2h-4z\"/>","arrow-right":"<path d=\"M4 11v2h16v-2zm12 2v2h2v-2zm-2 2v2h2v-2zm-2 2v2h2v-2zm4-6V9h2v2z\"/>\n <path d=\"M14 15V7h2v8zm-2 2V5h2v12z\"/>"};
3
3
  window.icon = (name, size = 16, cls = "") => { const p = ICON_PATHS[name]; if (!p) return ""; return `<svg class="ph ${cls}" width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor" shape-rendering="crispEdges" aria-hidden="true">${p}</svg>`; };
4
- window.ICON_NAMES = ["squares-four","timer","coins","pulse","folder-simple","folders","push-pin","push-pin-slash","x","plus","dots-three","dots-three-vertical","keyboard","play","tree-structure","robot","coin","cpu","arrows-clockwise","lightning","clock","wrench","file-text","git-branch","git-commit","arrow-left","warning","check","copy","arrow-square-out","moon","sun","monitor","gear","book-open","trash","magnifying-glass","terminal-window","stack","chart-bar","clock-counter-clockwise","brain","eye","pause","stop","broadcast","plugs-connected","plugs","currency-dollar","rows","list-bullets","sliders","comment-text","arrow-bar-left","arrow-bar-right","git-pull-request","star"];
4
+ window.ICON_NAMES = ["squares-four","timer","coins","pulse","folder-simple","folders","push-pin","push-pin-slash","x","plus","dots-three","dots-three-vertical","keyboard","play","tree-structure","robot","coin","cpu","arrows-clockwise","lightning","clock","wrench","file-text","git-branch","git-commit","arrow-left","warning","check","copy","arrow-square-out","moon","sun","monitor","gear","book-open","trash","magnifying-glass","terminal-window","stack","chart-bar","clock-counter-clockwise","brain","eye","pause","stop","broadcast","plugs-connected","plugs","currency-dollar","rows","list-bullets","sliders","comment-text","arrow-bar-left","arrow-bar-right","git-pull-request","star","shield","bell","arrow-right"];
package/web/index.html CHANGED
@@ -141,6 +141,18 @@
141
141
  .proj:hover small{display:none}
142
142
  .proj .act:hover{color:var(--fg);background:var(--line)}
143
143
  .proj .act.rm:hover{color:var(--bad)}
144
+ .srch{display:flex;gap:8px;margin-bottom:14px}
145
+ .srch input{flex:1;max-width:640px;background:var(--panel);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);padding:8px 12px;font:var(--fs-md) var(--sans)}
146
+ .srch input:focus{border-color:var(--acc);outline:none}
147
+ .hit{padding:10px 12px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel);margin-bottom:8px}
148
+ .hit .ht{display:flex;gap:8px;align-items:center;margin-bottom:4px}
149
+ .hit .hs{font-size:var(--fs-sm);color:var(--fg-2);white-space:pre-wrap}
150
+ .hit mark{background:var(--warn-soft);color:var(--fg);border-radius:2px;padding:0 1px}
151
+ .dr-rules{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 16px;margin:10px 0}
152
+ .dr-rule{display:flex;align-items:center;gap:8px;font-size:var(--fs-sm)}
153
+ .dr-rule select{background:var(--panel-2);color:var(--fg);border:1px solid var(--line);border-radius:var(--r-sm);padding:2px 4px}
154
+ .dr-flaky{padding:6px 8px;border:1px solid var(--line);border-radius:var(--r-sm);margin:6px 0;background:var(--panel-2)}
155
+ table.plain{width:100%;border-collapse:collapse;font-size:var(--fs-sm)} table.plain td{padding:3px 6px;border-top:1px solid var(--line);vertical-align:top}
144
156
  #picker:empty{display:none}
145
157
  #picker{position:fixed;inset:0;background:var(--overlay);display:grid;place-items:center;z-index:50}
146
158
  .pk{width:min(560px,92vw);max-height:78vh;display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-pop);overflow:hidden}
@@ -149,6 +161,41 @@
149
161
  .pk-row{display:flex;align-items:center;gap:9px;padding:var(--pad-row);border-radius:var(--r-sm);cursor:pointer;color:var(--fg-2)}
150
162
  .pk-row:hover{background:var(--panel-2)}.pk-row .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
151
163
  .pk-row.up{color:var(--dim)}.pk-row .badge{margin:0}
164
+ .pk-b{padding:12px 14px;display:grid;gap:10px}
165
+ .pk-b label{display:grid;gap:4px;font:500 var(--fs-sm) var(--sans);color:var(--dim)}
166
+ .pk-b input,.pk-b textarea,.pk-b select{width:100%;background:var(--panel-2);border:1px solid var(--line);color:var(--fg);
167
+ border-radius:var(--r-sm);padding:7px 9px;font:var(--fs-md) var(--sans);outline:none}
168
+ .pk-b textarea{min-height:120px;resize:vertical;font-family:var(--mono);font-size:var(--fs-sm);line-height:1.5}
169
+ .pk-b input:focus,.pk-b textarea:focus,.pk-b select:focus{border-color:var(--acc)}
170
+ .pk-b .row{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}
171
+ /* What's New (release notes) */
172
+ .wn .pk-b{max-height:64vh;overflow:auto;gap:2px}
173
+ .wn h3{margin:0 0 2px;font:600 var(--fs-lg) var(--sans);color:var(--fg)}
174
+ .wn .date{color:var(--dim);font-size:var(--fs-sm);margin-bottom:12px}
175
+ .wn h4{margin:14px 0 4px;font:600 var(--fs-md) var(--sans);color:var(--acc);text-transform:none;letter-spacing:0}
176
+ .wn ul{margin:0 0 6px;padding-left:18px}
177
+ .wn li{margin:5px 0;line-height:1.55;color:var(--fg-2)}
178
+ .wn p{margin:0 0 10px;color:var(--fg-2);line-height:1.6}
179
+ .wn code{font-family:var(--mono);font-size:var(--fs-sm);background:var(--panel-2);border-radius:var(--r-xs);padding:1px 5px}
180
+ .wn a{color:var(--acc)}
181
+ .wn b{color:var(--fg)}
182
+ .wn .snip{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);padding:9px 11px;font-family:var(--mono);font-size:var(--fs-sm);line-height:1.5;white-space:pre-wrap;word-break:break-word;margin:2px 0 12px;color:var(--fg-2)}
183
+ .wn .cbtn{font-weight:500;font-size:var(--fs-sm);color:var(--acc);margin-left:8px}
184
+ .rp .snip{max-height:32vh;overflow:auto}
185
+ .rp .pk-f input[type=range]{accent-color:var(--acc)}
186
+ /* pending permission prompts (M3.2) */
187
+ .perm{background:var(--warn-soft);border:1px solid var(--warn);border-radius:var(--r-sm);padding:10px 12px;margin-top:10px}
188
+ .perm-t{font:500 var(--fs-md) var(--sans);color:var(--fg)}
189
+ .perm-c{font-family:var(--mono);font-size:var(--fs-sm);color:var(--fg-2);margin:6px 0 8px;word-break:break-all;background:var(--panel-2);border-radius:var(--r-xs);padding:6px 8px}
190
+ .perm-b{display:flex;gap:8px}
191
+ .perm-b .ok{color:var(--acc);border-color:var(--acc-soft)}
192
+ .perm-b .danger{color:var(--warn);border-color:var(--warn-soft)}
193
+ /* stdin box for spawned sessions (M3.3) */
194
+ .stdin{display:flex;gap:8px;margin-top:10px;align-items:center}
195
+ .stdin input{flex:1;background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);padding:8px 10px;font:var(--fs-md) var(--sans);outline:none}
196
+ .stdin input:focus{border-color:var(--acc)}
197
+ .stdin button.danger{color:var(--warn);border-color:var(--warn-soft)}
198
+ .stdin .hint{color:var(--dim);font-size:var(--fs-sm)}
152
199
  .pk-f{display:flex;gap:8px;padding:12px 14px;border-top:1px solid var(--line)}
153
200
  .pk-f button{flex:none}.pk-f .grow{flex:1}
154
201
  .pk-f .primary{background:var(--acc);border-color:var(--acc);color:var(--acc-contrast)}
@@ -239,6 +286,7 @@
239
286
  /* session detail */
240
287
  .sess{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:stretch}
241
288
  .sess>*{height:calc(100vh - 140px);min-height:320px}
289
+ .sess.has-stdin>*{height:calc(100vh - 196px)}
242
290
  @media (max-width:980px){.sess{grid-template-columns:1fr}.sess>*{height:auto;max-height:calc(100vh - 140px)}}
243
291
  #log{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);
244
292
  padding:6px 0;overflow:auto}
@@ -424,6 +472,7 @@
424
472
  <a href="#" data-view="timeline" class="nav"><i data-icon="clock-counter-clockwise"></i>Timeline</a>
425
473
  <a href="#" data-view="spend" class="nav"><i data-icon="coins"></i>Spend</a>
426
474
  <a href="#" data-view="stats" class="nav"><i data-icon="chart-bar"></i>Stats</a>
475
+ <a href="#" data-view="search" class="nav"><i data-icon="magnifying-glass"></i>Search</a>
427
476
  <span class="sp"></span>
428
477
  <span id="today"></span>
429
478
  <span id="daemon"><span class="dot"></span><span class="lbl">Daemon</span></span>
@@ -436,6 +485,7 @@
436
485
  <main id="main"></main>
437
486
  <div id="picker"></div>
438
487
  <script src="/icons.js"></script>
488
+ <script src="/release-notes.js"></script>
439
489
  <script src="/viz.js"></script>
440
490
  <script src="/table.js"></script>
441
491
  <script src="/app.js"></script>
@@ -0,0 +1,2 @@
1
+ // generated by tools/build.ts from CHANGELOG.md
2
+ window.RELEASE_NOTES = {"0.6.0":{"date":"2026-08-23","html":"<p>The learn release: the data Swarm has been collecting starts paying back. Replay what an agent did, see what each task cost, turn an incident into a rule, resume a session that died, try a rule on history before switching it on, read your backlog from GitHub or Linear, and search everything Swarm remembers.</p>\n<h4>Added</h4>\n<ul><li><b>Session Replay</b> — a <b>Replay</b> button on any session steps through its tool calls one at a time, showing the full input and output of each (Prev/Next, a slider, ←/→ keys). See exactly what an agent did, in order (M4.1).</li><li><b>Cost by task</b> — the Spend view attributes cost and tokens to each task (matched to a claim by the session's worktree), plus a <b>Context budget</b> table ranking sessions by how much context they re-processed — a signal for agents re-reading the same material. <code>GET /v1/attribution</code> (M4.2).</li><li><b>Codify an incident</b> — the Incidents feed has a <b>Codify</b> action that turns an incident into a <code>.swarm.toml</code> rule snippet and a CLAUDE.md lesson, both copyable. A rule that keeps firing as <code>ask</code> suggests hardening to <code>deny</code> (M4.3).</li><li><b>Desktop notifications</b> — opt-in native notifications (settings menu) for a spawned run waiting on a permission, or a claim orphaned with unfinished work; clicking opens the Allow/Deny card or the Board. Quiet while you're looking at the dashboard (M4.7).</li><li><b>Auto-handoff, and resume where it died</b> — whenever a session working in a claimed worktree pauses or ends, Swarm derives a handoff from what it did: files edited, the last verification-looking command, the last request, the last thing it said. One <code>auto:</code> handoff per session, replaced on every pause, silenced by a handoff left on purpose. An ended session's page gets <b>Resume where it died</b>, which spawns a run on the task from that handoff plus the session's last actions; <code>swarm run resume &lt;session-id&gt;</code>; <code>GET/POST /v1/sessions/:id/resume</code> (M4.4).</li><li><b>Rule dry-run</b> — <b>Dry-run rules</b> on the Incidents view replays a project's recorded tool calls through the rules under modes you pick: what would have been asked or denied, per rule, before you switch anything on. It also flags <b>flaky signals</b> — a rule that keeps firing on the same command that is then allowed through anyway. Nothing is recorded. <code>swarm rules dryrun [--set rule=mode,…]</code>; <code>GET /v1/rules/dryrun</code> (M4.6).</li><li><b>GitHub Issues and Linear as task sources</b> — <code>[tasks] source = \"github\"</code> reads the repo's issues through the logged-in <code>gh</code> (optional <code>labels</code> filter); <code>source = \"linear\"</code> reads Linear through its API with <code>LINEAR_API_KEY</code> from the daemon's environment (optional <code>team</code>). Both land in the Board's Tasks, <code>swarm tasks</code> and <code>swarm_next_task</code> like a markdown backlog: closed/completed is done, in-progress is active, <em>depends on #n</em> / <em>blocked by</em> become dependencies. Read-only; no credential stored (M4.8).</li><li><b>What's New in the app</b> — the dashboard shows the release notes for the running version: a <b>What's New</b> item in the settings menu, in the desktop app's <b>Swarm</b> menu, and in the tray. It also opens once on its own the first time you run a new version. Notes are parsed from <code>CHANGELOG.md</code> into <code>release-notes.js</code> at build time, so they work offline with no repo checkout.</li><li>The desktop <b>Check for Updates…</b> is in the system menu bar (Swarm menu), not only the tray.</li></ul>"},"0.5.0":{"date":"2026-08-22","html":"<p>The drive release: Swarm doesn't just watch agents now — it starts them, in a claimed worktree, and brokers what they're allowed to do. Plus the coordination primitives that make an autonomous run safe to leave alone: leases that renew themselves, gates that gate, and a handoff the next session reads on its own.</p>\n<h4>Added</h4>\n<ul><li><b><code>swarm run</code></b> — spawn an agent on a task. <code>swarm run --task login-form --prompt \"…\"</code> claims the task and the daemon starts <code>claude -p</code> in its worktree with stream-json on both ends. Steer it with <code>swarm run send</code>, stop it with <code>swarm run stop</code> (stdin closed, then the process registry's pid-based TERM/KILL — never by pattern), list with <code>swarm run ls</code>. The session shows in Fleet as ▶ spawned and is ingested like any other; every finished turn is a <code>run.result</code> event with cost and turns (M3.1).</li><li><b>Run from the dashboard</b> — Ready (or held) task rows on the Board get a <b>Run</b> action: a drawer with the prompt prefilled from the task, permission mode, model and max turns (⌘⏎ to submit). The spawned session opens with a stdin box to steer it and a <b>Stop</b> button (M3.3).</li><li><b>Permission broker</b> — a <code>swarm run</code> agent's tool-permission prompts go through the same rules as your interactive sessions: a rule <code>deny</code> auto-denies with the reason, an unflagged tool auto-allows so the agent can make progress, and anything the rules mark <code>ask</code> is held and surfaced on the session as an <b>Allow / Deny</b> card. No blocking on a terminal you can't see. Uses <code>--permission-prompt-tool stdio</code>; <code>POST /v1/runs/:id/permissions/:reqId</code> (M3.2).</li><li><b>Leases renew themselves.</b> A session working inside a claimed worktree extends the lease on any activity (hook or transcript growth) once it is past half-way — no more <code>swarm renew</code> in a long session. Expired leases whose worktree still holds uncommitted or unpushed work are marked <b>Orphaned</b> within a minute and open an <code>orphaned_claim</code> incident; nothing is removed automatically (M1.2).</li><li><b>Handoffs, injected on start</b> — <code>swarm handoff &lt;task&gt; --done … --remaining … [--files] [--verify]</code> (or <code>swarm_handoff</code>) records what the last holder leaves; <code>swarm resume</code> / <code>swarm_resume</code> reads it. The next session that starts inside that task's worktree gets it automatically as <code>SessionStart</code> context, along with what it holds and the lease left, gate status, held resources, and the repo's rule modes (M1.3).</li><li><b>Gates</b> — verification runs recorded against a task: <code>swarm gate record login-form review pass --rubric \"tests green, error paths read\"</code> (or <code>swarm_gate_record</code>). A run without a rubric is rejected; the latest run per gate decides; failed runs are never deleted and open a <code>gate_failed</code> incident. <code>.swarm.toml [gates] required = [\"review\"]</code> declares what every task must pass; the Board's Tasks grid shows ✓ / ✗ / — per gate and a <b>Recent gates</b> section lists the runs (M2.2).</li><li><b>The MCP tools finally connect.</b> <code>swarm_status</code>, <code>swarm_claim</code>, <code>swarm_next_task</code>, <code>swarm_handoff</code>, <code>swarm_gate_record</code>, <code>swarm_acquire_resource</code> and the rest are reachable from Claude Code — see the fix below.</li><li>Dashboard deep links (<code>?view=board&amp;project=&lt;id&gt;&amp;session=&lt;id&gt;</code>) and a screenshot carousel with a lightbox on the website; <code>tools/screens.ts</code> re-captures the shots with Playwright at 2×.</li></ul><h4>Fixed</h4>\n<ul><li><b>Swarm's MCP tools were never reachable.</b> <code>swarm install</code> wrote <code>mcpServers.swarm</code> into <code>~/.claude/settings.json</code>, which Claude Code ignores — user-scope MCP servers live in <code>~/.claude.json</code> (what <code>claude mcp add -s user</code> edits). Install now registers there (and cleans the stale settings.json entry); <code>claude mcp list</code> shows <code>swarm ✔ Connected</code>. <b>Re-run <code>swarm install</code> after upgrading.</b></li><li><b>The daemon reads global config from where its state lives.</b> <code>[rules]</code> / <code>[gates]</code> / <code>[tasks]</code> in <code>~/.swarm/config.toml</code> are resolved against the daemon's home (<code>SWARM_HOME</code>), matching the DB and logs — spawned runs, which execute in a worktree without the repo's <code>.swarm.toml</code>, still see machine-wide rules.</li></ul>"},"0.4.1":{"date":"2026-08-22","html":"<h4>Fixed</h4>\n<ul><li><b>PRs view went dark under the desktop app.</b> A daemon launched from the Dock gets macOS's bare GUI <code>PATH</code>, so Homebrew's <code>gh</code> / <code>glab</code> were invisible and the forge silently returned nothing. The daemon now also looks in <code>/opt/homebrew/bin</code>, <code>/usr/local/bin</code>, Linuxbrew and <code>~/.local/bin</code>; <code>swarm doctor</code> reports forge CLI auth and warns when <code>glab</code> relies on a shell-only <code>GITLAB_TOKEN</code>.</li><li>Icons are vertically centred on their text again (<code>vertical-align: middle</code> instead of a fixed <code>-3px</code> tuned for the old type scale).</li><li>npm publish moves to <b>trusted publishing</b> (OIDC, no <code>NPM_TOKEN</code>), the same setup as fancy-menus.</li></ul>"},"0.4.0":{"date":"2026-08-22","html":"<p>The enforcement release: rules that watch file writes, not just Bash; a backlog Swarm can read; servers Swarm starts and stops by pid; and an Incidents feed you can clear.</p>\n<h4>Added</h4>\n<ul><li><b>Rules on file writes</b> — two new rules evaluated on <code>Write</code> / <code>Edit</code> / <code>MultiEdit</code> / <code>NotebookEdit</code> paths (and Bash working directories), not only Bash commands. <code>no_foreign_worktree</code> (default <code>ask</code>) stops a session from editing inside a worktree another claim holds — <em>never touch a worktree you don't hold</em> is now a hook decision, with holding inferred from the session's cwd. <code>claim_required_to_write</code> (opt-in) makes a repo's shared checkout read-only without a claim: claim a task, get a worktree, write there. Both per repo as <code>ask | deny | off</code>.</li><li><b>Incidents view</b> — the denied-action feed as its own tab: Open / All, per-rule counts, reason and session per row, <b>Ack</b> and <b>Ack all</b>; the open count sits in the nav. <code>GET /v1/incidents?open=1&amp;project=</code>, <code>POST /v1/incidents/:seq/ack</code>, <code>POST /v1/incidents/ack</code>, <code>/v1/state.openIncidents</code>. The Board keeps a short open-only section.</li><li><b>Task source</b> — <code>.swarm.toml</code> <code>[tasks] source = \"docs/plan.md\"</code> points at a markdown file whose <code>ID | Task | Depends | Status</code> tables are the backlog (✅ / 🟡 / ⚪, dependencies by task id or milestone prefix). The Board gets a <b>Tasks</b> section (Ready / Open / All, <em>Claim</em> per row), the CLI <code>swarm tasks [--ready]</code>, and agents <code>swarm_next_task</code> — the first unclaimed task whose dependencies are done. Swarm's own roadmap is its task source. Markdown only (OQ-5 decided).</li><li><b><code>swarm serve</code> / <code>swarm proc</code></b> — <code>swarm serve start --name web -- npm run dev</code> allocates a free port (ledger + bind probe), runs the command detached with <code>PORT</code> set and logs under <code>~/.swarm/logs/&lt;project&gt;/</code>, registers pid + start time, and acquires the singleton — so a second <code>web</code> fails closed and the port is protected for every other session with no config. <code>serve ls | stop [name|pid]</code>, <code>proc start | ls | stop</code> for workers without a port. Stop signals registry pids only, verified by start time; nothing is ever killed by pattern. <code>POST /v1/ports/allocate</code>, <code>GET/POST/DELETE /v1/processes</code>; <b>Processes</b> section on the Board with <em>Stop</em>.</li><li><b>Star nudge</b> — once a month at most, never on first open, the dashboard asks for a GitHub star. <em>Later</em> snoozes 30 days, <em>Don't ask again</em> is final; localStorage only.</li><li><b>Sidebar drag-and-drop</b> — pinned projects reorder by dragging; the order persists on the daemon (<code>PUT /v1/projects/order</code>, <code>Project.order</code>).</li><li><b>Desktop app menu</b> — a real application menu (Swarm / Edit / View / Window): ⌘C/⌘V work, <b>View › Zoom In / Zoom Out / Actual Size</b> (<code>⌘+</code> <code>⌘−</code> <code>⌘0</code>) scale the dashboard (persisted), plus Reload and Full Screen.</li></ul><h4>Fixed</h4>\n<ul><li><b>Shared-tree rules no longer lose sight of a session mid-turn.</b> <code>shared_tree</code> / <code>destructive_git</code> keyed on a 2-minute last-seen window fed only by hooks, so a neighbour three minutes into a long turn became invisible — and its uncommitted work unguarded. Transcript growth now counts as activity (the tailer bumps <code>last_seen_at</code>), and the liveness window is the daemon's 10-minute idle threshold (<code>LIVE_WINDOW_MS</code>). A false positive costs one confirmation; a false negative cost someone's work.</li><li><code>destructive_git</code> also matches <code>git stash drop</code>, <code>git stash clear</code> and <code>git branch -D</code>.</li><li>Dashboard type scale is one step larger across the board (base 13 → 14 px; the smallest labels 10 → 11 px) — it had drifted too small, especially in the desktop app.</li><li>The <b>PRs</b> tab icon (and the branch/commit glyphs) were near-invisible at 15 px; they use the pixelarticons <em>sharp</em> variants now.</li><li>The daemon dot stayed red for up to 15 s after load on a healthy connection (the SSE stream sent nothing until its first heartbeat); the stream now flushes immediately.</li><li>The nav flashed \"Fleet\" before the restored tab was applied; session-detail event kinds (<code>userpromptsubmit</code>) no longer overflow into the message column; \"Unpinned · seen, not pinned\" keeps its spacing.</li></ul><h4>Changed — docs</h4>\n<ul><li>README and site now say what the code does: Codex CLI and Grok sessions are tailed alongside Claude Code; the requirements and architecture diagram list all three.</li><li>Rules are described as <b>guardrails against accidents, not a sandbox</b> — the guide has a new \"What rules are — and aren't\" section spelling out that a denied Bash command can be routed around (script, heredoc, direct file edit), and that worktree isolation via claims is the real fix. The site's feature cards lead with claims, rules and resources instead of Fleet and Spend.</li></ul><h4>Changed — performance</h4>\n<ul><li><b>Daemon never spawns <code>git</code> on a request.</b> Worktree status (<code>git worktree list</code> + <code>status</code>/<code>rev-list</code> per worktree, ~0.8 s across a fleet) moves to a 15 s background refresh with async <code>Bun.spawn</code>; <code>/v1/state</code> serves the cache (612 ms → ~15 ms). Claim/release invalidate it.</li><li><b>Hook round-trips are two indexed statements</b>, not two <code>git rev-parse</code> spawns plus a transcript-directory scan: <code>cwd → project</code> is cached 60 s, the inline transcript tail is debounced to once per 2 s per session (the 5 s tailer covers steady state), and subagent directories are re-listed only when their mtime moves.</li><li><b>Events store ~2 KB, not ~10 KB.</b> <code>tool_input</code> is clipped at 2 KB and <code>tool_response</code> at 4 KB in <code>payload</code> (<code>{truncated, bytes, preview}</code>), and the tool I/O is no longer duplicated in <code>raw</code>. Existing databases are rewritten once on boot and <code>VACUUM</code>ed (96 MB → 27 MB here). Retention: events older than 30 days are pruned daily (incidents kept), <code>raw</code> is cleared after 7 days.</li><li><b>Wire shape.</b> SSE frames, <code>GET /v1/events</code> replays and <code>GET /v1/sessions/:id/events</code> carry <code>seq/ts/type/projectId/sessionId/payload{hook,summary,…}</code> only — no <code>raw</code>, no tool I/O (a 5.5 MB session fetch is now ~150 KB). <code>GET /v1/events/:seq</code> returns one stored event in full; <code>?full=1</code> on the SSE replay does the same. <code>?since=0</code> replays the last 200 events, not the table.</li><li><b>Incremental session view</b> — <code>GET /v1/sessions/:id/events?after=&lt;seq&gt;&amp;afterTs=&lt;iso&gt;</code>; the dashboard appends instead of re-fetching 500 events + 500 turns on every hook.</li><li><b>Dashboard render loop</b> — one <code>requestAnimationFrame</code> scheduler, snapshot <code>seq</code> short-circuit, paused while the tab is hidden, exponential SSE reconnect backoff; session log merges two sorted lists and caches rendered rows; data-grid memoises persisted layout and uses one <code>Intl.Collator</code>; charts memoise the turn strip.</li><li>SQLite: indexes on <code>events(type, seq)</code> and <code>turns(ts)</code>, <code>mmap_size</code> 256 MB, cached prepared statements (<code>db.query</code>), <code>sessions</code>/<code>spend</code>/<code>incidents</code> memoised per write generation; <code>/v1/spend</code> is its own endpoint.</li><li>Background tick: Codex/Grok discovery every 15 s when idle; Grok <code>summary.json</code> re-read only on mtime change.</li></ul>"},"0.3.0":{"date":"2026-08-22","html":"<p>The coordination release: rules you can configure, runtime resources agents can hold, and the merge queue at the end of the loop.</p>\n<h4>Added</h4>\n<ul><li><b>Config system</b> — <code>~/.swarm/config.toml</code> (global) deep-merged with an optional <code>&lt;repo&gt;/.swarm.toml</code>. Lenient validation: bad config can never take the daemon down. Daemon port preference is <code>SWARM_PORT</code> &gt; config &gt; 7777. See <code>docs/13-config.md</code>.</li><li><b>Rule engine v2</b> — every rule is per-repo configurable as <code>ask | deny | off</code>: <code>shared_tree</code>, <code>destructive_git</code>, <code>pattern_kill</code>, and the new <code>protected_ports</code> (kill/free of a configured port — <code>lsof | kill</code>, <code>fuser -k</code>, <code>kill-port</code> — is asked or denied). <code>deny</code> is returned to Claude Code as a real permission denial.</li><li><b>Incidents</b> — every non-allow decision is recorded (<code>incident.opened</code>: rule, action, command, reason), exposed at <code>GET /v1/incidents</code>, included in <code>/v1/state</code>, and shown on the Board.</li><li><b>Runtime resources (Phase 1)</b> — named singletons for what agents fight over at runtime (dev servers, databases, ports). Fail-closed acquire: holdings live while their pid runs or their lease hasn't expired; the same owner refreshes; dead holdings reap instead of blocking. Release is fail-closed too (owner required, <code>--force</code> overrides). Held ports automatically join the protected-ports rule — acquiring <code>db</code> on 5432 guards <code>lsof -ti:5432 | xargs kill</code> for every other agent, no config needed. HTTP <code>GET/POST /v1/resources</code>, <code>DELETE /v1/resources/:name</code>; MCP <code>swarm_acquire_resource</code> / <code>swarm_release_resource</code> / <code>swarm_resources</code>; CLI <code>swarm res ls|acquire|release</code>.</li><li><b>PRs view</b> — one merge queue across GitHub and GitLab. Forge detection from the git remote (ssh/https, GitLab subgroups, self-hosted), polled through the locally-authenticated <code>gh</code> / <code>glab</code> CLIs with the project root as cwd — no tokens stored, 2-minute per-project cache floor. <code>GET /v1/prs</code>, <code>POST /v1/prs/merge</code> (squash). Merge is offered only on green, mergeable, non-draft rows, behind a confirm.</li><li><b>Board view</b> — Claims, Worktrees, Resources, and Incidents move out of Fleet into their own view; Fleet shows sessions only (Live + Earlier). Last view and project selection persist across reloads.</li><li><b>Stats view</b> — <code>GET /v1/stats</code>; activity line, calendar heatmap, and streaks (daily buckets in local time, DST-immune). <code>swarm stats</code> on the CLI.</li><li><b>Data-grid everywhere</b> — Claims, Worktrees, Resources, Incidents, PRs, and all six Spend tables render through the same sortable / resizable / reorderable grid with per-column filters, a column-visibility menu, and persisted layouts. Header ticks and tooltips make the affordances discoverable.</li><li><b>Desktop: Check for Updates…</b> in the tray menu, wired to the Tauri updater with native dialogs (available / up-to-date / failed) and install-and-restart on accept.</li><li><b>Agent badge</b> on every Fleet and session row, so mixed-agent fleets are labelled consistently.</li><li><b>Website</b> — getswarm.vercel.app: OS-detected downloads from the latest GitHub release, the <code>bunx</code> one-liner, sharing tags with hero art, and (this release) rendered docs and release notes.</li><li><b>Design tokens</b> — the dashboard's CSS contains zero raw hex / rgba / font-size / duration values; the system is documented in <code>docs/12-design-tokens.md</code> with a drift grep.</li><li>Swarm now dogfoods its own rules via the repo's <code>.swarm.toml</code> (<code>shared_tree</code> / <code>destructive_git</code> deny, daemon port protected).</li></ul><h4>Fixed</h4>\n<ul><li><b>Hook resilience</b> — the PreToolUse hook falls back to the default port when <code>daemon.json</code> points at a dead daemon, so a crashed daemon no longer silently disables the guard (this was the gap behind a real <code>git add -A</code> collision).</li><li>Resource liveness: pid 0 was treated as a live process (<code>kill(0)</code> addresses the process group), so those holdings never reaped; tracked pids are now <code>&gt; 0</code>. <code>heldPorts()</code> is one SELECT on the hook path; lazy reap on acquire, sweep on the 5 s tick. Unknown session IDs on acquire no longer mint phantom sessions.</li><li>Session view is two equal columns again (a bare <code>aside</code> selector in the sidebar-collapse CSS captured the session side panel); the log keeps your scroll position across live updates and follows the tail only when pinned to the bottom.</li><li>A pinned project whose root vanished is merged into the live same-name entry (repo renames produced duplicate sidebar rows); the sidebar <code>⋯</code> appears on hover in the count's slot and reserves no space.</li><li>Desktop: quit actually quits, window close hides (macOS convention) and the dock icon restores it, and the <code>swarmd</code> sidecar dies with the app. Dev builds serve the repo's live dashboard instead of a stale staged snapshot.</li><li>Release pipeline: npm publish is skipped cleanly when <code>NPM_TOKEN</code> is absent (since 0.4.1: trusted publishing, no token).</li></ul>"},"0.2.2":{"date":"2026-08-21","html":"<h4>Added</h4>\n<ul><li>Publishable <code>@ra3orblade/swarm</code> npm package (bundled bins + dashboard); <code>bunx @ra3orblade/swarm setup</code> onboarding.</li><li>Enterprise data-grid for Fleet with a collapsible sidebar; pixel-art icon set and bespoke empty-state illustrations; folder picker; green chart palette.</li><li>Desktop: macOS window chrome, animated pixel-logo splash, free-port daemon startup.</li></ul><h4>Fixed</h4>\n<ul><li>Release builds bundle every platform target; Linux ships <code>.deb</code> + <code>.rpm</code> (AppImage disabled until <code>linuxdeploy</code> on GitHub runners is debugged).</li></ul>"},"0.0.6":{"date":"2026-08-21","html":"<p>First signed and notarized macOS desktop build; <code>release.yml</code> became a three-OS matrix (macOS / Windows / Linux) with a native sidecar per runner.</p>"}};