← back to ddgonzal3__rally

Function bodies 465 total

All specs Real LLM only Function bodies
ShipTerminalView function · typescript · L340-L489 (150 LOC)
src/components/ShipStatusPill.tsx
function ShipTerminalView({
  session,
  visible,
}: {
  session: NonNullable<ReturnType<typeof useWorkspaceStore.getState>["shipSession"]> & { ptyId: string };
  visible: boolean;
}) {
  const containerRef = useRef<HTMLDivElement>(null);
  const termRef = useRef<XTerminal | null>(null);
  const [termHeight, setTermHeight] = useState(420);

  // The xterm stays alive for the entire session, processing output
  // incrementally from the store buffer — even when the overlay is
  // collapsed (offscreen). Key design decisions:
  //
  // 1. Raw bytes only: the store buffers raw PTY bytes. We write them
  //    directly to xterm — no TextDecoder/TextEncoder round-trip, which
  //    corrupts multi-byte UTF-8 chars split across read boundaries.
  //
  // 2. Cols locked at 80: matches the PTY spawn width. Rows are fitted
  //    to the container and the PTY is resized to match, so both stay
  //    in sync (prevents cursor positioning garble).
  //
  // 3. Incremental processing: chunks are p
clamp function · typescript · L14-L16 (3 LOC)
src/components/Sidebar.tsx
function clamp(value: number, min: number, max: number): number {
  return Math.max(min, Math.min(max, value));
}
autoScrollWorkspaceList function · typescript · L18-L34 (17 LOC)
src/components/Sidebar.tsx
function autoScrollWorkspaceList(listEl: HTMLElement | null, pointerY: number) {
  if (!listEl) return;
  const rect = listEl.getBoundingClientRect();
  if (pointerY < rect.top + WORKSPACE_DRAG_SCROLL_EDGE) {
    const strength =
      (rect.top + WORKSPACE_DRAG_SCROLL_EDGE - pointerY) /
      WORKSPACE_DRAG_SCROLL_EDGE;
    listEl.scrollTop -= Math.ceil(strength * WORKSPACE_DRAG_MAX_SCROLL_STEP);
    return;
  }
  if (pointerY > rect.bottom - WORKSPACE_DRAG_SCROLL_EDGE) {
    const strength =
      (pointerY - (rect.bottom - WORKSPACE_DRAG_SCROLL_EDGE)) /
      WORKSPACE_DRAG_SCROLL_EDGE;
    listEl.scrollTop += Math.ceil(strength * WORKSPACE_DRAG_MAX_SCROLL_STEP);
  }
}
computeInsertIndex function · typescript · L36-L54 (19 LOC)
src/components/Sidebar.tsx
function computeInsertIndex(
  orderedIds: string[],
  draggedId: string,
  itemRefs: Map<string, HTMLDivElement>,
  pointerY: number,
): number {
  if (orderedIds.length <= 1) return 0;
  let insertionIndex = 0;
  for (const id of orderedIds) {
    if (id === draggedId) continue;
    const el = itemRefs.get(id);
    if (!el) continue;
    const rect = el.getBoundingClientRect();
    if (pointerY > rect.top + rect.height / 2) {
      insertionIndex++;
    }
  }
  return clamp(insertionIndex, 0, orderedIds.length - 1);
}
Sidebar function · typescript · L56-L369 (314 LOC)
src/components/Sidebar.tsx
export function Sidebar() {
  const workspaces = useWorkspaceStore((s) => s.workspaces);
  const activeWorkspaceId = useWorkspaceStore((s) => s.activeWorkspaceId);
  const setActive = useWorkspaceStore((s) => s.setActive);
  const removeWorkspace = useWorkspaceStore((s) => s.removeWorkspace);
  const renameWorkspace = useWorkspaceStore((s) => s.renameWorkspace);
  const reorderWorkspace = useWorkspaceStore((s) => s.reorderWorkspace);
  const [showAddModal, setShowAddModal] = useState(false);
  const [renamingId, setRenamingId] = useState<string | null>(null);
  const [renameValue, setRenameValue] = useState("");
  const [draggingId, setDraggingId] = useState<string | null>(null);
  const [dragToIndex, setDragToIndex] = useState<number | null>(null);
  const [dragOffsetY, setDragOffsetY] = useState(0);
  const [dragItemHeight, setDragItemHeight] = useState(0);
  const renameInputRef = useRef<HTMLInputElement>(null);
  const listRef = useRef<HTMLDivElement>(null);
  const itemRefs = useR
SyncConfirmModal function · typescript · L13-L162 (150 LOC)
src/components/SyncConfirmModal.tsx
export function SyncConfirmModal({
  open,
  onClose,
  onConfirm,
  branch,
  mainBranch,
  behind,
  anchorRef,
}: SyncConfirmModalProps) {
  const [running, setRunning] = useState(false);
  const [visible, setVisible] = useState(false);
  const [cardPos, setCardPos] = useState<{ top: number; right: number } | null>(null);
  const backdropRef = useRef<HTMLDivElement>(null);

  // Animate in + compute anchor position
  useEffect(() => {
    if (open) {
      setRunning(false);
      requestAnimationFrame(() => {
        if (anchorRef?.current && backdropRef.current) {
          const btnRect = anchorRef.current.getBoundingClientRect();
          const bgRect = backdropRef.current.getBoundingClientRect();
          const zoom = parseFloat(localStorage.getItem("rally:zoomLevel") || "1");
          setCardPos({
            top: (btnRect.bottom - bgRect.top + 6) / zoom,
            right: (bgRect.right - btnRect.right) / zoom,
          });
        } else {
          setCardPos(null);
   
shortenPath function · typescript · L10-L12 (3 LOC)
src/components/TerminalLauncher.tsx
function shortenPath(p: string): string {
  return p.replace(/^\/Users\/[^/]+/, "~");
}
All rows scored by the Repobility analyzer (https://repobility.com)
folderName function · typescript · L14-L16 (3 LOC)
src/components/TerminalLauncher.tsx
function folderName(p: string): string {
  return p.split("/").pop() || p;
}
handleClick function · typescript · L29-L33 (5 LOC)
src/components/TerminalLauncher.tsx
    function handleClick(e: MouseEvent) {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
parseLatestOsc7Cwd function · typescript · L45-L58 (14 LOC)
src/components/Terminal.tsx
function parseLatestOsc7Cwd(text: string): string | null {
  OSC7_REGEX.lastIndex = 0;
  let match: RegExpExecArray | null = null;
  let latestPath: string | null = null;
  while ((match = OSC7_REGEX.exec(text)) !== null) {
    latestPath = match[1];
  }
  if (!latestPath) return null;
  try {
    return decodeURIComponent(latestPath);
  } catch {
    return latestPath;
  }
}
normalizeTerminalTitle function · typescript · L60-L62 (3 LOC)
src/components/Terminal.tsx
function normalizeTerminalTitle(title: string | null | undefined): string {
  return (title ?? "").trim();
}
isClaudeCodeTitle function · typescript · L64-L67 (4 LOC)
src/components/Terminal.tsx
function isClaudeCodeTitle(title: string): boolean {
  const lower = title.toLowerCase();
  return lower === "claude" || lower.startsWith("claude ");
}
getStoredZoomLevel function · typescript · L79-L83 (5 LOC)
src/components/Terminal.tsx
function getStoredZoomLevel(): number {
  const saved = localStorage.getItem("rally:zoomLevel");
  const zoom = saved ? Number(saved) : 1;
  return Number.isFinite(zoom) && zoom > 0 ? zoom : 1;
}
zoomProposeDimensions function · typescript · L93-L96 (4 LOC)
src/components/Terminal.tsx
function zoomProposeDimensions(
  term: XTerminal,
  zoom: number,
): { cols: number; rows: number } | null {
safeFit function · typescript · L136-L168 (33 LOC)
src/components/Terminal.tsx
function safeFit(term: XTerminal, fitAddon: FitAddon, zoom = 1): boolean {
  // Always use our custom dimension calculator so scrollbar width is
  // consistent (8px from CSS). FitAddon assumes 15px native scrollbar.
  const dims = zoomProposeDimensions(term, zoom)
    ?? (zoom === 1 ? fitAddon.proposeDimensions() : null);
  if (!dims) return false;
  if (!Number.isFinite(dims.cols) || !Number.isFinite(dims.rows)) return false;
  const cols = Math.round(dims.cols);
  const rows = Math.round(dims.rows);
  if (cols < MIN_COLS || rows < MIN_ROWS) return false;
  if (cols === term.cols && rows === term.rows) return false;

  const buf = term.buffer.active;
  const distFromBottom = buf.baseY - buf.viewportY;
  const wasAtBottom = distFromBottom <= 1;

  term.resize(cols, rows);

  const newBuf = term.buffer.active;
  if (wasAtBottom) {
    // User was at the bottom — keep them there
    if (newBuf.viewportY !== newBuf.baseY) {
      term.scrollToBottom();
    }
  } else {
    // User had sc
Open data scored by Repobility · https://repobility.com
fitRowsWithLockedCols function · typescript · L170-L187 (18 LOC)
src/components/Terminal.tsx
function fitRowsWithLockedCols(term: XTerminal, fitAddon: FitAddon, lockedCols: number, zoom = 1): boolean {
  // Always use our custom dimension calculator so scrollbar width is
  // consistent (8px from CSS). FitAddon assumes 15px native scrollbar.
  const dims = zoomProposeDimensions(term, zoom)
    ?? (zoom === 1 ? fitAddon.proposeDimensions() : null);
  if (!dims || !Number.isFinite(dims.rows)) return false;
  const rows = Math.max(MIN_ROWS, Math.round(dims.rows));
  if (rows === term.rows && term.cols === lockedCols) return false;
  const buf = term.buffer.active;
  const distFromBottom = buf.baseY - buf.viewportY;
  term.resize(lockedCols, rows);
  const newBuf = term.buffer.active;
  const targetViewport = Math.max(0, newBuf.baseY - distFromBottom);
  if (newBuf.viewportY !== targetViewport) {
    term.scrollToLine(targetViewport);
  }
  return true;
}
applyZoomStyles function · typescript · L376-L397 (22 LOC)
src/components/Terminal.tsx
    function applyZoomStyles(z: number) {
      const xtermEl = term.element;
      if (!xtermEl) return;
      if (z === 1) {
        xtermEl.style.zoom = "";
        xtermEl.style.position = "";
        xtermEl.style.top = "";
        xtermEl.style.left = "";
      } else {
        xtermEl.style.zoom = String(1 / z);
        // Absolute positioning removes .xterm from flex flow so it
        // doesn't fight justifyContent/flex sizing. No explicit
        // width/height — let xterm size itself from its content.
        // Any gap between .xterm and the container is filled by the
        // container background (--terminal-bg), not black.
        xtermEl.style.position = "absolute";
        xtermEl.style.top = "0";
        xtermEl.style.left = "6px";
      }
      term.options.fontSize = Math.round(BASE_FONT_SIZE * z);
      term.options.cursorWidth = Math.max(1, Math.round(BASE_CURSOR_WIDTH * z));
    }
fitRowsOnly function · typescript · L589-L591 (3 LOC)
src/components/Terminal.tsx
    function fitRowsOnly(): boolean {
      return fitRowsWithLockedCols(term, fitAddon, LOCKED_COLS, uiZoomRef.current);
    }
connectToPty function · typescript · L593-L717 (125 LOC)
src/components/Terminal.tsx
    async function connectToPty(ptyId: string) {
      ptyIdRef.current = ptyId;
      osc7TailRef.current = "";

      unlistenOutputRef.current = await listen<{ data: number[] }>(
        `pty-output-${ptyId}`,
        (event) => {
          const chunk = new Uint8Array(event.payload.data);
          // Write to xterm FIRST — lowest latency for visible output
          term.write(chunk);
          // Buffer for replay (cheap — just array push)
          appendPtyBuffer(ptyId, chunk);
          // Defer heavier parsing to avoid blocking the render
          if (onCwdChanged) {
            queueMicrotask(() => {
              const text = outputDecoder.decode(chunk, { stream: true });
              const combined = osc7TailRef.current + text;
              osc7TailRef.current = combined.slice(-OSC7_TAIL_MAX);
              const newCwd = parseLatestOsc7Cwd(combined);
              if (newCwd && newCwd !== lastCwdRef.current) {
                lastCwdRef.current = newCwd;
              
attachExistingPty function · typescript · L719-L789 (71 LOC)
src/components/Terminal.tsx
    async function attachExistingPty() {
      if (ptySpawned || !existingPtyId) return;
      ptySpawned = true;

      try {
        // Check foreground process BEFORE replaying output to avoid a
        // cursor flash when reconnecting to a PTY running Claude Code.
        // The cached state on the Rust side makes this fast (~lock + clone).
        try {
          const proc = await api.getPtyForegroundProcess(existingPtyId);
          syncForegroundProcess(proc);
        } catch { /* PTY might be dead — proceed anyway */ }

        if (lockCols) {
          fitRowsOnly();
        } else {
          safeFit(term, fitAddon, uiZoomRef.current);
        }

        // Replay buffered output from ship session or script run
        if (lockCols) {
          const session = useWorkspaceStore.getState().shipSession;
          if (session && session.ptyId === existingPtyId) {
            for (const chunk of shipOutputBuffer) {
              term.write(chunk);
            }
          }
    
spawnPty function · typescript · L791-L844 (54 LOC)
src/components/Terminal.tsx
    async function spawnPty() {
      if (ptySpawned) return;
      ptySpawned = true;

      try {
        safeFit(term, fitAddon, uiZoomRef.current);
        // Ensure at least 80x24 — protects against xterm auto-sizing to
        // a tiny container during initial layout settling
        const spawnCols = Math.max(term.cols, 80);
        const spawnRows = Math.max(term.rows, 24);
        const ptyId = await api.spawnPty(cwd, command ?? null, spawnCols, spawnRows);

        // Persist ptyId so it survives layout-induced remounts
        onPtySpawned?.(ptyId);

        await connectToPty(ptyId);

        // Send initialInput after a delay to let the command start
        if (initialInput) {
          setTimeout(() => {
            if (ptyIdRef.current) {
              api.writePty(
                ptyIdRef.current,
                Array.from(encoder.encode(initialInput + "\r"))
              );
            }
          }, 1500);
        }

        // Sync dimensions after the async gap
ToastCard function · typescript · L48-L104 (57 LOC)
src/components/ToastContainer.tsx
function ToastCard({ toast, onDismiss }: { toast: Toast; onDismiss: () => void }) {
  const [closing, setClosing] = useState(false);

  const dismiss = useCallback(() => {
    setClosing(true);
    setTimeout(onDismiss, 200); // match animation duration
  }, [onDismiss]);

  useEffect(() => {
    // Warning toasts persist until dismissed by default
    const duration = toast.duration ?? (toast.type === "warning" ? 0 : 8000);
    if (duration === 0) return; // persistent
    const timer = setTimeout(dismiss, duration);
    return () => clearTimeout(timer);
  }, [toast.duration, toast.type, dismiss]);

  const accentColor = TYPE_COLORS[toast.type];

  return (
    <div
      style={{
        ...cardStyles.card,
        opacity: closing ? 0 : 1,
        transform: closing ? "translateX(-20px)" : "translateX(0)",
        transition: "opacity 0.2s ease, transform 0.2s ease",
      }}
    >
      <div style={{ ...cardStyles.accent, background: accentColor }} />
      <div style={cardStyles.c
ToastContainer function · typescript · L171-L188 (18 LOC)
src/components/ToastContainer.tsx
export function ToastContainer() {
  const toasts = useToastStore((s) => s.toasts);
  const dismissToast = useToastStore((s) => s.dismissToast);

  if (toasts.length === 0) return null;

  return (
    <div style={containerStyles.container}>
      {toasts.map((toast) => (
        <ToastCard
          key={toast.id}
          toast={toast}
          onDismiss={() => dismissToast(toast.id)}
        />
      ))}
    </div>
  );
}
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
isLocalhostUrl function · typescript · L11-L13 (3 LOC)
src/components/WebViewPane.tsx
function isLocalhostUrl(url: string): boolean {
  return /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?/i.test(url);
}
isFilePath function · typescript · L16-L18 (3 LOC)
src/components/WebViewPane.tsx
function isFilePath(url: string): boolean {
  return url.startsWith("/") || url.startsWith("~");
}
nearestZoomIndex function · typescript · L22-L33 (12 LOC)
src/components/WebViewPane.tsx
function nearestZoomIndex(current: number): number {
  let best = 0;
  let bestDist = Math.abs(ZOOM_LEVELS[0] - current);
  for (let i = 1; i < ZOOM_LEVELS.length; i++) {
    const dist = Math.abs(ZOOM_LEVELS[i] - current);
    if (dist < bestDist) {
      best = i;
      bestDist = dist;
    }
  }
  return best;
}
WebViewPane function · typescript · L35-L322 (288 LOC)
src/components/WebViewPane.tsx
export function WebViewPane({ url, paneId }: WebViewPaneProps) {
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [srcdoc, setSrcdoc] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [refreshKey, setRefreshKey] = useState(0);
  const [zoom, setZoom] = useState(1);
  // For localhost URLs: track whether the server is reachable
  const [serverUp, setServerUp] = useState<boolean | null>(null); // null = checking
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // Search state
  const [searchOpen, setSearchOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const searchInputRef = useRef<HTMLInputElement>(null);

  // Normalize URL: if user typed "localhost:3000", prepend http://
  const iframeSrc = isFilePath(url) ? undefined
    : url.startsWith("http") ? url
    : `http://${url}`;

  const isLocalhost = isLocalhostUrl(if
RefreshIcon function · typescript · L326-L345 (20 LOC)
src/components/WebViewPane.tsx
function RefreshIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
      <path
        d="M13.5 8a5.5 5.5 0 1 1-1.28-3.52"
        stroke="var(--text-dim)"
        strokeWidth="1.5"
        strokeLinecap="round"
        fill="none"
      />
      <path
        d="M13.5 3v1.5H12"
        stroke="var(--text-dim)"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}
ExternalLinkIcon function · typescript · L347-L367 (21 LOC)
src/components/WebViewPane.tsx
function ExternalLinkIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
      <path
        d="M6.5 3.5H3.5v9h9v-3"
        stroke="var(--text-dim)"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
        fill="none"
      />
      <path
        d="M10 2.5h3.5V6M13.5 2.5 7.5 8.5"
        stroke="var(--text-dim)"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}
GlobeOffIcon function · typescript · L369-L378 (10 LOC)
src/components/WebViewPane.tsx
function GlobeOffIcon() {
  return (
    <svg width="32" height="32" viewBox="0 0 24 24" fill="none">
      <circle cx="12" cy="12" r="9.5" stroke="var(--text-dim)" strokeWidth="1.5" />
      <ellipse cx="12" cy="12" rx="4" ry="9.5" stroke="var(--text-dim)" strokeWidth="1.5" />
      <line x1="2.5" y1="12" x2="21.5" y2="12" stroke="var(--text-dim)" strokeWidth="1.5" />
      <line x1="4" y1="4" x2="20" y2="20" stroke="var(--text-dim)" strokeWidth="2" strokeLinecap="round" />
    </svg>
  );
}
ZoomInIcon function · typescript · L380-L388 (9 LOC)
src/components/WebViewPane.tsx
function ZoomInIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
      <circle cx="7" cy="7" r="4.5" stroke="var(--text-dim)" strokeWidth="1.3" />
      <path d="M10.5 10.5L14 14" stroke="var(--text-dim)" strokeWidth="1.3" strokeLinecap="round" />
      <path d="M5 7h4M7 5v4" stroke="var(--text-dim)" strokeWidth="1.3" strokeLinecap="round" />
    </svg>
  );
}
Repobility · severity-and-effort ranking · https://repobility.com
ZoomOutIcon function · typescript · L390-L398 (9 LOC)
src/components/WebViewPane.tsx
function ZoomOutIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
      <circle cx="7" cy="7" r="4.5" stroke="var(--text-dim)" strokeWidth="1.3" />
      <path d="M10.5 10.5L14 14" stroke="var(--text-dim)" strokeWidth="1.3" strokeLinecap="round" />
      <path d="M5 7h4" stroke="var(--text-dim)" strokeWidth="1.3" strokeLinecap="round" />
    </svg>
  );
}
SearchIcon function · typescript · L400-L407 (8 LOC)
src/components/WebViewPane.tsx
function SearchIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
      <circle cx="7" cy="7" r="4.5" stroke="var(--text-dim)" strokeWidth="1.3" />
      <path d="M10.5 10.5L14 14" stroke="var(--text-dim)" strokeWidth="1.3" strokeLinecap="round" />
    </svg>
  );
}
useGitDiffActions function · typescript · L19-L237 (219 LOC)
src/hooks/useGitDiffActions.ts
export function useGitDiffActions({
  rootPath,
  mainBranch,
  enabled = true,
}: UseGitDiffActionsOptions) {
  const setActiveTab = useWorkspaceStore((s) => s.setGitDiffActiveTab);
  const prStatus = useWorkspaceStore((s) =>
    rootPath ? s.prStatuses[rootPath] : null,
  );
  const refreshPrStatusForPath = useWorkspaceStore(
    (s) => s.refreshPrStatusForPath,
  );

  const [unstagedFiles, setUnstagedFiles] = useState<DiffFile[]>([]);
  const [stagedFiles, setStagedFiles] = useState<DiffFile[]>([]);
  const [commits, setCommits] = useState<CommitEntry[]>([]);
  const [changes, setChanges] = useState<ChangesSummary | null>(null);
  const [diffStatAdd, setDiffStatAdd] = useState(0);
  const [diffStatDel, setDiffStatDel] = useState(0);
  const [loading, setLoading] = useState(true);
  const [revertConfirming, setRevertConfirming] = useState(false);
  const [creatingPr, setCreatingPr] = useState(false);

  const lastFetchedPath = useRef<string | null>(null);

  const fetchDiffs = useCa
stripAnsi function · typescript · L4-L6 (3 LOC)
src/lib/ansi.ts
export function stripAnsi(text: string): string {
  return text.replace(ANSI_RE, "");
}
isSubMenu function · typescript · L35-L37 (3 LOC)
src/lib/contextMenu.ts
function isSubMenu(a: MenuAction | SubMenuAction | "separator"): a is SubMenuAction {
  return typeof a === "object" && "children" in a;
}
buildMenuItem function · typescript · L39-L48 (10 LOC)
src/lib/contextMenu.ts
async function buildMenuItem(a: MenuAction | SubMenuAction | "separator"): Promise<MenuItem | PredefinedMenuItem | Submenu> {
  if (a === "separator") return PredefinedMenuItem.new({ item: "Separator" });
  if (isSubMenu(a)) {
    const children = await Promise.all(
      a.children.map((c) => buildMenuItem(c))
    );
    return Submenu.new({ text: a.label, items: children });
  }
  return MenuItem.new({ text: a.label, action: a.action, accelerator: a.accelerator ?? undefined, enabled: !a.disabled });
}
showContextMenu function · typescript · L50-L52 (3 LOC)
src/lib/contextMenu.ts
export async function showContextMenu(
  actions: (MenuAction | SubMenuAction | "separator")[],
  at?: { x: number; y: number },
parseUnifiedDiff function · typescript · L29-L105 (77 LOC)
src/lib/diffParser.ts
export function parseUnifiedDiff(raw: string): DiffFile[] {
  if (!raw.trim()) return [];

  const files: DiffFile[] = [];
  const fileSections = raw.split(/^diff --git /m).filter(Boolean);

  for (const section of fileSections) {
    const lines = section.split("\n");
    const pathMatch = lines[0]?.match(/^a\/(.*?) b\/(.*)$/);
    if (!pathMatch) continue;

    const file: DiffFile = {
      oldPath: pathMatch[1],
      newPath: pathMatch[2],
      additions: 0,
      deletions: 0,
      hunks: [],
      isNew: false,
      isDeleted: false,
      isRenamed: pathMatch[1] !== pathMatch[2],
    };

    for (const line of lines.slice(1, 6)) {
      if (line.startsWith("new file")) file.isNew = true;
      if (line.startsWith("deleted file")) file.isDeleted = true;
    }

    let currentHunk: DiffHunk | null = null;
    let oldLine = 0;
    let newLine = 0;

    for (const line of lines) {
      const hunkMatch = line.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@(.*)/);
      if (hunkMa
All rows scored by the Repobility analyzer (https://repobility.com)
createUntrackedDiffFile function · typescript · L111-L143 (33 LOC)
src/lib/diffParser.ts
export function createUntrackedDiffFile(filePath: string, content: string): DiffFile {
  const contentLines = content.split("\n");
  // Remove trailing empty line from split (if file ends with newline)
  if (contentLines.length > 0 && contentLines[contentLines.length - 1] === "") {
    contentLines.pop();
  }

  const lines: DiffLine[] = contentLines.map((line, i) => ({
    type: "add" as const,
    content: line,
    newLineNumber: i + 1,
  }));

  return {
    oldPath: filePath,
    newPath: filePath,
    additions: lines.length,
    deletions: 0,
    hunks: lines.length > 0
      ? [
          {
            header: `@@ -0,0 +1,${lines.length} @@`,
            oldStart: 0,
            newStart: 1,
            lines,
          },
        ]
      : [],
    isNew: true,
    isDeleted: false,
    isRenamed: false,
  };
}
generateHunkPatch function · typescript · L149-L181 (33 LOC)
src/lib/diffParser.ts
export function generateHunkPatch(file: DiffFile, hunk: DiffHunk): string {
  const oldPath = file.isNew ? "/dev/null" : `a/${file.oldPath}`;
  const newPath = file.isDeleted ? "/dev/null" : `b/${file.newPath}`;

  let oldCount = 0;
  let newCount = 0;
  const patchLines: string[] = [];

  for (const line of hunk.lines) {
    if (line.type === "context") {
      patchLines.push(` ${line.content}`);
      oldCount++;
      newCount++;
    } else if (line.type === "delete") {
      patchLines.push(`-${line.content}`);
      oldCount++;
    } else if (line.type === "add") {
      patchLines.push(`+${line.content}`);
      newCount++;
    }
  }

  const header = `@@ -${hunk.oldStart},${oldCount} +${hunk.newStart},${newCount} @@`;

  return [
    `diff --git a/${file.oldPath || file.newPath} b/${file.newPath || file.oldPath}`,
    `--- ${oldPath}`,
    `+++ ${newPath}`,
    header,
    ...patchLines,
    "", // trailing newline
  ].join("\n");
}
subscribe function · typescript · L49-L54 (6 LOC)
src/lib/dragContext.ts
function subscribe(fn: () => void): () => void {
  listeners.push(fn);
  return () => {
    listeners = listeners.filter((l) => l !== fn);
  };
}
notify function · typescript · L56-L58 (3 LOC)
src/lib/dragContext.ts
function notify() {
  listeners.forEach((fn) => fn());
}
getSnapshot function · typescript · L60-L62 (3 LOC)
src/lib/dragContext.ts
function getSnapshot(): DragState {
  return state;
}
useDragState function · typescript · L65-L67 (3 LOC)
src/lib/dragContext.ts
export function useDragState(): Readonly<DragState> {
  return useSyncExternalStore(subscribe, getSnapshot);
}
getDragState function · typescript · L69-L71 (3 LOC)
src/lib/dragContext.ts
export function getDragState(): Readonly<DragState> {
  return state;
}
startDrag function · typescript · L74-L119 (46 LOC)
src/lib/dragContext.ts
export function startDrag(groupId: string, paneId: string, x: number, y: number) {
  state = {
    isDragging: true,
    type: "pane",
    groupId,
    paneId,
    filePaths: [],
    prevMouseX: x,
    prevMouseY: y,
    mouseX: x,
    mouseY: y,
    flightPodId: null,
    flightTabIndex: null,
  };

  const onMouseMove = (e: MouseEvent) => {
    state = {
      ...state,
      prevMouseX: state.mouseX,
      prevMouseY: state.mouseY,
      mouseX: e.clientX,
      mouseY: e.clientY,
    };
    notify();
  };

  const onMouseUp = () => {
    document.removeEventListener("mousemove", onMouseMove);
    document.removeEventListener("mouseup", onMouseUp);
    document.body.style.cursor = "";
    document.body.style.userSelect = "";
    // Notify with isDragging still true so drop targets can act
    notify();
    // Then end the drag
    setTimeout(() => {
      state = IDLE_STATE;
      notify();
    }, 0);
  };

  document.addEventListener("mousemove", onMouseMove);
  document.addEventLi
Open data scored by Repobility · https://repobility.com
startFlightTabDrag function · typescript · L122-L167 (46 LOC)
src/lib/dragContext.ts
export function startFlightTabDrag(podId: string, tabIndex: number, x: number, y: number) {
  state = {
    isDragging: true,
    type: "pane",
    groupId: null,
    paneId: null,
    filePaths: [],
    prevMouseX: x,
    prevMouseY: y,
    mouseX: x,
    mouseY: y,
    flightPodId: podId,
    flightTabIndex: tabIndex,
  };

  const onMouseMove = (e: MouseEvent) => {
    state = {
      ...state,
      prevMouseX: state.mouseX,
      prevMouseY: state.mouseY,
      mouseX: e.clientX,
      mouseY: e.clientY,
    };
    notify();
  };

  const onMouseUp = () => {
    document.removeEventListener("mousemove", onMouseMove);
    document.removeEventListener("mouseup", onMouseUp);
    document.body.style.cursor = "";
    document.body.style.userSelect = "";
    // Notify with isDragging still true so drop targets can act
    notify();
    // Then end the drag
    setTimeout(() => {
      state = IDLE_STATE;
      notify();
    }, 0);
  };

  document.addEventListener("mousemove", onMouseMo
startFileDrag function · typescript · L170-L215 (46 LOC)
src/lib/dragContext.ts
export function startFileDrag(filePaths: string[], x: number, y: number) {
  state = {
    isDragging: true,
    type: "file",
    groupId: null,
    paneId: null,
    filePaths,
    prevMouseX: x,
    prevMouseY: y,
    mouseX: x,
    mouseY: y,
    flightPodId: null,
    flightTabIndex: null,
  };

  const onMouseMove = (e: MouseEvent) => {
    state = {
      ...state,
      prevMouseX: state.mouseX,
      prevMouseY: state.mouseY,
      mouseX: e.clientX,
      mouseY: e.clientY,
    };
    notify();
  };

  const onMouseUp = () => {
    document.removeEventListener("mousemove", onMouseMove);
    document.removeEventListener("mouseup", onMouseUp);
    document.body.style.cursor = "";
    document.body.style.userSelect = "";
    // Notify with isDragging still true so drop targets can act
    notify();
    // Then end the drag
    setTimeout(() => {
      state = IDLE_STATE;
      notify();
    }, 0);
  };

  document.addEventListener("mousemove", onMouseMove);
  document.addEventLi
startExternalFileDrag function · typescript · L221-L236 (16 LOC)
src/lib/dragContext.ts
export function startExternalFileDrag(filePaths: string[], x: number, y: number) {
  state = {
    isDragging: true,
    type: "file",
    groupId: null,
    paneId: null,
    filePaths,
    prevMouseX: x,
    prevMouseY: y,
    mouseX: x,
    mouseY: y,
    flightPodId: null,
    flightTabIndex: null,
  };
  notify();
}
‹ prevpage 4 / 10next ›