2121
2222import com .botwithus .bot .core .runtime .ScriptRunner ;
2323
24+ import com .google .gson .Gson ;
25+ import com .google .gson .GsonBuilder ;
26+ import com .google .gson .reflect .TypeToken ;
27+
2428import java .awt .image .BufferedImage ;
2529import java .io .PrintStream ;
2630import java .nio .file .Files ;
@@ -297,14 +301,69 @@ public void openConfigPanel(ScriptRunner runner) {
297301 if (configPanelOpener != null ) configPanelOpener .accept (runner );
298302 }
299303
300- // --- Connection Group management ---
304+ // --- Connection Group management & persistence ---
305+
306+ private static final Path GROUPS_FILE = Path .of (System .getProperty ("user.home" ), ".botwithus" , "groups.json" );
307+
308+ /** Simple DTO for JSON serialization of a group. */
309+ private static class GroupData {
310+ String description ;
311+ List <String > members ;
312+ GroupData () {}
313+ GroupData (String description , List <String > members ) {
314+ this .description = description ;
315+ this .members = members ;
316+ }
317+ }
318+
319+ /** Loads persisted groups from ~/.botwithus/groups.json. */
320+ public void loadGroups () {
321+ if (!Files .exists (GROUPS_FILE )) return ;
322+ try {
323+ String json = Files .readString (GROUPS_FILE );
324+ Gson gson = new Gson ();
325+ Map <String , GroupData > data = gson .fromJson (json ,
326+ new TypeToken <LinkedHashMap <String , GroupData >>() {}.getType ());
327+ if (data != null ) {
328+ groups .clear ();
329+ for (var entry : data .entrySet ()) {
330+ ConnectionGroup group = new ConnectionGroup (entry .getKey ());
331+ GroupData gd = entry .getValue ();
332+ if (gd .description != null ) group .setDescription (gd .description );
333+ if (gd .members != null ) gd .members .forEach (group ::add );
334+ groups .put (entry .getKey (), group );
335+ }
336+ }
337+ } catch (Exception e ) {
338+ System .err .println ("[CliContext] Failed to load groups: " + e .getMessage ());
339+ }
340+ }
341+
342+ /** Persists current groups to ~/.botwithus/groups.json. */
343+ void saveGroups () {
344+ try {
345+ Files .createDirectories (GROUPS_FILE .getParent ());
346+ Gson gson = new GsonBuilder ().setPrettyPrinting ().create ();
347+ Map <String , GroupData > data = new LinkedHashMap <>();
348+ for (var entry : groups .entrySet ()) {
349+ ConnectionGroup g = entry .getValue ();
350+ data .put (entry .getKey (), new GroupData (g .getDescription (), new ArrayList <>(g .getConnectionNames ())));
351+ }
352+ Files .writeString (GROUPS_FILE , gson .toJson (data ));
353+ } catch (Exception e ) {
354+ System .err .println ("[CliContext] Failed to save groups: " + e .getMessage ());
355+ }
356+ }
301357
302358 public void createGroup (String name ) {
303359 groups .put (name , new ConnectionGroup (name ));
360+ saveGroups ();
304361 }
305362
306363 public boolean deleteGroup (String name ) {
307- return groups .remove (name ) != null ;
364+ boolean removed = groups .remove (name ) != null ;
365+ if (removed ) saveGroups ();
366+ return removed ;
308367 }
309368
310369 public ConnectionGroup getGroup (String name ) {
@@ -315,6 +374,22 @@ public Map<String, ConnectionGroup> getGroups() {
315374 return Collections .unmodifiableMap (groups );
316375 }
317376
377+ public void addToGroup (String groupName , String connectionName ) {
378+ ConnectionGroup group = groups .get (groupName );
379+ if (group != null ) {
380+ group .add (connectionName );
381+ saveGroups ();
382+ }
383+ }
384+
385+ public void removeFromGroup (String groupName , String connectionName ) {
386+ ConnectionGroup group = groups .get (groupName );
387+ if (group != null ) {
388+ group .remove (connectionName );
389+ saveGroups ();
390+ }
391+ }
392+
318393 /**
319394 * Returns the list of active (connected) Connection objects for a group.
320395 * Connections that are in the group but not currently connected are skipped.
0 commit comments