Skip to content

feat: sync ! command autocomplete with upstream MindRoom bot commands#3008

Closed
basnijholt wants to merge 18 commits into
cinnyapp:devfrom
mindroom-ai:t3code/autocomplete-commands
Closed

feat: sync ! command autocomplete with upstream MindRoom bot commands#3008
basnijholt wants to merge 18 commits into
cinnyapp:devfrom
mindroom-ai:t3code/autocomplete-commands

Conversation

@basnijholt

Copy link
Copy Markdown

Summary

Makes the MindRoom ! command autocomplete in the composer mirror the actual command set of the upstream MindRoom bot (mindroom/src/mindroom/commands/parsing.py, CommandType + _COMMAND_DOCS), so every command the bot understands is autocompletable and no dead commands are suggested.

  • Added missing commands: !model [name|list|reset], !thread_mode [room|thread|reset|show], !reload-plugins
  • Removed stale entries:
    • !skill — explicitly removed upstream; parses as UNKNOWN (see upstream test_removed_skill_command_is_unknown)
    • !widget — does not exist upstream and has no client-side handler
  • Entries are ordered to match the order !help lists them (upstream CommandType enum order)
  • New test asserts every syntax string starts with !<name>, guarding that autocomplete-inserted text stays valid

Admin-only commands (!reload-plugins, !config, !thread_mode) are kept in the list since the frontend has no admin-status signal and the bot replies with a clear permission error.

Validation

  • npm run typecheck
  • npm run build
  • npx eslint src/app/mindroom/commands/
  • npx vitest run src/app/mindroom/commands/ ✅ (6 tests)
  • Independent subagent review pass against the upstream parser: verified all 10 non-UNKNOWN commands are covered, inserted text (including trailing space and hyphen in reload-plugins) matches the upstream regexes after message.strip(), and no listed command parses as UNKNOWN.

basnijholt added 18 commits May 28, 2026 22:55
* fix(message-extras): allow safe inline svg

Permit inline SVG primitives in MindRoom message extras while explicitly stripping script-bearing SVG vectors, external references, animation tags, style attributes, and event handlers.

* fix(message-extras): harden svg sanitizer review gaps

* fix(message-extras): preserve svg aspect ratio

Allow preserveAspectRatio through the message extras SVG sanitizer with explicit camelCase restoration so safe inline charts can control viewport scaling without reopening URL or script surfaces.

* docs: record safe svg rebase validation
Voice recordings in the Cinny PWA were uploading at the browser's default MediaRecorder bitrate, which on iOS Safari produced AAC at roughly 188 kbps and ~767 KB for a 32-second clip. On slow mobile connections that file size is annoyingly large for what is supposed to be a quick, casual voice note.

The fix sets `audioBitsPerSecond: 32000` on the MediaRecorder constructor and requests constrained `getUserMedia` input before recording: mono capture, a 24 kHz speech-oriented sample rate, plus echo cancellation, noise suppression, and auto-gain control. If a browser rejects those mic constraints with OverconstrainedError, recording falls back to unconstrained audio capture so the user is never blocked. The fallback path also re-checks the recording session id so a hook that unmounted during the initial permission prompt does not trigger a second mic prompt on a dead component.

The bitrate value is Signal-equivalent for voice and keeps Opus essentially transparent on Chromium browsers while still materially shrinking AAC output on iOS. The mono channel-count constraint is the load-bearing iOS win, since WebKit historically has been inconsistent about respecting `audioBitsPerSecond` for the AAC encoder; mono input compresses more efficiently regardless of whether the bitrate hint is honored.
* Use WebGL background for splash screens

* fix(splash): address WebGL background review

* refactor(splash): rely on default particle background
* Fix config retry click handling

* Address config retry review feedback
* Send attachments before the caption text (CINNY-108)

Invert the room-input send-session ordering so attachments send first in
selection order and the caption text sends last. MindRoom's backend
coalesces a media batch into one agent turn and closes it on the trailing
text event (mindroom#1255), so the caption must arrive after the uploads.

- Drop the auto-thread-text-root mode: text plus attachments now uses the
  upload-root shape (first attachment is the room-level root, remaining
  attachments and the caption thread under it).
- The caption threads under the upload root; reply metadata stays on the
  root upload.
- Reset the composer when the session snapshots the caption instead of
  when the text event sends, since the caption can now wait behind slow
  uploads.
- Mock components/editor/utils in RoomInput.test.ts: the controller
  imports the reset helpers from there, and its real resetEditor call
  crashed against the stubbed slate Editor (previously swallowed by the
  send-step catch).

* Restore a failed caption into the composer (CINNY-108)

With media-first ordering the caption usually fails only after every
upload has sent and left the board, so the board's Send-again affordance
(the only way to resume a blockedRoot session) no longer existed: the
caption was silently lost, and the zombie session would flush the stale
caption into a later unrelated send while swallowing that send's input.

- The send-text failure path no longer sets blockedRoot; it restores the
  composer from a snapshot of editor.children taken at session start
  (cloned, since slate mutates children in place), clears textPending,
  and lets the session finish. Upload retries stay resumable; the
  session never resends a restored caption.
- New restoreEditorContent helper in components/editor/utils prepends
  the snapshot, drops the placeholder paragraph when the composer was
  empty, and keeps anything typed since the snapshot.
- Controller tests cover composer restore plus session completion
  without stale resends, and upload-retry resume after a failed caption.
- Wrap the over-printWidth lines this branch introduced and shorten two
  test titles (repo prettier is pinned at printWidth 100).
Mirror the upstream MindRoom command set (mindroom/commands/parsing.py)
in the frontend autocomplete list:

- Add missing commands: !model, !thread_mode, !reload-plugins
- Remove stale entries: !skill (removed upstream, parses as unknown)
  and !widget (does not exist upstream or client-side)
- Order entries to match the order !help lists them
- Add a test guarding that every syntax string starts with its name
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@basnijholt

Copy link
Copy Markdown
Author

Opened against the wrong repository by mistake — this belongs on the mindroom-cinny fork. Apologies for the noise.

@basnijholt basnijholt closed this Jul 1, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant