Function bodies 465 total
updateDragPosition function · typescript · L239-L249 (11 LOC)src/lib/dragContext.ts
export function updateDragPosition(x: number, y: number) {
if (!state.isDragging) return;
state = {
...state,
prevMouseX: state.mouseX,
prevMouseY: state.mouseY,
mouseX: x,
mouseY: y,
};
notify();
}endDrag function · typescript · L251-L254 (4 LOC)src/lib/dragContext.ts
export function endDrag() {
state = IDLE_STATE;
notify();
}getFileIcon function · typescript · L260-L283 (24 LOC)src/lib/fileIcons.ts
export function getFileIcon(fileName: string): IconDef {
const lower = fileName.toLowerCase();
// Check exact filename match first
const nameIcon = NAME_MAP[lower];
if (nameIcon && ICONS[nameIcon]) return ICONS[nameIcon];
// Check multi-part extensions (e.g., spec.ts, test.tsx)
const parts = lower.split(".");
if (parts.length >= 3) {
const multiExt = parts.slice(-2).join(".");
const multiIcon = EXT_MAP[multiExt];
if (multiIcon && ICONS[multiIcon]) return ICONS[multiIcon];
}
// Check single extension
const ext = parts.length > 1 ? parts[parts.length - 1] : "";
if (ext) {
const extIcon = EXT_MAP[ext];
if (extIcon && ICONS[extIcon]) return ICONS[extIcon];
}
return ICONS._default;
}injectSetiFont function · typescript · L290-L304 (15 LOC)src/lib/fileIcons.ts
export function injectSetiFont() {
if (injected) return;
injected = true;
const style = document.createElement("style");
style.textContent = `
@font-face {
font-family: "seti";
src: url("/seti.woff") format("woff");
font-weight: normal;
font-style: normal;
font-display: block;
}
`;
document.head.appendChild(style);
}normalizeHighlightLang function · typescript · L6-L24 (19 LOC)src/lib/markdown.ts
function normalizeHighlightLang(lang: string): string {
switch (lang.toLowerCase()) {
case "shell":
return "sh";
case "py3":
return "python";
case "tsx":
case "typescriptreact":
return "jsx";
case "json5":
case "jsonc":
return "json";
case "c#":
case "csharp":
return "cs";
default:
return lang;
}
}escapeCodeHtml function · typescript · L26-L28 (3 LOC)src/lib/markdown.ts
function escapeCodeHtml(code: string): string {
return code.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
}renderMarkdown function · typescript · L46-L49 (4 LOC)src/lib/markdown.ts
export function renderMarkdown(text: string): string {
const html = marked.parse(text, { async: false }) as string;
return DOMPurify.sanitize(html);
}Repobility — same analyzer, your code, free for public repos · /scan/
detectPorts function · typescript · L25-L47 (23 LOC)src/lib/portDetection.ts
export function detectPorts(raw: string): ParsedPort[] {
const text = stripAnsi(raw);
const seen = new Set<number>();
const results: ParsedPort[] = [];
for (const match of text.matchAll(URL_RE)) {
const port = parseInt(match[1], 10);
if (port > 0 && port <= 65535 && !seen.has(port)) {
seen.add(port);
results.push({ port, url: `http://localhost:${port}` });
}
}
for (const match of text.matchAll(ANNOUNCE_RE)) {
const port = parseInt(match[1], 10);
if (port > 0 && port <= 65535 && !seen.has(port)) {
seen.add(port);
results.push({ port, url: `http://localhost:${port}` });
}
}
return results;
}wordBoundary function · typescript · L32-L34 (3 LOC)src/lib/syntaxHighlight.ts
function wordBoundary(words: string): RegExp {
return new RegExp(`\\b(${words})\\b`, "g");
}getLangForPath function · typescript · L149-L154 (6 LOC)src/lib/syntaxHighlight.ts
export function getLangForPath(filePath: string): string | null {
const dot = filePath.lastIndexOf(".");
if (dot === -1) return null;
const ext = filePath.slice(dot + 1).toLowerCase();
return EXT_MAP[ext] ?? null;
}escapeHtml function · typescript · L159-L161 (3 LOC)src/lib/syntaxHighlight.ts
export function escapeHtml(str: string): string {
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
}highlightLine function · typescript · L169-L233 (65 LOC)src/lib/syntaxHighlight.ts
export function highlightLine(code: string, lang: string | null): string {
if (!lang || !LANG_RULES[lang]) {
return escapeHtml(code);
}
const rules = LANG_RULES[lang];
const tokens: Token[] = [];
// Collect all matches from all rules
for (const rule of rules) {
// Reset lastIndex for global regexes before each use
rule.pattern.lastIndex = 0;
let match: RegExpExecArray | null;
while ((match = rule.pattern.exec(code)) !== null) {
tokens.push({
start: match.index,
end: match.index + match[0].length,
className: rule.className,
});
// Guard against zero-length matches causing infinite loops
if (match[0].length === 0) {
rule.pattern.lastIndex++;
}
}
}
if (tokens.length === 0) {
return escapeHtml(code);
}
// Sort by start position; for ties, longer match wins (earlier rule takes precedence via stable sort)
tokens.sort((a, b) => a.start - b.start || b.end - a.end);
// Remove oopenUrl function · typescript · L5-L15 (11 LOC)src/lib/tauri.ts
export function openUrl(url: string) {
if (!/^https?:\/\//i.test(url)) return;
invoke("plugin:shell|open", { path: url }).catch((err) => {
console.warn("shell:open failed, falling back to window.open:", err);
try {
window.open(url, "_blank");
} catch (e) {
console.error("window.open also failed:", e);
}
});
}findLinksInText function · typescript · L25-L35 (11 LOC)src/lib/terminalLinkProvider.ts
function findLinksInText(text: string): LinkMatch[] {
const matches: LinkMatch[] = [];
URL_REGEX.lastIndex = 0;
let m: RegExpExecArray | null;
while ((m = URL_REGEX.exec(text)) !== null) {
// Strip trailing punctuation that's likely not part of the URL
let url = m[0];
while (url.length > 0 && /[.,;:!?)>}\]']$/.test(url)) {
url = url.slice(0, -1);
}resolvePath function · typescript · L106-L126 (21 LOC)src/lib/terminalLinkProvider.ts
function resolvePath(filePath: string, cwd: string): string {
if (filePath.startsWith("/")) return filePath;
// Join with CWD
const base = cwd.endsWith("/") ? cwd : cwd + "/";
let resolved = base + filePath;
// Normalize: collapse /./ and resolve /../
resolved = resolved.replace(/\/\.\//g, "/");
// Resolve .. segments
const parts = resolved.split("/");
const normalized: string[] = [];
for (const part of parts) {
if (part === "..") {
normalized.pop();
} else if (part !== ".") {
normalized.push(part);
}
}
return normalized.join("/");
}Repobility · MCP-ready · https://repobility.com
TerminalLinkProvider class · typescript · L137-L276 (140 LOC)src/lib/terminalLinkProvider.ts
export class TerminalLinkProvider implements ILinkProvider {
private _cmdHeld = false;
private _activeLinks = new Set<ILink>();
constructor(
private terminal: Terminal,
private getCwd: () => string,
private onFileOpen: OnFileOpen,
) {}
get cmdHeld(): boolean {
return this._cmdHeld;
}
set cmdHeld(value: boolean) {
if (this._cmdHeld === value) return;
this._cmdHeld = value;
// Update decorations on all active links
for (const link of this._activeLinks) {
if (link.decorations) {
link.decorations.pointerCursor = value;
link.decorations.underline = value;
}
}
}
provideLinks(bufferLineNumber: number, callback: (links: ILink[] | undefined) => void): void {
const buffer = this.terminal.buffer.active;
const line = buffer.getLine(bufferLineNumber - 1);
if (!line) {
callback(undefined);
return;
}
// Collect wrapped lines: join current line with any continuation lines below.
/constructor method · typescript · L141-L145 (5 LOC)src/lib/terminalLinkProvider.ts
constructor(
private terminal: Terminal,
private getCwd: () => string,
private onFileOpen: OnFileOpen,
) {}provideLinks method · typescript · L163-L275 (113 LOC)src/lib/terminalLinkProvider.ts
provideLinks(bufferLineNumber: number, callback: (links: ILink[] | undefined) => void): void {
const buffer = this.terminal.buffer.active;
const line = buffer.getLine(bufferLineNumber - 1);
if (!line) {
callback(undefined);
return;
}
// Collect wrapped lines: join current line with any continuation lines below.
// xterm marks continuation lines with isWrapped=true.
const lineTexts: string[] = [];
const lineWidths: number[] = [];
const startLineIdx = bufferLineNumber - 1;
lineTexts.push(line.translateToString(true));
lineWidths.push(lineTexts[0].length);
// Gather subsequent wrapped lines
for (let i = startLineIdx + 1; i < buffer.length; i++) {
const nextLine = buffer.getLine(i);
if (!nextLine || !nextLine.isWrapped) break;
const nextText = nextLine.translateToString(true);
lineTexts.push(nextText);
lineWidths.push(nextText.length);
}
const fullText = lineTexts.join("");
constrelativeTime function · typescript · L2-L15 (14 LOC)src/lib/time.ts
export function relativeTime(isoDate: string): string {
if (!isoDate) return "";
const diff = Date.now() - new Date(isoDate).getTime();
const mins = Math.floor(diff / 60000);
if (mins < 1) return "just now";
if (mins < 60) return `${mins}m ago`;
const hrs = Math.floor(mins / 60);
if (hrs < 24) return `${hrs}h ago`;
const days = Math.floor(hrs / 24);
if (days < 30) return `${days}d ago`;
const months = Math.floor(days / 30);
if (months < 12) return `${months}mo ago`;
return new Date(isoDate).toLocaleDateString();
}findNode function · typescript · L341-L350 (10 LOC)src/lib/types.ts
export function findNode(
root: LayoutNode,
id: string
): LayoutNode | null {
if (root.type === "group") {
return root.groupId === id ? root : null;
}
if (root.id === id) return root;
return findNode(root.children[0], id) ?? findNode(root.children[1], id);
}replaceNode function · typescript · L353-L369 (17 LOC)src/lib/types.ts
export function replaceNode(
root: LayoutNode,
id: string,
replacement: LayoutNode
): LayoutNode {
if (root.type === "group") {
return root.groupId === id ? replacement : root;
}
if (root.id === id) return replacement;
return {
...root,
children: [
replaceNode(root.children[0], id, replacement),
replaceNode(root.children[1], id, replacement),
],
};
}findParent function · typescript · L375-L378 (4 LOC)src/lib/types.ts
export function findParent(
root: LayoutNode,
childId: string
): { parent: Extract<LayoutNode, { type: "split" }>; index: 0 | 1 } | null {findFirstGroupInSubtree function · typescript · L396-L402 (7 LOC)src/lib/types.ts
export function findFirstGroupInSubtree(node: LayoutNode): string | null {
if (node.type === "group") return node.groupId;
return (
findFirstGroupInSubtree(node.children[0]) ??
findFirstGroupInSubtree(node.children[1])
);
}Want this analysis on your repo? https://repobility.com/scan/
computeGroupBounds function · typescript · L411-L430 (20 LOC)src/lib/types.ts
function computeGroupBounds(
node: LayoutNode,
bounds: GroupBounds = { x: 0, y: 0, w: 1, h: 1 },
): Map<string, GroupBounds> {
if (node.type === "group") {
return new Map([[node.groupId, bounds]]);
}
const { direction, ratio, children } = node;
let b0: GroupBounds, b1: GroupBounds;
if (direction === "horizontal") {
b0 = { x: bounds.x, y: bounds.y, w: bounds.w * ratio, h: bounds.h };
b1 = { x: bounds.x + bounds.w * ratio, y: bounds.y, w: bounds.w * (1 - ratio), h: bounds.h };
} else {
b0 = { x: bounds.x, y: bounds.y, w: bounds.w, h: bounds.h * ratio };
b1 = { x: bounds.x, y: bounds.y + bounds.h * ratio, w: bounds.w, h: bounds.h * (1 - ratio) };
}
const map = computeGroupBounds(children[0], b0);
for (const [k, v] of computeGroupBounds(children[1], b1)) map.set(k, v);
return map;
}findNeighborGroup function · typescript · L437-L497 (61 LOC)src/lib/types.ts
export function findNeighborGroup(
root: LayoutNode,
activeGroupId: string,
direction: NavigationDirection,
): string | null {
const allBounds = computeGroupBounds(root);
const activeBounds = allBounds.get(activeGroupId);
if (!activeBounds) return null;
// Alias with definite type so inner function doesn't need null checks
const active: GroupBounds = activeBounds;
const aCx = active.x + active.w / 2;
const aCy = active.y + active.h / 2;
function findBest(requireOverlap: boolean): string | null {
let best: string | null = null;
let bestPrimary = Infinity;
let bestOrthogonal = Infinity;
for (const [groupId, b] of allBounds) {
if (groupId === activeGroupId) continue;
const cx = b.x + b.w / 2;
const cy = b.y + b.h / 2;
if (requireOverlap) {
// Candidate must overlap on the orthogonal axis.
// For left/right: must share vertical space. For up/down: must share horizontal space.
const EPS = 1e-9;
findBest function · typescript · L451-L491 (41 LOC)src/lib/types.ts
function findBest(requireOverlap: boolean): string | null {
let best: string | null = null;
let bestPrimary = Infinity;
let bestOrthogonal = Infinity;
for (const [groupId, b] of allBounds) {
if (groupId === activeGroupId) continue;
const cx = b.x + b.w / 2;
const cy = b.y + b.h / 2;
if (requireOverlap) {
// Candidate must overlap on the orthogonal axis.
// For left/right: must share vertical space. For up/down: must share horizontal space.
const EPS = 1e-9;
if (direction === "left" || direction === "right") {
if (b.y + b.h <= active.y + EPS || b.y >= active.y + active.h - EPS) continue;
} else {
if (b.x + b.w <= active.x + EPS || b.x >= active.x + active.w - EPS) continue;
}
}
let primary: number;
let orthogonal: number;
switch (direction) {
case "right": primary = cx - aCx; orthogonal = Math.abs(cy - aCy); break;
case "left": primacreateProductLayout function · typescript · L501-L516 (16 LOC)src/lib/types.ts
export function createProductLayout(): WorkspaceLayout {
const claudePane: Pane = {
id: crypto.randomUUID(),
type: "claude-launcher",
title: "Claude Code",
};
const g1: PaneGroup = {
id: crypto.randomUUID(),
panes: [claudePane],
activePaneId: claudePane.id,
};
return {
root: { type: "group", groupId: g1.id },
groups: { [g1.id]: g1 },
};
}createDefaultLayout function · typescript · L518-L555 (38 LOC)src/lib/types.ts
export function createDefaultLayout(): WorkspaceLayout {
const claudePane: Pane = {
id: crypto.randomUUID(),
type: "claude-launcher",
title: "Claude Code",
};
const terminalPane: Pane = {
id: crypto.randomUUID(),
type: "terminal",
title: "Terminal",
};
const g1: PaneGroup = {
id: crypto.randomUUID(),
panes: [claudePane],
activePaneId: claudePane.id,
};
const g2: PaneGroup = {
id: crypto.randomUUID(),
panes: [terminalPane],
activePaneId: terminalPane.id,
};
return {
root: {
type: "split",
id: crypto.randomUUID(),
direction: "vertical",
children: [
{ type: "group", groupId: g1.id },
{ type: "group", groupId: g2.id },
],
ratio: 0.5,
},
groups: {
[g1.id]: g1,
[g2.id]: g2,
},
};
}useDetectedPorts function · typescript · L6-L11 (6 LOC)src/lib/useDetectedPorts.ts
export function useDetectedPorts(workspaceId: string | null): DetectedPort[] {
return useWorkspaceStore((s) => {
if (!workspaceId) return EMPTY_PORTS;
return s.detectedPorts[workspaceId] ?? EMPTY_PORTS;
});
}isWatcherScript function · typescript · L6-L8 (3 LOC)src/lib/watcherStatus.ts
export function isWatcherScript(name: string): boolean {
return name.toLowerCase().includes("watch");
}normalizeLine function · typescript · L42-L44 (3 LOC)src/lib/watcherStatus.ts
function normalizeLine(line: string): string {
return line.replace(ANSI_REGEX, "").replace(/\r/g, "").trim();
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
isIgnorableErrorLine function · typescript · L46-L51 (6 LOC)src/lib/watcherStatus.ts
function isIgnorableErrorLine(line: string): boolean {
return /\b0 errors?\b/i.test(line) ||
/searchable error logs/i.test(line) ||
/deprecationwarning/i.test(line) ||
/prone to errors that have security implications/i.test(line);
}hasWatcherError function · typescript · L53-L56 (4 LOC)src/lib/watcherStatus.ts
function hasWatcherError(line: string): boolean {
if (!line || isIgnorableErrorLine(line)) return false;
return WATCHER_ERROR_PATTERNS.some((pattern) => pattern.test(line));
}hasScriptError function · typescript · L58-L61 (4 LOC)src/lib/watcherStatus.ts
function hasScriptError(line: string): boolean {
if (!line || isIgnorableErrorLine(line)) return false;
return SCRIPT_ERROR_PATTERNS.some((pattern) => pattern.test(line));
}hasSuccess function · typescript · L63-L66 (4 LOC)src/lib/watcherStatus.ts
function hasSuccess(line: string): boolean {
if (!line) return false;
return SUCCESS_PATTERNS.test(line);
}hasBuilding function · typescript · L68-L71 (4 LOC)src/lib/watcherStatus.ts
function hasBuilding(line: string): boolean {
if (!line) return false;
return BUILDING_PATTERNS.test(line);
}decodeChunks function · typescript · L73-L76 (4 LOC)src/lib/watcherStatus.ts
function decodeChunks(chunks: Uint8Array[]): string {
const decoder = new TextDecoder("utf-8", { fatal: false });
return chunks.map((c) => decoder.decode(c, { stream: true })).join("");
}createInitialWatcherStatus function · typescript · L78-L80 (3 LOC)src/lib/watcherStatus.ts
function createInitialWatcherStatus(): CachedWatcherStatus {
return { status: "building", chunkCount: 0, buildCompletionCount: 0 };
}applyWatcherText function · typescript · L82-L85 (4 LOC)src/lib/watcherStatus.ts
function applyWatcherText(
status: WatcherBuildStatus,
text: string,
): { status: WatcherBuildStatus; completions: number } {Repobility — same analyzer, your code, free for public repos · /scan/
observeWatcherOutput function · typescript · L119-L132 (14 LOC)src/lib/watcherStatus.ts
export function observeWatcherOutput(
bufferKey: string,
text: string,
): WatcherObservation {
const cached = watcherStatusCache.get(bufferKey) ?? createInitialWatcherStatus();
const { status, completions } = applyWatcherText(cached.status, text);
const buildCompletionCount = cached.buildCompletionCount + completions;
watcherStatusCache.set(bufferKey, {
status,
chunkCount: cached.chunkCount + 1,
buildCompletionCount,
});
return { status, buildCompletionCount };
}getWatcherBuildStatus function · typescript · L134-L160 (27 LOC)src/lib/watcherStatus.ts
export function getWatcherBuildStatus(bufferKey: string): WatcherBuildStatus {
const buf = scriptOutputBuffers.get(bufferKey);
if (!buf || buf.length === 0) return "building";
let cached = watcherStatusCache.get(bufferKey);
// Buffer was reset (new run) — clear stale cache
if (cached && buf.length < cached.chunkCount) {
watcherStatusCache.delete(bufferKey);
cached = undefined;
}
if (cached && cached.chunkCount === buf.length) return cached.status;
const startIdx = cached?.chunkCount ?? 0;
let currentStatus = cached?.status ?? createInitialWatcherStatus().status;
let completionCount = cached?.buildCompletionCount ?? 0;
if (buf.length > startIdx) {
const newChunks = buf.slice(startIdx);
const text = decodeChunks(newChunks);
const result = applyWatcherText(currentStatus, text);
currentStatus = result.status;
completionCount += result.completions;
}
watcherStatusCache.set(bufferKey, { status: currentStatus, chunkCount: buf.length, bclearWatcherStatusCache function · typescript · L162-L164 (3 LOC)src/lib/watcherStatus.ts
export function clearWatcherStatusCache(bufferKey: string): void {
watcherStatusCache.delete(bufferKey);
}inferScriptCompletionStatus function · typescript · L166-L183 (18 LOC)src/lib/watcherStatus.ts
export function inferScriptCompletionStatus(
bufferKey: string,
scriptName: string,
): "success" | "error" {
const buf = scriptOutputBuffers.get(bufferKey);
if (!buf || buf.length === 0) return "success";
if (isWatcherScript(scriptName)) {
return getWatcherBuildStatus(bufferKey) === "error" ? "error" : "success";
}
const text = decodeChunks(buf);
for (const raw of text.split("\n")) {
const line = normalizeLine(raw);
if (hasScriptError(line)) return "error";
}
return "success";
}getWatcherDisplayStatus function · typescript · L185-L190 (6 LOC)src/lib/watcherStatus.ts
export function getWatcherDisplayStatus(run: ScriptRun | undefined): WatcherBuildStatus {
if (!run) return "idle";
if (run.status === "running") return run.watcherBuildStatus ?? "building";
if (run.watcherBuildStatus === "error" || run.status === "error") return "error";
return "idle";
}getStatusColor function · typescript · L192-L199 (8 LOC)src/lib/watcherStatus.ts
export function getStatusColor(status: WatcherBuildStatus): string {
switch (status) {
case "error": return "var(--status-red)";
case "success": return "var(--status-green)";
case "building": return "var(--status-amber)";
case "idle": return "var(--text-dim)";
}
}getDisplayName function · typescript · L201-L203 (3 LOC)src/lib/watcherStatus.ts
export function getDisplayName(scriptName: string): string {
return scriptName.replace(/\.(sh|bash)$/, "");
}attachWindowErrorHandler function · typescript · L4-L22 (19 LOC)src/lib/windowUtils.ts
function attachWindowErrorHandler(w: WebviewWindow, context: string) {
w.once("tauri://error", (e) => {
const payload = e?.payload;
const detail =
typeof payload === "string"
? payload
: payload && typeof payload === "object" && "message" in payload
? String((payload as { message?: unknown }).message ?? "")
: "";
console.error(`Failed to create window (${context}):`, e);
addToast({
type: "warning",
title: "Window open failed",
message: detail
? `Could not open ${context}. ${detail}`
: `Could not open ${context}.`,
});
});
}Repobility · MCP-ready · https://repobility.com
openInNewWindow function · typescript · L28-L52 (25 LOC)src/lib/windowUtils.ts
export function openInNewWindow(url: string, title?: string) {
const label = `rally-view-${crypto.randomUUID()}`;
// For localhost/http URLs, load directly. For file paths, use a file:// URL.
let loadUrl = url;
if (url.startsWith("/")) {
loadUrl = `file://${url}`;
} else if (!url.startsWith("http")) {
loadUrl = `http://${url}`;
}
const displayTitle = title || url;
const w = new WebviewWindow(label, {
url: loadUrl,
title: displayTitle,
width: 1200,
height: 800,
resizable: true,
fullscreen: false,
decorations: true,
});
attachWindowErrorHandler(w, "window");
}openWindow function · typescript · L54-L81 (28 LOC)src/lib/windowUtils.ts
export function openWindow(opts?: {
workspaceId?: string;
blankWorkspace?: boolean;
}) {
const label = `rally-${crypto.randomUUID()}`;
const params = new URLSearchParams();
if (opts?.workspaceId) {
params.set("workspaceId", opts.workspaceId);
} else if (opts?.blankWorkspace) {
params.set("blankWorkspace", "1");
}
const query = params.toString();
const url = query ? `/?${query}` : "/";
const w = new WebviewWindow(label, {
url,
title: "Rally",
width: 1400,
height: 900,
resizable: true,
fullscreen: false,
decorations: true,
titleBarStyle: "overlay",
hiddenTitle: true,
});
attachWindowErrorHandler(w, "a new window");
}getCssVar function · typescript · L3-L5 (3 LOC)src/lib/xtermTheme.ts
function getCssVar(name: string): string {
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
}