Conversation
…config fixes after Django upgrade (#3345) * fix(admin): restore topic autocomplete in SeasonalTopicAdmin after Django upgrade - Remove raw_id_fields for topic/secondary_topic in SeasonalTopicAdmin; in Django 1.11 autocomplete_fields was silently ignored so raw_id_fields drove the popup picker, but Django 2.0+ recognises autocomplete_fields and the two settings conflicted, breaking the Select2 widget. - Catch ProgrammingError (table doesn't exist) in RemoteConfigCache.get_cache so management commands don't crash before migrations are applied. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: trigger image rebuild for sc-44504 cauldron * chore: trigger chart version build for sc-44504 * fix(admin): fix PoolFilter crash on missing pool + update help text for autocomplete - PoolFilter.queryset now handles TopicPool.DoesNotExist gracefully instead of crashing - Update SeasonalTopicAdmin help text from 'magnifying glass' (raw_id_fields era) to 'Type to search' (autocomplete_fields) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(admin): default Topic Pool Management filter to All Topics Previously defaulted to Library Pool, causing searches to return 0 results for topics not in that pool. Changing to All Topics makes search work as expected for finding any topic to manage its pools. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(admin): expand pool filter scope during search, keep Library default when browsing When searching, switch to All Topics so results aren't silently restricted to Library Pool. Default browsing view stays on Library Pool. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(admin): restore library pool default, add search hint for cross-pool search Reverts the context-sensitive pool filter logic (which silently switched to 'all topics' on search) in favour of the stable library-pool default (~21k topics, intentional for performance). Adds search_help_text to TopicAdmin so users know to select 'All Topics' before searching outside the library pool. Also includes the ProgrammingError guard in RemoteConfigCache (handles missing DB tables during startup). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(admin): restore raw_id_fields magnifying glass for seasonal topic selection Switches SeasonalTopicAdmin back from autocomplete_fields to raw_id_fields so the magnifying glass popup is restored. The popup shows pool/whitelist columns from TopicAdmin, which users need to identify the correct topic slug. Root cause of the original breakage was not raw_id_fields itself but the PoolFilter defaulting to Library Pool in the popup — making searches return zero results for non-library topics. Fixed by detecting _popup=1 in the request and defaulting to 'all' topics in that context only. The same _popup fix also benefits FeaturedTopicAdmin which already used raw_id_fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(admin): remove popup pool override — library pool default is correct for topic selection Users only select library pool topics for seasonal/featured pages, so the popup should default to Library Pool just like the regular list view. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(admin): deduplicate topic popup results and sort by slug Two issues in the raw_id_fields popup: 1. Duplicate rows: PoolFilter adds an INNER JOIN on the M2M through table. Django admin only calls distinct() when search_fields contain __ lookups; our direct-field searches (slug, en_title, he_title) don't trigger that, so any duplicate rows from the JOIN pass through. Fixed by overriding get_queryset() to call .distinct(). 2. Inconsistent ordering: no ordering was set, so results came back in undefined DB order and "shabbat" could appear anywhere in the list. Fixed by adding ordering = ['slug'] so exact/shorter matches appear first. The DB should also be checked for duplicate rows in django_topics_topic_pools: SELECT topic_id, topicpool_id, COUNT(*) FROM django_topics_topic_pools GROUP BY topic_id, topicpool_id HAVING COUNT(*) > 1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(remote_config): log warning when ProgrammingError silenced in cache startup Silently returning {} made it impossible to diagnose 'why is remote_config empty?' issues in production. A warning log now surfaces the exception type and message so the cause is visible in server logs without changing the startup behavior. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(remote_config): cover empty cache fallback on ProgrammingError Patches _build_cache to raise ProgrammingError and asserts get_cache() returns {} without re-raising, guarding the missing-table path during Django/DB upgrades before migrations run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Apply suggestion from @yodem --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…t 401 (#3412) The pytest-job mints a 1h GCP access token and bakes it into the kubeconfig via get-gke-credentials. When the test wait approaches the 60-minute timeout the token expires before the Get Logs / Cleanup pyTest Pod steps run, causing "the server has asked for the client to provide credentials" / Unauthorized failures. Setting use_auth_provider: true makes the kubeconfig use the gke-gcloud-auth-plugin exec provider, which re-mints credentials on each call instead of relying on a frozen token. Applied to all three GKE-authenticating jobs for consistency. sc-44850 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: csrf first pass * chore: fix edit_text * chore: fix comment syntax * chore: remove unnecessary comments * chore: remove fallback * chore: SSR for misc pages * chore: change to const
…ser menu, Module picker) (#3416) * chore: raise up above menu * chore: z-index variables * chore: create vars
* feat(ref api): endpoint and part of the view/ * fix(ref api): add signature to get and wrap dict with jsonResponse * feat(ref api): remove index data * feat(Ref): ref function returns its parts, and adding it to ref api * feat(Ref): ref function returns its parts, and adding it to ref api * feat(Ref): change attr name for default node metadata. * feat(Ref): add navigation_refs. * refactor(Ref): add ja param to more functionss for saving mongo calls. * refactor(ref api): call the vstate when index node is ja, and use it in ref methods. * feat(ref api): add next and prev. * refactor(Ref): change ref_parts to get_lineage_titles_top_down, and do not return the sections (section are not defined well as parts when the ref is range). * refactor(Ref): remove get_lineage_titles_top_down as we have `address` function on the node. * feat(ref api): change re parts to get_lineage_titles_top_down and add normalized sections. * feat(ref api): many things. * chore(ref api): remove todo. * fix(ref api): move prev and next into navigation_refs. * feat(ref api): add parent ref. * fix(ref api): some virtual nodes problems. * fix(Ref): fix next and prev segment for virtual node. * text(ref api) * docs(ref api): add documentation to openAPI.json. * refactor(ref api): `lineage_refs_top_down` rather than `lineage_titles_top_down` and `parent_ref`. * feat(Ref): add `vstate` param to functions that already have `state_ja` param, but call other functions that use `vstate`. * feat(ref api): add `vstate` to improve performance. * refactor(Ref): use vstate rather than state_ja. * refactor(Ref): use vstate in `is_empty` and `get_state_ja` rather than having private functions doing it. * feat(database): add QueryCounter class and use it in tests env to monitor number of times mongo is queried. * test(ref api): add get_ref function with assertion about number of calls. * chore(ref api): remove redundant import. * fix(ref api): check first available section exists before normalizing. * docs(ref api): first available section can be null Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix(Ref.prev_segment_ref): change 0 to -1 for it should be the last segment of previous section. * fix(Ref.is_empty): fix call on segment ref with vstate. * feat(QueryCounter): do not count any command to avoid counting connection/handshake commands. Rather give the user to pass what commands he wants to count. * fix(tests): remove redundant non-existing import * fix(ref api): fix lineage refs to be top down. * docs(ref api): remove false comment. * feat(ref api): add address types and scection names to default child. * docs(ref api): add nullable to prev_segment_ref. * fix(ref api): handle DictionaryEntryNotFoundError as not being a ref. * refactor(ref api): rename lineage_refs_top_down to shortest_path_to_root. * refactor(Ref): add function `get_subrefs_count` and use it in `all_subrefs`, `prev_segment_ref` and `next_segment_ref`. * docs(ref api): move Misc tag last, add missing default values to path params. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* test * feat(csv upload): Now you can upload csv of multiple indices at once, all for single version * feat(modtools): add bulk-version editor (views, urls, UI panel) * chore: remove stray kubectl files * fix(modtools): remove stray diff marker in JSX * fix(urls): point bulk-version routes at sefaria_views * feat(modtools): render BulkVersionEditor panel * feat(modtools): redundent element by mistake * feat(modtools): workflowy bulk import, duplicate index, bulk index metadata * fix(modtools): flatten /api/index/titles response for Workflowy panel * fix(modtools): add workflowy helper, safe index edit, tidy UI * fix(modtools): tidy UI a bit; workflowy bulk tool revision * fix(modtools): workflowy bulk tool revision * fix(modtools): rendering issue * fix(modtools): rendering issue * fix(modtools): duplicate_index_api function * fix(modtools): bulk workflowey upadte * fix(modtools): duplicate index (all fields) correction * fix(modtools): duplicate index (all fields) correction * fix(modtools): duplicate index (all fields) correction * fix(modtools): fix * fix(modtools): bulk edit index metadata fix * fix(modtools): bulk edit index metadata fix * fix(modtools): bulk edit index metadata fix * fix(modtools): clear every cache layer just like BookPage.jsx does * fix(modtools): wait for $.ajax calls * fix(modtools): wait for $.ajax calls * fix(modtools): fix edit bulk tool * fix(modtools): include toc zoom, dependence, base text and collective title in bult index edit tool * fix(modtools): fix logic * fix(modtools): debug * fix(modtools): fix logic * fix(modtools): authors save bug * fix(modtools): reverse * fix(modtools): toc zoom debug * fix(modtools): Node Title Editor Tool and Auto-Link Commentary Tool try * fix(modtools): endpoint typo * fix(modtools): mapping * feat(export): stream-safe CSV importer & 10× faster bulk version upload * fix(upload): allow 4-row CSV header, pad short data lines, remove duplicate view * feat(export): sanitize * feat(export): Tiny autosave helper * cleaner version of csv bulk upload * auto-linking-tool patch * Adds a cache‑reset hop (/admin/reset/<title>) after the PATCH and before the rebuild. * try different font in reader * fix * multiworkflowy option incorporated to regular workflowy component * redundant func removed * fix node edit tool * delete duplicate index tool * robust bulkindexeditortool * collective title logic fix * fix * not sure honestly * chore: excluded claudemd file from git * fix: remove duplicate API endpoint and fix PropTypes syntax - Remove duplicate indices_by_version_api (kept version_indices_api) - Update frontend to use /api/version-indices consistently - Fix missing ModeratorToolsPanel.propTypes declaration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(backend): PyMongo 4.x compatibility and partial success handling - Fix deprecated db.history.update() calls in history.py and helper/text.py - Changed to update_many() which is the PyMongo 4.x equivalent - This was causing TypeError when bulk editing versions - Improve version_bulk_edit_api to handle partial failures gracefully - Now returns detailed success/failure info: {status, count, total, successes, failures} - Catches individual version save errors instead of failing entire operation - Allows frontend to show which versions failed and why Fixes critical bug reported in Shortcut #36475 testing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(modtools): Add dedicated CSS file with Sefaria design system - CSS variables for consistent colors (--modtools-primary, etc.) - Internal Admin Tool banner for clear identification - Button variants: primary, secondary, danger, small - Selection controls: Select All/Deselect All buttons - Field group sections with headers and grid layout - Validation error states and field error messages - Status messages: success, warning, error, info - Warning/info/danger boxes for confirmations - Changes preview panel - Loading states with spinner animation - Responsive breakpoints for mobile (768px, 1024px) Part of Shortcut #36475 (Kehati Tools) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Add shared components for modtools refactor New shared components: - ModToolsSection: Section wrapper with title/Hebrew title - IndexSelector: Checkbox list with Select All/Deselect All buttons, selection count display ("X of Y selected"), Clear functionality - StatusMessage: Auto-detects message type from emoji prefix (✅❌⚠️ ) - index.js: Barrel export for clean imports These components are reusable across all modtools panels. Part of Shortcut #36475 (Kehati Tools) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Add field metadata constants New constants file: - VERSION_FIELD_METADATA: Defines all editable Version fields with labels, types, placeholders, help text, direction (rtl/ltr), and select options - INDEX_FIELD_METADATA: Defines all editable Index fields Fields include proper metadata for: - Text inputs: versionTitle, versionSource, purchaseInformationURL - Select inputs: status, license, direction - Number inputs: priority - Textarea inputs: versionNotes - Boolean selects: isPrimary, isSource, digitizedBySefaria Part of Shortcut #36475 (Kehati Tools) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Add refactored tool components Refactored components from ModeratorToolsPanel.jsx: BulkVersionEditor (primary focus of #36475): - Field grouping: Identification, Source & License, Metadata, Notes - URL validation for versionSource, purchase URLs - Select All/Deselect All with selection count - Clear search button and no-results message - Soft delete: marks versions with [MARKED FOR DELETION] prefix - Confirmation dialog for delete action - Changes preview before saving - Validation error display BulkIndexEditor: - Bulk edit Index metadata - Uses shared IndexSelector component AutoLinkCommentaryTool: - Create commentary links for base texts - Checks dependencies before operations NodeTitleEditor: - Edit schema node titles within Index records - Validates title format (ASCII, no special chars) Part of Shortcut #36475 (Kehati Tools) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Add module entry point and update main panel Module entry point (modtools/index.js): - Exports all tool components - Exports shared components - Exports field metadata constants - Enables clean imports: import { BulkVersionEditor } from './modtools' ModeratorToolsPanel.jsx updates: - Import CSS file via webpack - Import refactored components from modtools module - Components now use shared styling and patterns Part of Shortcut #36475 (Kehati Tools) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Add comprehensive documentation New documentation files: AI_AGENT_GUIDE.md: - Quick reference tables for file locations and API endpoints - Data model gotchas (Version fields, Index commentary fields) - Common code patterns with examples - Known bugs to fix - CSS class reference - Testing approach (Jest + Pytest examples) - Decisions log tracking implementation choices - File structure diagram - Useful MongoDB/Python queries ARCHITECTURE.md: - Component structure and responsibilities - Data flow diagrams - API documentation PROGRESS.md: - Tracks completed phases (1-6) - Lists pending work items - Documents questions for later - Records strategies and notes Part of Shortcut #36475 (Kehati Tools) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Update PROGRESS.md with completed commits - Mark all 7 commits as complete with commit hashes - Update PR status to reflect #2527 has full description - Note PR is still in draft status 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Correct import paths for sefaria modules Fixed import paths in all tool components: - Changed '../../../sefaria/sefariaJquery' to '../../sefaria/sefariaJquery' - Changed '../../../sefaria/sefaria' to '../../sefaria/sefaria' Components are in static/js/modtools/components/ which is 2 levels deep from static/js/, not 3. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test(modtools): Add API tests and fix error handling - Add comprehensive pytest tests for modtools API endpoints: - TestVersionIndicesAPI: auth, response format, empty results - TestVersionBulkEditAPI: staff auth, POST requirement, validation, detailed response - TestCheckIndexDependenciesAPI: staff auth, response format - Fix version_bulk_edit_api to return JSON error response instead of raising InputError for empty indices (consistent API behavior) - Update ARCHITECTURE.md documentation: - Updated API response format to show detailed success/failure structure - Struck through fixed issues in Known Issues section - Updated File Structure to reflect new modtools/ folder hierarchy - Updated CSS Classes to reference modtools.css 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Redesign UI with card-based index selector - Replace checkbox list with 3-column card grid for index selection - Add category metadata display on cards (e.g., "Tanakh • Prophets") - Add search/filter functionality for cards - Fix duplicate Select All/Deselect All buttons (single header checkbox) - Add proper top margin to page container - Fix dropdown width cutoff ("All langs" → "All languages") - Enhance version_indices_api to return category metadata - Improve overall styling with better spacing and visual hierarchy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Hide empty result containers in Workflowy upload - Only show upload message div when there's content to display - Only show upload result textarea when there's content - Reduced textarea rows from 30 to 20 for better proportions - Standardized conditional rendering to use && pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Fix warningBox list spacing and add page bottom margin - Add padding-bottom to .modTools for better page spacing - Add warningBox li styles for tighter bullet point spacing - Keep strong text inline within list items for better flow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(modtools): Improve design system and UI consistency - Reorganize CSS with numbered sections and better documentation - Add typography scale (--mt-text-xs through --mt-text-2xl) - Add font weight tokens (--mt-font-normal/medium/semibold/bold) - Add line height tokens (--mt-leading-tight/normal/relaxed) - Add border width tokens and semantic status text colors - Add layout variables (--mt-max-width, --mt-shadow-focus) - Replace hardcoded values with design tokens throughout - Add layout pattern classes: searchRow, filterRow, actionRow, optionRow - Add utility classes: sectionIntro, subsectionHeading, nodeListContainer - Update all components to use CSS classes instead of inline styles - Make page scroll instead of inner sections (remove indexCardGrid max-height) - Fix search button height to match input fields - Center Clear Search button - Put filter labels inline with dropdowns 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Update documentation for card-based UI - Fix outdated CSS line count references (was 579, now dynamic) - Update "Known Bugs to Fix" → "Known Issues (Resolved)" since bugs are fixed - Add recent commits to PROGRESS.md (API tests, card-based UI) - Update API docs to show metadata response format - Update IndexSelector description: checkbox list → card-based grid - Simplify code examples to reflect current patterns 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Add comprehensive help documentation to all tools Add a HelpButton component with modal that displays detailed documentation for each modtools tool. Content managers can now click the "?" button in the top-right corner of each tool section to understand exactly what the tool does before using it. Documentation added to: - Bulk Edit Version Metadata: fields, mark for deletion, use cases - Bulk Edit Index Metadata: fields, auto-detection, term creation - Auto-Link Commentaries: mapping algorithms, X on Y pattern - Edit Node Titles: validation rules, dependency checking 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Prevent ESC key from navigating away when help modal is open Use capture phase event listener with preventDefault and stopPropagation to intercept ESC key before global navigation handlers can process it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Add help documentation to all legacy tools Add HelpButton with comprehensive documentation to the 6 legacy tool sections in ModeratorToolsPanel.jsx: - Bulk Download Text: Pattern matching, output formats - Bulk Upload CSV: CSV format, encoding requirements - Workflowy Outline Upload: OPML import, options explained - Upload Links: CSV format, link types, project naming - Remove Links: Exact match requirements, error handling - Download Links: Reference fields, filters, output format Each help modal includes: - What the tool does - Step-by-step workflow - Field/option descriptions with tables - Important notes and warnings - Common use cases - Troubleshooting tips 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Correct link type capitalization in help docs "Mesorat HaShas" → "Mesorat hashas" to match the actual option values used in the code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Make all sections collapsible with unified component - Refactor ModToolsSection to be the single wrapper for all sections - Add collapse toggle on left side, help button on right side - All sections start collapsed by default for cleaner initial view - Convert all inline sections in ModeratorToolsPanel to use ModToolsSection - Pass helpContent prop to ModToolsSection instead of using separate HelpButton - Add smooth CSS animations for collapse/expand transitions - Ensure keyboard accessibility (Enter/Space to toggle) - Add print styles to show collapsed content when printing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Update documentation for collapsible sections - Document HelpButton component in file structure - Update CSS class reference with new collapsible section classes - Add Phase 6 (Collapsible Sections) to progress tracker - Update shared components documentation with new features - Minor CSS whitespace fix from linter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Fix section header title alignment with collapse toggle - Reset legacy padding from s2.css that was causing vertical misalignment - Set line-height: 1 to ensure proper flexbox centering - Add white-space: nowrap to prevent title text wrapping - Always show section border (remove transparent state on collapsed) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(modtools): Standardize search UI across bulk editor tools - Add Clear Search button, no-results message, and category metadata to BulkIndexEditor and AutoLinkCommentaryTool (matching BulkVersionEditor) - Update IndexSelector docs to reflect shared usage across tools - Replace deprecated onKeyPress with onKeyDown in all search inputs - Remove unused React import from BulkIndexEditor 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style(modtools): Add visual indicator for required fields Add red asterisk styling for required fields in the bulk editor forms. This addresses the ticket requirement: "Required fields are clearly marked" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Add comprehensive documentation suite - Add COMPONENT_LOGIC.md: Detailed logic flows, state machines, decision trees for each tool component - Add DESIGN_SYSTEM.md: Complete CSS documentation with color tokens, typography, spacing, and component patterns - Rewrite AI_AGENT_GUIDE.md: Comprehensive quick reference with common tasks, patterns, troubleshooting, and decision trees - Update ARCHITECTURE.md: Add cross-references to new docs - Update PROGRESS.md: Document Phase 8 documentation work This documentation suite helps new developers and AI agents understand the ModTools codebase quickly and make informed changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Fix incorrect status field value in help text The help content incorrectly said "none" allows edits, but the actual select option value is an empty string (with label "None (editable)"). Updated to say "empty/unset allows edits" for accuracy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: trigger CI * test(modtools): Add comprehensive test suite for modtools APIs Frontend (Jest): - stripHtmlTags: 17 tests for XSS prevention, HTML removal, entity decoding - fieldMetadata: 39 tests for field structure, validation, constants Backend (pytest): - Links upload/delete: auth, POST, file requirements - Text upload: staff access, method validation - Workflowy upload: auth, files requirements - Bulk download: staff access, response formats - Links download: CSV handling, invalid refs Total: 83 tests (56 Jest + 27 pytest) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(modtools): Convert search results from card grid to list layout Replace the 3-column card-based grid in IndexSelector with a more compact list-based layout. The list displays the same metadata (title, categories) in a single row format with category badges. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore(modtools): Temporarily disable BulkIndexEditor, AutoLinkCommentary, and NodeTitleEditor Comment out three modtools tickets that are not ready for use: - BulkIndexEditor: Bulk edit index metadata - AutoLinkCommentaryTool: Auto-link commentaries to base texts - NodeTitleEditor: Edit node titles within an Index schema The components are left in the codebase but commented out. TODO comments note there are open tickets to reintroduce them when ready. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Align form fields and normalize search button size - Fix field alignment in fieldGroupGrid by using align-items: end so inputs align regardless of help text presence - Fix oversized search button by changing searchRow to flex-start and using standard button padding instead of stretch 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Address code review feedback from automated analysis Security & Validation: - Add field whitelist for version_bulk_edit_api to prevent arbitrary attribute injection - Add try-catch for JSON parsing with proper error responses - Replace bare except clauses with specific Exception handling Bug Fixes: - Fix hasChanges logic for toc_zoom field (0 is a valid value) - Fix title_valid validation check (check for !== true instead of === false) Accessibility: - Restore focus to help button when modal closes Testing: - Fix conditional assertions that silently passed without verification 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Add disabled component notes and fix empty indices status code - Add NOTE comments to disabled components (BulkIndexEditor, AutoLinkCommentaryTool, NodeTitleEditor) indicating they are retained for future re-enablement - Add NOTE to check_index_dependencies_api and reader/views.py index_post explaining these are for disabled features - Fix empty indices error response: status 500 → 400 (client error) - Update test to expect 400 for empty indices 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(modtools): Clean up backend API code - Remove redundant imports in version_indices_api and version_bulk_edit_api - Move docstring to correct position in version_indices_api - Simplify data extraction in version_bulk_edit_api - Add comment explaining library.get_index() cache efficiency - Use getattr() for cleaner category access - Remove unnecessary comment from history.py PyMongo fix - Fix whitespace alignment in urls.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(modtools): Simplify bulk edit API response and improve error display - Remove redundant count/total fields from API response (frontend calculates from arrays) - Rename loop variable `t` to `title` for clarity - Improve error display with bullet points and newlines for readability - Update docstring to match simplified response format - Update tests to match new response format 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Fix outdated API response comment in BulkVersionEditor 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(modtools): Improve variable naming in version_bulk_edit_api - vtitle → version_title - lang → language - title → index_title - v → version - k, val → field_name, field_value Makes the code more readable and self-documenting. * refactor(modtools): Clean up backend API code - Reorder functions to match URL endpoint order - Improve variable naming across all three endpoints: * vtitle/lang → version_title/language * title → index_title * q → query * idx → index - Remove redundant 'dependent_count' field (frontend can use array length) - Update tests to match API changes * docs: Updated comment of not used code to mention it should be reviewed when used * refactor(modtools): Improve variable naming in Index API - j → json_data - func → tracker_func - e → error Makes the code more readable and consistent with naming conventions. * chore: added temp pr description md file * chore: modtools ai agent guide rename to include "modtools" * docs(modtools): Remove outdated PROGRESS.md file - Deleted PROGRESS.md as it contains historical project tracking now complete - Removed PROGRESS.md references from AI_AGENT_GUIDE.md and ARCHITECTURE.md - Kept 4 essential docs: AI_AGENT_GUIDE, COMPONENT_LOGIC, DESIGN_SYSTEM, ARCHITECTURE * docs(modtools): Update filename references to MODTOOLS_AI_AGENT_GUIDE.md - Updated all references from AI_AGENT_GUIDE.md to MODTOOLS_AI_AGENT_GUIDE.md - Fixed cross-references in ARCHITECTURE.md - Fixed file structure documentation in both files * docs(modtools): Remove line numbers and add doc references to components - Removed specific line number references from documentation (e.g., text.py:1270) - Added documentation pointers to all component file headers: - ModeratorToolsPanel.jsx - BulkVersionEditor.jsx - BulkIndexEditor.jsx - AutoLinkCommentaryTool.jsx - NodeTitleEditor.jsx - Makes docs more maintainable and discoverable for developers * refactor(modtools): Modernize BulkVersionEditor to use fetch API - Replace jQuery ($.ajax, $.getJSON) with native fetch API - Convert callbacks to async/await pattern - Remove emoji characters from user messages - Improve error handling with try/catch blocks * refactor(modtools): Use Sefaria.apiRequestWithBody for all API calls - Replace manual fetch calls with Sefaria.apiRequestWithBody utility - Handles URL parameter building automatically via URLSearchParams - Consistent error handling and CSRF token management - Cleaner, more maintainable API call pattern * docs(modtools): Simplify BulkVersionEditor workflow description in PR doc * refactor(modtools): Modernize AutoLinkCommentaryTool to use Sefaria API utilities * refactor(modtools): Modernize BulkIndexEditor to use Sefaria API utilities * docs(modtools): Add shared components documentation to PR description * docs(modtools): Complete PR description with tests and review readiness * docs(modtools): Clarify URL validation purpose in BulkVersionEditor * refactor(modtools): Rename validateField to validateUrlField for clarity * refactor(modtools): Improve URL validation flow to only check URL fields * refactor(modtools): Extract validation logic and clarify comments * fix(modtools): Remove versionTitle from editable fields to prevent data corruption versionTitle is the search parameter used to identify which versions to update. Allowing it to be edited would cause partial failures as the search key changes during bulk operations. Users should edit version titles individually, not in bulk. * docs(modtools): Document versionTitle bug fix in PR description * refactor(modtools): Extract duplicate API call logic in BulkVersionEditor Extracted common bulk edit API call and response handling into performBulkEdit helper function. This removes ~50 lines of duplication between save() and markForDeletion() while keeping each function's unique logic clear. * fix(modtools): Use failureCount in markForDeletion error message * refactor(modtools): Remove unnecessary fallback in renderField All fields in FIELD_GROUPS are guaranteed to have metadata in VERSION_FIELD_METADATA, so the fallback code for missing metadata is defensive programming that's not needed. * docs(modtools): Reorganize PR description for better code review flow - Moved Code Modernization from frontend section to Code Quality Improvements - Added detailed implementation info to frontend sections (state, functions, line numbers) - Expanded shared components descriptions with props and usage - Added specific line numbers and details to field metadata section - Makes frontend changes easier to review, similar to backend detail level * refactor(modtools): Remove unused required field indicator Since versionTitle (the only required field) was removed from editable fields, the required indicator code is no longer needed. All remaining fields are optional. * feat(modtools): Add field clearing functionality to BulkVersionEditor Users can now completely remove fields from versions using checkboxes: - Added 'fieldsToClear' state to track fields marked for deletion - Added 'handleClearToggle' to manage clear checkbox state - Inputs are disabled when field is marked for clearing - Frontend sends null value for cleared fields - Backend detects null and uses delattr to remove field from MongoDB - Updated help documentation to explain clearing feature - Updated PR description with clearing feature details This addresses the issue where there was no way to remove a field value from all versions in a bulk operation. * docs(modtools): Document field clearing feature in AI agent guide Added comprehensive documentation for the field clearing feature: - Data Models section: Explains null value handling for clearing fields - Common Tasks section: Step-by-step implementation guide - Shows both frontend (checkbox, state) and backend (delattr) handling * test(modtools): Add comprehensive tests for field clearing functionality * fix(modtools): Fix parameter name mismatch in check_index_dependencies_api The URL route defined the parameter as 'title' but the function expected 'index_title', causing a TypeError. Updated function to use 'title' to match the URL configuration. * style(modtools): Improve visual feedback for cleared fields - Add grey background, reduced opacity, and not-allowed cursor for disabled inputs - Shorten checkbox label from 'Clear this field from all selected versions' to 'Clear this field' - Update help documentation to match new label text * refactor(modtools): Replace emoji-based message system with MESSAGE_TYPES enum - Create MESSAGE_TYPES constant with SUCCESS, ERROR, WARNING, INFO - Update StatusMessage to accept {type, message} objects (backward compatible with strings) - Replace all string type literals with MESSAGE_TYPES enum - Remove unused React import from StatusMessage - Validation messages now use WARNING type (yellow/amber) for better visibility - Fixes issue where validation messages were invisible due to same styling as success * fix(modtools): Show validation messages proactively and grey out Save button - Add getValidationState() to compute validation message based on current state - Show 'No indices selected' when none are checked (proactively) - Show 'No fields to update or clear' when no changes made (proactively) - Show validation errors proactively instead of on click - Grey out Save button when any WARNING message is active - Remove redundant validation checks from save() - handled by disabled state - Include fieldsToClear in hasChanges calculation - Remove redundant 'Found X texts' message (shown in IndexSelector) - Move StatusMessage above Save button for visibility - Move Delete button to bottom with separator * fix(modtools): Show cleared fields in changes preview Fields marked for clearing via 'Clear this field' checkbox now appear in the 'Changes to apply' preview with '(clear)' indicator. * fix(modtools): Remove unnecessary language parameter from bulk edit API The bulk edit API was requiring a language parameter, but since title + versionTitle is already unique (defined as pkeys in the Version model), the language is not needed to identify versions. When users didn't select a language filter, the frontend was sending language: "" which caused the API to query for versions with an empty language string, resulting in "No Version found" errors for all updates. Changes: - Backend: Remove language from required fields; use only title + versionTitle - Frontend: Don't send language parameter in bulk edit payload - Tests: Add test verifying API works without language parameter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Add missing Hebrew titles to link management sections Three ModToolsSection components were missing titleHe props, causing them to appear as empty boxes in Hebrew interface mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Update PR description with accurate line counts and complete coverage - Updated shared component line counts (IndexSelector: ~183, ModToolsSection: ~137, HelpButton: ~98) - Added messageTypes.js to constants documentation - Updated render section line numbers (526-725) - Added test file line counts - Documented MESSAGE_TYPES enum replacement and proactive validation - Added check_index_dependencies_api parameter fix to bug fixes section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: comment * refactor(modtools): Simplify IndexSelector props by combining indices and metadata Combine `indices` (string[]) and `indexMetadata` (object) props into single `indices` prop (Array<{title, categories?}>). This eliminates potential mismatch between parallel data structures and provides a cleaner API. - IndexSelector now expects objects with title and optional categories - Parent components transform API response before passing to IndexSelector - Updated BulkVersionEditor, BulkIndexEditor, AutoLinkCommentaryTool - Updated PR documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Add missing fieldMetadata constants to documentation - Added ALL_VERSION_FIELDS (lines 273-281) - Added LINK_TYPE_OPTIONS (lines 301-308) - Reordered constants to match file order (INDEX_FIELD_METADATA first) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(modtools): Clean up unused code and consolidate MESSAGE_TYPES - Move MESSAGE_TYPES into StatusMessage.jsx (delete separate constants file) - Remove unused ALL_VERSION_FIELDS from fieldMetadata.js - Remove unused LINK_TYPE_OPTIONS from fieldMetadata.js - Update tests to remove tests for deleted constants - Restructure PR description with summary first, then detailed docs - Add note about internal tooling code standards 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Add comprehensive file documentation Added missing sections to PR description: - ModeratorToolsPanel refactoring (logic preserved, added stripHtmlTags utility) - CSS styles documentation with internal tooling note - Index/export files - Documentation files (docs/modtools/) - Other branch changes (editor.js autosave, s2.css fonts) - Complete file list for easy reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Add .gitignore to file list 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: Remove test README.md file Removes test file that was accidentally committed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: Revert unrelated changes to editor.js and s2.css Removed: - Autosave helper in s1/editor.js (unrelated to modtools PR) - Heebo font classes in s2.css (not needed) - Restored GUIDE OVERLAY section comment 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Remove reverted files from documentation Updated PR description to remove references to: - static/js/s1/editor.js (autosave helper - reverted) - static/css/s2.css (heebo fonts - reverted) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Consolidate documentation from 4 files to 2 Merged AI_AGENT_GUIDE + ARCHITECTURE + DESIGN_SYSTEM into single MODTOOLS_GUIDE.md. Kept COMPONENT_LOGIC.md for detailed logic flows. Before: 4 files, 2206 lines After: 2 files, ~850 lines 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Remove redundant status:locked note The note about status:"locked" preventing non-staff edits is irrelevant in this context since the Bulk Version Editor is staff-only and staff bypass the locked check anyway. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Expand summary to highlight UI overhaul and full scope Summary now covers: - Primary feature (Bulk Version Editor) - UI overhaul (shared components, new stylesheet) - Backend changes (APIs, PyMongo migration) - Disabled tools built for future use 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Shorten Code Quality Improvements section Reduced from ~50 lines to ~10, keeping only: - Changes outside ModTools (PyMongo, parameter fix, reader/views.py) - Key patterns in new code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(modtools): Extract tools into separate component files - Extract 6 tools from ModeratorToolsPanel.jsx to individual files: - BulkDownloadText, BulkUploadCSV, WorkflowyModeratorTool - UploadLinksFromCSV, DownloadLinks (renamed from GetLinks), RemoveLinksFromCsv - Create utils/stripHtmlTags.js for shared HTML sanitization - Main file reduced from ~1373 to ~98 lines - Modernized BulkDownloadText and BulkUploadCSV to functional components - Updated modtools/index.js with new exports 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Update description with component extraction details 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(modtools): Update documentation paths in header comment Remove references to non-existent docs (ARCHITECTURE.md, DESIGN_SYSTEM.md, MODTOOLS_AI_AGENT_GUIDE.md) and update to reflect actual files: - MODTOOLS_GUIDE.md - COMPONENT_LOGIC.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(history): Add activity logging for version metadata changes Add audit trail for version metadata edits (license, status, priority, etc.) which were previously untracked. Changes now appear on /activity page with a new "Version Metadata" filter option. - Add log_version_metadata() in sefaria/model/history.py - Add update_version_metadata() in sefaria/tracker.py for centralized updates - Update version_bulk_edit_api, flag_text_api, lock_text_api to use tracker - Add activity feed template block and filter dropdown option 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(pr): Reorganize sections for better flow - Move Activity Feed/History Logging up in backend (section 2) - Move ModeratorToolsPanel Refactoring to first in frontend - Move Components Disabled to end of frontend section - Remove redundant Code Quality Improvements section - Remove duplicate Testing section - Renumber all sections to reflect new order 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Add inner wrapper to allow scrolling from side margins Inner scrollable elements were capturing scroll events. By making the outer container full-width and adding a max-width inner wrapper, users can now scroll the page from the side margins. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: Remove temp PR description file Moved content to actual PR description on GitHub. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(modtools): Correct documentation path in component headers Update references from non-existent MODTOOLS_AI_AGENT_GUIDE.md to the actual file MODTOOLS_GUIDE.md in 4 component files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: urls_share version api * chore: fix re_path * feat: add required field label styling and validation in BulkVersionEditor * chore: replace required field label with note in BulkVersionEditor and update styling * chore: restore path * chore: make comment clearer * chore: hard delete * feat: add version bulk rename API for updating version titles across multiple indices * feat: rename version title tool * chore: add renaming state and deleting state * chore: add console logging * chore: comment out css import * chore: include modtools css in base.html * helm: added modtools api prefixes * feat: update HTTP routes for version APIs to use exact path matching * chore: add comment and remove exact path for version indices * chore: change times * fix: enhance error handling in BulkUploadCSV component for non-JSON responses * chore: ensure_csrf_cookie * chore: allow 100 minutes in httproute * feat(Mod Tools): splitCsvsByIndex * chore: 100m to 10m * chore: version rename API instead of bulk version rename API * chore: show status * chore: add logging * chore: Positional Arguments can't be used in ElasticSearch 8.x * chore: 10m to 5m * chore: remove version rename frontend and backend * Revert "chore: remove version rename frontend and backend" This reverts commit 0a029e7. * chore: celery first pass * chore(BulkVersionEditor): Remove waitForRenameTaskResult function and update renameVersions logic to handle fire-and-forget behavior for version renaming. Adjust success and error messages to inform users about checking Slack for task results. * chore: log slack_response * chore: best effort reindex * chore: process_version_title_change_in_global_notifications * chore: csrf first pass * chore: csrf first pass * chore: fix edit_text * chore: fix comment syntax * chore: fix comment syntax * markdown comment fix Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * markdown comment fix Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: remove duplicate * chore: update django-csrf * chore: remove unnecessary comments * chore: remove fallback * chore: SSR for misc pages * chore: change to const * chore: version collision logic improved * chore: add PATCH and catch * chore: update md * chore: update md * chore: restore POST --------- Co-authored-by: NechapsaVenachkora <NechapsaVenachkora@users.noreply.github.com> Co-authored-by: YishaiGlasner <60393023+YishaiGlasner@users.noreply.github.com> Co-authored-by: Akiva Berger <akiva10b@gmail.com> Co-authored-by: dcschreiber <danielschreiber@sefaria.org> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: hebrew header for sheets with ref on chiburim * fix: address comments * Update static/js/sheets/SheetsWithRefPage.jsx Co-authored-by: YishaiGlasner <60393023+YishaiGlasner@users.noreply.github.com> * fix: migrate to use ._v --------- Co-authored-by: YishaiGlasner <60393023+YishaiGlasner@users.noreply.github.com>
* chore: fix spelling mistake * chore: should not be contenteditable
The v0 series of get-gke-credentials is end-of-life and now hard-errors. Without use_auth_provider the kubeconfig bakes the static 1-hour access token from auth@v2, so kubectl steps that run past the hour mark (long pytest waits) fail with Unauthorized / "cluster unreachable". Bump all three get-gke-credentials steps to @v2 and add use_auth_provider: true so the kubeconfig uses the gke-gcloud-auth-plugin exec provider and re-mints credentials per call. Also bump the deprecated setup-gcloud steps to @v2. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#3378) * Overwrite e2e-tests with origin/playwright-mdl content * chore: update Playwright configuration * feat: starting to refractor the self contained MDL tests to align with the rests of the POM tests. * feat: Enhance module header interactions and language handling - Improved dropdown interaction by ensuring overlays are dismissed before clicking. - Added special handling for language selection in dropdowns, utilizing URL-based strategies. - Updated utility functions to simplify modal and popup dismissals using a click-if-visible approach. - Refactored language change logic to prioritize cookie setting and URL navigation. - Updated Playwright configuration to allow dynamic base URLs via environment variables for better test flexibility. * refactor: streamline modal handling by consolidating hide functions * refactor: simplify language verification logic in toggleLanguage function * feat: add tests for trending topics functionality in Voices module * feat: add VALID_TOPICS constant and improve module button navigation handling in Voices tests * feat: add cross-module redirect tests for Library to Voices and no-redirect loops in Voices module; update selectors and dependencies * feat: enhance cross-module redirect tests and improve navigation handling; add gotoOrThrow utility for better error handling * feat: implement cross-subdomain cookie handling for improved storage state management * feat: rename browser test configurations for clarity and consistency; update test directories for modularization tests * feat: refactor module URLs to use environment variable for sandbox domain; update tests for consistency across modules * feat: add cross-module login scenarios and improve user menu handling; refactor module URLs to use environment variable * feat: enhance cross-module login tests and update user menu selectors; add new test scripts for browser compatibility * feat: enhance cross-module redirect tests; add response status checks and update module selectors * feat: Fix auth context sharing in goToPageWithUser Add auth cookies to provided context instead of creating separate browser context. This ensures fixture pages inherit authentication state, fixing test isolation issues where tests would fail with language/domain mismatches when run as part of full suite. Backward compatible with existing test patterns. * feat: enhance cross-module login scenarios; add explicit wait for profile picture visibility after login * feat: update profile redirect test to use 'qa-automation' user * feat: update module URLs to support English and Hebrew versions; refactor tests and constants accordingly * feat: implement Help Sheet to Zendesk redirects tests for English and Hebrew versions; add redirect mappings * feat: Create the first of many sanity tests. Added two new pages to thew page objecvt modal for profile page and edit profilepage. * feat: removing console logs on first sanity tests * feat(Sheets Sanity): Created a Sanity test that checks the lifecycle of sheet creation. Fixed old Selectors and moved log out to end. * docs: Add comprehensive documentation for the e2e Sanity Test Suite, detailing core, user flow, sheet workflow, and cross-module redirect tests. * feat: removing old files * feat: add Sanity test 3; Search bar verification and results * feat: path sheet workflow tests to add images and youtube videos and verify it works * refractor: fix wait times and configuration to handle bigger load on tests * refactor: sanity tests - update load state waits to 'domcontentloaded' for improved performance and reliability * feat: remove the temporary go live folder for testing in sanity * feat: moved cross module redirect tests out of misc/ directory back into the main sanity tests as a non temp test * feat: enhance user login checks with debug logging and improved wait states * feat: add TIMEOUT_MULTIPLIER env variable with t() helper for e2e tests * feat: apply TIMEOUT_MULTIPLIER t() wrapper to all page objects * feat: Implement mobile E2E testing infrastructure including constants, documentation, and a hamburger menu sanity test. * feat(e2e): apply TIMEOUT_MULTIPLIER t() wrapper to all spec files Wrap all timeout values and waitForTimeout() calls in spec files with the t() helper function so they respect TIMEOUT_MULTIPLIER. Files updated: - Sanity: cross-module-login, user-flow-sanity, sheet-workflow-sanity, search-sanity, cross-module-redirects - Tests: regression-tests, sheet-editor-resource-panel, sheetEditor, autosave - Voices: trending-topics, header - Library: header - Misc: help-sheet-redirects - Mobile: mobile-hamburger-sanity * docs(e2e): add TIMEOUT_MULTIPLIER documentation to README - Added 'Timeout Multiplier' subsection under Environment Setup - Updated Configuration Reference with accurate timeout values - Included usage examples showing correct t() wrapper pattern * feat: remove old mobile web testing plan and implementation (working on a better ne, needed a fresh start) * feat: rename voices and library folder. Harden goToPageWithLang function. and remove old outdated tests to pave way for new * feat(e2e): add Library Texts Tree Traversal tests for Tanach * docs(e2e): rewrite READM and fix SANITY.md * feat(e2e): implement Library Assistant end-to-end tests and related configurations like POM and new account that has LA enabled * feat(e2e): add negative coverage tests for Library Assistant visibility and enhance page object with expectNotPresent method * feat(e2e): add tests for Library Assistant header menu and responsive behavior * feat(e2e): update Library Assistant tests for running on firefox and safari Co-authored-by: Copilot <copilot@github.com> * refactor(e2e): remove unused browser configurations from Playwright setup ('all') * chore(env): update example.env with comments for clarity on adding a user for Library Assistant * refactor(e2e): streamline search and user flow tests by removing redundant code and enhancing modal handling. Sanity Tests are now reliable and consitent * fix(e2e): harden header new-tab test and modal-dismiss loop against parallel-run flakes, reduces time for dismissing popups * fix(e2e): update footer link URLs for About and Help sections to ensure correct navigation behavior * fix(e2e): replace 'networkidle' with 'domcontentloaded' for improved page load handling in header and navigation tests * fix(e2e): replace 'networkidle' with 'domcontentloaded' for improved page load handling across various tests * fix(e2e): make the header spec tests have more conistency in what they are clicking. Archive trendin topics test * fix(e2e): fix timing issue with modal popup * feat(e2e): add tests for Terms and Privacy Policy links in sidebar footer * fix(e2e): update regex patterns for footer link hrefs to improve matching * feat(e2e-mobile): Add mobile hamburger menu tests and page object implementation part 1. * feat(e2e-mobile): Implement mobile authentication flow tests and enhance mobile hamburger functionality * feat(e2e): Add end-to-end tests for Resource Panel features - Introduce a new page object for the Resource Panel to encapsulate interactions and assertions related to the panel's UI components and behaviors. * feat(e2e): Update header menu test to include 'Settings' item for staff users * rename(e2e): rename mobile folder to mobiel web for clarity * feat(e2e-mobile): Add mobile hamburger menu and authentication flow tests back in under new folder name * feat(e2e): Resource Panel Part 2 — 13 new spec files covering RP-060 → RP-212 (42 tests across Connections List, Text List, Topics, Web Pages, Sheets, Manuscripts, Notes, Add to Sheet, Share, Search in Text, Feedback, Guide, Hebrew UI) Extends the POM with helpers for every new mode and brings the Resource Panel suite from 37 to 79 tests, all passing against real production data with zero skips. * refactor(e2e): move auth to globalSetup; eliminate per-worker login races Replace the per-test "log in lazily and write auth_*.json on first call" pattern with a one-time globalSetup that logs every account in once before any worker starts and writes a read-only storage-state file per profile. Workers only ever read those files thereafter, so the file-write race that caused auth-gated tests to flake on every full-parallel run is now structurally impossible. Also fixes missing awaits in loginAs, a single-cookie clear in expireLogoutCookie, a redundant double-navigation in goToPageWithUser, and removes the BROWSER_SETTINGS.english/.hebrew footguns plus their now-unused helpers. * test(e2e): introduce two-layer overlay suppression and fix sanity-suite flakes Strapi-driven banners (Sustainer modal et al.) are now suppressed at context level via `installOverlaySuppression` — `addInitScript` short-circuits `modal_*`/`banner_*` localStorage reads, `context.route` empties the `/api/strapi/graphql-cache` payload, and a `cookiesNotificationAccepted=1` cookie is pre-seeded; `hideAllModalsAndPopups` is now a slim parallel click-fallback for the remaining non-Strapi overlays. Also: Sanity 7's logout now uses `enAdmin` so it stops invalidating the `enUser` session that sheet-workflow-sanity depends on, Sanity 9e waits for the SPA URL update instead of `domcontentloaded`, RP-190's `hasGuideButton` timeout was bumped from 3s to 15s, 102 redundant `hideAllModalsAndPopups` calls were dropped across 28 spec files, and 6 stale Zendesk slugs in `helpDeskLinksConstants.ts` were refreshed — all six chrome projects now pass 261/261 at full parallelism. * fix(e2e): change playwright mobile config setup to use mobile web folder instead of mobile * refractor(e2e): change playwright.mobile.config to playwright.mobileweb.config for consistency * docs(e2e): enhance README and comments with details on destructive auth tests and session management * feat(e2e): Add end-to-end tests for Voices Topics landing and topic pages - Implement `voices-topics-landing.spec.ts` to test the Trending Topics sidebar on the landing page, ensuring it lists 5–15 topics and each is navigable. - Create `voices-topics.spec.ts` for comprehensive end-to-end tests on individual topic pages, covering content display, language support, sheet interactions, and navigation. - Introduce `voicesTopicPage.ts` as a Page Object Model (POM) for the Voices topic page, encapsulating methods for interacting with the page elements and assertions. * feat(e2e): Enhance user menu interaction for logged-in state and improve locator precision * feat(e2e): Improve Guided Learning button visibility checks and increase timeout for full-parallel load * feat(e2e): Update share URL checks to be case-insensitive for sandbox compatibility * feat(e2e): Remove unused cookieObject and enhance cookie domain handling for cross-subdomain tests * docs(e2e): production rewrite of README handbook + fix stale sub-doc references README.md: rewrite as a humans-first handbook with a front-loaded quick start, a README-vs-CLAUDE doc map, and a utils.ts catalogue. Correct page-object count (20), complete the PageManager accessor list, fix mobile/ -> mobile web/ paths, remove the obsolete chrome-all/firefox-all/safari-all troubleshooting entry, re-point canonical exemplars to resourcePanelPage/voicesTopicPage + the Resource Panel/Voices Topics specs, document fixtures/ and archived-tests/, and switch the TOC to lint-clean auto-generated heading anchors. assistant/README.md: drop the nonexistent ai-chatbot.csv references; correct the coverage from 10 to the real 16 behavioral + 4 LA-NEG tests; refresh the TODO. mobile web/README.md: fix the self-referencing mobile/ paths -> mobile web/. Voices Topics + Resource Panel READMEs: fix the broken mobile/ link and remove references to the .claude/ scratch directory and its test-plan CSVs. * fix(e2e): repair broken package.json playwright test scripts The test:* aliases referenced an old project-naming scheme (chromium / library / voices / misc / webkit-library) that no longer exists in playwright.config.ts. Point them at the real project names (chrome-* / firefox-* / safari-*), drop the unmappable generic browser aliases, and add aliases for the newer suites (sanity, assistant, resource-panel, voices-topics) plus the mobile config. * docs(e2e): rename Sanity/SANITY.md to README.md for folder consistency * docs(e2e): add per-folder READMEs and modernize the Sanity guide Every meaningful subfolder now has an onboarding doc: - pages/README.md — page-object index: canonical models (resourcePanelPage, voicesTopicPage), every pm.onX() accessor, and legacy/orphan markers - library/, voices/, Misc/ — per-folder guides (scope, ID schemes, baseURL) - Full testing by Feature/README.md — index of the deep feature suites - archived-tests/README.md — why specs are archived and how to run them locally Sanity/README.md (renamed from SANITY.md in the prior commit): rewritten into the house style (ID tables, per-spec detail, architecture, gotchas incl. the Sanity 7 -> enAdmin destructive-auth constraint). Root README directory map + Related-docs updated to surface the new docs and the Sanity README rename. * docs(e2e): commit CLAUDE.md handbook for the test suite Un-ignore e2e-tests/CLAUDE.md and add it to the repo so the prescriptive rules for writing tests, extending page objects, and auditing existing code are version-controlled alongside the suite. The global CLAUDE.md ignore rule is preserved with a negation so only the e2e-tests handbook is opted in. * fix(e2e): harden RP-056 lexicon invalid-entry assertion for local runs Scope the assertion to the autocomplete widget's own `.dictionary-toc-autocomplete` class instead of `.connectionsPanel` (so it holds when jQuery UI mounts the dropdown on <body>), and skip the Enter press that could close the dropdown before assertion. * test(e2e): cut artifact overhead and add local retry to stabilize flaky runs Resource Panel tests (RP-053, RP-122, RP-123) intermittently hit the 50s timeout under full parallelism (8 workers): a starved worker stalled on context.newPage()/panel rendering, and the forced teardown left half-written trace files (the ENOENT artifact errors). All three pass in isolation in 5-7s, confirming flake-not-bug. - video: retain-on-failure -> off. retain-on-failure records video for every test then discards on pass; pure overhead and redundant with the trace. - trace: retain-on-failure -> on-first-retry. No artifacts on the happy path; a full trace is still captured when a failed test is retried. - retries (desktop): 0 -> 1 locally so a starvation blip self-heals. CI keeps 2. Mobile config already retried locally; only its video/trace were updated. Full chrome-resource-panel suite: 79 passed, 0 retries, 3.4m -> 1.1m. * feat(e2e): add Hebrew Library Assistant suite + fix MDL auth for logged-in .il The Library Assistant chatbot is now bilingual, so mirror the English LA coverage in Hebrew. Verified every label against the LIVE deployed component (the source i18n catalog differed from prod), and reworked the auth layer to support a logged-in session on the Hebrew (.org.il) domain. * fix(e2e): update user menu interaction to handle React re-renders and ensure dropdown visibility * feat(e2e): add Library Topics test suite (LIB-001 → LIB-029) * feat(e2e): enhance header tests for logged-in users and update user menu items * fix(e2e): improve error handling and messaging for login failures in global setup --------- Co-authored-by: Copilot <copilot@github.com>
* deploy(preprod): app=6.101.2-preprod.2 chart=0.85.10-preprod.1 [skip ci] * deploy(prod): app=6.101.2-prod.1 chart=0.85.8-prod.3 [skip ci] * fix(search): restore default 'path' field for text filters (sc-44603) Hotfix to prod replicating PR #3368. Selecting a path filter on a text search (e.g. filtering "מעל" to Psalms) returned no results and a 500 from /api/search-wrapper. The search page sends text filters with agg_type=None, relying on the documented contract that make_filter() supplies the default field ("path") for that query type. Commit 1252655 ("keyword-search-in-connected-refs") tightened the text branch to `agg_type == "path"`, routing the agg_type=None default into `Term(**{None: agg_key})`, which raises TypeError -> HTTP 500. Fix the root cause in reader/views.py: always pass "path" explicitly for URL-bootstrapped text filters. Keep the None guard in make_filter as a documented defensive fallback (matching `agg_type in (None, "path")`). Frontend: pre-index aggregation bucket counts before building the filter tree so a selected path filter shows its real count instead of "(0)". Adds backend (search_test.py) and e2e (search-filter-sanity.spec.ts) regression tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: disable asset image from caching * fix: make hotfix a valid semantic tag * deploy(prod): app=6.101.2-prod.2 chart=0.85.8-prod.3 [skip ci] * fix: update ddtrace install script * deploy(preprod): app=6.101.2-preprod.3 chart=0.85.10-preprod.1 [skip ci] * deploy(prod): app=6.101.2-prod.3 chart=0.85.8-prod.3 [skip ci] * fix: update DD custom binary * deploy(preprod): app=6.101.14-preprod.1 chart=0.85.12-preprod.1 [skip ci] * deploy(prod): app=6.101.14-prod.1 chart=0.85.12-prod.1 [skip ci] * deploy(preprod): app=6.101.14-preprod.2 chart=0.85.12-preprod.1 [skip ci] * deploy(prod): app=6.101.14-prod.2 chart=0.85.12-prod.1 [skip ci] * fix: shift to use .get() * Normalize linked ref search filters * Extract linked ref filter normalization * Document filter value extraction * Clean up linked ref filter formatting * Test linked ref search filter helpers * Preserve default search filters for linked ref normalization * deploy(prod): app=6.101.14-prod.3 chart=0.85.12-prod.1 [skip ci] --------- Co-authored-by: akiva10b <akiva10b@users.noreply.github.com> Co-authored-by: yodem <yotam@sefaria.org> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Brendan Galloway <brendan@flanksource.com> Co-authored-by: yodem <yodem@users.noreply.github.com> Co-authored-by: Akiva Berger <akiva10b@gmail.com> Co-authored-by: saengel <sarah@sefaria.org> Co-authored-by: yonadavGit <92536571+yonadavGit@users.noreply.github.com> Co-authored-by: nsantacruz <nsantacruz@users.noreply.github.com>
* chore: remove divine name code * chore: remove nosub * chore: fix spelling mistake * chore: should not be contenteditable
* chore: update_many instead of versionset * chore: test_index_name_change_with_nonprimary_version_first * chore: better test
* fix(explore page route and others): The recent Django upgrade broke views switching from urls to re_path. Django 6.0 None-filtering breaks views whose parameters are required positional args but correspond to optional URL groups * fix(explore page route and others): Fix parameter name mismatch for redirect * fix(explore page route and others): Ensure errors are returned with guards if parameters aren't passed through the URLs
* fix(search): restore default 'path' field for text filters (sc-44603)
Selecting a path filter on a text search (e.g. filtering "מעל" to Psalms)
returned no results and a 500 from /api/search-wrapper. The search page
sends text filters with agg_type=None, relying on the documented contract
that make_filter() supplies the default field ("path") for that query type.
Commit 1252655 ("keyword-search-in-connected-refs") tightened the text
branch from `if type == "text":` to `if type == "text" and agg_type == "path":`
so a new non-path text agg_type (linked_refs) could use a Term filter. That
routed the agg_type=None default into `Term(**{None: agg_key})`, which raises
TypeError: keywords must be strings -> HTTP 500, breaking all text path
filters (both URL-applied and clicked).
Honor the None default again by matching `agg_type in (None, "path")`, which
fixes URL-load, in-app click, and the empty-filter_fields fallback, while
preserving the Term path for linked_refs and all sheet filters.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(sc-44545): design spec for login page cross-flow navigation
Spec for making the path to registration discoverable on the login page:
reusable Django include partial, placement under the H1, blue+underlined
link styling, EN/HE copy from the story. Documents why a React migration
was rejected for this story and how the design leaves a seam for SC-44544.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(sc-44545): revise spec — Figma source of truth, Django 6, general vars
- Figma (file 2WflG98PDhWQ7OKrDkaCPb, node 35:425) is source of truth for
layout/styling/CSS + dev-mode notes; story stays authoritative for strings
(they agree). Pulled exact specs from 35:430 and all three annotation notes.
- Corrected link color to --sefaria-blue (#18345D, Figma Semantic/Text/Link),
SemiBold 600, underlined, 4px gap; prompt --darker-grey (#575757). No hex.
- CSS uses general vars from color-palette.css in global static.css (no global
PostCSS; it is CSS-modules-only for the React bundle).
- Django 6.0.4: resolve register URL via {% url ... as %} + {% include with %}.
- Added mobile + Hebrew/RTL coverage to testing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(sc-44545): implementation plan for login cross-flow navigation
5 bite-sized tasks (TDD-adapted for template/CSS): update HAM-A003 E2E
selector, create reusable partial, wire into login.html + remove old link,
add Figma-sourced scoped CSS via general vars, end-to-end visual/behavior
verification (EN/HE/mobile + register regression + next preservation).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(sc-44545): HAM-A003 expects new Sign Up cross-flow link on login
* feat(sc-44545): add reusable cross-flow nav partial for auth pages
* feat(sc-44545): move registration link under login title via partial
* style(sc-44545): scoped .registration-prompt link styling from Figma tokens
* fix(sc-44545): restore re_path in sites/sefaria/urls.py for Django 6
Master's url() (django.conf.urls.url, removed in Django 4.0) breaks URLConf
load on Django 6 -> NameError -> /healthz-rollout 500 -> cauldron web pod
never ready. Folded here so this PR's cauldron image builds clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* style(sc-44545): match Figma login form spacing/sizing (300px, 48px controls, responsive)
* fix(sc-44545): keep .inner top offset so login title clears the header
* fix(sc-44545): scope login layout CSS + tighten cross-flow link gap
- Scope #login layout rules under #login.registrationContent so they
don't leak into other templates that use id="login" (translate_campaign).
- Remove literal space before the cross-flow link so the 4px CSS
margin (RTL-safe) controls the gap, matching Figma.
Addresses Copilot review comments on PR #3370.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore(sc-44545): drop bundled sc-44603 search fix from this branch
The sc-44603 search path-filter fix was unrelated scope flagged in
review. It was already hotfixed to prod via #3380; the master
back-merge is tracked separately. Reverting these two files to master
keeps PR #3370 login-only.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: auto opt-in to Library Assistant after promo-driven auth
Anon users who click the Library Assistant promo CTA were enrolled in
the experiment only after a second 'Join' click post-login. Route the
promo's login/register ?next= through a new /enable-library-assistant
landing view: once auth completes the user lands there, is enrolled in
the experiments whitelist (reusing _set_user_experiments), and is
redirected back to where they were. The assistant then appears on
reload with no extra click.
- New view enable_library_assistant: same-host-validated redirect,
forwards the register welcome flag, bounces anon hits to login.
- Banner anon CTAs now target the opt-in landing via nested ?next=.
- Normal (non-promo) logins are unaffected.
- Tests cover enroll+redirect, anon->login, offsite-next fallback,
welcome forwarding, default, and idempotency.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: drop story ID from login CSS comment
Source files shouldn't carry Shortcut story IDs (branch/commit refs are
enough). Replicated on the login-page branch.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: drop story ID from login CSS comment
Source files shouldn't carry Shortcut story IDs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: guard opt-in against cross-site GET + expand tests
Skip Library Assistant enrollment when the browser reports a cross-site
request (Sec-Fetch-Site), so a cross-site <img> can't silently enroll a
logged-in user; the real same-origin post-login redirect is unaffected.
Add tests for protocol-relative next, welcome appended to an existing
query string, and the cross-site skip; assert no duplicate settings row.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: remove comments
* chore(sc-44545): remove outdated login cross-flow navigation plan and design spec files
* chore: trigger CI for login page anon LA candidate handling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: ensure npm is available in pre-commit hook for GUI git clients
* Revert .husky/pre-commit to master
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* deploy(preprod): app=6.101.2-preprod.2 chart=0.85.10-preprod.1 [skip ci] * deploy(prod): app=6.101.2-prod.1 chart=0.85.8-prod.3 [skip ci] * fix(search): restore default 'path' field for text filters (sc-44603) Hotfix to prod replicating PR #3368. Selecting a path filter on a text search (e.g. filtering "מעל" to Psalms) returned no results and a 500 from /api/search-wrapper. The search page sends text filters with agg_type=None, relying on the documented contract that make_filter() supplies the default field ("path") for that query type. Commit 1252655 ("keyword-search-in-connected-refs") tightened the text branch to `agg_type == "path"`, routing the agg_type=None default into `Term(**{None: agg_key})`, which raises TypeError -> HTTP 500. Fix the root cause in reader/views.py: always pass "path" explicitly for URL-bootstrapped text filters. Keep the None guard in make_filter as a documented defensive fallback (matching `agg_type in (None, "path")`). Frontend: pre-index aggregation bucket counts before building the filter tree so a selected path filter shows its real count instead of "(0)". Adds backend (search_test.py) and e2e (search-filter-sanity.spec.ts) regression tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: disable asset image from caching * fix: make hotfix a valid semantic tag * deploy(prod): app=6.101.2-prod.2 chart=0.85.8-prod.3 [skip ci] * fix: update ddtrace install script * deploy(preprod): app=6.101.2-preprod.3 chart=0.85.10-preprod.1 [skip ci] * deploy(prod): app=6.101.2-prod.3 chart=0.85.8-prod.3 [skip ci] * fix: update DD custom binary * deploy(preprod): app=6.101.14-preprod.1 chart=0.85.12-preprod.1 [skip ci] * deploy(prod): app=6.101.14-prod.1 chart=0.85.12-prod.1 [skip ci] * deploy(preprod): app=6.101.14-preprod.2 chart=0.85.12-preprod.1 [skip ci] * deploy(prod): app=6.101.14-prod.2 chart=0.85.12-prod.1 [skip ci] * fix: shift to use .get() * Normalize linked ref search filters * Extract linked ref filter normalization * Document filter value extraction * Clean up linked ref filter formatting * Test linked ref search filter helpers * Preserve default search filters for linked ref normalization * deploy(prod): app=6.101.14-prod.3 chart=0.85.12-prod.1 [skip ci] * deploy(preprod): app=6.101.14-preprod.3 chart=0.85.12-preprod.2 [skip ci] --------- Co-authored-by: akiva10b <akiva10b@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Brendan Galloway <brendan@flanksource.com> Co-authored-by: yodem <yodem@users.noreply.github.com> Co-authored-by: Akiva Berger <akiva10b@gmail.com> Co-authored-by: saengel <sarah@sefaria.org> Co-authored-by: yonadavGit <92536571+yonadavGit@users.noreply.github.com> Co-authored-by: Noah Santacruz <noahssantacruz@gmail.com> Co-authored-by: nsantacruz <nsantacruz@users.noreply.github.com>
Promote to preprod — 2026-06-25 14:16 UTC
yodem
added a commit
that referenced
this pull request
Jun 30, 2026
Root cause of the 'app=unknown, chart=unknown' rollback reference (e.g. PR #3447): version extraction used 'python3 -c "..."' double-quoted inside $(...), so bash collapsed the quote class within the program text and Python raised 'SyntaxError: closing parenthesis ]' — swallowed by 2>&1 and turned into 'unknown'. Both fields failed identically, hence both showed unknown. Changes in this commit: - Rewrite extraction via a single-quoted heredoc (no bash substitution on the regex), passing the YAML through an env var. Verified against the prod helmrelease as it was when #3447 was generated: now yields app=v6.101.14-prod.3, chart=0.85.12-prod.1. - Fetch promotion refs with explicit forced refspecs so origin/<target> is reliably the true remote tip for both changelog and rollback lookup (hardening). - Randomize the GITHUB_OUTPUT heredoc delimiter for ai_summary so a model summary containing a bare 'EOF' line can't inject extra output keys. - Resolve the 'already exists' PR URL by SOURCE->TARGET pair via 'gh pr list' (with jq '// empty') instead of a bare 'gh pr view' that returned the wrong PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 30, 2026
yodem
added a commit
that referenced
this pull request
Jun 30, 2026
Root cause of the 'app=unknown, chart=unknown' rollback reference (e.g. PR #3447): version extraction used 'python3 -c "..."' double-quoted inside $(...), so bash collapsed the quote class within the program text and Python raised 'SyntaxError: closing parenthesis ]' — swallowed by 2>&1 and turned into 'unknown'. Both fields failed identically, hence both showed unknown. Changes in this commit: - Rewrite extraction via a single-quoted heredoc (no bash substitution on the regex), passing the YAML through an env var. Verified against the prod helmrelease as it was when #3447 was generated: now yields app=v6.101.14-prod.3, chart=0.85.12-prod.1. - Fetch promotion refs with explicit forced refspecs so origin/<target> is reliably the true remote tip for both changelog and rollback lookup (hardening). - Randomize the GITHUB_OUTPUT heredoc delimiter for ai_summary so a model summary containing a bare 'EOF' line can't inject extra output keys. - Resolve the 'already exists' PR URL by SOURCE->TARGET pair via 'gh pr list' (with jq '// empty') instead of a bare 'gh pr view' that returned the wrong PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
yodem
added a commit
that referenced
this pull request
Jun 30, 2026
…Rs (#3463) Auto-generated promotion PRs render the Rollback Reference as 'app=unknown, chart=unknown' (e.g. #3447, #3461). Root cause: the version extraction used 'python3 -c "..."' double-quoted inside $(...), so bash collapsed the [\"\''] quote class to ["\''] within the program text and Python raised 'SyntaxError: closing parenthesis ]' — swallowed by 2>&1 and turned into 'unknown'. Both fields failed identically, hence both unknown. Rewrite extraction via a single-quoted heredoc (no bash substitution on the regex), passing the YAML through an env var. Verified against the prod helmrelease live when #3447 was generated: now yields the real app=v6.101.14-prod.3, chart=0.85.12-prod.1. Hardening folded in: - Fetch refs with explicit forced refspecs so origin/<target> is reliably the true remote tip for both changelog and rollback lookup. - Randomize the GITHUB_OUTPUT heredoc delimiter for ai_summary so a model summary containing a bare 'EOF' line can't inject extra output keys. - Resolve the 'already exists' PR URL by SOURCE->TARGET via 'gh pr list' (jq '// empty') instead of a bare 'gh pr view' that returned the wrong PR. Co-authored-by: Claude Opus 4.8 (1M context) <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.
Promote
preprod→prodRollback Reference
produnknown, chart=unknownChanges
Auto-generated by Manual Promotion workflow