mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
feat(readmymind): alternates row, phone accessory key, phone-sized modal (phase 3 part 1)
The Read My Mind modal grows up and reaches phones: - Alternate suggestions (the predictor's verify/redirect kinds) now render as tappable rows below the main field. Tapping one swaps it into the editable field; the edit you were making folds back into the row you leave, so toggling between alternates never loses typing. Rethink now records the WHOLE shown set (main + alternates) as rejected. - Phones get a 🧠 key on the keyboard accessory bar (both simple and extended layouts), gated on the same synced readMyMindEnabled setting via an rmm-enabled marker class on the BAR element: setMode() rebuilds the buttons' innerHTML, so per-key state would be wiped. Synced at init and re-synced by applyHeaderVisibilitySettings() on every settings apply, so a live toggle needs no reload. The header button stays off phones. - On phones the modal renders as a small dialog (mirrors modal-sm) instead of the full-screen default, with wrap-friendly finger-sized footer buttons. Not modal-sm itself: that caps desktop width at 340px and this modal wants 560px there. - On touch devices the ready/swap paths no longer focus the field, so the OS keyboard does not pop over the alternates that just rendered. - New static guard test/readmymind-phone-key.test.ts pins the dual-template key, the marker-class gating, the phone-hidden header button, the small-dialog phone modal, and the no-innerHTML discipline. Part 2 of phase 3 (rethink steering, the free-text steer note) is next; the API already accepts steer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -441,6 +441,7 @@ const KeyboardAccessoryBar = {
|
||||
<rect x="8" y="2" width="8" height="4" rx="1" ry="1"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="accessory-btn accessory-btn-rmm" data-action="readmymind" title="Read My Mind: predict your next prompt">🧠</button>
|
||||
<button class="accessory-btn" data-action="esc" title="Escape">Esc</button>
|
||||
<button class="accessory-btn accessory-btn-dismiss" data-action="dismiss" title="Dismiss keyboard">
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
|
||||
@@ -478,6 +479,7 @@ const KeyboardAccessoryBar = {
|
||||
</button>
|
||||
<button class="accessory-btn" data-action="pick-path" title="Insert a file or folder path">📁 Path</button>
|
||||
<button class="accessory-btn" data-action="clear-input" title="Clear the current unsent input">⌫ All</button>
|
||||
<button class="accessory-btn accessory-btn-rmm" data-action="readmymind" title="Read My Mind: predict your next prompt">🧠</button>
|
||||
<button class="accessory-btn" data-action="tab" title="Tab">Tab</button>
|
||||
<button class="accessory-btn" data-action="shift-tab" title="Shift+Tab">⇧Tab</button>
|
||||
<button class="accessory-btn" data-action="effort-max" title="/effort max">Max</button>
|
||||
@@ -502,6 +504,9 @@ const KeyboardAccessoryBar = {
|
||||
this.element = document.createElement('div');
|
||||
this.element.className = 'keyboard-accessory-bar';
|
||||
this.element.innerHTML = this._simpleButtons;
|
||||
// The 🧠 key is opt-in (`readMyMindEnabled`, synced): it ships in both
|
||||
// templates but stays display:none until the bar carries the marker class.
|
||||
this.syncReadMyMind();
|
||||
|
||||
// Add click handlers — preventDefault stops event from reaching terminal
|
||||
this.element.addEventListener('click', (e) => {
|
||||
@@ -607,6 +612,11 @@ const KeyboardAccessoryBar = {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'readmymind':
|
||||
// Opens the shared Read My Mind modal (readmymind-ui.js); the modal
|
||||
// takes focus, so deliberately NOT in the terminal-refocus set.
|
||||
app.openReadMyMind?.();
|
||||
break;
|
||||
case 'paste':
|
||||
this.pasteFromClipboard();
|
||||
break;
|
||||
@@ -652,6 +662,17 @@ const KeyboardAccessoryBar = {
|
||||
this._confirmAction = null;
|
||||
},
|
||||
|
||||
/** Reveal/hide the 🧠 key from the synced `readMyMindEnabled` setting.
|
||||
* The marker class lives on the BAR because setMode() rebuilds the buttons'
|
||||
* innerHTML on every layout switch (per-key state would be wiped). Called at
|
||||
* init and re-synced by applyHeaderVisibilitySettings() on every settings
|
||||
* apply, so a live toggle needs no reload. */
|
||||
syncReadMyMind() {
|
||||
if (!this.element) return;
|
||||
const enabled = typeof app !== 'undefined' && typeof app.readMyMindEnabled === 'function' && app.readMyMindEnabled();
|
||||
this.element.classList.toggle('rmm-enabled', enabled === true);
|
||||
},
|
||||
|
||||
/** Send a slash command to the active session.
|
||||
* Sends text and Enter separately so Ink processes them as distinct events. */
|
||||
sendCommand(command) {
|
||||
|
||||
Reference in New Issue
Block a user