feat(init,config): prototype-proven init + config TUI; remove validated-UI framework#1368
Draft
Aaronontheweb wants to merge 81 commits into
Draft
feat(init,config): prototype-proven init + config TUI; remove validated-UI framework#1368Aaronontheweb wants to merge 81 commits into
Aaronontheweb wants to merge 81 commits into
Conversation
908ece4 to
6ed2445
Compare
Adds three sequential OpenSpec changes for the netclaw init/config UX overhaul planned in /home/petabridge/.claude/plans/so-a-big-ux-mossy-newt.md: 1. section-editor-abstraction — introduces ISectionEditor, registry, merge-on-save, single-step orchestrator mode, and refactors Provider/Identity/Posture to be reentrant. Lays the contract every future editable section must honor. Closes netclaw-dev#455. 2. netclaw-config-command — new menu-driven `netclaw config` TUI command composing 10 section editors (Search, 3x chat channels, Exposure Mode, Security Posture, Audience Profiles, Outbound + Inbound Webhooks, External Skills, Skill Feeds, Browser Automation), plus a generic ListEditor<T> framework, 4 new doctor checks, 12 smoke tapes + audit. Closes netclaw-dev#1150. 3. simplify-netclaw-init — trims `netclaw init` to provider + identity + posture, adds existing-config refusal + --force backup-and-reset paths, post-flight nudge pointing operators at `netclaw config`. All three validated with `openspec validate <change> --type change`. Sequential dependencies: A enables the abstraction, B introduces the command and editors, C cuts the long wizard. PR review can sequence the implementation accordingly. No production code changes in this PR; planning artifacts only.
Self-review pass on the three init/config UX changes surfaced real issues. Fixes: UI mockups landed in the repo (were stuck in ~/.claude/plans/): - docs/ui/TUI-002-netclaw-config-wireframes.md (dashboard + 12 editors + 8 page templates + doctor results + nudge) - docs/ui/TUI-003-simplified-init-wireframes.md (3 init steps + post-flight + refusal + force-reset confirm) - Each change's design.md references its corresponding wireframe document as the authoritative visual contract ISectionEditor vs menu split (Change A): - ISectionEditor gains `bool ShowInMenu` flag (default true) - MenuRegistryAuditTests waives tape-existence check for ShowInMenu == false editors (e.g. Provider, Identity covered by init-wizard.tape and the netclaw provider CLI) - Round-trip test + RelevantDoctorChecks contract still applies to every registered editor regardless of ShowInMenu Schema/SectionId mismatches: - Identity is NOT a top-level schema key; added to exemption list with category "synthetic-spans-multiple-sections" and ShowInMenu = false in Change A's tasks - Top-level Security, Daemon, Tools added to exemption list in Change B's tasks with category "covered by another editor's dotted-path SectionId" naming the covering editor - Exemption-list spec scenarios cover both top-level and dotted-path coverage netclaw config show|validate reserved (Change B): - Reserved subcommands now print an explicit "not yet implemented; PRD-004" notice and exit non-zero, preserving the documented future surface (previously rejected as unknown) Important items tightened across the changes: - Change B section editors explicitly REFACTOR existing init step viewmodels (not create duplicates) where the section already has an init step - Daemon-restart nudge now specifies the PID-file + TCP probe with a 250 ms bound; timeout suppresses the nudge (conservative) - In-place rename for list items now specifies originalKey/newKey tracking, secrets-store rekey, and array-position preservation - BrowserAutomation schema-migration scenarios cover both the editor opening over a pre-existing config and doctor --fix auto-insert - --force non-TTY refusal scenario added in Change C - .bak filename collision handled via -1/-2 suffix; timestamp moves from unix-seconds to unix-millis - Multi-instance editing and Test Connection partial-failure shape documented in Change B's design Risks section All three changes re-validated: openspec validate section-editor-abstraction --type change ✓ openspec validate netclaw-config-command --type change ✓ openspec validate simplify-netclaw-init --type change ✓
Wire Search into netclaw config so we can validate preserved-state section editing, semantic config and secrets saves, and probe-gated warnings before expanding the dashboard.
Preserve the active text input across redraws so inline edits keep their cursor position. Trim duplicate feedback so provider setup reads more cleanly.
Keep search backend setup on an explicit path from provider selection through validation and save. Preserve inactive backend settings so switching providers does not silently wipe prior configuration.
Return Esc from the saved state to the Search backend list instead of exiting the editor. Clarify the provider markers so active and configured backends are visually distinct.
Brings design/tui-prototype/ (browser mockup of the netclaw init + config TUI) and its FINDINGS.md onto this line as the design source of truth for reconciling the init/config UX and reworking validated-ui-components. Squash-imported from branch claude-wt-netclaw-config-tui-design (full 13-commit history preserved there). FINDINGS.md records the validated UX decisions, per-area corrections, the lighter validation stance (nullable dynamic check, no analyzer, no mandatory commit object, typed probe result), the keep/rework/delete/cancel tally, and the agreed process.
Companion to design/tui-prototype/FINDINGS.md. Defines the goal and the task-level route to take both netclaw init and netclaw config through the full OpenSpec lifecycle (reconcile -> apply -> verify -> sync -> archive) and land the prototype-proven UX in Termina. Grounded in the real task tallies on this branch: simplify-netclaw-init 0/30, netclaw-validated-ui-components 19/63 (revise lighter), netclaw-config-command 60/67, section-editor-abstraction 42/42 (confirm). Sequenced init -> infra -> config UX -> section-editor with the C# files, spec deltas, and verification gates per step.
…-install menu Reduce `netclaw init` from 11 steps to a minimal bootstrap — Provider → Identity → Security Posture → Enabled Features (Personal skips) → Health Check. Channels, Search, Browser Automation, and Skill Sources move to `netclaw config`. On an existing install, init now opens an explicit action menu (Redo identity setup / Open configuration editor / Start over from scratch / Cancel) instead of silently re-walking setup. "Open configuration editor" hands off to a shared config-editor host; "Start over" runs a double-confirmed reset (setup-only vs full). Identity stays init-owned and is editable on its own via a single-step redo that writes only identity files. The post-flight summary nudges toward `netclaw chat` and `netclaw config`. Implements the simplify-netclaw-init OpenSpec change (archived). Validated with the full CLI unit suite and the init-wizard + new init-existing smoke tapes.
…Sources validation The validated-UI commit framework (NetclawUiCommit, the commit pipeline, the NetclawValidated* components, SkillSourcesCommitFactory, and the never-built Roslyn analyzer) was over-opinionated: it had a single consumer (Skill Sources) yet forced every mutation through a generic pipeline. The TUI prototype confirmed inline validation — the pattern every other config page already uses — is the target. Migrate Skill Sources to the Search editor's pattern: a lightweight result record, inline structural validation, inline reachability probes, and the shared probe-warning dialog, persisting through the view model's existing section-preserving writers. The page is now presentational — an inverted audit test enforces it never writes config directly. Removes ~1145 net lines (5 framework files + 4 framework test files). The superseded netclaw-validated-ui-components OpenSpec change is archived without syncing its framework spec delta, so the main specs carry no framework mandates. Full CLI suite green; config-ops-surfaces smoke green.
Align `netclaw config` with the validated TUI prototype: - Dashboard shows a live status-summary column (e.g. `Search ✓ Brave`, `Security & Access Team · 4/6 enabled`) read fresh from config, with the focused row's description as a dim help line. - Channels resolve a typed channel against the adapter BEFORE adding it; a non-resolving channel is rejected, a resolved one is added at the deployment-posture default audience and focused for ←/→ tuning. - Telemetry & Alerting exposes the full NotificationsConfig.Webhooks list via a multi-webhook editor (Name / URL / one auth header, Format auto-detected from hooks.slack.com), replacing the single-webhook form. - A unified full-width teal selection bar replaces the ▶/> marker prefixes across Channels, Security & Access, Skill Sources, Inbound Webhooks, and Telemetry, matching the dashboard. Completes the netclaw-config-command OpenSpec change (archived) and adds the autosave-consistency and section-preserving-persistence invariants to the main spec. Full CLI suite green (1027 tests); config smoke tapes green.
The section-editor abstraction (ConfigEditorSession + the single-step orchestrator) is the persistence seam that Skill Sources now migrates onto and that the config leaf editors write through, so removing the validated-UI framework confirmed its centrality rather than undermining it. Its delta is already reflected in the main netclaw-onboarding spec; archived --skip-specs.
- smoke: drop the deleted init-wizard-reverse-proxy tape from LIGHT_TAPES (the rebase union wrongly retained it, red-ing run-smoke.sh light) - config dashboard: read Browser Automation enablement from the canonical browser MCP server entries instead of a non-existent Browser.Enabled flag - config host: drop the redundant NetclawPaths DI registration - specs: de-duplicate the leaked ADDED requirements in netclaw-onboarding; document the shipped config UX (status dashboard, channels resolve-before-add, multi-webhook list, unified selection bar) in netclaw-config-command - tests: cover skill-server token rotation (new/blank/probe-latch), the IdentityRedo don't-clobber-config invariant + Esc routing, the ConfigAutosave exception path, setup-only reset deletion semantics, and generalize the presentational-write audit guard across all config pages Note: the review also flagged the /config host omitting ConfigureNativeSelection. Enabling raw input there breaks the vhs config-* smoke tapes (authored for the cooked-input config host), so it is intentionally deferred — see the code comment. Full CLI suite 1039 green; slopwatch + headers clean.
Fixes surfaced while driving `netclaw config` interactively against the prototype-proven design (see design/tui-prototype/MANUAL_REVIEW_FINDINGS.md). - Native selection: the `/config` Termina host now calls ConfigureNativeSelection like every other host (init/provider/model/chat/...). It was the lone cooked-input host, so it enabled mouse tracking and broke native terminal drag-select. - Inbound Webhooks enable-first: `Webhooks.Enabled` is only the feature toggle (the runtime 404s every request when no routes exist, so it is inert and default-deny). Enabling with no routes now persists with an advisory instead of a hard block, and the doctor check downgrades enabled-but-no-routes from Error to Warning. Matches inbound-webhooks/spec.md. - Telemetry webhook form placeholders: ConfigSelectionRow gains a two-tone CreateLabeled (bright label, dim-gray placeholder, bright real value) so `(optional)` / the example URL no longer read as entered values; the URL example is prefixed `e.g.`. - Skill Sources probe-driven disclosure: remote-feed add now matches SearXNG -- enter URL, probe with no auth, and reveal the bearer-token field only on a 401/403, then re-probe. Removes the upfront "No auth required / Bearer token" choice screen and its handlers. Also fixes two latent defects that prevented force-adding an unreachable open feed: ContinueAddRemoteUrl cleared the save-anyway fingerprint on every Enter, and the page re-staged the input on every Enter (clearing the fingerprint via MarkDirty through the real input pipeline). Tests updated/added across all four areas (VM, doctor, page-integration, coverage audit) and the config-surfaces smoke tape.
…sub-VM flag
The Channels editor save validated and probed an adapter using the picker's
Step.IsAdapterEnabled, but BuildContribution gated persistence on the
per-adapter sub-VM's *Enabled flag. When those two enabled-states disagreed, a
save validated + probed the adapter as enabled, then wrote only
{Adapter}.Enabled=false (dropping AllowedChannelIds and audiences) while
session.Save() ran and the status still showed "saved" — a success-reporting
silent half-write that lost channel config and bot tokens on disk.
BuildContribution now reads the single source of truth (Step.IsAdapterEnabled,
the same source dynamic validation uses) and threads `enabled` into the
per-adapter contributions; the sub-VM *Enabled flags remain reload-sync targets
but no longer decide whether a section is written. A save can no longer report
success while half-writing an adapter the editor treats as enabled.
Adds an invariant regression test (Save()==true implies the enabled adapter's
section + secret reached disk; proven load-bearing) plus an end-to-end
navigation test that enables Slack by name and Discord by id, escapes, and
asserts both sections and bot tokens survive on disk.
…rves an existing Daemon
WizardConfigBuilder seeds the output from the existing config to preserve
sections the wizard doesn't touch. After rebasing onto dev's UpdateChannel
preservation (which deliberately leaves the typed Daemon null for a default
`stable` channel), that seed carried the stale `Daemon: { UpdateChannel:
"stable" }` straight through to disk.
When no typed Daemon is contributed, strip a default `stable` UpdateChannel
from the copied Daemon and drop the section only if nothing else remains; a
Daemon carrying real fields (exposure mode, host, proxies, port) stays
preserved, so the exposure editor's section-contribution merge is unaffected.
6ed2445 to
91422b4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #1275 (folds in the guided-config-surfaces work). Reconciles
netclaw initandnetclaw configagainst a terminal-faithful browser prototype (design/tui-prototype/), then implements the proven UX in Termina. Four OpenSpec changes, all archived.simplify-netclaw-init
netclaw initreduced 11 → 5 steps: Provider → Identity → Security Posture → Enabled Features (Personal skips) → Health Check. Channels, Search, Browser Automation, and Skill Sources move tonetclaw config.netclaw chat+netclaw config.netclaw-validated-ui-components — removed
netclaw-config-command
Search ✓ Brave,Security & Access Team · 4/6 enabled).NotificationsConfig.Webhooks.section-editor-abstraction
ConfigEditorSessionis now the single persistence seam the migrated editors write through.Testing
init-wizard, newinit-existing, and config tapes driving the new dashboard / multi-webhook / channels UX).Draft — pending hands-on interactive TUI testing + code review before merge.