feat(web): реализовать рабочую область проверки решения (#125)#233
Merged
Conversation
Pure move, no behavior change: server.py (HTTP handler), viewmodels.py
(grade_path/grade_benchmark/_case_view), static/{index.html,app.css,app.js}
(HTML/CSS/JS extracted from the inline string). Public API
(grade_benchmark/grade_path/run_server) unchanged; _Handler/_INDEX_HTML/
_case_view re-exported from web/__init__.py for test back-compat. JS moved
out of _INDEX_HTML into static/app.js, so the 3 esc()-hardening regression
tests (issue #214) now grep the new web._APP_JS re-export instead.
Lays the groundwork for the split-pane workspace, extended error cards,
and glossary section this issue adds on top.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ts (issue #125) Prep for the web workspace's ErrorCard/glossary endpoints: - GraderConfig.glossary_store / glossary_missing_queue (config.py) — where the web layer's future glossary adapter will look for a local card store and the missing-concept queue; both optional/defaulted, no behavior change for existing users. .grader_glossary_missing.json gitignored (local state, same posture as .grader_cache/). - core/grader_core.run_single_test now returns "exit_code" (additive key, every branch) — needed for the web ErrorCard's exit_code field without re-implementing execution in the web layer. - core/glossary.all_entries() — lists the compact curated glossary, used as zero-config fallback content for the web Glossary section. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sue #125) _case_view() now adds case_n, severity, stdin, expected, actual, stderr, exit_code, timeout_s, suggestions, glossary_ids, and actions on top of the existing n/verdict/time/error/diff/glossary keys — additive only, so the existing /api/grade contract and its tests are unchanged. - stdin comes from a second (cheap) load_test_cases() call in grade_path(), zipped by position with run_tests()'s case results — no core signature change needed. - glossary_ids/suggestions are RE-only (TLE has no curated content to link to; fabricating some would be inventing content, not adapting existing data — left out per the #125 plan). - actions is a pure function over exactly the 5 MVP action-card ids (run_again/copy_input/copy_output/explain_error/open_glossary) — never create_test/compare_solutions, which stay out of scope for this issue. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…#125) When an RE case's exception has no curated glossary card (lookup_from_error misses), grade_path() now best-effort queues it via MissingConceptDetector.detect_from_error() + append_missing_entries() into CONFIG.glossary_missing_queue (or an explicit missing_queue_path, mainly for tests). Wrapped in try/except (GlossaryError, OSError) — a bad/unwritable queue path degrades gracefully instead of breaking grading, same posture as the existing opt-in cache (#56). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
glossary_adapter.py is a thin pass-through over JsonGlossaryProvider (#126) with a zero-config fallback onto core/glossary.py's compact ~28-entry set when CONFIG.glossary_store is unset or the configured file is missing/bad — so the future Glossary section UI has content to show on a fresh install. New routes on _Handler.do_GET: - GET /api/glossary?q= -> GlossaryCard[] (empty q = list all) - GET /api/glossary/<id> -> GlossaryCard or 404 JSON - GET /api/glossary/missing -> GlossaryMissingEntry[] (J7 backlog) Also fixes a test-isolation bug caught while adding these: a _case_view() unit test for an unknown RE exception didn't pin missing_queue_path, so it wrote a real entry into the repo's working directory via the J7 wiring added in the previous commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
COMMANDS is a plain list[dict] of the 7 MVP commands (run_again, copy_input, copy_output, explain_error, open_glossary, toggle_theme, switch_section) -- the single source of truth that will drive the command palette, action cards, and scenario buttons on the frontend, so "which button when" isn't reimplemented three times. Deliberate simplification vs. the design doc's free-form predicate strings: `when` is a fixed tag vocabulary (always/has_stdin/has_output/is_failure/ has_glossary/...) instead of an eval()'d expression -- unjustified complexity for 7 commands. GET /api/commands?context=tag1,tag2 filters server-side; omitted context returns the full registry. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…issue #125) Replaces the single-page tests/bench view with the full workspace design from docs/web-mvp.md: - Split-pane layout: topbar (section switch, theme toggle, Ctrl+K), resizable sidebar (run history, recent paths), result panel (command bar + table), detail panel (ErrorCard for the selected case). - ErrorCard detail panel renders stdin/expected/actual/diff/stderr/exit_code /timeout_s (all through the existing esc() hardening) plus the glossary mini-card, with the 5 MVP action cards (run_again/copy_input/copy_output/ explain_error/open_glossary) driven by the server-computed `actions` list. - Command palette (Ctrl+K/⌘K): fuzzy-ish substring search over title/ keywords, arrow-key nav, Enter to run, Escape to close with focus return, role="dialog" overlay. - Scenario buttons (result panel, shown only when nothing is selected) and action cards (detail panel, shown only when a case is selected) both render from the same contextTags()/visibleCommands() filter over the /api/commands registry -- one source of truth, no duplicated "which button when" logic. - Glossary section: search + card list + card detail + a read-only "Недостающее" backlog view (J7), with open_glossary doing an in-memory section switch + card selection (no URL-hash routing, per the #125 plan). - Narrow-viewport (<=860px) collapses panels to a vertical stack and hides drag handles. Also fixes two bugs found while manually verifying in a browser: - `[hidden]` was losing the cascade to `.workspace`/`.palette-overlay`'s `display: flex` (same specificity, author style wins) -- the glossary section and command palette were both visible on load. Added an explicit `[hidden] { display: none !important; }` rule. - Theme toggle changed `color-scheme` but body/html had no background tied to it, so light/dark had no visible effect -- added `background: Canvas; color: CanvasText` to html/body. - Long sidebar entries (paths) overflowed and pushed a page-level horizontal scrollbar -- added `overflow-wrap: anywhere` on .side-list items and scoped overflow-x to individual .panel elements instead of the page. - Topbar didn't wrap at narrow widths, so its controls visually overlapped and swallowed clicks meant for other buttons -- added flex-wrap for the <=860px breakpoint. Manually verified end-to-end via a running server (browser preview tool): AC/WA/RE case selection and detail panel, command palette open/search/ arrow-nav/Enter/Escape+focus-return, theme toggle, glossary search/card detail/backlog, the open_glossary deep-link, and the narrow-viewport collapse. No JS test runner in this repo (by design, see docs/web-mvp.md non-goals) -- frontend logic has no automated coverage beyond this manual pass; Python-side contracts (ErrorCard fields, endpoints, command registry) remain covered by pytest. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ANGELOG entry - docs/web-mvp.md: MVP/v1/later table rows for #125 (split-pane, ErrorCard WA/TLE, action cards, palette, scenario buttons, glossary section) flipped from "дизайн" to "реализовано"; endpoint table marks the 4 implemented routes; intro/closing notes point at src/stepik_grader/web/ instead of the old single-file web.py. - docs/claude-handoff.md: #125 section rewritten to "закрыт" status (matches the existing convention for #126/#163/etc in this file) so a future Claude session doesn't redo it; dependency-order section updated to reflect only #186/#187/#129 remain open for epic #123. - docs/glossary.md: documents the new GraderConfig.glossary_store/ glossary_missing_queue fields the web adapter reads. - CHANGELOG.md [Unreleased]: Added entry for the web workspace, Refactored entry for the web.py -> web/ package split. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Реализация issue #125 (эпик #123) — split-pane workspace раздела «Проверка решений» + раздел «Глоссарий» поверх готового store (#126).
web.py→web/-подпакет (server.py/viewmodels.py/glossary_adapter.py/commands.py/static/) — чистый перенос, публичный API (grade_benchmark/grade_path/run_server) не изменился./api/grade(case_n/severity/stdin/expected/actual/stderr/exit_code/timeout_s/suggestions/glossary_ids/actions) — аддитивно, старый контракт не ломается.GET /api/glossary,/api/glossary/<id>,/api/glossary/missing,/api/commands.contextTags()/visibleCommands().core/:exit_codeвrun_single_test,core/glossary.all_entries().GraderConfig:glossary_store,glossary_missing_queue.Сознательно вне скоупа (design-only / другие issue): Downloader (#186), микро-бенчмарк в web (#187),
create_test/compare_solutions, hash-роутинг, экспорт в Glossary-Python, полный a11y-аудит — подробности вdocs/web-mvp.mdиdocs/claude-handoff.md.Test plan
pytest tests/ -x -q --tb=short— зелёные (868 passed; 37 pre-existing subprocess-related failures на этой машине, идентичные на main)ruff check ./ruff format --check .— чистоmypy src/stepik_grader --ignore-missing-imports— чистоopen_glossary, схлопывание на узком экранеCHANGELOG.md— запись под[Unreleased]🤖 Generated with Claude Code