feat(tui,server,config): live config editor + artifact viewer
Two operator features over the existing WebSocket protocol, plus a tui-go nav fix. Config editor (g / palette "config"): - core:config gains a thin registry stack: OrchestrationKnobs ([orchestration] block), CorrexConfigWriter (round-trip TOML serializer; parseToml(write(c))==c), ConfigHolder (AtomicReference live config), and EditableConfig (allowlist of editable fields + patch applier; security fields are absent so they can never be patched). - ConfigService validates -> persists (atomic temp+move) -> swaps the holder -> rebuilds config-derived services. Live-apply is scoped to safe seams: stage timeout, compaction threshold (now a supplier), router knobs (routerFacade rebuild), and personalization/project toggles all take effect on the next session/turn; in-flight sessions keep the config they started with. server.host/port are persisted + badged "restart required", not hot-swapped. - Protocol: GetConfig / UpdateConfig / ConfigSnapshot; TUI overlay with type-aware editing (bool toggle, enum cycle, inline int/string edit) and save. Artifact viewer (v / palette "artifacts"): - Server assembles a session's artifacts from the event log and resolves bytes from the CAS store (StreamQueries.listArtifacts) — a replay-neutral snapshot read. TUI overlay lists artifacts and shows scrollable content. tui-go fix: workflow failure no longer clears selectedID (which yanked the user to the list); listNav lands on the first session when nothing is selected instead of wrapping to a random one. Config is not event-sourced (it lives in TOML); editing stays outside the log.
This commit is contained in:
@@ -45,6 +45,8 @@ const (
|
||||
TypeModelList = "model.list"
|
||||
TypeResourceStatus = "resource.status"
|
||||
TypeRouterNarration = "router.narration"
|
||||
TypeArtifactList = "artifact.list"
|
||||
TypeConfigSnapshot = "config.snapshot"
|
||||
)
|
||||
|
||||
// ServerMessage is a flat decode of every server->client variant. Field names
|
||||
@@ -107,6 +109,28 @@ type ServerMessage struct {
|
||||
Stages []StageToolDecl `json:"stages"`
|
||||
Workflows []WorkflowDto `json:"workflows"`
|
||||
AssessedIssues []AssessedIssueDto `json:"issues"`
|
||||
Artifacts []ArtifactDto `json:"artifacts"`
|
||||
|
||||
// config.snapshot
|
||||
ConfigFields []ConfigFieldDto `json:"fields"`
|
||||
ConfigRestartRequired []string `json:"restartRequired"`
|
||||
ConfigError *string `json:"error"`
|
||||
}
|
||||
|
||||
type ConfigFieldDto struct {
|
||||
Key string `json:"key"`
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
Options []string `json:"options"`
|
||||
RestartRequired bool `json:"restartRequired"`
|
||||
}
|
||||
|
||||
type ArtifactDto struct {
|
||||
ArtifactID string `json:"artifactId"`
|
||||
StageID string `json:"stageId"`
|
||||
SchemaVersion int `json:"schemaVersion"`
|
||||
Phase string `json:"phase"`
|
||||
Content *string `json:"content"`
|
||||
}
|
||||
|
||||
type SessionStateDto struct {
|
||||
@@ -228,6 +252,21 @@ func CancelSession(sessionID string) []byte {
|
||||
return encode("CancelSession", map[string]any{"sessionId": sessionID})
|
||||
}
|
||||
|
||||
// ListArtifacts asks the server for the artifacts produced by a session, with content.
|
||||
func ListArtifacts(sessionID string) []byte {
|
||||
return encode("ListArtifacts", map[string]any{"sessionId": sessionID})
|
||||
}
|
||||
|
||||
// GetConfig requests the current editable config (replied to with a config.snapshot).
|
||||
func GetConfig() []byte {
|
||||
return encode("GetConfig", map[string]any{})
|
||||
}
|
||||
|
||||
// UpdateConfig asks the server to apply and persist a config patch (key -> string value).
|
||||
func UpdateConfig(patch map[string]string) []byte {
|
||||
return encode("UpdateConfig", map[string]any{"patch": patch})
|
||||
}
|
||||
|
||||
// ApprovalResponse answers an approval gate. decision is "APPROVE" or "REJECT".
|
||||
func ApprovalResponse(requestID, decision string, steeringNote *string) []byte {
|
||||
return encode("ApprovalResponse", map[string]any{
|
||||
|
||||
Reference in New Issue
Block a user