Skip to content

Commit 310c244

Browse files
authored
Merge of #706
2 parents 512d2da + bca8df7 commit 310c244

214 files changed

Lines changed: 1661 additions & 2897 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
File renamed without changes.

.cursor/rules/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Managed by Tessl
2+
tessl__*.mdc

.reek.yml

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,11 @@
11
# Auto generated by Reeks --todo flag
22
---
33
detectors:
4-
BooleanParameter:
5-
exclude:
6-
- Railsboot::Accordion::ItemComponent#initialize
7-
- Railsboot::AccordionComponent#initialize
8-
- Railsboot::AlertComponent#initialize
9-
- Railsboot::BadgeComponent#initialize
10-
- Railsboot::Breadcrumb::ItemComponent#initialize
11-
- Railsboot::ButtonComponent#initialize
12-
- Railsboot::Carousel::ItemComponent#initialize
13-
- Railsboot::CloseButtonComponent#initialize
14-
- Railsboot::ContainerComponent#initialize
15-
- Railsboot::Dropdown::LinkComponent#initialize
16-
- Railsboot::FormField::ValidationComponent#initialize
17-
- Railsboot::FormFieldComponent#initialize
18-
- Railsboot::ListGroup::ItemComponent#initialize
19-
- Railsboot::ListGroupComponent#initialize
20-
- Railsboot::ModalComponent#initialize
21-
- Railsboot::Nav::ItemComponent#initialize
22-
- Railsboot::Stepper::ItemComponent#initialize
234
ControlParameter:
245
exclude:
256
- BootstrapIconHelper#boolean_icon
267
DuplicateMethodCall:
278
exclude:
28-
- Railsboot::ContainerComponent#initialize
29-
- Railsboot::HeadingComponent#initialize
309
- AdminController#create_user
3110
- AgentsController#create
3211
- AgentsController#update
@@ -70,7 +49,6 @@ detectors:
7049
- InitSchema#up
7150
FeatureEnvy:
7251
exclude:
73-
- Railsboot::Component#fetch_or_raise
7452
- ViewComponentHelper#component_class_for
7553
- Attack#percentage_complete
7654
- HashList#uncracked_list_checksum
@@ -109,76 +87,6 @@ detectors:
10987
- ApplicationViewComponentPreview
11088
- NavbarDropdownComponent
11189
- ProgressBarComponent
112-
- Railsboot::Accordion::ItemComponent
113-
- Railsboot::AccordionComponent
114-
- Railsboot::AlertComponent
115-
- Railsboot::BadgeComponent
116-
- Railsboot::BaseComponent
117-
- Railsboot::BlankSlateComponent
118-
- Railsboot::Breadcrumb::ItemComponent
119-
- Railsboot::BreadcrumbComponent
120-
- Railsboot::Button::ButtonComponent
121-
- Railsboot::Button::InputComponent
122-
- Railsboot::Button::LinkComponent
123-
- Railsboot::ButtonComponent
124-
- Railsboot::ButtonGroupComponent
125-
- Railsboot::Card::BodyComponent
126-
- Railsboot::Card::FooterComponent
127-
- Railsboot::Card::HeaderComponent
128-
- Railsboot::CardComponent
129-
- Railsboot::Carousel::ItemComponent
130-
- Railsboot::CarouselComponent
131-
- Railsboot::CloseButtonComponent
132-
- Railsboot::ContainerComponent
133-
- Railsboot::Dropdown::ActionComponent
134-
- Railsboot::Dropdown::DividerComponent
135-
- Railsboot::Dropdown::HeaderComponent
136-
- Railsboot::Dropdown::LinkComponent
137-
- Railsboot::DropdownComponent
138-
- Railsboot::ErrorsComponent
139-
- Railsboot::FlashComponent
140-
- Railsboot::FormField::CaptionComponent
141-
- Railsboot::FormField::ColorFieldComponent
142-
- Railsboot::FormField::DateFieldComponent
143-
- Railsboot::FormField::EmailFieldComponent
144-
- Railsboot::FormField::LabelComponent
145-
- Railsboot::FormField::PasswordFieldComponent
146-
- Railsboot::FormField::PhoneFieldComponent
147-
- Railsboot::FormField::SelectComponent
148-
- Railsboot::FormField::TextAreaComponent
149-
- Railsboot::FormField::TextFieldComponent
150-
- Railsboot::FormField::ValidationComponent
151-
- Railsboot::FormFieldComponent
152-
- Railsboot::HeaderComponent
153-
- Railsboot::HeadingComponent
154-
- Railsboot::ListGroup::ItemComponent
155-
- Railsboot::ListGroupComponent
156-
- Railsboot::Modal::BodyComponent
157-
- Railsboot::Modal::FooterComponent
158-
- Railsboot::Modal::HeaderComponent
159-
- Railsboot::ModalComponent
160-
- Railsboot::Nav::ItemComponent
161-
- Railsboot::NavComponent
162-
- Railsboot::Navbar::BrandComponent
163-
- Railsboot::Navbar::NavComponent
164-
- Railsboot::Navbar::TogglerComponent
165-
- Railsboot::NavbarComponent
166-
- Railsboot::Offcanvas::BodyComponent
167-
- Railsboot::Offcanvas::HeaderComponent
168-
- Railsboot::OffcanvasComponent
169-
- Railsboot::PaginationComponent
170-
- Railsboot::ProgressComponent
171-
- Railsboot::SpinnerComponent
172-
- Railsboot::Stepper::ItemComponent
173-
- Railsboot::StepperComponent
174-
- Railsboot::Table::BodyComponent
175-
- Railsboot::Table::CellComponent
176-
- Railsboot::Table::HeadComponent
177-
- Railsboot::Table::RowComponent
178-
- Railsboot::TableComponent
179-
- Railsboot::Toast::BodyComponent
180-
- Railsboot::Toast::HeaderComponent
181-
- Railsboot::ToastComponent
18290
- StatusPillComponent
18391
- Admin::AgentsController
18492
- Admin::ApplicationController
@@ -247,7 +155,6 @@ detectors:
247155
- AttackResource
248156
- HashcatBenchmark
249157
- HashcatStatus
250-
- Railsboot::HeadingComponentTest
251158
- ChangeWordListsSensitiveNullConstraint
252159
- ChangeWordListsProcessedNullConstraint
253160
- ChangeRuleListsSensitiveNullConstraint
@@ -322,12 +229,6 @@ detectors:
322229
- AddCascadeToCampaignHashLists
323230
- AddCascadeFromCampaignToProjects
324231
- AddCascadeFromAttackToCampaign
325-
LongParameterList:
326-
exclude:
327-
- Railsboot::ButtonComponent#initialize
328-
- Railsboot::FormField::SelectComponent#initialize
329-
- Railsboot::Nav::ItemComponent#initialize
330-
- Railsboot::ProgressComponent#initialize
331232
NestedIterators:
332233
exclude:
333234
- Api::V1::Client::TasksController#submit_crack
@@ -364,23 +265,13 @@ detectors:
364265
- Api::V1::Client::TasksController
365266
- ApplicationController
366267
- Attack
367-
TooManyConstants:
368-
exclude:
369-
- Railsboot::ButtonComponent
370268
TooManyInstanceVariables:
371269
exclude:
372-
- Railsboot::ButtonComponent
373-
- Railsboot::Dropdown::LinkComponent
374-
- Railsboot::FormField::SelectComponent
375-
- Railsboot::ListGroup::ItemComponent
376-
- Railsboot::Nav::ItemComponent
377-
- Railsboot::ProgressComponent
378270
- Api::V1::Client::CrackersController
379271
- AttacksController
380272
TooManyStatements:
381273
exclude:
382274
- initialize
383-
- Railsboot::Navbar::TogglerComponent#before_render
384275
- StatusPillComponent#status_class
385276
- StatusPillComponent#status_icon
386277
- Admin::ApplicationController#not_authorized
@@ -461,7 +352,6 @@ detectors:
461352
- HabtmProjectsMaskLists#change
462353
UtilityFunction:
463354
exclude:
464-
- Railsboot::Component#fetch_or_fallback
465355
- AgentDashboard#display_resource
466356
- AttackDashboard#display_resource
467357
- CampaignDashboard#display_resource

AGENTS.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
This file provides guidance to Agents when working with code in this repository.
44

5+
@GOTCHAS.md
6+
57
> **See also:** [GOTCHAS.md](GOTCHAS.md) — edge cases, hard-won lessons, and "watch out for" patterns organized by domain. Read the relevant section before working in that area.
68
9+
@DESIGN.md
10+
711
## Project Overview
812

913
CipherSwarm is a distributed hash cracking system built on Rails 8.1+ inspired by Hashtopolis. It manages hash-cracking tasks across multiple agents using a web-based interface with real-time capabilities via Hotwire.
@@ -159,6 +163,15 @@ just assets-build
159163
just assets-watch
160164
```
161165

166+
### Catppuccin Macchiato Theme
167+
168+
- `_catppuccin.scss` defines the full palette + Bootstrap variable overrides — imported BEFORE `@import "bootstrap"`
169+
- Primary accent: `$ctp-violet: #a855f7` (DarkViolet lightened), not Catppuccin's Mauve
170+
- Surface hierarchy: Crust (navbar) → Mantle (sidebar) → Base (body) → Surface0 (cards/inputs)
171+
- `application.bootstrap.scss` adds component-level dark theme overrides (cards, tables, dropdowns, inputs, Tom Select)
172+
- Self-hosted fonts via `@fontsource`: Space Grotesk (headings), IBM Plex Sans (body), JetBrains Mono (code) — air-gap safe
173+
- Font woff2 files copied to `app/assets/builds/` by `build:css:fonts` script in package.json
174+
162175
### API Documentation
163176

164177
```bash
@@ -284,7 +297,7 @@ Business logic is extracted into service objects and models:
284297
- All paginated views must use `<%== @pagy.series_nav(:bootstrap) %>` with a `<noscript><%== @pagy.series_nav %></noscript>` fallback
285298
- Some views use a local `pagy` variable (from partials) instead of `@pagy` — same API applies
286299
- Guard both `series_nav` and `<noscript>` inside `if pagy.pages > 1` (see `campaigns/_error_log.html.erb` for reference)
287-
- `Railsboot::PaginationComponent` wraps `series_nav(:bootstrap)` with noscript fallback for reuse in view components
300+
- Pagination uses inline `series_nav(:bootstrap)` calls directly in views (no wrapper component)
288301

289302
### Caching & Real-Time Backend
290303

@@ -490,6 +503,20 @@ From .cursor/rules/core-principals.mdc and rails.mdc:
490503

491504
### Common Patterns
492505

506+
**Layout Grid (Logged-In vs Logged-Out):**
507+
508+
- Main content column is conditional: `col-md-10` when sidebar present (logged in), `col-12` when not
509+
- Sidebar uses `d-none d-md-block` (hidden on mobile) + Bootstrap offcanvas (`#sidebarOffcanvas`) for mobile navigation
510+
- Mobile offcanvas includes sidebar nav AND navbar items (Tools, Account) via `_sidebar_navbar_items.html.erb`
511+
- Flash messages rendered inline in layout: `notice``alert-success`, `alert``alert-danger`, `info``alert-info`
512+
- Skip link (`visually-hidden-focusable`) is first child of `<body>`, targets `id="main-content"` on `<main>`
513+
514+
**Toast Notifications:**
515+
516+
- Error/danger toasts persist (no auto-hide) — users must manually dismiss via close button
517+
- Success/warning/info toasts auto-dismiss after 5 seconds
518+
- `ToastNotificationComponent#autohide?` returns `false` for `danger` variant
519+
493520
**Nested Resources:**
494521

495522
- Attacks are nested under Campaigns: `/campaigns/:campaign_id/attacks`
@@ -544,6 +571,12 @@ From .cursor/rules/core-principals.mdc and rails.mdc:
544571

545572
> **More pattern gotchas** (CanCanCan nesting, nullable params, Redis locks, logging, upsert_all, FK cascades, transactions) — see [GOTCHAS.md § Database & ActiveRecord](GOTCHAS.md#database--activerecord) and [GOTCHAS.md § Infrastructure](GOTCHAS.md#infrastructure)
546573
574+
**Railsboot Component Removal (Complete):**
575+
576+
- Railsboot components (`app/components/railsboot/`) have been fully removed
577+
- All views now use plain ERB + Bootstrap utility classes directly
578+
- Bootstrap JS dependencies: dropdowns, offcanvas, toasts (via Stimulus), modals, collapse
579+
547580
### Development Workflow
548581

549582
1. Use `just dev` to start the development server (Rails + assets + Sidekiq)
@@ -630,3 +663,7 @@ TEST_DATABASE_URL=postgres://root:password@localhost:5432/cipher_swarm_test bund
630663
- Logging Guide: docs/development/logging-guide.md
631664
- API Documentation: /api-docs (when server running)
632665
- Justfile Documentation: .kiro/steering/justfile.md
666+
667+
## Agent Rules <!-- tessl-managed -->
668+
669+
@.tessl/RULES.md follow the [instructions](.tessl/RULES.md)

DESIGN.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Design Context
2+
3+
## Users
4+
5+
CipherSwarm serves red team operators, blue team analysts, infrastructure administrators, and project managers working in trusted LAN environments. They manage distributed hash-cracking campaigns across multiple agents. The primary job: orchestrate attacks, monitor progress in real time, and review results — often across long-running operations where checking in periodically matters more than constant attention.
6+
7+
### Brand Personality
8+
9+
**Technical, clean, efficient.** The interface should evoke **control and confidence** — operators should feel they know exactly what's happening at all times. Not flashy, not playful. An engineering tool that respects the user's expertise and gets out of the way.
10+
11+
### Aesthetic Direction
12+
13+
- **Theme**: Catppuccin Macchiato dark palette with DarkViolet accents (planned in v2-upgrade-overview.md)
14+
- **References**: Linear/Vercel (clean, minimal, fast developer tool aesthetic) + Grafana/Datadog (dense dashboards, real-time metrics, data-forward)
15+
- **Anti-references**: Generic Bootstrap apps, AI-generated "dashboard" aesthetics (gradient text, glassmorphism, hero metrics), overly playful or consumer-oriented SaaS
16+
- **Mode**: Dark-first (Catppuccin Macchiato). Light mode is a future consideration, not a priority.
17+
18+
### Design Principles
19+
20+
1. **Information density over decoration** — Show data, not chrome. Every pixel should earn its place. Dense is fine if it's scannable.
21+
2. **Hierarchy through typography, not ornamentation** — Use weight, size, and spacing to create hierarchy. Avoid borders, shadows, and containers when whitespace will do.
22+
3. **Status at a glance** — Campaign/task/agent state must be immediately readable. Color-coded status indicators are a core design element, not an afterthought.
23+
4. **Motion for feedback, not flair** — Animate state changes and loading. No decorative animations. Respect `prefers-reduced-motion`.
24+
5. **WCAG 2.1 AA compliance** — Accessibility is a hard requirement, not a goal. Skip links, proper ARIA, 4.5:1 contrast ratios, keyboard navigation.

GOTCHAS.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ Hard-won lessons, edge cases, and "watch out for" patterns. Organized by domain.
44

55
Referenced from [AGENTS.md](AGENTS.md) — read the relevant section before working in that area.
66

7+
## Frontend & Accessibility
8+
9+
- **Navbar dropdowns must use `<button>` not `<a href="#">`** — both `_navbar.html.erb` and `NavbarDropdownComponent` had `<a href="#" role="button">` which causes scroll-to-top and is semantically wrong. Always use `<button type="button" class="nav-link dropdown-toggle">`.
10+
- **Use Bootstrap z-index utilities (`z-1` through `z-3`)** instead of inline `style="z-index: ..."` — keeps values in sync with Bootstrap's layering system.
11+
- **Sidebar `<ul>` needs `aria-label="Main navigation"`** — the `<aside>` provides the landmark but doesn't describe the navigation purpose.
12+
- **Turbo morph preserves old DOM across navigations**`data-turbo-permanent` on navbar collapse kept stale elements alive even after the template changed. When debugging layout changes, use cache-busting URLs (`?_=timestamp`) or `Turbo.visit(url, {action: "replace"})` to force a full re-render.
13+
- **Railsboot components fully removed** — all views now use plain ERB + Bootstrap classes. The Railsboot component layer was an abstraction that made customization harder (e.g., auto-rendering child components). When adding new UI, use Bootstrap HTML directly.
14+
- **Propshaft caches asset digests in-memory** — after `bun run build:css` or `just assets-build`, Propshaft continues serving the old fingerprinted CSS until the Rails server restarts. Use `touch tmp/restart.txt` to trigger Puma reload. Hard-refreshing the browser is NOT sufficient.
15+
- **`rails assets:clobber` deletes ALL build artifacts** — removes JS, CSS, and font files from `app/assets/builds/`. Must run `just assets-build` (full rebuild) to recover, not just `bun run build:css`.
16+
717
## State Machines
818

919
**Agent States:**

V2 Operational Excellence/tickets/Agent_Monitoring_&_Real-Time_Updates.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Implement comprehensive agent monitoring with real-time status updates, performa
9393

9494
- [x] `AgentStatusCardComponent` created with status badge, hash rate, error count
9595
- [ ] `AgentDetailTabsComponent` created with slot rendering for tabs
96-
- [ ] Components follow existing Railsboot patterns
96+
- [ ] Components use plain Bootstrap HTML and utility classes (Railsboot abstraction layer has been removed)
9797
- [ ] Components tested with component specs
9898

9999
### Testing
@@ -161,6 +161,16 @@ Broadcast partials run in background jobs without access to `current_user`, sess
161161
- Test Turbo Stream broadcasts don't interfere with Stimulus controller
162162
- Ensure broadcasts work in air-gapped environment (no external dependencies)
163163

164+
**Component Development Guidelines:**
165+
166+
The Railsboot component abstraction layer has been fully removed from the codebase. All new components should follow this pattern:
167+
168+
- Use plain ERB templates
169+
- Render direct Bootstrap classes and HTML structure
170+
- Use ViewComponent for reusable components, but render plain Bootstrap markup
171+
- Refer to [AGENTS.md](AGENTS.md) for frontend development patterns and layout guidelines
172+
- Refer to [GOTCHAS.md](GOTCHAS.md) for accessibility considerations and common pitfalls when building real-time UI updates
173+
164174
## Estimated Effort
165175

166176
**2-3 days** (views + components + Turbo Streams + tests)

0 commit comments

Comments
 (0)