mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-10-31 19:10:30 +00:00
4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
248a4b3cd1
|
feat(status): show the session's /goal on one line above Tokens (#1228)
## Summary OpenCode's built-in `/goal <objective>` keeps a session working turn after turn until its reviewer judges the objective met, and pauses the goal on its own after a stop, a failed run, stalls, its round limit or a service restart. CodeNomad already listed `/goal` in the composer picker (it comes from `command.list`) but showed nothing of the goal itself. While the shown session has a goal, the **Status** tab now shows **one line above Tokens**: - a status badge: **Active**, **Paused** or **Complete**; - the objective on one line with an ellipsis; hovering or focusing it shows the full objective and the reason for the last change (why it paused or was met), which is also the row's accessible description; - the rounds used out of the maximum (`2/50`); - **Pause goal** / **Resume goal** (one button that keeps focus when the state flips) and **Clear goal**. Without a goal, without a session, on a runtime without goal support or after a failed read, nothing renders (no hint, no gap). The line is not a Status section: it cannot be hidden or reordered. ## How it works - **Read path:** the instance proxy refuses plugin RPCs, so `GET /api/workspaces/:id/sessions/:sessionId/goal` (`server/routes/session-goal.ts`, contract in `opencode/goal-contract.ts`) validates the session ID, reads the session, checks that its Location belongs to the workspace, then calls the fixed `opencode.goal` `get` in that Location (8 s timeout, abort on disconnect). It returns only the displayed fields; a missing RPC or method answers `unsupported`, any other failure or malformed output `unavailable`. - **Freshness:** plugin RPC events already reach the UI through the native event relay (as `rpc.codenomad.missions.changed` does), so the store follows `rpc.opencode.goal.changed` for tracked sessions, with a per-session version that drops replies older than a change already heard. It also reads when the line is shown (Status visible, session switch), on reconnect (coalesced) and after its own commands. It never polls; a failed read keeps the last goal shown; deleting the session or stopping the workspace drops it. - **Commands:** the buttons reuse the composer's native command path (`executeCustomCommand(..., "goal", "pause" | "resume" | "clear")`, with session admission, instruction sync and the profile environment). They are disabled while a command runs; a refused command (for example pausing without an active goal) shows OpenCode's message. ## Contract Upstream `@opencode/schema/goal` (anomalyco/opencode #59437, #59850; shipped in 2.2.1, identical goal files in 2.2.3 and 2.2.5): RPC `opencode.goal` with `get({ sessionID }) -> Goal.State | null` and event `changed { sessionID, goal }` published in the session's Location on every write. Documented in `dev-docs/OPENCODE_COMPATIBILITY.md` ("Session goal"); refresh policy row in `CACHE_REFRESH_CONVENTIONS.md`; line convention in `UI_SHELL.md`. ## Help New `conversations.md#goal` section (start, read, pause/resume/clear, automatic pauses) and a sentence in `settings.md` about the Status line, in English and all nine translations. ## Validation - Root and server typecheck clean. - Route tests 3/3; store tests 8/8 (with and without `--conditions=browser`), including rapid session switching through the shared background read queue and hidden sessions. - Browser: `session-goal` (no goal, active with Pause, paused with Resume and reason, Complete, Clear, command arguments, update after `changed`, keyboard focus kept on the toggle across Pause and Resume, line above Tokens) and `status-panel` 6/6; `status-tokens` and `fixture-wiring` also pass. - Ten-locale help 31/31. - Native `scripts/test-session-goal-native.mjs` against the exact OpenCode **2.2.5** CLI (twice): `get` returns null for a new session and another workspace gets 403; `/goal pause` without a goal fails with OpenCode's message; a goal set with the fake provider is paused by the reviewer, then resumed and cleared, with the `changed` events relayed to the owning workspace. CI runs it on the minimum and latest runtime lanes; the store test joins the UI unit list. - Full server suite on the rebased branch: 2,841 passed, 9 skipped; the `plugin-controls` (same-target serialization) and `panel-extension-api4` (deadline/abort) timing tests failed and the `index.test.ts` shutdown test was cancelled under full-suite load. None of them touches this change, and all three files pass alone (44/44). Large files touched with 1–4 line changes: `packages/server/src/server/http-server.ts` (~2,490 lines), `packages/ui/src/lib/api-client.ts` (~860 lines). |
||
|
|
5bc483d08d
|
feat(ui): toggle several rows at once by dragging across toggles (#1221)
Setting many rows of the same kind (Message content eyes, session
selection checkboxes, model visibility) took one click per row. Image
editors let users drag across a column of layer eyes instead; CodeNomad
now does the same.
Pressing a toggle and dragging out of it flips it, and every toggle of
the same column or list the pointer then crosses takes that new state;
toggles already in that state stay as they are. Releasing the button
clicks nothing, including the first toggle when the drag returns to it.
It works for mouse and pen; touch drags keep scrolling, and a touch
landing during a mouse drag leaves the sweep going.
Implementation: `lib/toggle-sweep.ts` installs one capture listener on
first use. Toggles opt in with `data-toggle-sweep={toggleSweepGroup(...)}`,
one group per column or list, so the Message content eyes and chevrons
sweep separately and exclusive selectors (tabs, presets) never sweep.
Each toggle changes through its own click, so its handlers, disabled
state and accessibility are unchanged; state is read from `checked`
(labels stand for their checkbox) or `aria-pressed`/`aria-checked`. The
drag is sampled every 4 px so fast moves skip no row, text selection
and native drag are blocked during a sweep, the trailing click is
swallowed, and a sweep whose release went elsewhere ends at the next
move without the button. `afterSweep` defers costly work until the
sweep ends.
Groups: Message content visibility and expansion columns, session
selection checkboxes, right-panel customization (built-in tabs and
Status sections; extension activation is a trust decision and stays
out), notification routing, model visibility, and the multi-select
options of agent forms and provider sign-in forms.
Message content dropped clicks made while a save was pending and showed
a row only once the server confirmed it, re-rendering the transcript
for each. Rows now show their requested state at once; a sweep saves
once, on release, so the transcript re-renders once. Saves run in
order and each batch of rows is sealed as it joins the queue, so a
later click never jumps ahead of a preset change nor rides along with a
sweep still held.
Notification routing shows each box at once, writes the whole table
once per sweep, runs its writes one after another so an older table
never lands last, and asks for System permission once per gesture.
Model visibility already showed pending changes and wrote them in
order.
Validation: browser regressions in transcript-presets (a single jump
across four eyes with slow saves, shown during the drag with nothing
saved, then one write on release; a hidden row that stays hidden; a
release back on the origin; the chevron column alone; a held sweep not
persisted by queued saves; a row clicked after a preset applying after
it), session-search (both directions, a release over a row title
opening no session, a lost release leaving no sweep, a touch mid-drag)
and notification-routing (one write per sweep, serialized writes with
the last winning, one permission request). Each fails with its part of
the fix removed. Two gatekeeper rounds ended with no P0-P2 finding; the
user validated the behaviour in a separate Electron dev instance.
dev-docs/UI_CONVENTIONS.md and dev-docs/TRANSCRIPT.md record the
convention, and the help describes the gesture in all ten languages.
|
||
|
|
1dabb5110f
|
docs(help): bring the user guide back in line with the current app (#1079)
docs(help): bring the user guide back in line with the current app The help was written on 2026-10-14 and about forty user-visible changes merged since without touching it, so several pages described controls that no longer exist: Missions still listed four playbooks and a Save step for preferences that now save on each change, the depth editor kept its old names, notifications still had their former switches, and voice input pointed to a microphone button that is not in the composer. Every English page was re-checked claim by claim against the current labels (English UI messages) and behaviour, then the nine translations were updated to match, using each locale's own UI labels. Notable corrections: Missions (Compare two models, autosaving defaults with Apply to / Global / Reset, Subsession nesting depth, prepared hand-offs, retired-task interrupts, the named causes of "Mission Control is unavailable", standalone server support); conversations and history (reasoning/tool durations, token lines adding up the cleanup selection, presets including Nothing, timeline markers following Message content, in-place reveal of long text, Open in session, focus after send, Queue message / Steer now, Retrying); settings (notification routing table and defaults, Stats, Mode, info tips, Server setting badge, localized native menus); shortcuts (72 actions, Clear shortcut, Ctrl/Cmd+K); voice (More actions entries, Save status); files (live Workspace refresh, Show 200 more); OpenCode, install, server and updates (2.1.1 recommended, OpenCode 2 beside an older installation, version card first, private loopback listener for Missions, preview releases offered once all builds are published); providers, integrations, browser, SideCars, desktop and remote pages. Translations also repaired older drift, mainly the project-tab closing passages. The Chat settings table header (Default state, its title, item column, the thinking row and its accessible label) was still English in eight locales; it is now translated so the help can cite what users see. AGENTS.md now asks every PR changing user-visible behavior to update the affected help pages in the same PR, since CI validates structure and links but not whether the text still matches the UI; it also corrects the needs-input notification default. USER_HELP.md no longer claims native menus stay English. Validation: npm run test:help (all ten locales, 25 pages, heading ids unchanged), a full help build, and the i18n and transcript-visibility unit tests. |
||
|
|
c0d53f13d4
|
docs(help): multilingual help site with in-app Help menu and palette entry (#859)
## Summary A complete public CodeNomad help site in the app's ten languages, published on GitHub Pages (https://neuralnomadsai.github.io/CodeNomad/) and opened from the app. - **Content:** 25 pages in 8 sections (Start, Workflows, OpenCode setup, Remote access, Customize, Extensions, Desktop, Help), written for OpenCode power users and covering the current version only. It includes everything user-relevant from `README.md`, `packages/server/README.md` (server, network, auth, TLS, Remote Control) and the user-facing dev-docs, with flags, defaults, labels and safety boundaries checked against source. - **Languages:** en, fr, de, es, he (RTL), ja, ne, ru, tr, zh-Hans. Interface labels reuse each locale's own app strings; native desktop menu names, code, commands, flags, paths and anchors stay unchanged. - **Site:** `scripts/build-help.mjs` renders `docs/help/<locale>/<slug>.md` with translated chrome (`docs/help/i18n/`), stable `{#id}` anchors identical across locales, same-article language links with hreflang, a root language chooser, and a first-party offline per-locale search (Ctrl/⌘+K, substring matching for CJK, Devanagari and Hebrew, hidden without JS). No analytics or remote resources. - **Validation:** `npm run test:help` fails on any missing page or string, heading drift, broken link/anchor/asset or invalid search target. `.github/workflows/help-pages.yml` validates PRs and deploys only from `dev`. - **App entry points:** one `open-help` command for the palette and a new **CodeNomad Help** item at the top of the Electron and Tauri Help menus. It opens the help in the invoking window's UI language through the existing external opener, falls back to the root URL for windows without the handler, and reports failures without replay. - Documents the strict boolean environment-variable rule from #959 and the updater entry points from #960. ## Review Delivered as a CodeNomad mission with independent review loops, each to zero findings: - English content audit (5 passes, 14 fixes) and technical gatekeeper (2 passes) before translation. - After translation: QA, UX review, and a final multilingual gatekeeper (35 translation/label findings fixed, then verified), plus a visual fix for the search focus ring and a verified sync with #960. ## Validation - `npm run test:help`: 9/9 (25 pages × 10 locales, strict, including negative tests); `npm run build:help`: 250 pages. - `node scripts/test-help-browser.mjs`: 44/44; Playwright: 500 page visits at 390 and 1280 px, all locales, no overflow, no external requests. - UI help-command and desktop-updates browser tests 19/19; help URL unit tests; Electron menu tests; UI and Electron typechecks; Tauri `cargo test` 272/272. |