ScuttleBot
Merge pull request #144 from ConflictHQ/feature/128-config-architecture feat: config architecture — Ergo hot-reload + expose missing settings
Commit
aeff8d0a1974897a49166be37eba0692a91a43700d0a57fa6967b7a45c55a8d5
Parent
900677e50c00eb2…
5 files changed
+8
+8
+35
-8
+35
-8
+7
| --- cmd/scuttlebot/main.go | ||
| +++ cmd/scuttlebot/main.go | ||
| @@ -352,10 +352,18 @@ | ||
| 352 | 352 | } |
| 353 | 353 | } |
| 354 | 354 | // Hot-reload bridge web TTL. |
| 355 | 355 | if bridgeBot != nil { |
| 356 | 356 | bridgeBot.SetWebUserTTL(time.Duration(updated.Bridge.WebUserTTLMinutes) * time.Minute) |
| 357 | + } | |
| 358 | + // Regenerate ircd.yaml and rehash Ergo on config changes. | |
| 359 | + if ergoMgr != nil { | |
| 360 | + if err := ergoMgr.UpdateConfig(updated.Ergo); err != nil { | |
| 361 | + log.Error("ergo config hot-reload failed", "err", err) | |
| 362 | + } else { | |
| 363 | + log.Info("ergo config reloaded") | |
| 364 | + } | |
| 357 | 365 | } |
| 358 | 366 | }) |
| 359 | 367 | |
| 360 | 368 | // Start HTTP REST API server. |
| 361 | 369 | var llmCfg *config.LLMConfig |
| 362 | 370 |
| --- cmd/scuttlebot/main.go | |
| +++ cmd/scuttlebot/main.go | |
| @@ -352,10 +352,18 @@ | |
| 352 | } |
| 353 | } |
| 354 | // Hot-reload bridge web TTL. |
| 355 | if bridgeBot != nil { |
| 356 | bridgeBot.SetWebUserTTL(time.Duration(updated.Bridge.WebUserTTLMinutes) * time.Minute) |
| 357 | } |
| 358 | }) |
| 359 | |
| 360 | // Start HTTP REST API server. |
| 361 | var llmCfg *config.LLMConfig |
| 362 |
| --- cmd/scuttlebot/main.go | |
| +++ cmd/scuttlebot/main.go | |
| @@ -352,10 +352,18 @@ | |
| 352 | } |
| 353 | } |
| 354 | // Hot-reload bridge web TTL. |
| 355 | if bridgeBot != nil { |
| 356 | bridgeBot.SetWebUserTTL(time.Duration(updated.Bridge.WebUserTTLMinutes) * time.Minute) |
| 357 | } |
| 358 | // Regenerate ircd.yaml and rehash Ergo on config changes. |
| 359 | if ergoMgr != nil { |
| 360 | if err := ergoMgr.UpdateConfig(updated.Ergo); err != nil { |
| 361 | log.Error("ergo config hot-reload failed", "err", err) |
| 362 | } else { |
| 363 | log.Info("ergo config reloaded") |
| 364 | } |
| 365 | } |
| 366 | }) |
| 367 | |
| 368 | // Start HTTP REST API server. |
| 369 | var llmCfg *config.LLMConfig |
| 370 |
| --- cmd/scuttlebot/main.go | ||
| +++ cmd/scuttlebot/main.go | ||
| @@ -352,10 +352,18 @@ | ||
| 352 | 352 | } |
| 353 | 353 | } |
| 354 | 354 | // Hot-reload bridge web TTL. |
| 355 | 355 | if bridgeBot != nil { |
| 356 | 356 | bridgeBot.SetWebUserTTL(time.Duration(updated.Bridge.WebUserTTLMinutes) * time.Minute) |
| 357 | + } | |
| 358 | + // Regenerate ircd.yaml and rehash Ergo on config changes. | |
| 359 | + if ergoMgr != nil { | |
| 360 | + if err := ergoMgr.UpdateConfig(updated.Ergo); err != nil { | |
| 361 | + log.Error("ergo config hot-reload failed", "err", err) | |
| 362 | + } else { | |
| 363 | + log.Info("ergo config reloaded") | |
| 364 | + } | |
| 357 | 365 | } |
| 358 | 366 | }) |
| 359 | 367 | |
| 360 | 368 | // Start HTTP REST API server. |
| 361 | 369 | var llmCfg *config.LLMConfig |
| 362 | 370 |
| --- cmd/scuttlebot/main.go | |
| +++ cmd/scuttlebot/main.go | |
| @@ -352,10 +352,18 @@ | |
| 352 | } |
| 353 | } |
| 354 | // Hot-reload bridge web TTL. |
| 355 | if bridgeBot != nil { |
| 356 | bridgeBot.SetWebUserTTL(time.Duration(updated.Bridge.WebUserTTLMinutes) * time.Minute) |
| 357 | } |
| 358 | }) |
| 359 | |
| 360 | // Start HTTP REST API server. |
| 361 | var llmCfg *config.LLMConfig |
| 362 |
| --- cmd/scuttlebot/main.go | |
| +++ cmd/scuttlebot/main.go | |
| @@ -352,10 +352,18 @@ | |
| 352 | } |
| 353 | } |
| 354 | // Hot-reload bridge web TTL. |
| 355 | if bridgeBot != nil { |
| 356 | bridgeBot.SetWebUserTTL(time.Duration(updated.Bridge.WebUserTTLMinutes) * time.Minute) |
| 357 | } |
| 358 | // Regenerate ircd.yaml and rehash Ergo on config changes. |
| 359 | if ergoMgr != nil { |
| 360 | if err := ergoMgr.UpdateConfig(updated.Ergo); err != nil { |
| 361 | log.Error("ergo config hot-reload failed", "err", err) |
| 362 | } else { |
| 363 | log.Info("ergo config reloaded") |
| 364 | } |
| 365 | } |
| 366 | }) |
| 367 | |
| 368 | // Start HTTP REST API server. |
| 369 | var llmCfg *config.LLMConfig |
| 370 |
+35
-8
| --- internal/api/ui/index.html | ||
| +++ internal/api/ui/index.html | ||
| @@ -858,10 +858,31 @@ | ||
| 858 | 858 | </div> |
| 859 | 859 | <div class="setting-row"> |
| 860 | 860 | <div class="setting-label">IRC address</div> |
| 861 | 861 | <div class="setting-desc">Address Ergo listens on for IRC connections. Requires restart.</div> |
| 862 | 862 | <input type="text" id="ergo-irc-addr" placeholder="127.0.0.1:6667" style="width:180px;padding:4px 8px;font-size:12px"> |
| 863 | + </div> | |
| 864 | + <div class="setting-row"> | |
| 865 | + <div class="setting-label">require SASL</div> | |
| 866 | + <div class="setting-desc">Enforce SASL authentication for all IRC connections. Only registered accounts can connect. Hot-reloads.</div> | |
| 867 | + <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> | |
| 868 | + <input type="checkbox" id="ergo-require-sasl"> | |
| 869 | + <span style="font-size:12px">enforce SASL</span> | |
| 870 | + </label> | |
| 871 | + </div> | |
| 872 | + <div class="setting-row"> | |
| 873 | + <div class="setting-label">default channel modes</div> | |
| 874 | + <div class="setting-desc">Modes applied to new channels (e.g. "+n", "+Rn"). Hot-reloads.</div> | |
| 875 | + <input type="text" id="ergo-default-modes" placeholder="+n" style="width:120px;padding:4px 8px;font-size:12px"> | |
| 876 | + </div> | |
| 877 | + <div class="setting-row"> | |
| 878 | + <div class="setting-label">message history</div> | |
| 879 | + <div class="setting-desc">Enable persistent message history (CHATHISTORY). Hot-reloads.</div> | |
| 880 | + <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> | |
| 881 | + <input type="checkbox" id="ergo-history-enabled"> | |
| 882 | + <span style="font-size:12px">enabled</span> | |
| 883 | + </label> | |
| 863 | 884 | </div> |
| 864 | 885 | <div class="setting-row"> |
| 865 | 886 | <div class="setting-label">external mode</div> |
| 866 | 887 | <div class="setting-desc">Disable subprocess management — scuttlebot expects Ergo to already be running. Requires restart.</div> |
| 867 | 888 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| @@ -3485,14 +3506,17 @@ | ||
| 3485 | 3506 | // general |
| 3486 | 3507 | document.getElementById('general-api-addr').value = cfg.api_addr || ''; |
| 3487 | 3508 | document.getElementById('general-mcp-addr').value = cfg.mcp_addr || ''; |
| 3488 | 3509 | // ergo |
| 3489 | 3510 | const e = cfg.ergo || {}; |
| 3490 | - document.getElementById('ergo-network-name').value = e.network_name || ''; | |
| 3491 | - document.getElementById('ergo-server-name').value = e.server_name || ''; | |
| 3492 | - document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; | |
| 3493 | - document.getElementById('ergo-external').checked = !!e.external; | |
| 3511 | + document.getElementById('ergo-network-name').value = e.network_name || ''; | |
| 3512 | + document.getElementById('ergo-server-name').value = e.server_name || ''; | |
| 3513 | + document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; | |
| 3514 | + document.getElementById('ergo-require-sasl').checked = !!e.require_sasl; | |
| 3515 | + document.getElementById('ergo-default-modes').value = e.default_channel_modes || ''; | |
| 3516 | + document.getElementById('ergo-history-enabled').checked = !!(e.history && e.history.enabled); | |
| 3517 | + document.getElementById('ergo-external').checked = !!e.external; | |
| 3494 | 3518 | // tls |
| 3495 | 3519 | const t = cfg.tls || {}; |
| 3496 | 3520 | document.getElementById('tls-domain').value = t.domain || ''; |
| 3497 | 3521 | document.getElementById('tls-email').value = t.email || ''; |
| 3498 | 3522 | document.getElementById('tls-allow-insecure').checked = !!t.allow_insecure; |
| @@ -3565,14 +3589,17 @@ | ||
| 3565 | 3589 | } |
| 3566 | 3590 | |
| 3567 | 3591 | function saveErgoConfig() { |
| 3568 | 3592 | saveConfigPatch({ |
| 3569 | 3593 | ergo: { |
| 3570 | - network_name: document.getElementById('ergo-network-name').value.trim() || undefined, | |
| 3571 | - server_name: document.getElementById('ergo-server-name').value.trim() || undefined, | |
| 3572 | - irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, | |
| 3573 | - external: document.getElementById('ergo-external').checked, | |
| 3594 | + network_name: document.getElementById('ergo-network-name').value.trim() || undefined, | |
| 3595 | + server_name: document.getElementById('ergo-server-name').value.trim() || undefined, | |
| 3596 | + irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, | |
| 3597 | + require_sasl: document.getElementById('ergo-require-sasl').checked, | |
| 3598 | + default_channel_modes: document.getElementById('ergo-default-modes').value.trim() || undefined, | |
| 3599 | + history: { enabled: document.getElementById('ergo-history-enabled').checked }, | |
| 3600 | + external: document.getElementById('ergo-external').checked, | |
| 3574 | 3601 | } |
| 3575 | 3602 | }, 'ergo-save-result'); |
| 3576 | 3603 | } |
| 3577 | 3604 | |
| 3578 | 3605 | function saveTLSConfig() { |
| 3579 | 3606 |
| --- internal/api/ui/index.html | |
| +++ internal/api/ui/index.html | |
| @@ -858,10 +858,31 @@ | |
| 858 | </div> |
| 859 | <div class="setting-row"> |
| 860 | <div class="setting-label">IRC address</div> |
| 861 | <div class="setting-desc">Address Ergo listens on for IRC connections. Requires restart.</div> |
| 862 | <input type="text" id="ergo-irc-addr" placeholder="127.0.0.1:6667" style="width:180px;padding:4px 8px;font-size:12px"> |
| 863 | </div> |
| 864 | <div class="setting-row"> |
| 865 | <div class="setting-label">external mode</div> |
| 866 | <div class="setting-desc">Disable subprocess management — scuttlebot expects Ergo to already be running. Requires restart.</div> |
| 867 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| @@ -3485,14 +3506,17 @@ | |
| 3485 | // general |
| 3486 | document.getElementById('general-api-addr').value = cfg.api_addr || ''; |
| 3487 | document.getElementById('general-mcp-addr').value = cfg.mcp_addr || ''; |
| 3488 | // ergo |
| 3489 | const e = cfg.ergo || {}; |
| 3490 | document.getElementById('ergo-network-name').value = e.network_name || ''; |
| 3491 | document.getElementById('ergo-server-name').value = e.server_name || ''; |
| 3492 | document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; |
| 3493 | document.getElementById('ergo-external').checked = !!e.external; |
| 3494 | // tls |
| 3495 | const t = cfg.tls || {}; |
| 3496 | document.getElementById('tls-domain').value = t.domain || ''; |
| 3497 | document.getElementById('tls-email').value = t.email || ''; |
| 3498 | document.getElementById('tls-allow-insecure').checked = !!t.allow_insecure; |
| @@ -3565,14 +3589,17 @@ | |
| 3565 | } |
| 3566 | |
| 3567 | function saveErgoConfig() { |
| 3568 | saveConfigPatch({ |
| 3569 | ergo: { |
| 3570 | network_name: document.getElementById('ergo-network-name').value.trim() || undefined, |
| 3571 | server_name: document.getElementById('ergo-server-name').value.trim() || undefined, |
| 3572 | irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, |
| 3573 | external: document.getElementById('ergo-external').checked, |
| 3574 | } |
| 3575 | }, 'ergo-save-result'); |
| 3576 | } |
| 3577 | |
| 3578 | function saveTLSConfig() { |
| 3579 |
| --- internal/api/ui/index.html | |
| +++ internal/api/ui/index.html | |
| @@ -858,10 +858,31 @@ | |
| 858 | </div> |
| 859 | <div class="setting-row"> |
| 860 | <div class="setting-label">IRC address</div> |
| 861 | <div class="setting-desc">Address Ergo listens on for IRC connections. Requires restart.</div> |
| 862 | <input type="text" id="ergo-irc-addr" placeholder="127.0.0.1:6667" style="width:180px;padding:4px 8px;font-size:12px"> |
| 863 | </div> |
| 864 | <div class="setting-row"> |
| 865 | <div class="setting-label">require SASL</div> |
| 866 | <div class="setting-desc">Enforce SASL authentication for all IRC connections. Only registered accounts can connect. Hot-reloads.</div> |
| 867 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| 868 | <input type="checkbox" id="ergo-require-sasl"> |
| 869 | <span style="font-size:12px">enforce SASL</span> |
| 870 | </label> |
| 871 | </div> |
| 872 | <div class="setting-row"> |
| 873 | <div class="setting-label">default channel modes</div> |
| 874 | <div class="setting-desc">Modes applied to new channels (e.g. "+n", "+Rn"). Hot-reloads.</div> |
| 875 | <input type="text" id="ergo-default-modes" placeholder="+n" style="width:120px;padding:4px 8px;font-size:12px"> |
| 876 | </div> |
| 877 | <div class="setting-row"> |
| 878 | <div class="setting-label">message history</div> |
| 879 | <div class="setting-desc">Enable persistent message history (CHATHISTORY). Hot-reloads.</div> |
| 880 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| 881 | <input type="checkbox" id="ergo-history-enabled"> |
| 882 | <span style="font-size:12px">enabled</span> |
| 883 | </label> |
| 884 | </div> |
| 885 | <div class="setting-row"> |
| 886 | <div class="setting-label">external mode</div> |
| 887 | <div class="setting-desc">Disable subprocess management — scuttlebot expects Ergo to already be running. Requires restart.</div> |
| 888 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| @@ -3485,14 +3506,17 @@ | |
| 3506 | // general |
| 3507 | document.getElementById('general-api-addr').value = cfg.api_addr || ''; |
| 3508 | document.getElementById('general-mcp-addr').value = cfg.mcp_addr || ''; |
| 3509 | // ergo |
| 3510 | const e = cfg.ergo || {}; |
| 3511 | document.getElementById('ergo-network-name').value = e.network_name || ''; |
| 3512 | document.getElementById('ergo-server-name').value = e.server_name || ''; |
| 3513 | document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; |
| 3514 | document.getElementById('ergo-require-sasl').checked = !!e.require_sasl; |
| 3515 | document.getElementById('ergo-default-modes').value = e.default_channel_modes || ''; |
| 3516 | document.getElementById('ergo-history-enabled').checked = !!(e.history && e.history.enabled); |
| 3517 | document.getElementById('ergo-external').checked = !!e.external; |
| 3518 | // tls |
| 3519 | const t = cfg.tls || {}; |
| 3520 | document.getElementById('tls-domain').value = t.domain || ''; |
| 3521 | document.getElementById('tls-email').value = t.email || ''; |
| 3522 | document.getElementById('tls-allow-insecure').checked = !!t.allow_insecure; |
| @@ -3565,14 +3589,17 @@ | |
| 3589 | } |
| 3590 | |
| 3591 | function saveErgoConfig() { |
| 3592 | saveConfigPatch({ |
| 3593 | ergo: { |
| 3594 | network_name: document.getElementById('ergo-network-name').value.trim() || undefined, |
| 3595 | server_name: document.getElementById('ergo-server-name').value.trim() || undefined, |
| 3596 | irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, |
| 3597 | require_sasl: document.getElementById('ergo-require-sasl').checked, |
| 3598 | default_channel_modes: document.getElementById('ergo-default-modes').value.trim() || undefined, |
| 3599 | history: { enabled: document.getElementById('ergo-history-enabled').checked }, |
| 3600 | external: document.getElementById('ergo-external').checked, |
| 3601 | } |
| 3602 | }, 'ergo-save-result'); |
| 3603 | } |
| 3604 | |
| 3605 | function saveTLSConfig() { |
| 3606 |
+35
-8
| --- internal/api/ui/index.html | ||
| +++ internal/api/ui/index.html | ||
| @@ -858,10 +858,31 @@ | ||
| 858 | 858 | </div> |
| 859 | 859 | <div class="setting-row"> |
| 860 | 860 | <div class="setting-label">IRC address</div> |
| 861 | 861 | <div class="setting-desc">Address Ergo listens on for IRC connections. Requires restart.</div> |
| 862 | 862 | <input type="text" id="ergo-irc-addr" placeholder="127.0.0.1:6667" style="width:180px;padding:4px 8px;font-size:12px"> |
| 863 | + </div> | |
| 864 | + <div class="setting-row"> | |
| 865 | + <div class="setting-label">require SASL</div> | |
| 866 | + <div class="setting-desc">Enforce SASL authentication for all IRC connections. Only registered accounts can connect. Hot-reloads.</div> | |
| 867 | + <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> | |
| 868 | + <input type="checkbox" id="ergo-require-sasl"> | |
| 869 | + <span style="font-size:12px">enforce SASL</span> | |
| 870 | + </label> | |
| 871 | + </div> | |
| 872 | + <div class="setting-row"> | |
| 873 | + <div class="setting-label">default channel modes</div> | |
| 874 | + <div class="setting-desc">Modes applied to new channels (e.g. "+n", "+Rn"). Hot-reloads.</div> | |
| 875 | + <input type="text" id="ergo-default-modes" placeholder="+n" style="width:120px;padding:4px 8px;font-size:12px"> | |
| 876 | + </div> | |
| 877 | + <div class="setting-row"> | |
| 878 | + <div class="setting-label">message history</div> | |
| 879 | + <div class="setting-desc">Enable persistent message history (CHATHISTORY). Hot-reloads.</div> | |
| 880 | + <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> | |
| 881 | + <input type="checkbox" id="ergo-history-enabled"> | |
| 882 | + <span style="font-size:12px">enabled</span> | |
| 883 | + </label> | |
| 863 | 884 | </div> |
| 864 | 885 | <div class="setting-row"> |
| 865 | 886 | <div class="setting-label">external mode</div> |
| 866 | 887 | <div class="setting-desc">Disable subprocess management — scuttlebot expects Ergo to already be running. Requires restart.</div> |
| 867 | 888 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| @@ -3485,14 +3506,17 @@ | ||
| 3485 | 3506 | // general |
| 3486 | 3507 | document.getElementById('general-api-addr').value = cfg.api_addr || ''; |
| 3487 | 3508 | document.getElementById('general-mcp-addr').value = cfg.mcp_addr || ''; |
| 3488 | 3509 | // ergo |
| 3489 | 3510 | const e = cfg.ergo || {}; |
| 3490 | - document.getElementById('ergo-network-name').value = e.network_name || ''; | |
| 3491 | - document.getElementById('ergo-server-name').value = e.server_name || ''; | |
| 3492 | - document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; | |
| 3493 | - document.getElementById('ergo-external').checked = !!e.external; | |
| 3511 | + document.getElementById('ergo-network-name').value = e.network_name || ''; | |
| 3512 | + document.getElementById('ergo-server-name').value = e.server_name || ''; | |
| 3513 | + document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; | |
| 3514 | + document.getElementById('ergo-require-sasl').checked = !!e.require_sasl; | |
| 3515 | + document.getElementById('ergo-default-modes').value = e.default_channel_modes || ''; | |
| 3516 | + document.getElementById('ergo-history-enabled').checked = !!(e.history && e.history.enabled); | |
| 3517 | + document.getElementById('ergo-external').checked = !!e.external; | |
| 3494 | 3518 | // tls |
| 3495 | 3519 | const t = cfg.tls || {}; |
| 3496 | 3520 | document.getElementById('tls-domain').value = t.domain || ''; |
| 3497 | 3521 | document.getElementById('tls-email').value = t.email || ''; |
| 3498 | 3522 | document.getElementById('tls-allow-insecure').checked = !!t.allow_insecure; |
| @@ -3565,14 +3589,17 @@ | ||
| 3565 | 3589 | } |
| 3566 | 3590 | |
| 3567 | 3591 | function saveErgoConfig() { |
| 3568 | 3592 | saveConfigPatch({ |
| 3569 | 3593 | ergo: { |
| 3570 | - network_name: document.getElementById('ergo-network-name').value.trim() || undefined, | |
| 3571 | - server_name: document.getElementById('ergo-server-name').value.trim() || undefined, | |
| 3572 | - irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, | |
| 3573 | - external: document.getElementById('ergo-external').checked, | |
| 3594 | + network_name: document.getElementById('ergo-network-name').value.trim() || undefined, | |
| 3595 | + server_name: document.getElementById('ergo-server-name').value.trim() || undefined, | |
| 3596 | + irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, | |
| 3597 | + require_sasl: document.getElementById('ergo-require-sasl').checked, | |
| 3598 | + default_channel_modes: document.getElementById('ergo-default-modes').value.trim() || undefined, | |
| 3599 | + history: { enabled: document.getElementById('ergo-history-enabled').checked }, | |
| 3600 | + external: document.getElementById('ergo-external').checked, | |
| 3574 | 3601 | } |
| 3575 | 3602 | }, 'ergo-save-result'); |
| 3576 | 3603 | } |
| 3577 | 3604 | |
| 3578 | 3605 | function saveTLSConfig() { |
| 3579 | 3606 |
| --- internal/api/ui/index.html | |
| +++ internal/api/ui/index.html | |
| @@ -858,10 +858,31 @@ | |
| 858 | </div> |
| 859 | <div class="setting-row"> |
| 860 | <div class="setting-label">IRC address</div> |
| 861 | <div class="setting-desc">Address Ergo listens on for IRC connections. Requires restart.</div> |
| 862 | <input type="text" id="ergo-irc-addr" placeholder="127.0.0.1:6667" style="width:180px;padding:4px 8px;font-size:12px"> |
| 863 | </div> |
| 864 | <div class="setting-row"> |
| 865 | <div class="setting-label">external mode</div> |
| 866 | <div class="setting-desc">Disable subprocess management — scuttlebot expects Ergo to already be running. Requires restart.</div> |
| 867 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| @@ -3485,14 +3506,17 @@ | |
| 3485 | // general |
| 3486 | document.getElementById('general-api-addr').value = cfg.api_addr || ''; |
| 3487 | document.getElementById('general-mcp-addr').value = cfg.mcp_addr || ''; |
| 3488 | // ergo |
| 3489 | const e = cfg.ergo || {}; |
| 3490 | document.getElementById('ergo-network-name').value = e.network_name || ''; |
| 3491 | document.getElementById('ergo-server-name').value = e.server_name || ''; |
| 3492 | document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; |
| 3493 | document.getElementById('ergo-external').checked = !!e.external; |
| 3494 | // tls |
| 3495 | const t = cfg.tls || {}; |
| 3496 | document.getElementById('tls-domain').value = t.domain || ''; |
| 3497 | document.getElementById('tls-email').value = t.email || ''; |
| 3498 | document.getElementById('tls-allow-insecure').checked = !!t.allow_insecure; |
| @@ -3565,14 +3589,17 @@ | |
| 3565 | } |
| 3566 | |
| 3567 | function saveErgoConfig() { |
| 3568 | saveConfigPatch({ |
| 3569 | ergo: { |
| 3570 | network_name: document.getElementById('ergo-network-name').value.trim() || undefined, |
| 3571 | server_name: document.getElementById('ergo-server-name').value.trim() || undefined, |
| 3572 | irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, |
| 3573 | external: document.getElementById('ergo-external').checked, |
| 3574 | } |
| 3575 | }, 'ergo-save-result'); |
| 3576 | } |
| 3577 | |
| 3578 | function saveTLSConfig() { |
| 3579 |
| --- internal/api/ui/index.html | |
| +++ internal/api/ui/index.html | |
| @@ -858,10 +858,31 @@ | |
| 858 | </div> |
| 859 | <div class="setting-row"> |
| 860 | <div class="setting-label">IRC address</div> |
| 861 | <div class="setting-desc">Address Ergo listens on for IRC connections. Requires restart.</div> |
| 862 | <input type="text" id="ergo-irc-addr" placeholder="127.0.0.1:6667" style="width:180px;padding:4px 8px;font-size:12px"> |
| 863 | </div> |
| 864 | <div class="setting-row"> |
| 865 | <div class="setting-label">require SASL</div> |
| 866 | <div class="setting-desc">Enforce SASL authentication for all IRC connections. Only registered accounts can connect. Hot-reloads.</div> |
| 867 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| 868 | <input type="checkbox" id="ergo-require-sasl"> |
| 869 | <span style="font-size:12px">enforce SASL</span> |
| 870 | </label> |
| 871 | </div> |
| 872 | <div class="setting-row"> |
| 873 | <div class="setting-label">default channel modes</div> |
| 874 | <div class="setting-desc">Modes applied to new channels (e.g. "+n", "+Rn"). Hot-reloads.</div> |
| 875 | <input type="text" id="ergo-default-modes" placeholder="+n" style="width:120px;padding:4px 8px;font-size:12px"> |
| 876 | </div> |
| 877 | <div class="setting-row"> |
| 878 | <div class="setting-label">message history</div> |
| 879 | <div class="setting-desc">Enable persistent message history (CHATHISTORY). Hot-reloads.</div> |
| 880 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| 881 | <input type="checkbox" id="ergo-history-enabled"> |
| 882 | <span style="font-size:12px">enabled</span> |
| 883 | </label> |
| 884 | </div> |
| 885 | <div class="setting-row"> |
| 886 | <div class="setting-label">external mode</div> |
| 887 | <div class="setting-desc">Disable subprocess management — scuttlebot expects Ergo to already be running. Requires restart.</div> |
| 888 | <label style="display:flex;align-items:center;gap:6px;cursor:pointer"> |
| @@ -3485,14 +3506,17 @@ | |
| 3506 | // general |
| 3507 | document.getElementById('general-api-addr').value = cfg.api_addr || ''; |
| 3508 | document.getElementById('general-mcp-addr').value = cfg.mcp_addr || ''; |
| 3509 | // ergo |
| 3510 | const e = cfg.ergo || {}; |
| 3511 | document.getElementById('ergo-network-name').value = e.network_name || ''; |
| 3512 | document.getElementById('ergo-server-name').value = e.server_name || ''; |
| 3513 | document.getElementById('ergo-irc-addr').value = e.irc_addr || ''; |
| 3514 | document.getElementById('ergo-require-sasl').checked = !!e.require_sasl; |
| 3515 | document.getElementById('ergo-default-modes').value = e.default_channel_modes || ''; |
| 3516 | document.getElementById('ergo-history-enabled').checked = !!(e.history && e.history.enabled); |
| 3517 | document.getElementById('ergo-external').checked = !!e.external; |
| 3518 | // tls |
| 3519 | const t = cfg.tls || {}; |
| 3520 | document.getElementById('tls-domain').value = t.domain || ''; |
| 3521 | document.getElementById('tls-email').value = t.email || ''; |
| 3522 | document.getElementById('tls-allow-insecure').checked = !!t.allow_insecure; |
| @@ -3565,14 +3589,17 @@ | |
| 3589 | } |
| 3590 | |
| 3591 | function saveErgoConfig() { |
| 3592 | saveConfigPatch({ |
| 3593 | ergo: { |
| 3594 | network_name: document.getElementById('ergo-network-name').value.trim() || undefined, |
| 3595 | server_name: document.getElementById('ergo-server-name').value.trim() || undefined, |
| 3596 | irc_addr: document.getElementById('ergo-irc-addr').value.trim() || undefined, |
| 3597 | require_sasl: document.getElementById('ergo-require-sasl').checked, |
| 3598 | default_channel_modes: document.getElementById('ergo-default-modes').value.trim() || undefined, |
| 3599 | history: { enabled: document.getElementById('ergo-history-enabled').checked }, |
| 3600 | external: document.getElementById('ergo-external').checked, |
| 3601 | } |
| 3602 | }, 'ergo-save-result'); |
| 3603 | } |
| 3604 | |
| 3605 | function saveTLSConfig() { |
| 3606 |
| --- internal/ergo/manager.go | ||
| +++ internal/ergo/manager.go | ||
| @@ -115,10 +115,17 @@ | ||
| 115 | 115 | } |
| 116 | 116 | wait = min(wait*2, restartMaxWait) //nolint:ineffassign,staticcheck |
| 117 | 117 | } |
| 118 | 118 | } |
| 119 | 119 | } |
| 120 | + | |
| 121 | +// UpdateConfig replaces the Ergo config, regenerates ircd.yaml, and rehashes. | |
| 122 | +// Use when scuttlebot.yaml Ergo settings change at runtime. | |
| 123 | +func (m *Manager) UpdateConfig(cfg config.ErgoConfig) error { | |
| 124 | + m.cfg = cfg | |
| 125 | + return m.Rehash() | |
| 126 | +} | |
| 120 | 127 | |
| 121 | 128 | // Rehash reloads the Ergo config. Call after writing a new ircd.yaml. |
| 122 | 129 | func (m *Manager) Rehash() error { |
| 123 | 130 | if err := m.writeConfig(); err != nil { |
| 124 | 131 | return fmt.Errorf("ergo: write config: %w", err) |
| 125 | 132 |
| --- internal/ergo/manager.go | |
| +++ internal/ergo/manager.go | |
| @@ -115,10 +115,17 @@ | |
| 115 | } |
| 116 | wait = min(wait*2, restartMaxWait) //nolint:ineffassign,staticcheck |
| 117 | } |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | // Rehash reloads the Ergo config. Call after writing a new ircd.yaml. |
| 122 | func (m *Manager) Rehash() error { |
| 123 | if err := m.writeConfig(); err != nil { |
| 124 | return fmt.Errorf("ergo: write config: %w", err) |
| 125 |
| --- internal/ergo/manager.go | |
| +++ internal/ergo/manager.go | |
| @@ -115,10 +115,17 @@ | |
| 115 | } |
| 116 | wait = min(wait*2, restartMaxWait) //nolint:ineffassign,staticcheck |
| 117 | } |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | // UpdateConfig replaces the Ergo config, regenerates ircd.yaml, and rehashes. |
| 122 | // Use when scuttlebot.yaml Ergo settings change at runtime. |
| 123 | func (m *Manager) UpdateConfig(cfg config.ErgoConfig) error { |
| 124 | m.cfg = cfg |
| 125 | return m.Rehash() |
| 126 | } |
| 127 | |
| 128 | // Rehash reloads the Ergo config. Call after writing a new ircd.yaml. |
| 129 | func (m *Manager) Rehash() error { |
| 130 | if err := m.writeConfig(); err != nil { |
| 131 | return fmt.Errorf("ergo: write config: %w", err) |
| 132 |