← back to jpdlr__hydra

Function bodies 224 total

All specs Real LLM only Function bodies
SessionCatalog.getSessionSnapshot method · typescript · L93-L103 (11 LOC)
electron/sessions/SessionCatalog.ts
  private getSessionSnapshot(forceRefresh: boolean): ClaudeSessionSummary[] {
    if (forceRefresh || this.cacheTtlMs <= 0) {
      return this.refreshCache()
    }

    const now = Date.now()
    if (this.cache && this.cache.expiresAt > now) {
      return this.cache.sessions
    }
    return this.refreshCache()
  }
SessionCatalog.refreshCache method · typescript · L105-L116 (12 LOC)
electron/sessions/SessionCatalog.ts
  private refreshCache(): ClaudeSessionSummary[] {
    const sessions = this.scanProjects()
    if (this.cacheTtlMs > 0) {
      this.cache = {
        sessions,
        expiresAt: Date.now() + this.cacheTtlMs
      }
    } else {
      this.cache = null
    }
    return sessions
  }
SessionCatalog.scanProjects method · typescript · L118-L130 (13 LOC)
electron/sessions/SessionCatalog.ts
  private scanProjects(): ClaudeSessionSummary[] {
    if (!existsSync(this.projectsDir)) return []

    const sessions: ClaudeSessionSummary[] = []
    const projects = readdirSync(this.projectsDir, { withFileTypes: true })
      .filter((entry) => entry.isDirectory())
      .map((entry) => join(this.projectsDir, entry.name))

    for (const projectDir of projects) {
      sessions.push(...this.readProjectSessions(projectDir))
    }
    return sessions
  }
SessionCatalog.readProjectSessions method · typescript · L132-L145 (14 LOC)
electron/sessions/SessionCatalog.ts
  private readProjectSessions(projectDir: string): ClaudeSessionSummary[] {
    const sessions: ClaudeSessionSummary[] = []
    const seenSessionIds = new Set<string>()

    const indexPath = join(projectDir, INDEX_FILENAME)
    if (existsSync(indexPath)) {
      sessions.push(...this.readFromSessionsIndex(indexPath, seenSessionIds))
    }

    // Fallback for project folders without sessions-index.json (or missing entries).
    sessions.push(...this.readFromJsonlFiles(projectDir, seenSessionIds))

    return sessions
  }
SessionCatalog.readFromSessionsIndex method · typescript · L147-L180 (34 LOC)
electron/sessions/SessionCatalog.ts
  private readFromSessionsIndex(indexPath: string, seenSessionIds: Set<string>): ClaudeSessionSummary[] {
    try {
      const raw = readFileSync(indexPath, 'utf-8')
      const parsed = JSON.parse(raw) as SessionsIndexFile
      const entries = parsed.entries ?? []

      return entries
        .filter((entry) => !!entry.sessionId && !!entry.fullPath)
        .map((entry) => {
          seenSessionIds.add(entry.sessionId)

          const modifiedAt =
            entry.modified ??
            (entry.fileMtime ? new Date(entry.fileMtime).toISOString() : new Date().toISOString())

          const createdAt = entry.created ?? modifiedAt

          return {
            sessionId: entry.sessionId,
            projectPath: entry.projectPath ?? parsed.originalPath ?? '',
            firstPrompt: (entry.firstPrompt ?? '').trim(),
            messageCount: Math.max(0, entry.messageCount ?? 0),
            createdAt,
            modifiedAt,
            gitBranch: entry.gitBranch ?? null,
     
SessionCatalog.readFromJsonlFiles method · typescript · L182-L220 (39 LOC)
electron/sessions/SessionCatalog.ts
  private readFromJsonlFiles(projectDir: string, seenSessionIds: Set<string>): ClaudeSessionSummary[] {
    let files: string[] = []
    try {
      files = readdirSync(projectDir, { withFileTypes: true })
        .filter((entry) => entry.isFile() && entry.name.endsWith('.jsonl'))
        .map((entry) => join(projectDir, entry.name))
    } catch {
      return []
    }

    const sessions: ClaudeSessionSummary[] = []

    for (const filePath of files) {
      const sessionId = basename(filePath, '.jsonl')
      if (seenSessionIds.has(sessionId)) continue

      const stat = statSync(filePath)
      if (stat.size <= 0) continue

      const header = this.readJsonlHeader(filePath)
      if (!header) continue

      seenSessionIds.add(header.sessionId)

      sessions.push({
        sessionId: header.sessionId,
        projectPath: header.cwd,
        firstPrompt: header.firstPrompt,
        messageCount: 0,
        createdAt: stat.birthtime.toISOString(),
        modifiedAt: stat.mtime.t
SessionCatalog.readJsonlHeader method · typescript · L222-L282 (61 LOC)
electron/sessions/SessionCatalog.ts
  private readJsonlHeader(filePath: string): JsonlHeader | null {
    try {
      const raw = readFileSync(filePath, 'utf-8').slice(0, JSONL_MAX_HEADER_CHARS)
      const lines = raw.split('\n')

      let sessionId = ''
      let cwd = ''
      let gitBranch: string | null = null
      let isSidechain = false
      let firstPrompt = ''

      for (const line of lines) {
        const trimmed = line.trim()
        if (!trimmed) continue

        let record: unknown
        try {
          record = JSON.parse(trimmed)
        } catch {
          continue
        }

        if (!record || typeof record !== 'object') continue
        const object = record as Record<string, unknown>

        if (!sessionId && typeof object.sessionId === 'string') {
          sessionId = object.sessionId
        }
        if (!cwd && typeof object.cwd === 'string') {
          cwd = object.cwd
        }
        if (!gitBranch && typeof object.gitBranch === 'string') {
          gitBranch = object.gitBranch
Repobility · code-quality intelligence · https://repobility.com
normalizeReleaseNotes function · typescript · L6-L23 (18 LOC)
electron/updates/UpdateService.ts
function normalizeReleaseNotes(notes: unknown): string | null {
  if (typeof notes === 'string') {
    return notes.trim() || null
  }

  if (Array.isArray(notes)) {
    const lines = notes
      .map((entry) => {
        if (!entry || typeof entry !== 'object') return ''
        const maybeNotes = (entry as { note?: unknown }).note
        return typeof maybeNotes === 'string' ? maybeNotes.trim() : ''
      })
      .filter(Boolean)
    return lines.length > 0 ? lines.join('\n\n') : null
  }

  return null
}
UpdateService.constructor method · typescript · L28-L107 (80 LOC)
electron/updates/UpdateService.ts
  constructor() {
    super()
    const supported = process.platform === 'win32'

    this.state = {
      supported,
      platform: process.platform,
      checking: false,
      available: false,
      downloaded: false,
      downloading: false,
      currentVersion: app.getVersion(),
      latestVersion: null,
      releaseDate: null,
      releaseNotes: null,
      error: null
    }

    if (!supported) return

    autoUpdater.autoDownload = false
    autoUpdater.autoInstallOnAppQuit = true

    autoUpdater.on('checking-for-update', () => {
      this.patch({ checking: true, error: null })
    })

    autoUpdater.on('update-available', (info) => {
      this.patch({
        checking: false,
        available: true,
        downloaded: false,
        latestVersion: info.version ?? null,
        releaseDate: info.releaseDate ?? null,
        releaseNotes: normalizeReleaseNotes(info.releaseNotes),
        error: null
      })
    })

    autoUpdater.on('update-not-available', () => 
UpdateService.checkForUpdates method · typescript · L113-L118 (6 LOC)
electron/updates/UpdateService.ts
  async checkForUpdates(): Promise<AppUpdateState> {
    if (!this.state.supported) return this.getState()
    this.patch({ error: null, checking: true })
    await autoUpdater.checkForUpdates()
    return this.getState()
  }
UpdateService.downloadUpdate method · typescript · L120-L126 (7 LOC)
electron/updates/UpdateService.ts
  async downloadUpdate(): Promise<AppUpdateState> {
    if (!this.state.supported) return this.getState()
    if (!this.state.available) return this.getState()
    this.patch({ error: null, downloading: true })
    await autoUpdater.downloadUpdate()
    return this.getState()
  }
UpdateService.installAndRestart method · typescript · L128-L134 (7 LOC)
electron/updates/UpdateService.ts
  installAndRestart(): boolean {
    if (!this.state.supported || !this.state.downloaded) return false
    setImmediate(() => {
      autoUpdater.quitAndInstall(false, true)
    })
    return true
  }
UsageTracker.mkdirSync method · typescript · L86-L96 (11 LOC)
electron/usage/UsageTracker.ts
    mkdirSync(dataDir, { recursive: true })
    this.usagePath = join(dataDir, 'usage.json')
    this.store = this.load()
  }

  recordAgentOutput(
    agent: AgentState,
    rawData: string,
    config: AppConfig,
    now: Date = new Date()
  ): { changed: boolean; alerts: UsageBudgetAlert[]; summary: UsageDailySummary | null } {
UsageTracker.getDashboard method · typescript · L155-L186 (32 LOC)
electron/usage/UsageTracker.ts
  getDashboard(config: AppConfig, options?: UsageDashboardOptions): UsageDashboardSnapshot {
    const dayLimit = Math.max(1, Math.min(90, options?.days ?? 14))
    this.pruneOldDays()

    const days = Object.keys(this.store.days)
      .sort((a, b) => b.localeCompare(a))
      .slice(0, dayLimit)
      .map((date) => this.buildDaySummary(date))
      .filter((summary): summary is UsageDailySummary => summary !== null)

    const todayDate = toDateKey(new Date())
    const today =
      days.find((summary) => summary.date === todayDate) ??
      this.buildDaySummary(todayDate) ??
      createEmptyDaySummary(todayDate)

    const finalDays = [...days]
    if (!finalDays.some((summary) => summary.date === today.date)) {
      finalDays.unshift(today)
    }

    if (finalDays.length > dayLimit) {
      finalDays.length = dayLimit
    }

    return {
      generatedAt: new Date().toISOString(),
      today,
      days: finalDays,
      budget: buildBudgetStatus(today, config)
    }
  }
UsageTracker.createEmptyDaySummary method · typescript · L169-L174 (6 LOC)
electron/usage/UsageTracker.ts
      createEmptyDaySummary(todayDate)

    const finalDays = [...days]
    if (!finalDays.some((summary) => summary.date === today.date)) {
      finalDays.unshift(today)
    }
Repobility · severity-and-effort ranking · https://repobility.com
UsageTracker.createStoredAgent method · typescript · L188-L200 (13 LOC)
electron/usage/UsageTracker.ts
  private createStoredAgent(agent: AgentState, now: Date): StoredUsageAgent {
    return {
      agentId: agent.id,
      agentName: agent.name,
      projectDir: agent.projectDir,
      projectName: basename(agent.projectDir) || agent.projectDir || 'Workspace',
      provider: agent.provider,
      model: agent.model,
      tokens: 0,
      costUsd: 0,
      updatedAt: now.toISOString()
    }
  }
UsageTracker.ensureDay method · typescript · L202-L221 (20 LOC)
electron/usage/UsageTracker.ts
  private ensureDay(dateKey: string, now: Date): StoredUsageDay {
    if (!this.store.days[dateKey]) {
      this.store.days[dateKey] = {
        date: dateKey,
        updatedAt: now.toISOString(),
        agents: {}
      }
    }

    if (!this.store.alerts[dateKey]) {
      this.store.alerts[dateKey] = {
        tokenWarningSent: false,
        tokenExceededSent: false,
        costWarningSent: false,
        costExceededSent: false
      }
    }

    return this.store.days[dateKey]
  }
UsageTracker.buildDaySummary method · typescript · L223-L286 (64 LOC)
electron/usage/UsageTracker.ts
  private buildDaySummary(dateKey: string): UsageDailySummary | null {
    const day = this.store.days[dateKey]
    if (!day) return null

    const agents: UsageAgentDailyStat[] = Object.values(day.agents)
      .map((agent) => ({
        ...agent,
        tokens: Math.max(0, Math.round(agent.tokens)),
        costUsd: roundCost(agent.costUsd)
      }))
      .sort((a, b) => {
        if (b.costUsd !== a.costUsd) return b.costUsd - a.costUsd
        if (b.tokens !== a.tokens) return b.tokens - a.tokens
        return a.agentName.localeCompare(b.agentName)
      })

    let totalTokens = 0
    let totalCost = 0
    const projects = new Map<string, UsageProjectDailyStat>()
    const projectAgentSets = new Map<string, Set<string>>()

    for (const agent of agents) {
      totalTokens += agent.tokens
      totalCost += agent.costUsd

      const existingProject = projects.get(agent.projectDir) ?? {
        projectDir: agent.projectDir,
        projectName: agent.projectName,
        agen
UsageTracker.evaluateBudgetTransitions method · typescript · L288-L354 (67 LOC)
electron/usage/UsageTracker.ts
  private evaluateBudgetTransitions(
    dateKey: string,
    summary: UsageDailySummary,
    config: AppConfig
  ): UsageBudgetAlert[] {
    const alerts: UsageBudgetAlert[] = []
    const state = this.store.alerts[dateKey]
    if (!state) return alerts

    const warningThreshold = clampWarningThreshold(config.usageBudgetWarningThresholdPct)
    const tokenBudget = config.usageDailyTokenBudget > 0 ? config.usageDailyTokenBudget : 0
    const costBudget = config.usageDailyCostBudgetUsd > 0 ? config.usageDailyCostBudgetUsd : 0

    if (tokenBudget > 0) {
      const thresholdValue = tokenBudget * (warningThreshold / 100)
      if (summary.tokens >= thresholdValue && !state.tokenWarningSent) {
        state.tokenWarningSent = true
        alerts.push({
          date: dateKey,
          metric: 'tokens',
          level: 'warning',
          usage: summary.tokens,
          budget: tokenBudget,
          percent: (summary.tokens / tokenBudget) * 100
        })
      }
      if (summary.
UsageTracker.load method · typescript · L356-L377 (22 LOC)
electron/usage/UsageTracker.ts
  private load(): UsageStore {
    try {
      if (existsSync(this.usagePath)) {
        const parsed = JSON.parse(readFileSync(this.usagePath, 'utf-8')) as Partial<UsageStore>
        if (parsed && typeof parsed === 'object') {
          return {
            schemaVersion: USAGE_SCHEMA_VERSION,
            days: sanitizeDayMap(parsed.days),
            alerts: sanitizeAlertMap(parsed.alerts)
          }
        }
      }
    } catch {
      // Best effort load. Corrupted state resets to empty.
    }

    return {
      schemaVersion: USAGE_SCHEMA_VERSION,
      days: {},
      alerts: {}
    }
  }
UsageTracker.save method · typescript · L379-L385 (7 LOC)
electron/usage/UsageTracker.ts
  private save(): void {
    try {
      writeFileSync(this.usagePath, JSON.stringify(this.store, null, 2), 'utf-8')
    } catch {
      // Best effort persistence.
    }
  }
UsageTracker.pruneOldDays method · typescript · L387-L396 (10 LOC)
electron/usage/UsageTracker.ts
  private pruneOldDays(): void {
    const dayKeys = Object.keys(this.store.days).sort((a, b) => b.localeCompare(a))
    if (dayKeys.length <= MAX_RETAINED_DAYS) return

    for (const key of dayKeys.slice(MAX_RETAINED_DAYS)) {
      delete this.store.days[key]
      delete this.store.alerts[key]
    }
    this.save()
  }
sanitizeDayMap function · typescript · L399-L416 (18 LOC)
electron/usage/UsageTracker.ts
function sanitizeDayMap(input: unknown): Record<string, StoredUsageDay> {
  if (!input || typeof input !== 'object') return {}
  const out: Record<string, StoredUsageDay> = {}

  for (const [date, day] of Object.entries(input as Record<string, unknown>)) {
    if (!day || typeof day !== 'object') continue
    const dayObject = day as Partial<StoredUsageDay>
    if (typeof dayObject.date !== 'string') continue
    const agents = sanitizeAgentMap(dayObject.agents)
    out[date] = {
      date: dayObject.date,
      updatedAt: typeof dayObject.updatedAt === 'string' ? dayObject.updatedAt : new Date().toISOString(),
      agents
    }
  }

  return out
}
Open data scored by Repobility · https://repobility.com
sanitizeAgentMap function · typescript · L418-L450 (33 LOC)
electron/usage/UsageTracker.ts
function sanitizeAgentMap(input: unknown): Record<string, StoredUsageAgent> {
  if (!input || typeof input !== 'object') return {}
  const out: Record<string, StoredUsageAgent> = {}

  for (const [agentId, value] of Object.entries(input as Record<string, unknown>)) {
    if (!value || typeof value !== 'object') continue
    const entry = value as Partial<StoredUsageAgent>
    if (
      typeof entry.agentId !== 'string' ||
      typeof entry.agentName !== 'string' ||
      typeof entry.projectDir !== 'string' ||
      typeof entry.projectName !== 'string' ||
      typeof entry.provider !== 'string' ||
      typeof entry.model !== 'string'
    ) {
      continue
    }

    out[agentId] = {
      agentId: entry.agentId,
      agentName: entry.agentName,
      projectDir: entry.projectDir,
      projectName: entry.projectName,
      provider: entry.provider,
      model: entry.model,
      tokens: sanitizeTokenCount(entry.tokens),
      costUsd: typeof entry.costUsd === 'number' && Number
sanitizeAlertMap function · typescript · L452-L468 (17 LOC)
electron/usage/UsageTracker.ts
function sanitizeAlertMap(input: unknown): Record<string, StoredBudgetAlertState> {
  if (!input || typeof input !== 'object') return {}
  const out: Record<string, StoredBudgetAlertState> = {}

  for (const [date, value] of Object.entries(input as Record<string, unknown>)) {
    if (!value || typeof value !== 'object') continue
    const entry = value as Partial<StoredBudgetAlertState>
    out[date] = {
      tokenWarningSent: entry.tokenWarningSent === true,
      tokenExceededSent: entry.tokenExceededSent === true,
      costWarningSent: entry.costWarningSent === true,
      costExceededSent: entry.costExceededSent === true
    }
  }

  return out
}
parseUsageSignals function · typescript · L470-L541 (72 LOC)
electron/usage/UsageTracker.ts
function parseUsageSignals(rawData: string): UsageSignals {
  const cleaned = rawData.replace(ANSI_REGEX, '').replace(CONTROL_CHARS, '')
  const lines = cleaned.split(/\r?\n/)

  let tokenCount: number | null = null
  let costSessionUsd: number | null = null
  let costTodayUsd: number | null = null

  for (const line of lines) {
    const trimmed = line.trim()
    if (!trimmed) continue

    const tokenOnlyMatch = trimmed.match(TOKEN_ONLY_PATTERN)
    if (tokenOnlyMatch?.[1]) {
      const parsed = parseTokenCount(tokenOnlyMatch[1])
      if (parsed !== null) {
        tokenCount = tokenCount === null ? parsed : Math.max(tokenCount, parsed)
      }
    }

    const tokenPrefixMatch = trimmed.match(TOKEN_COUNT_PREFIX_PATTERN)
    if (tokenPrefixMatch?.[1]) {
      const parsed = parseTokenCount(tokenPrefixMatch[1])
      if (parsed !== null) {
        tokenCount = tokenCount === null ? parsed : Math.max(tokenCount, parsed)
      }
    }

    const contextUsageMatch = trimmed.match(CONTE
parseTokenCount function · typescript · L549-L554 (6 LOC)
electron/usage/UsageTracker.ts
function parseTokenCount(value: string): number | null {
  const parsed = parseNumeric(value)
  if (parsed === null) return null
  if (parsed > MAX_TOKEN_SIGNAL) return null
  return parsed
}
sanitizeTokenCount function · typescript · L556-L564 (9 LOC)
electron/usage/UsageTracker.ts
function sanitizeTokenCount(value: unknown): number {
  if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
    return 0
  }
  if (value > MAX_TOKEN_SIGNAL) {
    return 0
  }
  return value
}
toDateKey function · typescript · L566-L571 (6 LOC)
electron/usage/UsageTracker.ts
function toDateKey(date: Date): string {
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  return `${year}-${month}-${day}`
}
buildBudgetStatus function · typescript · L582-L604 (23 LOC)
electron/usage/UsageTracker.ts
function buildBudgetStatus(today: UsageDailySummary | null, config: AppConfig): UsageBudgetStatus {
  const threshold = clampWarningThreshold(config.usageBudgetWarningThresholdPct)
  const tokenBudget = config.usageDailyTokenBudget > 0 ? config.usageDailyTokenBudget : null
  const costBudget = config.usageDailyCostBudgetUsd > 0 ? config.usageDailyCostBudgetUsd : null

  const tokenUsage = today?.tokens ?? 0
  const costUsage = today?.costUsd ?? 0

  const tokenUsagePct = tokenBudget ? (tokenUsage / tokenBudget) * 100 : null
  const costUsagePct = costBudget ? (costUsage / costBudget) * 100 : null

  return {
    dailyTokenBudget: tokenBudget,
    dailyCostBudgetUsd: costBudget,
    warningThresholdPct: threshold,
    tokenUsagePct,
    costUsagePct,
    tokenWarningReached: tokenBudget ? tokenUsage >= tokenBudget * (threshold / 100) : false,
    costWarningReached: costBudget ? costUsage >= costBudget * (threshold / 100) : false,
    tokenBudgetExceeded: tokenBudget ? tokenUsage >= tok
createEmptyDaySummary function · typescript · L606-L615 (10 LOC)
electron/usage/UsageTracker.ts
function createEmptyDaySummary(date: string): UsageDailySummary {
  return {
    date,
    tokens: 0,
    costUsd: 0,
    updatedAt: new Date().toISOString(),
    agents: [],
    projects: []
  }
}
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
appendPathEntries function · typescript · L12-L24 (13 LOC)
electron/util/fix-path.ts
function appendPathEntries(entries: Array<string | null | undefined>): void {
  const current = process.env.PATH ?? ''
  const existing = new Set(current.split(delimiter).filter((entry) => entry.length > 0))
  const merged = [...existing]

  for (const entry of entries) {
    if (!entry || entry.length === 0 || existing.has(entry)) continue
    existing.add(entry)
    merged.push(entry)
  }

  process.env.PATH = merged.join(delimiter)
}
fixPath function · typescript · L26-L60 (35 LOC)
electron/util/fix-path.ts
export function fixPath(): void {
  if (process.platform === 'win32') {
    const userHome = process.env.USERPROFILE || process.env.HOME
    appendPathEntries([
      process.env.APPDATA ? join(process.env.APPDATA, 'npm') : null,
      process.env.LOCALAPPDATA ? join(process.env.LOCALAPPDATA, 'Programs', 'nodejs') : null,
      userHome ? join(userHome, '.local', 'bin') : null
    ])
    return
  }

  if (process.platform !== 'darwin') return

  try {
    const shell = process.env.SHELL || '/bin/zsh'
    const result = execSync(`${shell} -ilc 'echo -n "__PATH__=$PATH"'`, {
      encoding: 'utf-8',
      timeout: 5000
    })

    const match = result.match(/__PATH__=(.+)/)
    if (match?.[1]) {
      process.env.PATH = match[1]
    }
  } catch {
    // Fallback: append common binary locations
    const home = process.env.HOME
    appendPathEntries([
      '/usr/local/bin',
      '/opt/homebrew/bin',
      home ? `${home}/.local/bin` : null,
      home ? `${home}/.nvm/versions/node/curre
WorkspaceStore.constructor method · typescript · L32-L37 (6 LOC)
electron/workspace/WorkspaceStore.ts
  constructor() {
    const userDataPath = app.getPath('userData')
    mkdirSync(userDataPath, { recursive: true })
    this.workspacePath = join(userDataPath, 'workspace.json')
    this.cache = this.load()
  }
WorkspaceStore.mkdirSync method · typescript · L34-L41 (8 LOC)
electron/workspace/WorkspaceStore.ts
    mkdirSync(userDataPath, { recursive: true })
    this.workspacePath = join(userDataPath, 'workspace.json')
    this.cache = this.load()
  }

  getAgents(): PersistedWorkspaceAgent[] {
    return this.cache.agents.map((agent) => ({ ...agent }))
  }
WorkspaceStore.setAgents method · typescript · L43-L50 (8 LOC)
electron/workspace/WorkspaceStore.ts
  setAgents(agents: PersistedWorkspaceAgent[]): PersistedWorkspaceAgent[] {
    this.cache = {
      ...this.cache,
      agents: agents.map((agent) => ({ ...agent }))
    }
    this.save()
    return this.getAgents()
  }
WorkspaceStore.load method · typescript · L52-L74 (23 LOC)
electron/workspace/WorkspaceStore.ts
  private load(): WorkspaceData {
    try {
      if (!existsSync(this.workspacePath)) {
        this.saveData(DEFAULT_WORKSPACE)
        return { ...DEFAULT_WORKSPACE, agents: [] }
      }

      const raw = readFileSync(this.workspacePath, 'utf-8')
      const parsed = JSON.parse(raw) as Partial<WorkspaceData>

      const agents = Array.isArray(parsed.agents)
        ? parsed.agents.filter((agent): agent is PersistedWorkspaceAgent => this.isAgent(agent))
        : []

      return {
        schemaVersion: 1,
        agents
      }
    } catch {
      this.saveData(DEFAULT_WORKSPACE)
      return { ...DEFAULT_WORKSPACE, agents: [] }
    }
  }
WorkspaceStore.isAgent method · typescript · L76-L90 (15 LOC)
electron/workspace/WorkspaceStore.ts
  private isAgent(value: unknown): value is PersistedWorkspaceAgent {
    if (!value || typeof value !== 'object') return false
    const obj = value as Record<string, unknown>
    const validProviders = ['claude', 'codex']
    return (
      typeof obj.id === 'string' &&
      typeof obj.name === 'string' &&
      typeof obj.projectDir === 'string' &&
      typeof obj.model === 'string' &&
      (obj.provider === undefined || validProviders.includes(obj.provider as string)) &&
      typeof obj.yolo === 'boolean' &&
      (typeof obj.sessionId === 'string' || obj.sessionId === null) &&
      typeof obj.createdAt === 'string'
    )
  }
WorkspaceStore.saveData method · typescript · L96-L102 (7 LOC)
electron/workspace/WorkspaceStore.ts
  private saveData(data: WorkspaceData): void {
    try {
      writeFileSync(this.workspacePath, JSON.stringify(data, null, 2), 'utf-8')
    } catch (error) {
      console.error('Failed to persist workspace state:', error)
    }
  }
Repobility · code-quality intelligence · https://repobility.com
listPublishedReleases function · javascript · L68-L94 (27 LOC)
scripts/release-guard.mjs
function listPublishedReleases(targetRepo) {
  try {
    const raw = execFileSync(
      'gh',
      [
        'release',
        'list',
        '--repo',
        targetRepo,
        '--exclude-drafts',
        '--exclude-pre-releases',
        '--limit',
        '200',
        '--json',
        'tagName'
      ],
      { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }
    ).trim()
    if (!raw) return []
    const parsed = JSON.parse(raw)
    return Array.isArray(parsed) ? parsed : []
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error)
    console.error(`Release guard failed while listing releases: ${message}`)
    process.exit(1)
  }
}
hasCommand function · javascript · L27-L34 (8 LOC)
scripts/release-preflight.mjs
function hasCommand(command) {
  try {
    execSync(`command -v ${command}`, { stdio: 'ignore' })
    return true
  } catch {
    return false
  }
}
safeCheck function · javascript · L36-L45 (10 LOC)
scripts/release-preflight.mjs
function safeCheck(name, command) {
  try {
    const output = execSync(command, { encoding: 'utf-8' }).trim()
    console.log(`[ok] ${name}: ${output}`)
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error)
    console.error(`[fail] ${name}: ${message}`)
    process.exit(1)
  }
}
getProviderForModel function · typescript · L60-L65 (6 LOC)
shared/types.ts
export function getProviderForModel(model: ModelId): ProviderId {
  for (const [provider, models] of Object.entries(PROVIDER_MODELS)) {
    if (models.some((m) => m.id === model)) return provider as ProviderId
  }
  return 'claude'
}
readWorkspaceUiState function · typescript · L36-L75 (40 LOC)
src/App.tsx
function readWorkspaceUiState(): PersistedWorkspaceUiState {
  try {
    const raw = localStorage.getItem(WORKSPACE_UI_STORAGE_KEY)
    if (!raw) {
      return {
        selectedProject: null,
        selectedAgentId: null,
        viewMode: null,
        expandedTilesByProject: {},
        sidebarWidth: null,
        editorOpen: null
      }
    }

    const parsed = JSON.parse(raw) as Partial<PersistedWorkspaceUiState>
    const viewMode = parsed.viewMode
    const safeViewMode: ViewMode | null = viewMode === 'grid' || viewMode === 'chat' ? viewMode : null

    return {
      selectedProject: typeof parsed.selectedProject === 'string' ? parsed.selectedProject : null,
      selectedAgentId: typeof parsed.selectedAgentId === 'string' ? parsed.selectedAgentId : null,
      viewMode: safeViewMode,
      expandedTilesByProject:
        parsed.expandedTilesByProject && typeof parsed.expandedTilesByProject === 'object'
          ? parsed.expandedTilesByProject
          : {},
      sidebar
writeWorkspaceUiState function · typescript · L77-L83 (7 LOC)
src/App.tsx
function writeWorkspaceUiState(state: PersistedWorkspaceUiState): void {
  try {
    localStorage.setItem(WORKSPACE_UI_STORAGE_KEY, JSON.stringify(state))
  } catch {
    // Best effort persistence.
  }
}
ChatView function · typescript · L37-L225 (189 LOC)
src/components/ChatView/ChatView.tsx
export function ChatView({
  agent,
  rawOutput,
  onSendInput,
  onTerminalData,
  onTerminalResize,
  onRestartAgent,
  onToggleYolo,
  onKillAgent,
  onRemoveAgent,
  editorOpen = false,
  onToggleEditor,
  editorTabs = [],
  editorActiveTabPath = null,
  editorFileContents,
  onEditorOpenFile,
  onEditorCloseTab,
  onEditorSelectTab,
  onEditorContentChange,
  onEditorSaveFile,
  theme = 'dark',
  defaultEditor = 'vscode',
  onSetDefaultEditor
}: ChatViewProps) {
  // Prevent browser focus-scroll from moving the outer container.
  const containerRef = useRef<HTMLDivElement>(null)
  const handleContainerScroll = useCallback(() => {
    const el = containerRef.current
    if (el && el.scrollTop !== 0) {
      el.scrollTop = 0
    }
  }, [])

  // Split panel width management
  const [splitRatio, setSplitRatio] = useState(0.5)
  const outerRef = useRef<HTMLDivElement>(null)

  const handleSplitDrag = useCallback((deltaX: number) => {
    const outer = outerRef.current
    if (!outer) 
CodeBracketIcon function · typescript · L227-L243 (17 LOC)
src/components/ChatView/ChatView.tsx
function CodeBracketIcon() {
  return (
    <svg
      className={styles.actionIcon}
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.4"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
    >
      <path d="M5.5 3.5L2 8l3.5 4.5" />
      <path d="M10.5 3.5L14 8l-3.5 4.5" />
    </svg>
  )
}
Repobility · severity-and-effort ranking · https://repobility.com
LockIcon function · typescript · L245-L279 (35 LOC)
src/components/ChatView/ChatView.tsx
function LockIcon({ unlocked }: { unlocked: boolean }) {
  if (unlocked) {
    return (
      <svg
        className={styles.actionIcon}
        viewBox="0 0 16 16"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.4"
        strokeLinecap="round"
        strokeLinejoin="round"
        aria-hidden="true"
      >
        <path d="M4 7h8a1 1 0 0 1 1 1v5H3V8a1 1 0 0 1 1-1Z" />
        <path d="M6 7V5.3a2.7 2.7 0 0 1 5.1-1.2" />
      </svg>
    )
  }

  return (
    <svg
      className={styles.actionIcon}
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.4"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
    >
      <path d="M4 7h8a1 1 0 0 1 1 1v5H3V8a1 1 0 0 1 1-1Z" />
      <path d="M5.4 7V5.1a2.6 2.6 0 0 1 5.2 0V7" />
    </svg>
  )
}
StatusBadge function · typescript · L281-L295 (15 LOC)
src/components/ChatView/ChatView.tsx
function StatusBadge({ status }: { status: string }) {
  const colors: Record<string, string> = {
    running: 'var(--color-status-running)',
    idle: 'var(--color-status-idle)',
    errored: 'var(--color-status-error)',
    starting: 'var(--color-status-starting)'
  }

  return (
    <span className={styles.statusBadge}>
      <span className={styles.statusDot} style={{ background: colors[status] }} />
      {status.charAt(0).toUpperCase() + status.slice(1)}
    </span>
  )
}
HydraIcon function · typescript · L297-L311 (15 LOC)
src/components/ChatView/ChatView.tsx
function HydraIcon() {
  return (
    <svg width="48" height="48" viewBox="0 0 28 28" fill="none" opacity="0.25">
      <g transform="translate(3, 2)">
        <path d="M7.5 20 Q5.5 14 4 10" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"/>
        <circle cx="3.5" cy="8" r="3.2" fill="currentColor"/>
        <path d="M11 20 L11 8" stroke="currentColor" strokeWidth="2.8" strokeLinecap="round"/>
        <circle cx="11" cy="4.5" r="3.8" fill="currentColor"/>
        <path d="M14.5 20 Q16.5 14 18 10" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"/>
        <circle cx="18.5" cy="8" r="3.2" fill="currentColor"/>
        <rect x="5" y="21" width="12" height="2.4" rx="1.2" fill="currentColor" opacity="0.35"/>
      </g>
    </svg>
  )
}
‹ prevpage 3 / 5next ›