Skip to content

feat: app://instructions + trim /settings panel to workspace-config only#7

Open
mgoldsborough wants to merge 1 commit intomainfrom
feat/app-instructions-and-settings-trim
Open

feat: app://instructions + trim /settings panel to workspace-config only#7
mgoldsborough wants to merge 1 commit intomainfrom
feat/app-instructions-and-settings-trim

Conversation

@mgoldsborough
Copy link
Copy Markdown
Contributor

Summary

Wires Collateral Studio up to NimbleBrain's bundle-side custom-instructions contract (`app://instructions`) and resolves the duplicate edit surfaces between the platform's `/settings/workspace/apps/synapse-collateral` panel and the in-app Settings drawer.

Principle applied

`/settings/workspace/apps/` is the canonical home for workspace-wide config that affects agent behavior even when nobody's in the app's UI. The in-app UI is for authoring (documents, templates, components, assets). The two surfaces should not duplicate each other.

Currently in /settings Verdict
Brand Voice → Custom Instructions Keep — now wired to `app://instructions`
Theme (colors + fonts) Keep — workspace-wide brand identity
Reusable Components Drop — promoted to in-app tab
Assets Drop — already had a full in-app `AssetsView`

Server changes (`src/mcp_collateral/`)

  • New `app://instructions` resource returning `voice.md` body. Platform wraps non-empty output in `` automatically.
  • Drop the manual voice → skill-resource splice (`` placeholder removed from `SKILL.md`).
  • `set_voice` enforces an 8 KiB UTF-8 cap (`MAX_VOICE_BYTES`), returns a structured tool error on overflow, and clears the file on empty input. `store.clear_voice()` added for the post-condition.
  • Inline settings HTML trimmed to Theme + Custom Instructions. Reads via `readResource("app://instructions")`, writes via `set_voice`. UTF-8-byte-aware character counter; Save disabled when over cap or unchanged; Reset button.

In-app changes (`ui/src/`)

  • Add `ComponentsView` + `useComponents` hook. Components is now a top-level tab next to Templates and Assets.
  • Delete `SettingsPanel.tsx` and the Settings button in `TopNav`. Voice lives only in /settings (renamed Custom Instructions); Components is a tab.
  • `useBrand.ts` → `useComponents.ts` (focused on the only thing the hook is still for).
  • Removed dead settings-overlay/settings-panel styles.

Tests

10 new tests in `tests/test_custom_instructions.py` covering:

  • Empty resource returns "" and creates no file
  • Round-trip via `set_voice` → `get_voice`
  • Empty content clears the file (idempotent)
  • 8 KiB cap (at, over, multibyte UTF-8 — confirms byte counting, not char)
  • Skill resource no longer inlines voice content

`uv run pytest tests/` → 103 passed.

Test plan

  • Run `uv run pytest tests/` locally
  • `cd ui && npm run build` succeeds
  • Manually open `/settings/workspace/apps/synapse-collateral` in NimbleBrain — verify only Theme + Custom Instructions render; saving voice persists; agent picks up the saved instructions on next turn
  • Open the in-app Components tab — verify it loads existing `components.typ`, allows editing, and saves
  • Confirm in-app TopNav has no "Settings" button anymore

Related

Wire collateral up to NimbleBrain's bundle-side custom-instructions
contract and remove the duplicate edit surfaces between the platform
/settings panel and the in-app Settings drawer.

Server side:
- Publish `app://instructions` returning the same body as `voice.md`.
  The platform reads it on every prompt assembly and wraps non-empty
  output in `<app-custom-instructions>` containment, so the manual
  voice → skill-resource splice is gone.
- Cap `set_voice` at 8 KiB UTF-8 (mirrors `MAX_INSTRUCTIONS_BYTES`).
  Empty content clears the file. Cap violations return a structured
  tool error rather than crossing the wire as a transport failure.
- Trim the inline settings HTML to **Theme** and **Custom Instructions**
  only. Components and Assets are removed — they're authoring surfaces,
  not workspace-wide config, and the in-app views are the canonical
  home for both.

In-app side:
- Promote Components to a top-level view (`ComponentsView` + tab).
- Delete `SettingsPanel` and the Settings button in TopNav. Voice now
  lives only in /settings (Custom Instructions); Components is a tab.
- Replace `useBrand` with a focused `useComponents` hook.

Tests:
- 10 new tests in `tests/test_custom_instructions.py` covering the
  resource round-trip, empty-clears-file, byte cap (including
  multibyte UTF-8), and that the skill resource no longer inlines
  voice content.
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.

1 participant