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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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);