← back to ddgonzal3__rally

Function bodies 465 total

All specs Real LLM only Function bodies
getXtermTheme function · typescript · L45-L53 (9 LOC)
src/lib/xtermTheme.ts
export function getXtermTheme(theme: ThemeName, variant?: 'popup'): Record<string, string> {
  return {
    background: getCssVar(variant === 'popup' ? '--terminal-popup-bg' : '--terminal-bg'),
    foreground: getCssVar('--terminal-fg'),
    cursor: getCssVar('--terminal-cursor'),
    selectionBackground: getCssVar('--terminal-selection'),
    ...xtermAnsiColors[theme],
  };
}
pushLimitedChunk function · typescript · L83-L92 (10 LOC)
src/stores/workspaceStore.ts
function pushLimitedChunk(
  buffer: Uint8Array[],
  chunk: Uint8Array,
  maxChunks: number,
) {
  buffer.push(chunk);
  if (buffer.length > maxChunks) {
    buffer.splice(0, buffer.length - maxChunks);
  }
}
appendPtyBuffer function · typescript · L94-L101 (8 LOC)
src/stores/workspaceStore.ts
export function appendPtyBuffer(ptyId: string, chunk: Uint8Array) {
  let buf = ptyOutputBuffers.get(ptyId);
  if (!buf) {
    buf = [];
    ptyOutputBuffers.set(ptyId, buf);
  }
  pushLimitedChunk(buf, chunk, MAX_PTY_BUFFER_CHUNKS);
}
clearPtyBuffer function · typescript · L103-L105 (3 LOC)
src/stores/workspaceStore.ts
export function clearPtyBuffer(ptyId: string) {
  ptyOutputBuffers.delete(ptyId);
}
cancelDrawerHoverClose function · typescript · L110-L115 (6 LOC)
src/stores/workspaceStore.ts
export function cancelDrawerHoverClose() {
  if (_drawerHoverTimer) {
    clearTimeout(_drawerHoverTimer);
    _drawerHoverTimer = null;
  }
}
startDrawerHoverClose function · typescript · L117-L123 (7 LOC)
src/stores/workspaceStore.ts
export function startDrawerHoverClose(close: () => void, delay = 120) {
  cancelDrawerHoverClose();
  _drawerHoverTimer = setTimeout(() => {
    _drawerHoverTimer = null;
    close();
  }, delay);
}
isRecord function · typescript · L142-L144 (3 LOC)
src/stores/workspaceStore.ts
function isRecord(value: unknown): value is Record<string, unknown> {
  return value !== null && typeof value === "object";
}
Open data scored by Repobility · https://repobility.com
buildRefs function · typescript · L190-L211 (22 LOC)
src/stores/workspaceStore.ts
  function buildRefs(
    state: PersistedWorkspaceState,
    version: number,
  ): PersistRefs {
    return {
      activeWorkspaceId: state.activeWorkspaceId,
      activePathIndex: state.activePathIndex,
      layouts: state.layouts,
      activeGroupIds: state.activeGroupIds,
      layoutPresets: state.layoutPresets,
      activePresetId: state.activePresetId,
      gitDiffActiveTab: state.gitDiffActiveTab,
      unifiedGitPanelOpen: state.unifiedGitPanelOpen,
      unifiedGitPanelPath: state.unifiedGitPanelPath,
      unifiedGitPanelTab: state.unifiedGitPanelTab,
      workspaceModes: state.workspaceModes,
      flightLayouts: state.flightLayouts,
      flightLayoutPresets: state.flightLayoutPresets,
      activeFlightPresetId: state.activeFlightPresetId,
      version,
    };
  }
sameRefs function · typescript · L213-L233 (21 LOC)
src/stores/workspaceStore.ts
  function sameRefs(
    a: PersistRefs | null,
    b: PersistRefs,
  ) {
    return !!a &&
      a.version === b.version &&
      a.activeWorkspaceId === b.activeWorkspaceId &&
      a.activePathIndex === b.activePathIndex &&
      a.layouts === b.layouts &&
      a.activeGroupIds === b.activeGroupIds &&
      a.layoutPresets === b.layoutPresets &&
      a.activePresetId === b.activePresetId &&
      a.gitDiffActiveTab === b.gitDiffActiveTab &&
      a.unifiedGitPanelOpen === b.unifiedGitPanelOpen &&
      a.unifiedGitPanelPath === b.unifiedGitPanelPath &&
      a.unifiedGitPanelTab === b.unifiedGitPanelTab &&
      a.workspaceModes === b.workspaceModes &&
      a.flightLayouts === b.flightLayouts &&
      a.flightLayoutPresets === b.flightLayoutPresets &&
      a.activeFlightPresetId === b.activeFlightPresetId;
  }
flushPending function · typescript · L235-L245 (11 LOC)
src/stores/workspaceStore.ts
  function flushPending() {
    if (persistTimer) {
      clearTimeout(persistTimer);
      persistTimer = null;
    }
    if (!pending) return;
    const next = pending;
    pending = null;
    localStorage.setItem(next.name, JSON.stringify(next.value));
    lastRefs = next.refs;
  }
sanitizePane function · typescript · L560-L588 (29 LOC)
src/stores/workspaceStore.ts
function sanitizePane(raw: unknown): Pane | null {
  if (!isRecord(raw)) return null;
  const id = typeof raw.id === "string" && raw.id ? raw.id : crypto.randomUUID();
  const rawType = typeof raw.type === "string" ? raw.type : "terminal";
  if (!VALID_PANE_TYPES.has(rawType)) return null;
  const type = rawType as Pane["type"];
  const title =
    typeof raw.title === "string" && raw.title
      ? raw.title
      : type === "editor" || type === "diff"
        ? "File"
        : type === "claude" || type === "claude-launcher"
          ? "Claude Code"
          : "Terminal";

  const pane: Pane = {
    id,
    type,
    title,
  };
  if (typeof raw.command === "string") pane.command = raw.command;
  if (typeof raw.filePath === "string") pane.filePath = raw.filePath;
  if (typeof raw.cwd === "string") pane.cwd = raw.cwd;
  if (typeof raw.initialInput === "string") pane.initialInput = raw.initialInput;
  if (typeof raw.ptyId === "string") pane.ptyId = raw.ptyId;
  if (typeof raw.scriptBu
sanitizeGroup function · typescript · L590-L621 (32 LOC)
src/stores/workspaceStore.ts
function sanitizeGroup(raw: unknown): PaneGroup | null {
  if (!isRecord(raw)) return null;
  const id = typeof raw.id === "string" && raw.id ? raw.id : crypto.randomUUID();
  const rawPanes = Array.isArray(raw.panes) ? raw.panes : [];
  const panes = rawPanes
    .map((p) => sanitizePane(p))
    .filter((p): p is Pane => p !== null);

  const rawActivePaneId =
    typeof raw.activePaneId === "string" ? raw.activePaneId : "";
  const activePaneId =
    panes.length > 0
      ? panes.some((p) => p.id === rawActivePaneId)
        ? rawActivePaneId
        : panes[0].id
      : "";

  const paneHistory =
    Array.isArray(raw.paneHistory)
      ? raw.paneHistory.filter(
          (id): id is string =>
            typeof id === "string" && panes.some((p) => p.id === id),
        )
      : undefined;

  return {
    id,
    panes,
    activePaneId,
    ...(paneHistory && paneHistory.length > 0 ? { paneHistory } : {}),
  };
}
sanitizeLayoutNode function · typescript · L623-L657 (35 LOC)
src/stores/workspaceStore.ts
function sanitizeLayoutNode(
  raw: unknown,
  groups: Record<string, PaneGroup>,
  depth = 0,
): LayoutNode | null {
  if (depth > 64 || !isRecord(raw) || typeof raw.type !== "string") return null;
  if (raw.type === "group") {
    if (typeof raw.groupId !== "string" || !groups[raw.groupId]) return null;
    return { type: "group", groupId: raw.groupId };
  }
  if (raw.type !== "split") return null;

  const children = Array.isArray(raw.children) ? raw.children : [];
  if (children.length !== 2) return null;
  const first = sanitizeLayoutNode(children[0], groups, depth + 1);
  const second = sanitizeLayoutNode(children[1], groups, depth + 1);
  if (!first || !second) return null;

  const direction =
    raw.direction === "vertical" ? "vertical" : "horizontal";
  const ratioRaw =
    typeof raw.ratio === "number" && Number.isFinite(raw.ratio)
      ? raw.ratio
      : 0.5;
  const ratio = Math.min(0.9, Math.max(0.1, ratioRaw));
  const id = typeof raw.id === "string" && raw.id ? raw.i
isClaudeCodeTitle function · typescript · L659-L662 (4 LOC)
src/stores/workspaceStore.ts
function isClaudeCodeTitle(title: string): boolean {
  const lower = title.trim().toLowerCase();
  return lower === "claude" || lower.startsWith("claude ");
}
shouldRestoreAsClaudeLauncher function · typescript · L664-L672 (9 LOC)
src/stores/workspaceStore.ts
function shouldRestoreAsClaudeLauncher(pane: Pane): boolean {
  if (pane.type === "claude") return true;
  if (pane.type !== "terminal") return false;
  if (pane.scriptBufferKey) return false;
  if (isClaudeCodeTitle(pane.title)) return true;
  const command = (pane.command ?? "").trim().toLowerCase();
  if (!command) return false;
  return command === "claude" || command.startsWith("claude ") || command.includes("/claude ");
}
Powered by Repobility — scan your code at https://repobility.com
sanitizePaneForPreset function · typescript · L675-L684 (10 LOC)
src/stores/workspaceStore.ts
function sanitizePaneForPreset(pane: Pane): Pane {
  const { ptyId: _, scriptBufferKey: _2, ...rest } = pane;
  if (!shouldRestoreAsClaudeLauncher(rest)) return rest;
  return {
    id: rest.id,
    type: "claude-launcher" as const,
    title: rest.type === "claude" ? rest.title : "Claude Code",
    ...(rest.cwd ? { cwd: rest.cwd } : {}),
  };
}
restoreLayouts function · typescript · L687-L750 (64 LOC)
src/stores/workspaceStore.ts
function restoreLayouts(layouts: Record<string, WorkspaceLayout>): Record<string, WorkspaceLayout> {
  const restored: Record<string, WorkspaceLayout> = {};
  if (!isRecord(layouts)) return restored;

  for (const [wsId, rawLayout] of Object.entries(layouts)) {
    if (!isRecord(rawLayout)) {
      restored[wsId] = createDefaultLayout();
      continue;
    }

    const rawGroups = isRecord(rawLayout.groups) ? rawLayout.groups : {};
    const groups: Record<string, PaneGroup> = {};
    for (const [gId, group] of Object.entries(rawGroups)) {
      const sanitizedGroup = sanitizeGroup(group);
      if (!sanitizedGroup) continue;
      groups[gId] = {
        ...sanitizedGroup,
        id: gId,
        panes: sanitizedGroup.panes.map((p) => {
          // Strip stale ptyIds — PTYs don't survive app restart.
          // CWD is preserved — OSC 7 tracking keeps it up to date with
          // the shell's actual directory, so it's correct on restore.
          const { ptyId: _, ...rest } = p
flattenLayoutGroups function · typescript · L757-L770 (14 LOC)
src/stores/workspaceStore.ts
function flattenLayoutGroups(layout: WorkspaceLayout): PaneGroup[] {
  const groups: PaneGroup[] = [];
  function walk(node: LayoutNode) {
    if (node.type === "group") {
      const g = layout.groups[node.groupId];
      if (g) groups.push(g);
    } else {
      walk(node.children[0]);
      walk(node.children[1]);
    }
  }
  walk(layout.root);
  return groups;
}
walk function · typescript · L759-L767 (9 LOC)
src/stores/workspaceStore.ts
  function walk(node: LayoutNode) {
    if (node.type === "group") {
      const g = layout.groups[node.groupId];
      if (g) groups.push(g);
    } else {
      walk(node.children[0]);
      walk(node.children[1]);
    }
  }
arraysEqual function · typescript · L772-L779 (8 LOC)
src/stores/workspaceStore.ts
function arraysEqual(a: string[], b: string[]): boolean {
  if (a === b) return true;
  if (a.length !== b.length) return false;
  for (let i = 0; i < a.length; i++) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}
gitStatusEqual function · typescript · L781-L792 (12 LOC)
src/stores/workspaceStore.ts
function gitStatusEqual(a: GitStatus, b: GitStatus): boolean {
  return (
    a.branch === b.branch &&
    a.dirty === b.dirty &&
    a.ahead === b.ahead &&
    a.behind === b.behind &&
    a.tracking_ahead === b.tracking_ahead &&
    a.tracking_behind === b.tracking_behind &&
    arraysEqual(a.modified_files, b.modified_files) &&
    arraysEqual(a.untracked_files, b.untracked_files)
  );
}
prStatusEqual function · typescript · L794-L807 (14 LOC)
src/stores/workspaceStore.ts
function prStatusEqual(a: PrStatus | null, b: PrStatus | null): boolean {
  if (a === b) return true;
  if (!a || !b) return false;
  return (
    a.number === b.number &&
    a.title === b.title &&
    a.url === b.url &&
    a.state === b.state &&
    a.is_draft === b.is_draft &&
    a.mergeable === b.mergeable &&
    a.review_decision === b.review_decision &&
    a.checks_status === b.checks_status
  );
}
remapTree function · typescript · L2927-L2936 (10 LOC)
src/stores/workspaceStore.ts
    function remapTree(node: LayoutNode): LayoutNode {
      if (node.type === "group") {
        return { type: "group", groupId: groupIdMap.get(node.groupId) ?? node.groupId };
      }
      return {
        ...node,
        id: crypto.randomUUID(),
        children: [remapTree(node.children[0]), remapTree(node.children[1])],
      };
    }
Same scanner, your repo: https://repobility.com — Repobility
isClaudeActiveInWorkspace function · typescript · L3818-L3829 (12 LOC)
src/stores/workspaceStore.ts
export function isClaudeActiveInWorkspace(workspaceId: string | null): boolean {
  if (!workspaceId) return false;
  const state = useWorkspaceStore.getState();
  const layout = state.layouts[workspaceId];
  if (!layout) return false;
  for (const group of Object.values(layout.groups)) {
    for (const pane of group.panes) {
      if (pane.type === "claude" && pane.title === "claude") return true;
    }
  }
  return false;
}
normalizeLayoutTree function · typescript · L3837-L3881 (45 LOC)
src/stores/workspaceStore.ts
function normalizeLayoutTree(node: LayoutNode): LayoutNode {
  if (node.type === "group") return node;

  // Recursively normalize children first
  const c0 = normalizeLayoutTree(node.children[0]);
  const c1 = normalizeLayoutTree(node.children[1]);

  // Check for H(V, V) pattern
  if (
    node.direction === "horizontal" &&
    c0.type === "split" && c0.direction === "vertical" &&
    c1.type === "split" && c1.direction === "vertical"
  ) {
    // H(r_h, V(r_v1, A, C), V(r_v2, B, D))
    // → V(r_v1, H(r_h, A, B), H(r_h, C, D))
    return {
      type: "split",
      id: c0.id,
      direction: "vertical",
      ratio: c0.ratio,
      children: [
        {
          type: "split",
          id: node.id,
          direction: "horizontal",
          ratio: node.ratio,
          children: [c0.children[0], c1.children[0]],
        },
        {
          type: "split",
          id: c1.id,
          direction: "horizontal",
          ratio: node.ratio,
          children: [c0.children[1],
findSplitById function · typescript · L3884-L3887 (4 LOC)
src/stores/workspaceStore.ts
function findSplitById(
  node: LayoutNode,
  id: string
): Extract<LayoutNode, { type: "split" }> | null {
collectPeerVerticalSplits function · typescript · L3902-L3909 (8 LOC)
src/stores/workspaceStore.ts
function collectPeerVerticalSplits(node: LayoutNode): string[] {
  if (node.type === "group") return [];
  if (node.direction === "vertical") return [node.id];
  return [
    ...collectPeerVerticalSplits(node.children[0]),
    ...collectPeerVerticalSplits(node.children[1]),
  ];
}
collectPeerHorizontalSplits function · typescript · L3915-L3922 (8 LOC)
src/stores/workspaceStore.ts
function collectPeerHorizontalSplits(node: LayoutNode): string[] {
  if (node.type === "group") return [];
  if (node.direction === "horizontal") return [node.id];
  return [
    ...collectPeerHorizontalSplits(node.children[0]),
    ...collectPeerHorizontalSplits(node.children[1]),
  ];
}
snapToPeerRatio function · typescript · L3930-L3958 (29 LOC)
src/stores/workspaceStore.ts
function snapToPeerRatio(
  root: LayoutNode,
  splitId: string,
  ratio: number
): number {
  // Walk up to find the nearest vertical ancestor
  let currentId = splitId;
  let ancestor: Extract<LayoutNode, { type: "split" }> | null = null;
  while (true) {
    const parentInfo = findParent(root, currentId);
    if (!parentInfo) break;
    if (parentInfo.parent.direction === "vertical") {
      ancestor = parentInfo.parent;
      break;
    }
    currentId = parentInfo.parent.id;
  }
  if (!ancestor) return ratio;

  const peerIds = collectPeerHorizontalSplits(ancestor);
  for (const peerId of peerIds) {
    if (peerId === splitId) continue;
    const peer = findSplitById(root, peerId);
    if (peer && Math.abs(ratio - peer.ratio) < SNAP_THRESHOLD) {
      return peer.ratio;
    }
  }
  return ratio;
}
syncPeers function · typescript · L3965-L3999 (35 LOC)
src/stores/workspaceStore.ts
function syncPeers(
  root: LayoutNode,
  changedSplitId: string,
  ratio: number,
  direction: "vertical" | "horizontal"
): LayoutNode {
  const oppositeDirection = direction === "vertical" ? "horizontal" : "vertical";
  const collectPeers = direction === "vertical" ? collectPeerVerticalSplits : collectPeerHorizontalSplits;

  // Walk up to find the nearest opposite-direction ancestor
  let currentId = changedSplitId;
  let ancestor: Extract<LayoutNode, { type: "split" }> | null = null;
  while (true) {
    const parentInfo = findParent(root, currentId);
    if (!parentInfo) break;
    if (parentInfo.parent.direction === oppositeDirection) {
      ancestor = parentInfo.parent;
      break;
    }
    currentId = parentInfo.parent.id;
  }
  if (!ancestor) return root;

  const peerIds = collectPeers(ancestor);

  let result = root;
  for (const peerId of peerIds) {
    if (peerId === changedSplitId) continue;
    const peer = findSplitById(result, peerId);
    if (peer) {
      result =
syncPeerVerticalSplits function · typescript · L4001-L4005 (5 LOC)
src/stores/workspaceStore.ts
function syncPeerVerticalSplits(
  root: LayoutNode, changedSplitId: string, ratio: number
): LayoutNode {
  return syncPeers(root, changedSplitId, ratio, "vertical");
}
Repobility · open methodology · https://repobility.com/research/
syncPeerHorizontalSplits function · typescript · L4007-L4011 (5 LOC)
src/stores/workspaceStore.ts
function syncPeerHorizontalSplits(
  root: LayoutNode, changedSplitId: string, ratio: number
): LayoutNode {
  return syncPeers(root, changedSplitId, ratio, "horizontal");
}
main function · rust · L1-L3 (3 LOC)
src-tauri/build.rs
fn main() {
    tauri_build::build()
}
getStoreState function · javascript · L21-L26 (6 LOC)
src-tauri/resources/test-bridge.js
  function getStoreState() {
    if (window.__rallyStoreAccessor) {
      return window.__rallyStoreAccessor();
    }
    return null;
  }
querySelector function · javascript · L28-L30 (3 LOC)
src-tauri/resources/test-bridge.js
  function querySelector(selector) {
    return document.querySelector(selector);
  }
querySelectorAll function · javascript · L32-L34 (3 LOC)
src-tauri/resources/test-bridge.js
  function querySelectorAll(selector) {
    return document.querySelectorAll(selector);
  }
check function · javascript · L164-L174 (11 LOC)
src-tauri/resources/test-bridge.js
        function check() {
          var state = getStoreState();
          if (!state) return false;
          var parts = path.split('.');
          var current = state;
          for (var i = 0; i < parts.length; i++) {
            if (current == null) return false;
            current = current[parts[i]];
          }
          return current === value;
        }
start function · rust · L10-L69 (60 LOC)
src-tauri/src/cli_server.rs
pub fn start(app_handle: tauri::AppHandle) {
    std::thread::spawn(move || {
        let listener = match TcpListener::bind(format!("127.0.0.1:{}", PORT)) {
            Ok(l) => l,
            Err(e) => {
                eprintln!("CLI server failed to bind on port {}: {}", PORT, e);
                return;
            }
        };

        for stream in listener.incoming() {
            let mut stream = match stream {
                Ok(s) => s,
                Err(_) => continue,
            };

            let mut buf = [0u8; 8192];
            let n = match stream.read(&mut buf) {
                Ok(n) if n > 0 => n,
                _ => continue,
            };

            let request = String::from_utf8_lossy(&buf[..n]);

            if let Some(path) = parse_request(&request) {
                // Emit event to the focused window (or all windows)
                let focused = app_handle
                    .webview_windows()
                    .into_values()
                  
parse_request function · rust · L73-L99 (27 LOC)
src-tauri/src/cli_server.rs
fn parse_request(request: &str) -> Option<String> {
    let first_line = request.lines().next()?;
    let parts: Vec<&str> = first_line.split_whitespace().collect();
    if parts.len() < 2 {
        return None;
    }

    let method = parts[0];
    let uri = parts[1];

    if uri != "/open" {
        return None;
    }

    if method == "POST" {
        // Body is after the blank line
        let body_start = request.find("\r\n\r\n").map(|i| i + 4)
            .or_else(|| request.find("\n\n").map(|i| i + 2))?;
        let body = request[body_start..].trim();
        if body.is_empty() || !body.starts_with('/') {
            return None;
        }
        Some(body.to_string())
    } else {
        None
    }
}
Open data scored by Repobility · https://repobility.com
emit_workspaces_updated function · rust · L11-L16 (6 LOC)
src-tauri/src/commands.rs
fn emit_workspaces_updated(app: &tauri::AppHandle) {
    if let Err(e) = app.emit("rally-workspaces-updated", ()) {
        eprintln!("Failed to emit rally-workspaces-updated: {}", e);
    }
}
list_directory function · rust · L28-L60 (33 LOC)
src-tauri/src/commands.rs
pub fn list_directory(path: String) -> Result<Vec<FileEntry>, String> {
    let dir = Path::new(&path);
    if !dir.is_dir() {
        return Err(format!("Not a directory: {}", path));
    }

    let mut entries: Vec<FileEntry> = fs::read_dir(dir)
        .map_err(|e| e.to_string())?
        .filter_map(|entry| {
            let entry = entry.ok()?;
            let name = entry.file_name().to_string_lossy().to_string();
            let is_dir = entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false);

            // Skip hidden/large dirs
            if is_dir && HIDDEN_DIRS.contains(&name.as_str()) {
                return None;
            }

            Some(FileEntry {
                name,
                path: entry.path().to_string_lossy().to_string(),
                is_dir,
            })
        })
        .collect();

    // Sort: directories first, then alphabetical
    entries.sort_by(|a, b| {
        b.is_dir.cmp(&a.is_dir).then(a.name.to_lowercase().cmp(&b.name.to_lower
list_gitignored function · rust · L65-L112 (48 LOC)
src-tauri/src/commands.rs
pub fn list_gitignored(dir_path: String) -> Result<Vec<String>, String> {
    // Read directory entries
    let entries: Vec<String> = fs::read_dir(&dir_path)
        .map_err(|e| format!("Failed to read directory: {}", e))?
        .filter_map(|entry| entry.ok())
        .map(|entry| entry.file_name().to_string_lossy().to_string())
        .collect();

    if entries.is_empty() {
        return Ok(Vec::new());
    }

    // Build list of full paths to check
    let paths: Vec<String> = entries.iter()
        .map(|name| format!("{}/{}", dir_path, name))
        .collect();

    // Run git check-ignore with all paths at once
    let mut cmd = Command::new("git");
    cmd.args(["check-ignore"])
        .args(&paths)
        .current_dir(&dir_path);

    let output = cmd.output();

    match output {
        Ok(out) => {
            // git check-ignore prints one ignored path per line.
            // Exit code 1 means no files are ignored (not an error).
            let stdout = String::
detect_git_info function · rust · L123-L134 (12 LOC)
src-tauri/src/commands.rs
pub async fn detect_git_info(path: String) -> Result<GitRepoInfo, String> {
    let repo_url = git_ops::git_cmd(&path, &["remote", "get-url", "origin"]).await
        .unwrap_or_default();
    let branch = git_ops::git_cmd(&path, &["symbolic-ref", "--short", "HEAD"]).await
        .unwrap_or_else(|_| "main".to_string());
    let name = Path::new(&path)
        .file_name()
        .map(|n| n.to_string_lossy().to_string())
        .unwrap_or_else(|| "workspace".to_string());

    Ok(GitRepoInfo { repo_url, branch, name })
}
list_workspaces function · rust · L137-L139 (3 LOC)
src-tauri/src/commands.rs
pub fn list_workspaces() -> Vec<Workspace> {
    workspace::load_workspaces()
}
update_git_watch_roots function · rust · L142-L148 (7 LOC)
src-tauri/src/commands.rs
pub fn update_git_watch_roots(
    app: tauri::AppHandle,
    watch_state: tauri::State<'_, GitWatchState>,
    roots: Vec<String>,
) -> Result<(), String> {
    watch_state.update_roots(app, roots)
}
create_workspace function · rust · L151-L182 (32 LOC)
src-tauri/src/commands.rs
pub async fn create_workspace(
    app: tauri::AppHandle,
    name: String,
    paths: Vec<String>,
) -> Result<Workspace, String> {
    if paths.is_empty() {
        return Err("At least one path is required".to_string());
    }
    let mut workspaces = workspace::load_workspaces();

    // Auto-detect git info from the primary path
    let primary = &paths[0];
    let repo_url = git_ops::git_cmd(primary, &["remote", "get-url", "origin"]).await
        .unwrap_or_default();
    let branch = git_ops::git_cmd(primary, &["rev-parse", "--abbrev-ref", "HEAD"]).await
        .unwrap_or_else(|_| "main".to_string());

    let ws = Workspace {
        id: uuid::Uuid::new_v4().to_string(),
        name,
        paths,
        repo_url,
        branch,
        main_branch: "main".to_string(),
        processes: vec![],
    };

    workspaces.push(ws.clone());
    workspace::save_workspaces(&workspaces)?;
    emit_workspaces_updated(&app);
    Ok(ws)
}
remove_workspace function · rust · L185-L191 (7 LOC)
src-tauri/src/commands.rs
pub fn remove_workspace(app: tauri::AppHandle, id: String) -> Result<(), String> {
    let mut workspaces = workspace::load_workspaces();
    workspaces.retain(|w| w.id != id);
    workspace::save_workspaces(&workspaces)?;
    emit_workspaces_updated(&app);
    Ok(())
}
Powered by Repobility — scan your code at https://repobility.com
reorder_workspace function · rust · L194-L220 (27 LOC)
src-tauri/src/commands.rs
pub fn reorder_workspace(
    app: tauri::AppHandle,
    id: String,
    to_index: usize,
) -> Result<(), String> {
    let mut workspaces = workspace::load_workspaces();
    if workspaces.len() <= 1 {
        return Ok(());
    }

    let from_index = workspaces
        .iter()
        .position(|w| w.id == id)
        .ok_or_else(|| format!("Workspace not found: {}", id))?;

    let target = to_index.min(workspaces.len() - 1);
    if from_index == target {
        return Ok(());
    }

    let workspace = workspaces.remove(from_index);
    workspaces.insert(target, workspace);

    workspace::save_workspaces(&workspaces)?;
    emit_workspaces_updated(&app);
    Ok(())
}
rename_workspace function · rust · L223-L237 (15 LOC)
src-tauri/src/commands.rs
pub fn rename_workspace(app: tauri::AppHandle, id: String, name: String) -> Result<(), String> {
    let trimmed = name.trim().to_string();
    if trimmed.is_empty() {
        return Err("Workspace name cannot be empty".to_string());
    }
    let mut workspaces = workspace::load_workspaces();
    let ws = workspaces
        .iter_mut()
        .find(|w| w.id == id)
        .ok_or_else(|| format!("Workspace not found: {}", id))?;
    ws.name = trimmed;
    workspace::save_workspaces(&workspaces)?;
    emit_workspaces_updated(&app);
    Ok(())
}
add_workspace_path function · rust · L240-L259 (20 LOC)
src-tauri/src/commands.rs
pub fn add_workspace_path(
    app: tauri::AppHandle,
    id: String,
    path: String,
) -> Result<Workspace, String> {
    let mut workspaces = workspace::load_workspaces();
    let ws = workspaces
        .iter_mut()
        .find(|w| w.id == id)
        .ok_or_else(|| format!("Workspace not found: {}", id))?;

    if !ws.paths.contains(&path) {
        ws.paths.push(path);
    }

    let result = ws.clone();
    workspace::save_workspaces(&workspaces)?;
    emit_workspaces_updated(&app);
    Ok(result)
}
‹ prevpage 6 / 10next ›