Files
NeuroSploit/web/public/vendor/xterm-addon-fit.js
T
CyberSecurityUPandClaude Opus 5 0ef0ce8d94 feat(web): xterm.js terminal dock + front-end QA pass
Replaces the floating REPL drawer with a docked terminal, and fixes the
usability problems a screenshot audit of the console turned up.

Terminal (the reason for the change):

- The drawer rendered the harness into a <div>, so the server had to strip
  ANSI before sending it: colour, the box-drawn /status panel and the banner
  all arrived flattened, and long lines rewrapped mid-glyph. The stream is now
  sent verbatim and rendered by xterm.js (vendored, nothing fetched at
  runtime), decoded with a streaming UTF-8 decoder so a multi-byte character
  split across two reads survives.
- The drawer floated bottom-right, directly over "Next →" and "Start
  Exploitation" — the wizard's primary buttons. The dock is a flex child of
  .main, so opening it shortens the view instead of covering it. Drag its top
  edge to resize; the height is remembered.
- The child is spawned over a pipe, not a PTY, so it never echoes: line
  editing is local — echo, ←/→, Home/End, history, Tab completion over the
  slash commands, Ctrl+C/L/U/K/A/E. Ctrl-C is delivered as SIGINT by the
  server, since a raw 0x03 byte over a pipe interrupts nothing.
- A target picker switches the terminal between a standalone REPL session and
  the engagement currently running, so mid-run instructions go to the same
  process doing the testing.

QA fixes:

- Findings tables sorted by severity (a LOW above a CRITICAL made a 27-row
  result unreadable), with sortable headers, a severity summary that doubles
  as a filter, a text filter, a sticky header, and horizontal scroll confined
  to the table instead of the whole page.
- alert()/prompt() replaced by inline field errors, a custom-lead modal and
  toasts — a modal alert hid the very field it was complaining about.
- Lead categories start collapsed (412 leads over ~30 categories); search
  auto-expands what it matches and shows per-category hit counts.
- Sidebar rows truncate inside the rail (a long target URL used to spill past
  its border), and carry a worst-severity dot, finding count and age.
- Past-run header shows when it ran, how many agents ran, the recon asset,
  PoC count and run id — two runs of one target were indistinguishable.
- Off-canvas sidebar below 768px had no way to be opened; added the toggle.
- Long evidence values (cookies, tokens) now wrap instead of running under
  the finding modal's edge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvdGy9XtVWSdXDTa3FFLJv
2026-09-07 13:33:16 -03:00

2 lines
1.5 KiB
JavaScript

!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(self,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core,t=e._renderService.dimensions;if(0===t.css.cell.width||0===t.css.cell.height)return;const r=0===this._terminal.options.scrollback?0:e.viewport.scrollBarWidth,i=window.getComputedStyle(this._terminal.element.parentElement),o=parseInt(i.getPropertyValue("height")),s=Math.max(0,parseInt(i.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),l=o-(parseInt(n.getPropertyValue("padding-top"))+parseInt(n.getPropertyValue("padding-bottom"))),a=s-(parseInt(n.getPropertyValue("padding-right"))+parseInt(n.getPropertyValue("padding-left")))-r;return{cols:Math.max(2,Math.floor(a/t.css.cell.width)),rows:Math.max(1,Math.floor(l/t.css.cell.height))}}}})(),e})()));
//# sourceMappingURL=addon-fit.js.map