Skip to content

feat(ui): prefill MCP instructions default + Reset-to-default button (MCP-2484)#685

Merged
Dumbris merged 2 commits into
mainfrom
mcp-2484-instructions-prefill
Jun 15, 2026
Merged

feat(ui): prefill MCP instructions default + Reset-to-default button (MCP-2484)#685
Dumbris merged 2 commits into
mainfrom
mcp-2484-instructions-prefill

Conversation

@Dumbris

@Dumbris Dumbris commented Jun 15, 2026

Copy link
Copy Markdown
Member

What

  • Prefill the instructions textarea with the built-in default (from /api/v1/status → default_instructions) when the user hasn't saved a custom value yet (fresh install / blank field)
  • Reset to default button — compact inline button next to the textarea that re-populates the field with the live backend default; appears only after the default resolves

Why

Fresh installs showed an empty textarea with no hint of what the built-in instructions look like. Users had no way to restore the default after clearing it.

How

fields.ts

  • Added resetDefault?: string to the SettingField interface
  • Exported isBlankInstructions(v) helper — treats null/undefined/empty/whitespace as blank (eligible for prefill)

SettingField.vue

  • In the textarea control block: render a compact ↩ Reset to default button when field.resetDefault is set; hidden until the async default resolves (no undefined flash)
  • Click emits resetDefault through the normal update:modelValue path so the section tracks it dirty and Save persists it

Settings.vue

  • advancedAccordions computed: injects placeholder and resetDefault from defaultInstructions into the instructions field
  • maybePrefillInstructions(): uses isBlankInstructions so whitespace-only saved values also get prefilled
  • Dual-trigger: called from both loadConfig() completion and loadDefaultInstructions() completion + a watcher on defaultInstructions — whichever resolves last triggers prefill

Tests

  • 9 new unit tests in frontend/tests/unit/instructions-prefill.spec.ts
  • All 186 frontend unit tests pass

Guard: never overwrite saved value

maybePrefillInstructions only runs when isBlankInstructions(state.working.instructions) — a saved custom value is never touched.

Closes MCP-2484

- Export isBlankInstructions() from fields.ts for whitespace-aware blank check
- Add resetDefault?: string to SettingField interface
- SettingField.vue: render compact Reset button when field.resetDefault is set
- Settings.vue: inject resetDefault + updated placeholder from /api/v1/status
  into the instructions field; maybePrefillInstructions() uses isBlankInstructions
  so whitespace-only saved values also get prefilled
- Dual-trigger prefill: runs from loadConfig() and loadDefaultInstructions()
  completion + watcher so whichever resolves last wins
- 9 new unit tests in instructions-prefill.spec.ts (all passing)
- All 186 frontend tests pass

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 15, 2026

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: e147de8
Status: ✅  Deploy successful!
Preview URL: https://590cbfe1.mcpproxy-docs.pages.dev
Branch Preview URL: https://mcp-2484-instructions-prefil.mcpproxy-docs.pages.dev

View logs

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Dumbris Dumbris changed the title [MCP-2484] UX: MCP server instructions — prefill editable default + Reset to default button feat(ui): prefill MCP instructions default + Reset-to-default button (MCP-2484) Jun 15, 2026
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

📦 Build Artifacts

Workflow Run: View Run
Branch: mcp-2484-instructions-prefill

Available Artifacts

  • archive-darwin-amd64 (28 MB)
  • archive-darwin-arm64 (25 MB)
  • archive-linux-amd64 (16 MB)
  • archive-linux-arm64 (14 MB)
  • archive-windows-amd64 (28 MB)
  • archive-windows-arm64 (25 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (21 MB)
  • installer-dmg-darwin-arm64 (19 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 27546045832 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

@Dumbris

Dumbris commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

codex review (gpt-5.5, in-checkout) → REQUEST_CHANGES. Async prefill, non-overwrite, and Reset (live default) all look correct — but the core "Save persists the text" requirement is not met:

  • Settings.vue:234 prefills state.working.instructions directly, but SettingsSection.vue:116 only marks a field dirty via onChange, and SettingsSection.vue:187 PATCHes only dirtyKeys.
  • So on the main prefill path, the default is displayed but not saveable/persisted unless the user edits the field or clicks Reset. A user who opens Settings and hits Save expecting to keep the (now-visible) default gets nothing persisted.

Fix: when prefilling the default into the textarea, also mark instructions dirty (route the prefill through the same onChange path, or add it to dirtyKeys) so Save persists it. (Reset already works because it goes through onChange.) Add a Playwright assertion: fresh install → open Settings → Save without editing → reload → instructions persisted.

…2484)

Codex REQUEST_CHANGES on #685: maybePrefillInstructions() writes the
built-in default straight onto state.working, but SettingsSection only
PATCHed its locally-tracked dirty keys (set via onChange). A user who
opened Settings and clicked Save without editing kept nothing.

Derive dirtiness in SettingsSection from working != original (union with
the explicit onChange-tracked dirty ref), so any value set outside a
control — notably the instructions prefill — is treated as dirty and
saved. Reset already worked (it goes through onChange); user edits and
discard/save semantics are unchanged.

- frontend/tests/unit/settings-section-prefill-dirty.spec.ts: prefilled
  value (working!=original) is dirty, Save PATCHes instructions, clears
  after save; equal working/original stays non-dirty.
- specs/060-settings-page/verification/instructions-prefill-persist.spec.ts:
  Playwright — fresh install, Save-without-editing persists, survives
  reload, Reset repopulates.

All 185 frontend unit tests pass; vue-tsc clean; Playwright green.
@Dumbris

Dumbris commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

Codex REQUEST_CHANGES addressed — pushed to this branch (e147de8)

Finding: maybePrefillInstructions() wrote the default straight onto state.working.instructions, but SettingsSection only PATCHed its onChange-tracked dirty keys → Save-without-editing persisted nothing.

Fix (frontend-only, SettingsSection.vue): derive dirtiness from working !== original (unioned with the explicit dirty ref), so a value set outside a control — the prefill — is treated as dirty and included in buildPartial/PATCH. Reset already worked (goes through onChange); user-edit, discard, and post-save clearing semantics are unchanged.

Verification

  • New component test settings-section-prefill-dirty.spec.ts: prefilled value (working≠original) → Save button enabled → patchConfig called with {instructions: …}; dirty clears after save; equal working/original stays non-dirty.
  • New Playwright specs/060-settings-page/verification/instructions-prefill-persist.spec.ts, run against a fresh mcpproxy: fresh install → open Settings → Save without editing → reload → instructions persisted ✓, and Reset-to-default repopulates ✓.
  • All 185 frontend unit tests pass; vue-tsc clean; make build green.

Acceptance criteria from the review (prefill-then-Save persists; existing edit/Reset/no-overwrite scenarios still pass) are all covered.

@mcpproxy-gatekeeper mcpproxy-gatekeeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code review ACCEPT (codex out of quota until ~4:34 PM → Claude-reviewer fallback). Round-2 fix derives field dirtiness from working!==original in SettingsSection, so the prefilled default is savable on Save-without-editing; non-overwrite + async-arrival hold; Reset works; no spurious dirtiness on other fields. 185 frontend unit tests pass. Windows Unit Tests failure is the known non-required internal/runtime flake.

@Dumbris Dumbris merged commit b8f0d86 into main Jun 15, 2026
56 of 57 checks passed
Dumbris added a commit that referenced this pull request Jun 15, 2026
Conflict from #685 (instructions prefill) + #681 (telemetry serialization)
landing on main while this branch was in review. Resolved Settings.vue:
- imports: union of watch (prefill) + nextTick/useRoute (banner focus deep-link)
- onMounted: keep #685's watch(defaultInstructions) prefill trigger, use this
  branch's async onMounted for the focus query-param handling, drop the
  duplicate loadConfig() (body already awaits loadConfig()).

Verified: 14 settings unit tests pass (instructions-prefill + prefill-dirty).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dumbris added a commit that referenced this pull request Jun 15, 2026
The three rapid-based property tests (TestRapidQuarantineStateMachine,
TestRapidInvariant_ChangedNeverAutoApproved, TestRapidInvariant_PendingNeverAutoApproved)
each create and tear down hundreds of BBolt-backed Runtimes per rapid.Check
run. Under -race they take several minutes; on Windows the slower file
IO/timers push them past the 5m package timeout of the Unit Tests
(windows-latest) job, which runs 'go test -race -timeout 5m ./...' without
-short. This produced flaky 'panic: test timed out after 5m0s' reds in
internal/runtime unrelated to any PR change (#675, #685, #684).

The existing testing.Short() guards never fire because the job omits -short.
Add a documented Windows skip (mirroring apply_config_restart_test.go) to the
offending tests only. The invariants they assert are platform-independent, so
Linux/macOS coverage plus the dedicated heavy-runtime CI job is sufficient.
The global timeout is left untouched.

Related #MCP-2493
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants