Mercurial
annotate hg-web/src/index.js @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | ffb764d2fcc5 |
| children |
| rev | line source |
|---|---|
|
135
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
1 const API_BASE = '/api/repo'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
2 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
3 function getCurrentPath() { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
4 const params = new URLSearchParams(window.location.search); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
5 return params.get('path') || ''; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
6 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
7 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
8 function renderBreadcrumb(path) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
9 const breadcrumb = document.getElementById('breadcrumb'); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
10 if (!path) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
11 breadcrumb.innerHTML = '<a href="/">Root</a>'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
12 return; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
13 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
14 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
15 const parts = path.split('/').filter(p => p); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
16 let currentPath = ''; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
17 let html = '<a href="/">Root</a>'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
18 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
19 parts.forEach((part, index) => { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
20 currentPath += (currentPath ? '/' : '') + part; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
21 html += ` <span>/</span> `; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
22 if (index === parts.length - 1) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
23 html += `<span>${part}</span>`; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
24 } else { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
25 html += `<a href="?path=${encodeURIComponent(currentPath)}">${part}</a>`; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
26 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
27 }); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
28 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
29 breadcrumb.innerHTML = html; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
30 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
31 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
32 function renderFiles(files, directories) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
33 if (!files || files.length === 0) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
34 fileList.style.display = 'none'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
35 emptyState.style.display = 'block'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
36 return; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
37 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
38 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
39 emptyState.style.display = 'none'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
40 fileList.style.display = 'block'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
41 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
42 let html = ''; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
43 directories.forEach(file => { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
44 const icon = '📁'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
45 const className = file.type; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
46 const href = `?path=${encodeURIComponent(file.abspath)}`; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
47 const target = ''; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
48 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
49 html += ` |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
50 <div class="file-item ${className}"> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
51 <span class="icon">${icon}</span> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
52 <span class="name"> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
53 <a href="${href}" ${target}>${file.basename}</a> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
54 </span> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
55 </div> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
56 `; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
57 }); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
58 files.forEach(file => { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
59 const icon = '📄'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
60 const className = file.type; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
61 const href = `/api/repo/file?path=${encodeURIComponent(file.abspath)}`; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
62 const target = 'target="_blank"'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
63 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
64 html += ` |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
65 <div class="file-item ${className}"> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
66 <span class="icon">${icon}</span> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
67 <span class="name"> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
68 <a href="${href}" ${target}>${file.basename}</a> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
69 </span> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
70 </div> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
71 `; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
72 }); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
73 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
74 fileList.innerHTML = html; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
75 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
76 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
77 async function loadReadme(path) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
78 const readmeSection = document.getElementById('readmeSection'); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
79 const readmeContent = document.getElementById('readmeContent'); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
80 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
81 try { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
82 const readmePath = path ? `${path}/README.md` : 'README.md'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
83 const response = await fetch(`/api/repo/readme?path=${encodeURIComponent(readmePath)}`); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
84 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
85 if (response.ok) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
86 const markdown = await response.text(); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
87 readmeSection.style.display = 'block'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
88 renderMarkdown(readmeContent, markdown); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
89 } else { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
90 readmeSection.style.display = 'none'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
91 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
92 } catch (error) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
93 readmeSection.style.display = 'none'; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
94 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
95 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
96 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
97 async function loadDirectory(path) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
98 try { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
99 const url = path ? `${API_BASE}/list?path=${encodeURIComponent(path)}` : `${API_BASE}/list`; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
100 const response = await fetch(url); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
101 const data = await response.json(); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
102 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
103 if (data.error) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
104 throw new Error(data.error); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
105 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
106 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
107 const { files, directories } = data; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
108 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
109 renderBreadcrumb(path); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
110 renderFiles(files, directories); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
111 loadReadme(path); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
112 } catch (error) { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
113 console.error('Error loading directory:', error); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
114 document.getElementById('fileList').innerHTML = ` |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
115 <div class="error-message">Error loading directory: ${error.message}</div> |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
116 `; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
117 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
118 } |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
119 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
120 window.addEventListener('popstate', (event) => { |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
121 const path = event.state?.path || ''; |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
122 loadDirectory(path); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
123 }); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
124 |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
125 const currentPath = getCurrentPath(); |
|
ffb764d2fcc5
[HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
126 loadDirectory(currentPath); |