@sideboard-ai/core 0.1.19 → 0.1.23

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/dist/index.cjs CHANGED
@@ -899,13 +899,383 @@ var init_cloud_connect_constants = __esm({
899
899
  }
900
900
  });
901
901
 
902
+ // src/git/team-meta.ts
903
+ var SOCCER_TEAM_META;
904
+ var init_team_meta = __esm({
905
+ "src/git/team-meta.ts"() {
906
+ "use strict";
907
+ SOCCER_TEAM_META = {
908
+ "aalborg": { location: "Aalborg, Denmark", league: "Danish Superliga" },
909
+ "aalesund": { location: "\xC5lesund, Norway", league: "Norwegian First Division" },
910
+ "aarhus": { location: "Aarhus, Denmark", league: "Danish Superliga" },
911
+ "aberdeen": { location: "Aberdeen, Scotland", league: "Scottish Premiership" },
912
+ "ac-milan": { location: "Milan, Italy", league: "Serie A" },
913
+ "ado-den-haag": { location: "The Hague, Netherlands", league: "Eerste Divisie" },
914
+ "aik": { location: "Stockholm, Sweden", league: "Allsvenskan" },
915
+ "ajaccio": { location: "Ajaccio, France", league: "Ligue 2" },
916
+ "ajax": { location: "Amsterdam, Netherlands", league: "Eredivisie" },
917
+ "al-ahly": { location: "Cairo, Egypt", league: "Egyptian Premier League" },
918
+ "al-hilal": { location: "Riyadh, Saudi Arabia", league: "Saudi Pro League" },
919
+ "alajuelense": { location: "Alajuela, Costa Rica", league: "Liga FPD" },
920
+ "almere-city": { location: "Almere, Netherlands", league: "Eredivisie" },
921
+ "amiens": { location: "Amiens, France", league: "Ligue 2" },
922
+ "angers": { location: "Angers, France", league: "Ligue 1" },
923
+ "anyang": { location: "Anyang, South Korea", league: "K League 1" },
924
+ "argentinos-juniors": { location: "Buenos Aires, Argentina", league: "Argentine Primera Divisi\xF3n" },
925
+ "arsenal": { location: "London, England", league: "Premier League" },
926
+ "aston-villa": { location: "Birmingham, England", league: "Premier League" },
927
+ "athletico-paranaense": { location: "Curitiba, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
928
+ "atlanta-united": { location: "Atlanta, USA", league: "MLS" },
929
+ "atlas": { location: "Guadalajara, Mexico", league: "Liga MX" },
930
+ "atletico-madrid": { location: "Madrid, Spain", league: "La Liga" },
931
+ "atletico-mineiro": { location: "Belo Horizonte, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
932
+ "atletico-san-luis": { location: "San Luis Potos\xED, Mexico", league: "Liga MX" },
933
+ "augsburg": { location: "Augsburg, Germany", league: "Bundesliga" },
934
+ "austin-fc": { location: "Austin, USA", league: "MLS" },
935
+ "auxerre": { location: "Auxerre, France", league: "Ligue 1" },
936
+ "avispa-fukuoka": { location: "Fukuoka, Japan", league: "J1 League" },
937
+ "az": { location: "Alkmaar, Netherlands", league: "Eredivisie" },
938
+ "bahia": { location: "Salvador, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
939
+ "banfield": { location: "Banfield, Argentina", league: "Argentine Primera Divisi\xF3n" },
940
+ "barcelona": { location: "Barcelona, Spain", league: "La Liga" },
941
+ "bayer-leverkusen": { location: "Leverkusen, Germany", league: "Bundesliga" },
942
+ "bayern-munich": { location: "Munich, Germany", league: "Bundesliga" },
943
+ "belgrano": { location: "C\xF3rdoba, Argentina", league: "Argentine Primera Divisi\xF3n" },
944
+ "benfica": { location: "Lisbon, Portugal", league: "Primeira Liga" },
945
+ "birmingham-legion": { location: "Birmingham, USA", league: "USL Championship" },
946
+ "boca-juniors": { location: "Buenos Aires, Argentina", league: "Argentine Primera Divisi\xF3n" },
947
+ "bodo-glimt": { location: "Bod\xF8, Norway", league: "Eliteserien" },
948
+ "bordeaux": { location: "Bordeaux, France", league: "Championnat National" },
949
+ "borussia-dortmund": { location: "Dortmund, Germany", league: "Bundesliga" },
950
+ "botafogo": { location: "Rio de Janeiro, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
951
+ "bragantino": { location: "Bragan\xE7a Paulista, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
952
+ "brann": { location: "Bergen, Norway", league: "Eliteserien" },
953
+ "brest": { location: "Brest, France", league: "Ligue 1" },
954
+ "brommapojkarna": { location: "Stockholm, Sweden", league: "Allsvenskan" },
955
+ "brondby": { location: "Br\xF8ndby, Denmark", league: "Danish Superliga" },
956
+ "brooklyn-fc": { location: "Brooklyn, USA", league: "USL Championship" },
957
+ "bucheon": { location: "Bucheon, South Korea", league: "K League 2" },
958
+ "caen": { location: "Caen, France", league: "Ligue 2" },
959
+ "cambuur": { location: "Leeuwarden, Netherlands", league: "Eerste Divisie" },
960
+ "carmelita": { location: "Alajuela, Costa Rica", league: "Liga de Ascenso" },
961
+ "cartagines": { location: "Cartago, Costa Rica", league: "Liga FPD" },
962
+ "ceara": { location: "Fortaleza, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
963
+ "celtic": { location: "Glasgow, Scotland", league: "Scottish Premiership" },
964
+ "central-cordoba": { location: "Santiago del Estero, Argentina", league: "Argentine Primera Divisi\xF3n" },
965
+ "cerezo-osaka": { location: "Osaka, Japan", league: "J1 League" },
966
+ "cf-montreal": { location: "Montreal, Canada", league: "MLS" },
967
+ "charleston-battery": { location: "Charleston, USA", league: "USL Championship" },
968
+ "charlotte-fc": { location: "Charlotte, USA", league: "MLS" },
969
+ "chelsea": { location: "London, England", league: "Premier League" },
970
+ "chicago-fire": { location: "Chicago, USA", league: "MLS" },
971
+ "chivas": { location: "Guadalajara, Mexico", league: "Liga MX" },
972
+ "clermont": { location: "Clermont-Ferrand, France", league: "Ligue 2" },
973
+ "club-america": { location: "Mexico City, Mexico", league: "Liga MX" },
974
+ "cologne": { location: "Cologne, Germany", league: "Bundesliga" },
975
+ "colorado-rapids": { location: "Commerce City, USA", league: "MLS" },
976
+ "columbus-crew": { location: "Columbus, USA", league: "MLS" },
977
+ "corinthians": { location: "S\xE3o Paulo, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
978
+ "cruz-azul": { location: "Mexico City, Mexico", league: "Liga MX" },
979
+ "cruzeiro": { location: "Belo Horizonte, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
980
+ "daejeon": { location: "Daejeon, South Korea", league: "K League 1" },
981
+ "dc-united": { location: "Washington, D.C., USA", league: "MLS" },
982
+ "defensa-y-justicia": { location: "Florencio Varela, Argentina", league: "Argentine Primera Divisi\xF3n" },
983
+ "degerfors": { location: "Degerfors, Sweden", league: "Allsvenskan" },
984
+ "detroit-city": { location: "Detroit, USA", league: "USL Championship" },
985
+ "dijon": { location: "Dijon, France", league: "Championnat National" },
986
+ "djurgarden": { location: "Stockholm, Sweden", league: "Allsvenskan" },
987
+ "dundee": { location: "Dundee, Scotland", league: "Scottish Premiership" },
988
+ "dundee-united": { location: "Dundee, Scotland", league: "Scottish Premiership" },
989
+ "dynamo-kyiv": { location: "Kyiv, Ukraine", league: "Ukrainian Premier League" },
990
+ "eintracht-frankfurt": { location: "Frankfurt, Germany", league: "Bundesliga" },
991
+ "el-paso-locomotive": { location: "El Paso, USA", league: "USL Championship" },
992
+ "elfsborg": { location: "Bor\xE5s, Sweden", league: "Allsvenskan" },
993
+ "emmen": { location: "Emmen, Netherlands", league: "Eerste Divisie" },
994
+ "esbjerg": { location: "Esbjerg, Denmark", league: "Danish 1st Division" },
995
+ "estudiantes": { location: "La Plata, Argentina", league: "Argentine Primera Divisi\xF3n" },
996
+ "everton": { location: "Liverpool, England", league: "Premier League" },
997
+ "excelsior": { location: "Rotterdam, Netherlands", league: "Eerste Divisie" },
998
+ "fagiano-okayama": { location: "Okayama, Japan", league: "J1 League" },
999
+ "falkirk": { location: "Falkirk, Scotland", league: "Scottish Championship" },
1000
+ "fc-cincinnati": { location: "Cincinnati, USA", league: "MLS" },
1001
+ "fc-copenhagen": { location: "Copenhagen, Denmark", league: "Danish Superliga" },
1002
+ "fc-dallas": { location: "Frisco, USA", league: "MLS" },
1003
+ "fc-seoul": { location: "Seoul, South Korea", league: "K League 1" },
1004
+ "fc-tokyo": { location: "Tokyo, Japan", league: "J1 League" },
1005
+ "fc-tulsa": { location: "Tulsa, USA", league: "USL Championship" },
1006
+ "feyenoord": { location: "Rotterdam, Netherlands", league: "Eredivisie" },
1007
+ "flamengo": { location: "Rio de Janeiro, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1008
+ "fluminense": { location: "Rio de Janeiro, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1009
+ "fortaleza": { location: "Fortaleza, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1010
+ "fortuna-sittard": { location: "Sittard, Netherlands", league: "Eredivisie" },
1011
+ "fredrikstad": { location: "Fredrikstad, Norway", league: "Eliteserien" },
1012
+ "freiburg": { location: "Freiburg, Germany", league: "Bundesliga" },
1013
+ "gais": { location: "Gothenburg, Sweden", league: "Allsvenskan" },
1014
+ "galatasaray": { location: "Istanbul, Turkey", league: "S\xFCper Lig" },
1015
+ "gamba-osaka": { location: "Osaka, Japan", league: "J1 League" },
1016
+ "gangwon": { location: "Gangneung, South Korea", league: "K League 1" },
1017
+ "gimcheon-sangmu": { location: "Gimcheon, South Korea", league: "K League 1" },
1018
+ "gimnasia": { location: "La Plata, Argentina", league: "Argentine Primera Divisi\xF3n" },
1019
+ "gladbach": { location: "M\xF6nchengladbach, Germany", league: "Bundesliga" },
1020
+ "go-ahead-eagles": { location: "Deventer, Netherlands", league: "Eredivisie" },
1021
+ "godoy-cruz": { location: "Mendoza, Argentina", league: "Argentine Primera Divisi\xF3n" },
1022
+ "gremio": { location: "Porto Alegre, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1023
+ "groningen": { location: "Groningen, Netherlands", league: "Eredivisie" },
1024
+ "guadalupe": { location: "Goicoechea, Costa Rica", league: "Liga de Ascenso" },
1025
+ "guanacasteca": { location: "Nicoya, Costa Rica", league: "Liga FPD" },
1026
+ "guingamp": { location: "Guingamp, France", league: "Ligue 2" },
1027
+ "gwangju": { location: "Gwangju, South Korea", league: "K League 1" },
1028
+ "hacken": { location: "Gothenburg, Sweden", league: "Allsvenskan" },
1029
+ "halmstad": { location: "Halmstad, Sweden", league: "Allsvenskan" },
1030
+ "hamburg": { location: "Hamburg, Germany", league: "2. Bundesliga" },
1031
+ "hammarby": { location: "Stockholm, Sweden", league: "Allsvenskan" },
1032
+ "hartford-athletic": { location: "Hartford, USA", league: "USL Championship" },
1033
+ "haugesund": { location: "Haugesund, Norway", league: "Eliteserien" },
1034
+ "hearts": { location: "Edinburgh, Scotland", league: "Scottish Premiership" },
1035
+ "heerenveen": { location: "Heerenveen, Netherlands", league: "Eredivisie" },
1036
+ "heidenheim": { location: "Heidenheim, Germany", league: "Bundesliga" },
1037
+ "helsingborg": { location: "Helsingborg, Sweden", league: "Superettan" },
1038
+ "heracles": { location: "Almelo, Netherlands", league: "Eredivisie" },
1039
+ "herediano": { location: "Heredia, Costa Rica", league: "Liga FPD" },
1040
+ "hibernian": { location: "Edinburgh, Scotland", league: "Scottish Premiership" },
1041
+ "hoffenheim": { location: "Sinsheim, Germany", league: "Bundesliga" },
1042
+ "horsens": { location: "Horsens, Denmark", league: "Danish 1st Division" },
1043
+ "houston-dynamo": { location: "Houston, USA", league: "MLS" },
1044
+ "huracan": { location: "Buenos Aires, Argentina", league: "Argentine Primera Divisi\xF3n" },
1045
+ "ifk-goteborg": { location: "Gothenburg, Sweden", league: "Allsvenskan" },
1046
+ "norrkoping": { location: "Norrk\xF6ping, Sweden", league: "Allsvenskan" },
1047
+ "incheon-united": { location: "Incheon, South Korea", league: "K League 1" },
1048
+ "independiente": { location: "Avellaneda, Argentina", league: "Argentine Primera Divisi\xF3n" },
1049
+ "indy-eleven": { location: "Indianapolis, USA", league: "USL Championship" },
1050
+ "instituto": { location: "C\xF3rdoba, Argentina", league: "Argentine Primera Divisi\xF3n" },
1051
+ "inter-miami": { location: "Fort Lauderdale, USA", league: "MLS" },
1052
+ "inter-milan": { location: "Milan, Italy", league: "Serie A" },
1053
+ "internacional": { location: "Porto Alegre, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1054
+ "jef-united": { location: "Chiba, Japan", league: "J2 League" },
1055
+ "jeju-sk": { location: "Jeju, South Korea", league: "K League 1" },
1056
+ "jeonbuk": { location: "Jeonju, South Korea", league: "K League 1" },
1057
+ "juarez": { location: "Ciudad Ju\xE1rez, Mexico", league: "Liga MX" },
1058
+ "juventude": { location: "Caxias do Sul, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1059
+ "juventus": { location: "Turin, Italy", league: "Serie A" },
1060
+ "kalmar": { location: "Kalmar, Sweden", league: "Superettan" },
1061
+ "kashima-antlers": { location: "Kashima, Japan", league: "J1 League" },
1062
+ "kashiwa-reysol": { location: "Kashiwa, Japan", league: "J1 League" },
1063
+ "kawasaki-frontale": { location: "Kawasaki, Japan", league: "J1 League" },
1064
+ "kfum-oslo": { location: "Oslo, Norway", league: "Eliteserien" },
1065
+ "kilmarnock": { location: "Kilmarnock, Scotland", league: "Scottish Premiership" },
1066
+ "kristiansund": { location: "Kristiansund, Norway", league: "Eliteserien" },
1067
+ "kyoto-sanga": { location: "Kyoto, Japan", league: "J1 League" },
1068
+ "la-galaxy": { location: "Carson, USA", league: "MLS" },
1069
+ "lafc": { location: "Los Angeles, USA", league: "MLS" },
1070
+ "lanus": { location: "Lan\xFAs, Argentina", league: "Argentine Primera Divisi\xF3n" },
1071
+ "las-vegas-lights": { location: "Las Vegas, USA", league: "USL Championship" },
1072
+ "lazio": { location: "Rome, Italy", league: "Serie A" },
1073
+ "le-havre": { location: "Le Havre, France", league: "Ligue 1" },
1074
+ "le-mans": { location: "Le Mans, France", league: "Ligue 2" },
1075
+ "leeds-united": { location: "Leeds, England", league: "Premier League" },
1076
+ "leicester-city": { location: "Leicester, England", league: "Championship" },
1077
+ "lens": { location: "Lens, France", league: "Ligue 1" },
1078
+ "leon": { location: "Le\xF3n, Mexico", league: "Liga MX" },
1079
+ "lexington-sc": { location: "Lexington, USA", league: "USL Championship" },
1080
+ "liberia": { location: "Liberia, Costa Rica", league: "Liga FPD" },
1081
+ "lille": { location: "Lille, France", league: "Ligue 1" },
1082
+ "lillestrom": { location: "Lillestr\xF8m, Norway", league: "Eliteserien" },
1083
+ "limon": { location: "Lim\xF3n, Costa Rica", league: "Liga de Ascenso" },
1084
+ "liverpool": { location: "Liverpool, England", league: "Premier League" },
1085
+ "livingston": { location: "Livingston, Scotland", league: "Scottish Championship" },
1086
+ "lorient": { location: "Lorient, France", league: "Ligue 1" },
1087
+ "loudoun-united": { location: "Leesburg, USA", league: "USL Championship" },
1088
+ "louisville-city": { location: "Louisville, USA", league: "USL Championship" },
1089
+ "lyngby": { location: "Kongens Lyngby, Denmark", league: "Danish Superliga" },
1090
+ "lyon": { location: "Lyon, France", league: "Ligue 1" },
1091
+ "machida-zelvia": { location: "Machida, Japan", league: "J1 League" },
1092
+ "mainz": { location: "Mainz, Germany", league: "Bundesliga" },
1093
+ "malmo": { location: "Malm\xF6, Sweden", league: "Allsvenskan" },
1094
+ "manchester-city": { location: "Manchester, England", league: "Premier League" },
1095
+ "manchester-united": { location: "Manchester, England", league: "Premier League" },
1096
+ "marseille": { location: "Marseille, France", league: "Ligue 1" },
1097
+ "mazatlan": { location: "Mazatl\xE1n, Mexico", league: "Liga MX" },
1098
+ "metz": { location: "Metz, France", league: "Ligue 1" },
1099
+ "miami-fc": { location: "Miami, USA", league: "USL Championship" },
1100
+ "midtjylland": { location: "Herning, Denmark", league: "Danish Superliga" },
1101
+ "minnesota-united": { location: "Saint Paul, USA", league: "MLS" },
1102
+ "mirassol": { location: "Mirassol, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1103
+ "mito-hollyhock": { location: "Mito, Japan", league: "J2 League" },
1104
+ "mjallby": { location: "H\xE4llevik, Sweden", league: "Allsvenskan" },
1105
+ "molde": { location: "Molde, Norway", league: "Eliteserien" },
1106
+ "monaco": { location: "Monaco", league: "Ligue 1" },
1107
+ "monterey-bay": { location: "Monterey, USA", league: "USL Championship" },
1108
+ "monterrey": { location: "Monterrey, Mexico", league: "Liga MX" },
1109
+ "montpellier": { location: "Montpellier, France", league: "Ligue 2" },
1110
+ "motherwell": { location: "Motherwell, Scotland", league: "Scottish Premiership" },
1111
+ "grecia": { location: "Grecia, Costa Rica", league: "Liga de Ascenso" },
1112
+ "nac-breda": { location: "Breda, Netherlands", league: "Eredivisie" },
1113
+ "nagoya-grampus": { location: "Nagoya, Japan", league: "J1 League" },
1114
+ "nancy": { location: "Nancy, France", league: "Ligue 2" },
1115
+ "nantes": { location: "Nantes, France", league: "Ligue 1" },
1116
+ "napoli": { location: "Naples, Italy", league: "Serie A" },
1117
+ "nashville-sc": { location: "Nashville, USA", league: "MLS" },
1118
+ "nec": { location: "Nijmegen, Netherlands", league: "Eredivisie" },
1119
+ "necaxa": { location: "Aguascalientes, Mexico", league: "Liga MX" },
1120
+ "new-england": { location: "Foxborough, USA", league: "MLS" },
1121
+ "new-mexico-united": { location: "Albuquerque, USA", league: "USL Championship" },
1122
+ "newcastle": { location: "Newcastle, England", league: "Premier League" },
1123
+ "newells": { location: "Rosario, Argentina", league: "Argentine Primera Divisi\xF3n" },
1124
+ "nice": { location: "Nice, France", league: "Ligue 1" },
1125
+ "nimes": { location: "N\xEEmes, France", league: "Championnat National" },
1126
+ "nordsjaelland": { location: "Farum, Denmark", league: "Danish Superliga" },
1127
+ "ny-red-bulls": { location: "Harrison, USA", league: "MLS" },
1128
+ "nycfc": { location: "New York City, USA", league: "MLS" },
1129
+ "oakland-roots": { location: "Oakland, USA", league: "USL Championship" },
1130
+ "ob-odense": { location: "Odense, Denmark", league: "Danish Superliga" },
1131
+ "odd": { location: "Skien, Norway", league: "Norwegian First Division" },
1132
+ "olympiacos": { location: "Piraeus, Greece", league: "Super League Greece" },
1133
+ "orange-county-sc": { location: "Irvine, USA", league: "USL Championship" },
1134
+ "orebro": { location: "\xD6rebro, Sweden", league: "Superettan" },
1135
+ "orlando-city": { location: "Orlando, USA", league: "MLS" },
1136
+ "pachuca": { location: "Pachuca, Mexico", league: "Liga MX" },
1137
+ "palmeiras": { location: "S\xE3o Paulo, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1138
+ "paris-fc": { location: "Paris, France", league: "Ligue 1" },
1139
+ "psg": { location: "Paris, France", league: "Ligue 1" },
1140
+ "pec-zwolle": { location: "Zwolle, Netherlands", league: "Eredivisie" },
1141
+ "perez-zeledon": { location: "San Isidro, Costa Rica", league: "Liga FPD" },
1142
+ "philadelphia-union": { location: "Chester, USA", league: "MLS" },
1143
+ "phoenix-rising": { location: "Phoenix, USA", league: "USL Championship" },
1144
+ "pittsburgh-riverhounds": { location: "Pittsburgh, USA", league: "USL Championship" },
1145
+ "platense": { location: "Florida, Argentina", league: "Argentine Primera Divisi\xF3n" },
1146
+ "pohang-steelers": { location: "Pohang, South Korea", league: "K League 1" },
1147
+ "portland-timbers": { location: "Portland, USA", league: "MLS" },
1148
+ "porto": { location: "Porto, Portugal", league: "Primeira Liga" },
1149
+ "psv": { location: "Eindhoven, Netherlands", league: "Eredivisie" },
1150
+ "puebla": { location: "Puebla, Mexico", league: "Liga MX" },
1151
+ "pumas": { location: "Mexico City, Mexico", league: "Liga MX" },
1152
+ "puntarenas": { location: "Puntarenas, Costa Rica", league: "Liga FPD" },
1153
+ "queretaro": { location: "Quer\xE9taro, Mexico", league: "Liga MX" },
1154
+ "racing": { location: "Avellaneda, Argentina", league: "Argentine Primera Divisi\xF3n" },
1155
+ "randers": { location: "Randers, Denmark", league: "Danish Superliga" },
1156
+ "rangers": { location: "Glasgow, Scotland", league: "Scottish Premiership" },
1157
+ "rb-leipzig": { location: "Leipzig, Germany", league: "Bundesliga" },
1158
+ "real-madrid": { location: "Madrid, Spain", league: "La Liga" },
1159
+ "real-salt-lake": { location: "Sandy, USA", league: "MLS" },
1160
+ "red-star": { location: "Saint-Ouen, France", league: "Ligue 2" },
1161
+ "reims": { location: "Reims, France", league: "Ligue 2" },
1162
+ "rennes": { location: "Rennes, France", league: "Ligue 1" },
1163
+ "rhode-island-fc": { location: "Pawtucket, USA", league: "USL Championship" },
1164
+ "river-plate": { location: "Buenos Aires, Argentina", league: "Argentine Primera Divisi\xF3n" },
1165
+ "rkc": { location: "Waalwijk, Netherlands", league: "Eredivisie" },
1166
+ "roma": { location: "Rome, Italy", league: "Serie A" },
1167
+ "rosario-central": { location: "Rosario, Argentina", league: "Argentine Primera Divisi\xF3n" },
1168
+ "rosenborg": { location: "Trondheim, Norway", league: "Eliteserien" },
1169
+ "sacramento-republic": { location: "Sacramento, USA", league: "USL Championship" },
1170
+ "saint-etienne": { location: "Saint-\xC9tienne, France", league: "Ligue 2" },
1171
+ "san-antonio-fc": { location: "San Antonio, USA", league: "USL Championship" },
1172
+ "san-carlos": { location: "Quesada, Costa Rica", league: "Liga FPD" },
1173
+ "san-diego-fc": { location: "San Diego, USA", league: "MLS" },
1174
+ "san-jose-earthquakes": { location: "San Jose, USA", league: "MLS" },
1175
+ "san-lorenzo": { location: "Buenos Aires, Argentina", league: "Argentine Primera Divisi\xF3n" },
1176
+ "sanfrecce-hiroshima": { location: "Hiroshima, Japan", league: "J1 League" },
1177
+ "santos": { location: "Santos, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1178
+ "santos-guapiles": { location: "Gu\xE1piles, Costa Rica", league: "Liga FPD" },
1179
+ "santos-laguna": { location: "Torre\xF3n, Mexico", league: "Liga MX" },
1180
+ "sao-paulo": { location: "S\xE3o Paulo, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1181
+ "saprissa": { location: "San Jos\xE9, Costa Rica", league: "Liga FPD" },
1182
+ "sarpsborg": { location: "Sarpsborg, Norway", league: "Eliteserien" },
1183
+ "schalke": { location: "Gelsenkirchen, Germany", league: "2. Bundesliga" },
1184
+ "seattle-sounders": { location: "Seattle, USA", league: "MLS" },
1185
+ "sevilla": { location: "Seville, Spain", league: "La Liga" },
1186
+ "shakhtar": { location: "Donetsk, Ukraine", league: "Ukrainian Premier League" },
1187
+ "shimizu-s-pulse": { location: "Shizuoka, Japan", league: "J1 League" },
1188
+ "silkeborg": { location: "Silkeborg, Denmark", league: "Danish Superliga" },
1189
+ "sirius": { location: "Uppsala, Sweden", league: "Allsvenskan" },
1190
+ "sochaux": { location: "Montb\xE9liard, France", league: "Championnat National" },
1191
+ "sonderjyske": { location: "Haderslev, Denmark", league: "Danish Superliga" },
1192
+ "sparta-rotterdam": { location: "Rotterdam, Netherlands", league: "Eredivisie" },
1193
+ "sport-recife": { location: "Recife, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1194
+ "sporting": { location: "Lisbon, Portugal", league: "Primeira Liga" },
1195
+ "sporting-jax": { location: "Jacksonville, USA", league: "MLS Next Pro" },
1196
+ "sporting-kc": { location: "Kansas City, USA", league: "MLS" },
1197
+ "sporting-san-jose": { location: "San Jos\xE9, Costa Rica", league: "Liga FPD" },
1198
+ "st-mirren": { location: "Paisley, Scotland", league: "Scottish Premiership" },
1199
+ "st-louis-city": { location: "St. Louis, USA", league: "MLS" },
1200
+ "st-pauli": { location: "Hamburg, Germany", league: "Bundesliga" },
1201
+ "stabaek": { location: "B\xE6rum, Norway", league: "Norwegian First Division" },
1202
+ "strasbourg": { location: "Strasbourg, France", league: "Ligue 1" },
1203
+ "stromsgodset": { location: "Drammen, Norway", league: "Eliteserien" },
1204
+ "stuttgart": { location: "Stuttgart, Germany", league: "Bundesliga" },
1205
+ "switchbacks": { location: "Colorado Springs, USA", league: "USL Championship" },
1206
+ "talleres": { location: "C\xF3rdoba, Argentina", league: "Argentine Primera Divisi\xF3n" },
1207
+ "tampa-bay-rowdies": { location: "St. Petersburg, USA", league: "USL Championship" },
1208
+ "tigre": { location: "Victoria, Argentina", league: "Argentine Primera Divisi\xF3n" },
1209
+ "tigres": { location: "San Nicol\xE1s de los Garza, Mexico", league: "Liga MX" },
1210
+ "tijuana": { location: "Tijuana, Mexico", league: "Liga MX" },
1211
+ "tokyo-verdy": { location: "Tokyo, Japan", league: "J1 League" },
1212
+ "toluca": { location: "Toluca, Mexico", league: "Liga MX" },
1213
+ "toronto-fc": { location: "Toronto, Canada", league: "MLS" },
1214
+ "tottenham": { location: "London, England", league: "Premier League" },
1215
+ "toulouse": { location: "Toulouse, France", league: "Ligue 1" },
1216
+ "tromso": { location: "Troms\xF8, Norway", league: "Eliteserien" },
1217
+ "troyes": { location: "Troyes, France", league: "Ligue 2" },
1218
+ "twente": { location: "Enschede, Netherlands", league: "Eredivisie" },
1219
+ "ulsan-hd": { location: "Ulsan, South Korea", league: "K League 1" },
1220
+ "union": { location: "Santa Fe, Argentina", league: "Argentine Primera Divisi\xF3n" },
1221
+ "union-berlin": { location: "Berlin, Germany", league: "Bundesliga" },
1222
+ "urawa-reds": { location: "Saitama, Japan", league: "J1 League" },
1223
+ "utrecht": { location: "Utrecht, Netherlands", league: "Eredivisie" },
1224
+ "v-varen-nagasaki": { location: "Nagasaki, Japan", league: "J2 League" },
1225
+ "valencia": { location: "Valencia, Spain", league: "La Liga" },
1226
+ "valerenga": { location: "Oslo, Norway", league: "Eliteserien" },
1227
+ "vancouver-whitecaps": { location: "Vancouver, Canada", league: "MLS" },
1228
+ "varnamo": { location: "V\xE4rnamo, Sweden", league: "Allsvenskan" },
1229
+ "vasco": { location: "Rio de Janeiro, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1230
+ "vejle": { location: "Vejle, Denmark", league: "Danish Superliga" },
1231
+ "velez": { location: "Buenos Aires, Argentina", league: "Argentine Primera Divisi\xF3n" },
1232
+ "viborg": { location: "Viborg, Denmark", league: "Danish Superliga" },
1233
+ "viking": { location: "Stavanger, Norway", league: "Eliteserien" },
1234
+ "vissel-kobe": { location: "Kobe, Japan", league: "J1 League" },
1235
+ "vitesse": { location: "Arnhem, Netherlands", league: "Eerste Divisie" },
1236
+ "vitoria": { location: "Salvador, Brazil", league: "Brasileir\xE3o S\xE9rie A" },
1237
+ "volendam": { location: "Volendam, Netherlands", league: "Eredivisie" },
1238
+ "werder-bremen": { location: "Bremen, Germany", league: "Bundesliga" },
1239
+ "west-ham": { location: "London, England", league: "Premier League" },
1240
+ "willem-ii": { location: "Tilburg, Netherlands", league: "Eerste Divisie" },
1241
+ "wolfsburg": { location: "Wolfsburg, Germany", league: "Bundesliga" },
1242
+ "yokohama-marinos": { location: "Yokohama, Japan", league: "J1 League" }
1243
+ };
1244
+ }
1245
+ });
1246
+
902
1247
  // src/git/teams.ts
1248
+ function withMeta(seed) {
1249
+ const baseSlug = seed.slug.replace(/-\d+$/, "");
1250
+ const meta = SOCCER_TEAM_META[baseSlug];
1251
+ return {
1252
+ name: seed.name,
1253
+ slug: seed.slug,
1254
+ location: meta?.location ?? "Unknown",
1255
+ league: meta?.league ?? "Unknown league"
1256
+ };
1257
+ }
1258
+ function lookupSoccerTeam(titleOrSlug) {
1259
+ const trimmed = titleOrSlug.trim();
1260
+ if (!trimmed) return null;
1261
+ const fromName = teamSlugFromName(trimmed);
1262
+ const slug = fromName ?? normalizeTakenSlug(trimmed);
1263
+ const baseSlug = slug.replace(/-\d+$/, "");
1264
+ const seed = FAMOUS_SOCCER_TEAM_SEEDS.find((t) => t.slug === baseSlug);
1265
+ if (!seed) return null;
1266
+ const suffixMatch = slug.match(/-(\d+)$/) || trimmed.match(/\s+(\d+)$/);
1267
+ const suffix = suffixMatch?.[1];
1268
+ return withMeta({
1269
+ name: suffix ? `${seed.name} ${suffix}` : seed.name,
1270
+ slug: suffix ? `${seed.slug}-${suffix}` : seed.slug
1271
+ });
1272
+ }
903
1273
  function teamNameFromSlug(slug) {
904
1274
  const normalized = slug.toLowerCase().replace(/^thread\//, "");
905
1275
  const suffixMatch = normalized.match(/^(.+)-(\d+)$/);
906
1276
  const base = suffixMatch?.[1] ?? normalized;
907
1277
  const suffix = suffixMatch?.[2];
908
- const team = FAMOUS_SOCCER_TEAMS.find((t) => t.slug === base);
1278
+ const team = FAMOUS_SOCCER_TEAM_SEEDS.find((t) => t.slug === base);
909
1279
  if (team) return suffix ? `${team.name} ${suffix}` : team.name;
910
1280
  return normalized.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
911
1281
  }
@@ -915,7 +1285,7 @@ function teamSlugFromName(name) {
915
1285
  const suffixMatch = trimmed.match(/^(.+?)\s+(\d+)$/);
916
1286
  const baseName = suffixMatch?.[1] ?? trimmed;
917
1287
  const suffix = suffixMatch?.[2];
918
- const team = FAMOUS_SOCCER_TEAMS.find(
1288
+ const team = FAMOUS_SOCCER_TEAM_SEEDS.find(
919
1289
  (t) => t.name.toLowerCase() === baseName.toLowerCase()
920
1290
  );
921
1291
  if (!team) return null;
@@ -943,26 +1313,27 @@ function allocateTeamName(taken, random = Math.random) {
943
1313
  const takenSet = new Set(
944
1314
  [...taken].map((s) => normalizeTakenSlug(s)).filter(Boolean)
945
1315
  );
946
- const available = FAMOUS_SOCCER_TEAMS.filter((t) => !takenSet.has(t.slug));
1316
+ const available = FAMOUS_SOCCER_TEAM_SEEDS.filter((t) => !takenSet.has(t.slug));
947
1317
  if (available.length > 0) {
948
1318
  const idx = Math.floor(random() * available.length);
949
- return available[idx];
1319
+ return withMeta(available[idx]);
950
1320
  }
951
1321
  for (let n = 2; n < 1e3; n++) {
952
- for (const t of FAMOUS_SOCCER_TEAMS) {
1322
+ for (const t of FAMOUS_SOCCER_TEAM_SEEDS) {
953
1323
  const slug = `${t.slug}-${n}`;
954
1324
  if (!takenSet.has(slug)) {
955
- return { name: `${t.name} ${n}`, slug };
1325
+ return withMeta({ name: `${t.name} ${n}`, slug });
956
1326
  }
957
1327
  }
958
1328
  }
959
1329
  throw new Error("No available soccer team names left");
960
1330
  }
961
- var FAMOUS_SOCCER_TEAMS;
1331
+ var FAMOUS_SOCCER_TEAM_SEEDS, FAMOUS_SOCCER_TEAMS;
962
1332
  var init_teams = __esm({
963
1333
  "src/git/teams.ts"() {
964
1334
  "use strict";
965
- FAMOUS_SOCCER_TEAMS = [
1335
+ init_team_meta();
1336
+ FAMOUS_SOCCER_TEAM_SEEDS = [
966
1337
  { name: "Aalborg", slug: "aalborg" },
967
1338
  { name: "Aalesund", slug: "aalesund" },
968
1339
  { name: "Aarhus", slug: "aarhus" },
@@ -1299,6 +1670,7 @@ var init_teams = __esm({
1299
1670
  { name: "Wolfsburg", slug: "wolfsburg" },
1300
1671
  { name: "Yokohama Marinos", slug: "yokohama-marinos" }
1301
1672
  ];
1673
+ FAMOUS_SOCCER_TEAMS = FAMOUS_SOCCER_TEAM_SEEDS.map(withMeta);
1302
1674
  }
1303
1675
  });
1304
1676
 
@@ -1623,6 +1995,7 @@ __export(worktree_exports, {
1623
1995
  listBranches: () => listBranches,
1624
1996
  listPrs: () => listPrs,
1625
1997
  listWorktrees: () => listWorktrees,
1998
+ lookupSoccerTeam: () => lookupSoccerTeam,
1626
1999
  mergePr: () => mergePr,
1627
2000
  normalizeWorktreePath: () => normalizeWorktreePath,
1628
2001
  originGhRepoEnv: () => originGhRepoEnv,
@@ -2494,7 +2867,7 @@ function coordinatorGreenfieldPlaybook(reposDir) {
2494
2867
  "- Examples:",
2495
2868
  ` - Clone: \`git clone <url> ${reposDir}/<name>\``,
2496
2869
  ` - New GitHub repo: \`gh repo create <owner>/<name> --private --clone -- ${reposDir}/<name>\` (or mkdir + git init + gh repo create + remote add + push)`,
2497
- "- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn \u2192 send_to_thread (`gh pr create --draft -R <origin-owner/name>`) or create_draft_pr.",
2870
+ "- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn \u2192 send_to_thread (`gh pr create --draft -R <origin-owner/name>`).",
2498
2871
  "- Always target the child worktree's **origin** (`github:` slug from list_workspaces / `git remote get-url origin` in that worktree). Never open PRs against `upstream`.",
2499
2872
  "- Do coding work in the child worktree thread, not by editing files in this home cwd."
2500
2873
  ].join("\n");
@@ -2534,8 +2907,8 @@ function ensureGlobalCoordinatorCwd() {
2534
2907
  "",
2535
2908
  "When creating threads, pass `repoPath` from `list_workspaces` (or the path you just registered) and `parentThreadId` for children.",
2536
2909
  "Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn.",
2537
- "Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 draft PR.",
2538
- "Prefer asking worktree agents to open draft PRs; use create_draft_pr as fallback."
2910
+ "Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 draft PR via worktree agent.",
2911
+ "Always ask worktree agents to open draft PRs (`send_to_thread` + `gh pr create --draft -R <origin>`); never open PRs from the orchestrator."
2539
2912
  ].join("\n");
2540
2913
  (0, import_node_fs6.writeFileSync)((0, import_node_path7.join)(dir, "CLAUDE.md"), `${body}
2541
2914
  `, "utf8");
@@ -2560,8 +2933,8 @@ function coordinatorSystemPrompt(opts) {
2560
2933
  COORDINATOR_TOOL_PLAYBOOK,
2561
2934
  coordinatorGreenfieldPlaybook(reposDir),
2562
2935
  "When creating threads, pass the correct repoPath for the target workspace and parentThreadId for children.",
2563
- "Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 send_to_thread (ask for `gh pr create --draft -R <origin-owner/name>` using the workspace github slug) \u2192 wait_for_turn. Use create_draft_pr only if the child cannot open the PR. Never target upstream.",
2564
- "Typical flow (new app): Bash under repos dir (clone or gh repo create) \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn \u2192 draft PR.",
2936
+ "Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 send_to_thread (ask for `gh pr create --draft -R <origin-owner/name>` using the workspace github slug) \u2192 wait_for_turn. Never target upstream. Never open PRs from the orchestrator.",
2937
+ "Typical flow (new app): Bash under repos dir (clone or gh repo create) \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn \u2192 draft PR via worktree agent.",
2565
2938
  `Goal: ${opts.goal}`,
2566
2939
  `Parent thread id (pass as parentThreadId when creating children): ${opts.parentId}`,
2567
2940
  "Registered workspaces:",
@@ -2596,10 +2969,8 @@ var init_coordinator_prompt = __esm({
2596
2969
  "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
2597
2970
  "Inspect / PRs:",
2598
2971
  "- get_diff \u2014 compact diff summary",
2599
- "- preview_land \u2014 preview push+PR (does not push)",
2600
- "- Prefer asking the worktree agent via send_to_thread to open a draft PR with `gh pr create --draft -R <origin-owner/name>` (use the workspace `github:` slug / that worktree's origin \u2014 never upstream) so it owns title/body from the diff.",
2601
- "- create_draft_pr \u2014 fallback: commit (if dirty), push to origin, open/update a DRAFT PR from the orchestrator (always against origin)",
2602
- "Human-only (do not attempt): ready-for-review confirm_land, purge_thread.",
2972
+ "- Ask the worktree agent via send_to_thread to open a draft PR with `gh pr create --draft -R <origin-owner/name>` (workspace `github:` slug / that worktree's origin \u2014 never upstream). Do not open PRs from the orchestrator yourself.",
2973
+ "Human-only (do not attempt): merge, ready-for-review land, purge_thread.",
2603
2974
  "Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",
2604
2975
  "Bash / Read / etc: allowed for (1) inspecting target worktrees / registered repo paths from MCP, and (2) greenfield setup under ~/sideboard/repos (git clone, gh repo create, git init+remote). Never git init/clone *inside* this synthetic home cwd \u2014 emptiness here is expected, not a bug."
2605
2976
  ].join("\n");
@@ -3713,10 +4084,6 @@ function findSideboardMcpJsEntry() {
3713
4084
  return null;
3714
4085
  }
3715
4086
  async function resolveSideboardMcpServer() {
3716
- const which = await run("which", ["sideboard"], { reject: false });
3717
- if (which.exitCode === 0 && which.stdout.trim()) {
3718
- return { name: "sideboard", command: which.stdout.trim(), args: ["mcp"] };
3719
- }
3720
4087
  const entry = findSideboardMcpJsEntry();
3721
4088
  if (entry) {
3722
4089
  const isCli = /[/\\]cli[/\\]dist[/\\]index\.js$/.test(entry);
@@ -3727,6 +4094,10 @@ async function resolveSideboardMcpServer() {
3727
4094
  args: isCli ? [entry, "mcp"] : [entry]
3728
4095
  };
3729
4096
  }
4097
+ const which = await run("which", ["sideboard"], { reject: false });
4098
+ if (which.exitCode === 0 && which.stdout.trim()) {
4099
+ return { name: "sideboard", command: which.stdout.trim(), args: ["mcp"] };
4100
+ }
3730
4101
  return { name: "sideboard", command: "sideboard", args: ["mcp"] };
3731
4102
  }
3732
4103
  async function buildInjectedMcpServers(opts) {
@@ -3769,7 +4140,7 @@ function writeMcpServersConfig(servers) {
3769
4140
  async function writeInjectedMcpConfig(opts) {
3770
4141
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
3771
4142
  }
3772
- var import_node_fs10, import_node_module, import_node_os6, import_node_path11, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache;
4143
+ var import_node_fs10, import_node_module, import_node_os6, import_node_path11, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache;
3773
4144
  var init_injected_mcp = __esm({
3774
4145
  "src/agents/injected-mcp.ts"() {
3775
4146
  "use strict";
@@ -3786,6 +4157,11 @@ var init_injected_mcp = __esm({
3786
4157
  "mcp__sideboard",
3787
4158
  "mcp__sideboard__*"
3788
4159
  ];
4160
+ SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS = [
4161
+ "mcp__sideboard__present_artifact",
4162
+ "mcp__sideboard__present_schema",
4163
+ "mcp__sideboard__present_files"
4164
+ ];
3789
4165
  BRIGHTSY_MCP_ALLOWED_TOOLS = [
3790
4166
  "mcp__brightsy",
3791
4167
  "mcp__brightsy__*"
@@ -3911,7 +4287,7 @@ function parseIssuesJson(raw) {
3911
4287
  }
3912
4288
  return [];
3913
4289
  }
3914
- var import_node_fs11, BASE_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
4290
+ var import_node_fs11, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
3915
4291
  var init_claude = __esm({
3916
4292
  "src/agents/claude.ts"() {
3917
4293
  "use strict";
@@ -3922,7 +4298,21 @@ var init_claude = __esm({
3922
4298
  init_injected_mcp();
3923
4299
  init_turn_input();
3924
4300
  init_types();
3925
- BASE_ALLOWED_TOOLS = ["Edit", "Write", "Bash", "Read", "Glob", "Grep"];
4301
+ BASE_ALLOWED_TOOLS = [
4302
+ "Edit",
4303
+ "Write",
4304
+ "Bash",
4305
+ "Read",
4306
+ "Glob",
4307
+ "Grep",
4308
+ "WebFetch",
4309
+ "WebSearch"
4310
+ ];
4311
+ CLAUDE_CHROME_ALLOWED_TOOLS = [
4312
+ "mcp__claude-in-chrome",
4313
+ "mcp__claude-in-chrome__*",
4314
+ "Skill(claude-in-chrome)"
4315
+ ];
3926
4316
  CLAUDE_PROMPT_ARG_MAX = 2e5;
3927
4317
  claudeAdapter = {
3928
4318
  kind: "claude",
@@ -3983,10 +4373,11 @@ var init_claude = __esm({
3983
4373
  const { isOrchestratorThread: isOrchestratorThread2 } = await Promise.resolve().then(() => (init_global_workspace(), global_workspace_exports));
3984
4374
  const isOrchestrator = isOrchestratorThread2(thread);
3985
4375
  const injectedServers = await buildInjectedMcpServers({
3986
- includeSideboard: isOrchestrator,
4376
+ includeSideboard: true,
3987
4377
  includeBrightsy: isBrightsyConnected()
3988
4378
  });
3989
4379
  const injectedBrightsyNames = injectedServers.filter((s) => s.name === "brightsy" || s.name.startsWith("brightsy_")).map((s) => s.name);
4380
+ const chromeOn = claudeChromeEnabled();
3990
4381
  let allowedTools;
3991
4382
  if (isOrchestrator) {
3992
4383
  allowedTools = [
@@ -3999,9 +4390,13 @@ var init_claude = __esm({
3999
4390
  allowedTools = [
4000
4391
  ...BASE_ALLOWED_TOOLS,
4001
4392
  ...mcpAllowTools(servers),
4393
+ ...SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS,
4002
4394
  ...brightsyMcpAllowedTools(injectedBrightsyNames)
4003
4395
  ];
4004
4396
  }
4397
+ if (chromeOn) {
4398
+ allowedTools = [...allowedTools, ...CLAUDE_CHROME_ALLOWED_TOOLS];
4399
+ }
4005
4400
  const args = [
4006
4401
  "-p",
4007
4402
  ...useStdin ? [] : [promptText],
@@ -4016,7 +4411,7 @@ var init_claude = __esm({
4016
4411
  if (mcpConfigPath) {
4017
4412
  args.push("--mcp-config", mcpConfigPath);
4018
4413
  }
4019
- if (claudeChromeEnabled()) {
4414
+ if (chromeOn) {
4020
4415
  args.push("--chrome");
4021
4416
  }
4022
4417
  if (useStdin) {
@@ -4858,6 +5253,7 @@ __export(index_exports, {
4858
5253
  brightsyMcpServerName: () => brightsyMcpServerName,
4859
5254
  buildCachedUserContent: () => buildCachedUserContent,
4860
5255
  buildClaudeStreamJsonUserMessage: () => buildClaudeStreamJsonUserMessage,
5256
+ buildDiffCommentAttachment: () => buildDiffCommentAttachment,
4861
5257
  buildForkTranscriptAttachment: () => buildForkTranscriptAttachment,
4862
5258
  buildSessionSeed: () => buildSessionSeed,
4863
5259
  buildWorkspaceScriptEnv: () => buildWorkspaceScriptEnv,
@@ -4919,6 +5315,7 @@ __export(index_exports, {
4919
5315
  forkMessageSlice: () => forkMessageSlice,
4920
5316
  forkThreadWorktree: () => forkThreadWorktree,
4921
5317
  formatAgentInstructions: () => formatAgentInstructions,
5318
+ formatArtifactDirective: () => formatArtifactDirective,
4922
5319
  formatBrightsyFetchError: () => formatBrightsyFetchError,
4923
5320
  formatGhLandError: () => formatGhLandError,
4924
5321
  formatIpcInvokeError: () => formatIpcInvokeError,
@@ -4993,6 +5390,7 @@ __export(index_exports, {
4993
5390
  loadRepoSettings: () => loadRepoSettings,
4994
5391
  loadWorkspaceSettings: () => loadWorkspaceSettings,
4995
5392
  locksDir: () => locksDir,
5393
+ lookupSoccerTeam: () => lookupSoccerTeam,
4996
5394
  maxConcurrentAgents: () => maxConcurrentAgents,
4997
5395
  maybeCompactContext: () => maybeCompactContext,
4998
5396
  mcpAllowTools: () => mcpAllowTools,
@@ -5018,6 +5416,7 @@ __export(index_exports, {
5018
5416
  readSkillBody: () => readSkillBody,
5019
5417
  readThread: () => readThread,
5020
5418
  readWorktreeFile: () => readWorktreeFile,
5419
+ readWorktreeFileForUpload: () => readWorktreeFileForUpload,
5021
5420
  readWorktreeInclude: () => readWorktreeInclude,
5022
5421
  refreshGitHubAuth: () => refreshGitHubAuth,
5023
5422
  removeWorkspace: () => removeWorkspace,
@@ -5321,6 +5720,18 @@ function toolDescription(name, input) {
5321
5720
  if (/connectedAgentRequest/i.test(name)) {
5322
5721
  return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
5323
5722
  }
5723
+ if (/present_artifact$/i.test(name)) {
5724
+ return str(input?.title) ? `Present ${str(input?.title)}` : "Present artifact";
5725
+ }
5726
+ if (/present_schema$/i.test(name)) {
5727
+ return str(input?.title) ? `Schema ${str(input?.title)}` : "Present schema";
5728
+ }
5729
+ if (/present_files$/i.test(name)) {
5730
+ return str(input?.title) ? `Files ${str(input?.title)}` : "Present files";
5731
+ }
5732
+ if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
5733
+ return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
5734
+ }
5324
5735
  if (!input) return n;
5325
5736
  if (/bash|shell|terminal/i.test(name) && str(input.command)) {
5326
5737
  const cmd = str(input.command);
@@ -5684,6 +6095,26 @@ function formatWorktreeDirective(thread, opts) {
5684
6095
  }
5685
6096
  return lines.join("\n");
5686
6097
  }
6098
+ function formatArtifactDirective() {
6099
+ return [
6100
+ "Sideboard side column (desktop UI):",
6101
+ "claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
6102
+ "Documents (HTML/SVG/markdown):",
6103
+ "1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
6104
+ "```html",
6105
+ "<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
6106
+ "```",
6107
+ "2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
6108
+ "CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
6109
+ "3) Call Sideboard MCP `present_schema` with title, mode (table|form), and either:",
6110
+ " - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
6111
+ " - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
6112
+ "Files / media browser (CMS file manager column):",
6113
+ "4) Call Sideboard MCP `present_files` with optional title, path, and datasource (brightsy|memory).",
6114
+ " Opens the Files column for browse/upload/pick. Do NOT say a file manager UI is missing.",
6115
+ "Never say artifacts, CMS UI, or the Files column are unavailable. Prefer present_schema for list/edit/publish; present_files for storage UI; html fences for standalone pages."
6116
+ ].join("\n");
6117
+ }
5687
6118
  var FILES_BY_AGENT = {
5688
6119
  claude: [
5689
6120
  "CLAUDE.md",
@@ -6555,6 +6986,27 @@ function isImageRelativePath(relativePath) {
6555
6986
  const ext = base.includes(".") ? base.split(".").pop() || "" : "";
6556
6987
  return IMAGE_EXTENSIONS.has(ext);
6557
6988
  }
6989
+ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
6990
+ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
6991
+ assertSafeRelativePath(relativePath);
6992
+ const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
6993
+ const abs = (0, import_node_path17.join)(worktreePath, relativePath);
6994
+ const st = (0, import_node_fs17.statSync)(abs);
6995
+ if (!st.isFile()) {
6996
+ throw new Error(`Not a file: ${relativePath}`);
6997
+ }
6998
+ if (st.size > maxBytes) {
6999
+ throw new Error(
7000
+ `File too large to upload (${st.size} bytes; max ${maxBytes})`
7001
+ );
7002
+ }
7003
+ const buf = (0, import_node_fs17.readFileSync)(abs);
7004
+ return {
7005
+ path: relativePath,
7006
+ contentBase64: buf.toString("base64"),
7007
+ size: buf.length
7008
+ };
7009
+ }
6558
7010
  function readWorktreeFile(worktreePath, relativePath, opts) {
6559
7011
  assertSafeRelativePath(relativePath);
6560
7012
  const maxBytes = opts?.maxBytes ?? 2e5;
@@ -6847,6 +7299,53 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
6847
7299
  };
6848
7300
  }
6849
7301
 
7302
+ // src/composer/diff-comment.ts
7303
+ function lineRangeLabel(lines) {
7304
+ const nos = lines.map((l) => l.lineNo);
7305
+ const start = Math.min(...nos);
7306
+ const end = Math.max(...nos);
7307
+ return start === end ? `L${start}` : `L${start}-${end}`;
7308
+ }
7309
+ function formatDiffBody(lines) {
7310
+ return lines.map((l) => {
7311
+ const prefix = l.side === "add" ? "+" : l.side === "del" ? "-" : " ";
7312
+ return `${prefix}${l.text}`;
7313
+ }).join("\n");
7314
+ }
7315
+ function buildDiffCommentAttachment(input) {
7316
+ const comment = input.comment.trim();
7317
+ if (!input.path.trim()) {
7318
+ throw new Error("diff comment requires a file path");
7319
+ }
7320
+ if (!comment) {
7321
+ throw new Error("diff comment requires a note");
7322
+ }
7323
+ if (input.lines.length === 0) {
7324
+ throw new Error("diff comment requires at least one cited line");
7325
+ }
7326
+ const range = lineRangeLabel(input.lines);
7327
+ const name = `${input.path}:${range}`;
7328
+ const content = [
7329
+ `Diff review comment on \`${input.path}\` (${range}).`,
7330
+ "",
7331
+ "Address this feedback on the cited lines. Prefer a precise fix over rewriting unrelated code.",
7332
+ "",
7333
+ "### Reviewer comment",
7334
+ comment,
7335
+ "",
7336
+ "### Cited diff",
7337
+ "```diff",
7338
+ formatDiffBody(input.lines),
7339
+ "```"
7340
+ ].join("\n");
7341
+ return {
7342
+ id: input.id ?? `diff-comment-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
7343
+ name,
7344
+ kind: "diff-comment",
7345
+ content
7346
+ };
7347
+ }
7348
+
6850
7349
  // src/composer/summarize.ts
6851
7350
  init_run();
6852
7351
  init_path();
@@ -8303,9 +8802,18 @@ var Orchestrator = class {
8303
8802
  parentId: threadId,
8304
8803
  goal: thread.sourceRef || thread.title
8305
8804
  }) : null;
8805
+ const artifactReminder = thread.agent !== "brightsy" ? [
8806
+ "Sideboard side column (important):",
8807
+ "There is no claude.ai Artifact tool here \u2014 that is normal.",
8808
+ "HTML/SVG/markdown: ```html fence or MCP present_artifact.",
8809
+ "CMS forms/tables: MCP present_schema (Brightsy resource_id or inline schema+schemaUi).",
8810
+ "Files column: MCP present_files (brightsy account storage or memory).",
8811
+ "Do not say artifacts/CMS UI are unavailable."
8812
+ ].join(" ") : null;
8306
8813
  const agentPrompt = [
8307
8814
  thread.planMode ? PLAN_MODE_INSTRUCTION : null,
8308
8815
  orchestrationReminder,
8816
+ artifactReminder,
8309
8817
  expandedPrompt
8310
8818
  ].filter(Boolean).join("\n\n");
8311
8819
  const instructionFiles = loadAgentInstructions(thread.worktreePath, thread.agent);
@@ -8330,6 +8838,7 @@ var Orchestrator = class {
8330
8838
  () => null
8331
8839
  )
8332
8840
  });
8841
+ const artifactDirective = isBrightsy ? null : formatArtifactDirective();
8333
8842
  const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
8334
8843
  const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
8335
8844
  const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled2() ? formatRenameBranchDirective(fresh, {
@@ -8357,6 +8866,7 @@ var Orchestrator = class {
8357
8866
  const cachedPrefix = [
8358
8867
  coordinatorDirective,
8359
8868
  worktreeDirective,
8869
+ artifactDirective,
8360
8870
  renameBranchDirective,
8361
8871
  ...fresh.agent === "claude" && fresh.sessionId ? [] : [instructions, seed]
8362
8872
  ].filter(Boolean).join("\n\n---\n\n");
@@ -8777,6 +9287,13 @@ var Orchestrator = class {
8777
9287
  }
8778
9288
  return readWorktreeFile(thread.worktreePath, relativePath);
8779
9289
  }
9290
+ async readFileForUpload(threadRef, relativePath) {
9291
+ const thread = this.requireThread(threadRef);
9292
+ if (relativePath.includes("..") || relativePath.startsWith("/")) {
9293
+ throw new Error("Invalid path");
9294
+ }
9295
+ return readWorktreeFileForUpload(thread.worktreePath, relativePath);
9296
+ }
8780
9297
  async writeFile(threadRef, relativePath, content) {
8781
9298
  const thread = this.requireThread(threadRef);
8782
9299
  if (relativePath.includes("..") || relativePath.startsWith("/")) {
@@ -9158,6 +9675,82 @@ async function startMcpServer() {
9158
9675
  return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
9159
9676
  }
9160
9677
  );
9678
+ server.tool(
9679
+ "present_artifact",
9680
+ "Show an HTML, SVG, or markdown document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Prefer type=html for interactive pages.",
9681
+ {
9682
+ title: import_zod.z.string().describe("Short title shown in the artifact pane header"),
9683
+ type: import_zod.z.enum(["html", "svg", "markdown"]).describe("Artifact kind \u2014 html opens an iframe preview"),
9684
+ content: import_zod.z.string().describe("Full document body (complete HTML page, SVG markup, or markdown)"),
9685
+ artifact_id: import_zod.z.string().optional().describe("Stable id when updating the same artifact across turns")
9686
+ },
9687
+ async ({ title, type, content, artifact_id }) => {
9688
+ const id = artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
9689
+ const payload = {
9690
+ ok: true,
9691
+ artifact_id: id,
9692
+ title,
9693
+ type,
9694
+ content,
9695
+ message: "Artifact accepted. Sideboard desktop opens it in the side column beside chat."
9696
+ };
9697
+ return { content: [{ type: "text", text: JSON.stringify(payload) }] };
9698
+ }
9699
+ );
9700
+ server.tool(
9701
+ "present_schema",
9702
+ "Open Sideboard\u2019s schema-driven CMS side column (filterable table and/or form). Pass JSON Schema + schemaUi (Brightsy extensions supported). Use datasource=brightsy with resource_id (record type UUID) when logged into Brightsy; use datasource=inline with embedded resource/records for any other source.",
9703
+ {
9704
+ title: import_zod.z.string().describe("Pane title"),
9705
+ mode: import_zod.z.enum(["table", "form"]).optional().describe("table = list/filter records; form = edit one record"),
9706
+ datasource: import_zod.z.enum(["brightsy", "inline"]).optional().describe("brightsy resolves via login; inline uses embedded resource/records"),
9707
+ resource_id: import_zod.z.string().optional().describe("Brightsy record type UUID (or generic resource id)"),
9708
+ record_id: import_zod.z.string().optional().describe("Record id when opening form mode"),
9709
+ resource: import_zod.z.record(import_zod.z.unknown()).optional().describe("Inline { id, title, schema, schemaUi?, slug? }"),
9710
+ record: import_zod.z.record(import_zod.z.unknown()).optional().describe("Inline record { id, data, published_at? }"),
9711
+ records: import_zod.z.array(import_zod.z.record(import_zod.z.unknown())).optional().describe("Inline records for table mode"),
9712
+ pane_id: import_zod.z.string().optional().describe("Stable pane id across updates")
9713
+ },
9714
+ async (args) => {
9715
+ const id = args.pane_id?.trim() || `schema_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
9716
+ const payload = {
9717
+ ok: true,
9718
+ pane_id: id,
9719
+ title: args.title,
9720
+ mode: args.mode ?? (args.record_id || args.record ? "form" : "table"),
9721
+ datasource: args.datasource ?? (args.resource ? "inline" : "brightsy"),
9722
+ resource_id: args.resource_id,
9723
+ record_id: args.record_id,
9724
+ resource: args.resource,
9725
+ record: args.record,
9726
+ records: args.records,
9727
+ message: "Schema pane accepted. Sideboard desktop opens the CMS column beside chat."
9728
+ };
9729
+ return { content: [{ type: "text", text: JSON.stringify(payload) }] };
9730
+ }
9731
+ );
9732
+ server.tool(
9733
+ "present_files",
9734
+ "Open Sideboard\u2019s Files column (CMS-style file manager: browse, upload, pick). Use datasource=brightsy when the user is logged into Brightsy account storage; datasource=memory for a session-local demo store. Prefer this over claiming a file manager UI is unavailable. Pair with present_schema when editing records that need media.",
9735
+ {
9736
+ title: import_zod.z.string().optional().describe("Pane title (default: Files)"),
9737
+ datasource: import_zod.z.enum(["brightsy", "memory"]).optional().describe("brightsy = account storage via login; memory = session demo store"),
9738
+ path: import_zod.z.string().optional().describe("Initial folder path (e.g. public)"),
9739
+ pane_id: import_zod.z.string().optional().describe("Stable pane id across updates")
9740
+ },
9741
+ async (args) => {
9742
+ const id = args.pane_id?.trim() || `files_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
9743
+ const payload = {
9744
+ ok: true,
9745
+ pane_id: id,
9746
+ title: args.title?.trim() || "Files",
9747
+ datasource: args.datasource ?? "brightsy",
9748
+ path: args.path,
9749
+ message: "Files pane accepted. Sideboard desktop opens the Files column beside chat."
9750
+ };
9751
+ return { content: [{ type: "text", text: JSON.stringify(payload) }] };
9752
+ }
9753
+ );
9161
9754
  server.tool(
9162
9755
  "create_thread",
9163
9756
  "Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces and parentThreadId when spawning from an orchestrator. Then use send_to_thread to chat.",
@@ -9499,45 +10092,6 @@ async function startMcpServer() {
9499
10092
  };
9500
10093
  }
9501
10094
  );
9502
- server.tool(
9503
- "preview_land",
9504
- "Preview push+PR land (does NOT push). Use before create_draft_pr.",
9505
- { ref: import_zod.z.string() },
9506
- async ({ ref }) => {
9507
- const preview = await orch.previewLand(ref);
9508
- return { content: [{ type: "text", text: JSON.stringify(preview, null, 2) }] };
9509
- }
9510
- );
9511
- server.tool(
9512
- "create_draft_pr",
9513
- "Commit dirty changes if needed, push the thread branch to origin, and create/update a DRAFT GitHub PR against that worktree's origin (never upstream). Ready-for-review / non-draft land stays human-only (CLI/app confirm_land). Prefer this when the orchestrator should open a PR itself; alternatively send_to_thread asking the worktree agent to run `gh pr create --draft -R <origin-owner/name>`.",
9514
- { ref: import_zod.z.string() },
9515
- async ({ ref }) => {
9516
- try {
9517
- const result = await orch.confirmLand(ref, { draft: true });
9518
- return {
9519
- content: [
9520
- {
9521
- type: "text",
9522
- text: JSON.stringify(
9523
- {
9524
- prUrl: result.prUrl,
9525
- pushed: result.pushed,
9526
- committed: result.committed,
9527
- draft: true
9528
- },
9529
- null,
9530
- 2
9531
- )
9532
- }
9533
- ]
9534
- };
9535
- } catch (err) {
9536
- const message = err instanceof Error ? err.message : String(err);
9537
- return { content: [{ type: "text", text: message }], isError: true };
9538
- }
9539
- }
9540
- );
9541
10095
  server.tool(
9542
10096
  "list_branches",
9543
10097
  "List git branches in a registered workspace. Pass repoPath from list_workspaces (unmerged into the default branch by default \u2014 for create_thread sourceType=branch).",
@@ -9993,6 +10547,7 @@ init_injected_mcp();
9993
10547
  brightsyMcpServerName,
9994
10548
  buildCachedUserContent,
9995
10549
  buildClaudeStreamJsonUserMessage,
10550
+ buildDiffCommentAttachment,
9996
10551
  buildForkTranscriptAttachment,
9997
10552
  buildSessionSeed,
9998
10553
  buildWorkspaceScriptEnv,
@@ -10054,6 +10609,7 @@ init_injected_mcp();
10054
10609
  forkMessageSlice,
10055
10610
  forkThreadWorktree,
10056
10611
  formatAgentInstructions,
10612
+ formatArtifactDirective,
10057
10613
  formatBrightsyFetchError,
10058
10614
  formatGhLandError,
10059
10615
  formatIpcInvokeError,
@@ -10128,6 +10684,7 @@ init_injected_mcp();
10128
10684
  loadRepoSettings,
10129
10685
  loadWorkspaceSettings,
10130
10686
  locksDir,
10687
+ lookupSoccerTeam,
10131
10688
  maxConcurrentAgents,
10132
10689
  maybeCompactContext,
10133
10690
  mcpAllowTools,
@@ -10153,6 +10710,7 @@ init_injected_mcp();
10153
10710
  readSkillBody,
10154
10711
  readThread,
10155
10712
  readWorktreeFile,
10713
+ readWorktreeFileForUpload,
10156
10714
  readWorktreeInclude,
10157
10715
  refreshGitHubAuth,
10158
10716
  removeWorkspace,