• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

agentic-dev-library / thumbcode / 22324268802

23 Feb 2026 08:48PM UTC coverage: 58.65% (+3.1%) from 55.51%
22324268802

push

github

jbdevprimary
chore: update PRD status, clean ralph session, fix formatting

- Update prd.json to reflect 9/24 stories completed and merged to main
- Remove stale ralph-tui session files (iterations/, session.json)
- Apply Biome auto-formatting fixes to anthropic-client.ts and check-contrast.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

1600 of 3067 branches covered (52.17%)

Branch coverage included in aggregate %.

0 of 2 new or added lines in 1 file covered. (0.0%)

175 existing lines in 29 files now uncovered.

2597 of 4089 relevant lines covered (63.51%)

41.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.41
/src/components/project/ProjectFileExplorer.tsx
1
/**
2
 * ProjectFileExplorer
3
 *
4
 * Renders a GitHub repository file browser with directory navigation.
5
 * Consumes data from the useProjectFiles hook.
6
 */
7

8
import type { GitHubContent } from '@thumbcode/core';
9
import { FileText, Folder, FolderOpen, Loader2 } from 'lucide-react';
10

11
interface ProjectFileExplorerProps {
12
  contents: GitHubContent[];
13
  currentPath: string;
14
  parentPath: string;
15
  isLoading: boolean;
16
  error: string | null;
17
  onNavigate: (path: string) => void;
18
}
19

20
export function ProjectFileExplorer({
21
  contents,
22
  currentPath,
23
  parentPath,
24
  isLoading,
25
  error,
26
  onNavigate,
27
}: Readonly<ProjectFileExplorerProps>) {
28
  return (
10✔
29
    <div className="space-y-2">
30
      <div className="flex items-center gap-2 text-neutral-400 font-body text-sm mb-4">
31
        <FolderOpen size={16} />
32
        <span>{currentPath || 'Root'}</span>
20✔
33
      </div>
34

35
      {isLoading && (
14✔
36
        <div className="flex items-center justify-center py-8">
37
          <Loader2 size={24} className="text-neutral-500 animate-spin" />
38
        </div>
39
      )}
40

41
      {error && (
10!
42
        <div className="bg-surface rounded-organic-card shadow-organic-card p-6 text-center">
43
          <p className="text-coral-500 font-body text-sm">{error}</p>
44
        </div>
45
      )}
46

47
      {!isLoading && !error && (
22✔
48
        <div className="space-y-1">
49
          {currentPath && (
6!
50
            <button
51
              type="button"
UNCOV
52
              onClick={() => onNavigate(parentPath)}
×
53
              className="w-full flex items-center gap-3 px-3 py-2 rounded-organic-card hover:bg-surface-elevated transition-colors text-left"
54
            >
55
              <Folder size={16} className="text-teal-400 shrink-0" />
56
              <span className="font-body text-sm text-neutral-300">..</span>
57
            </button>
58
          )}
59
          {contents.map((item) => (
60
            <button
4✔
61
              type="button"
62
              key={item.sha}
63
              onClick={() => {
UNCOV
64
                if (item.type === 'dir') onNavigate(item.path);
×
65
              }}
66
              className={`w-full flex items-center gap-3 px-3 py-2 rounded-organic-card transition-colors text-left ${
67
                item.type === 'dir' ? 'hover:bg-surface-elevated cursor-pointer' : 'cursor-default'
4✔
68
              }`}
69
            >
70
              {item.type === 'dir' ? (
4✔
71
                <Folder size={16} className="text-teal-400 shrink-0" />
72
              ) : (
73
                <FileText size={16} className="text-neutral-500 shrink-0" />
74
              )}
75
              <span className="font-body text-sm text-white truncate">{item.name}</span>
76
              {item.type === 'file' && item.size > 0 && (
8✔
77
                <span className="font-mono text-xs text-neutral-600 ml-auto shrink-0">
78
                  {item.size > 1024 ? `${(item.size / 1024).toFixed(1)}KB` : `${item.size}B`}
2!
79
                </span>
80
              )}
81
            </button>
82
          ))}
83
          {contents.length === 0 && (
10✔
84
            <p className="text-neutral-500 font-body text-sm text-center py-4">Empty directory</p>
85
          )}
86
        </div>
87
      )}
88
    </div>
89
  );
90
}
91

92
/** No-repo fallback */
93
export function ProjectFileExplorerEmpty() {
UNCOV
94
  return (
×
95
    <div className="bg-surface rounded-organic-card shadow-organic-card p-6 text-center">
96
      <Folder size={32} className="text-neutral-600 mx-auto mb-3" />
97
      <p className="text-neutral-500 font-body text-sm">
98
        Could not parse repository info from URL.
99
      </p>
100
    </div>
101
  );
102
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc