@zoulabo/line-hive 0.2.15 → 0.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -3
- package/dist/i18n.js +2 -2
- package/dist/i18n.js.map +1 -1
- package/dist/index.js +45 -10
- package/dist/index.js.map +1 -1
- package/dist/line/client.js +14 -0
- package/dist/line/client.js.map +1 -1
- package/dist/line/fileRelay.js +320 -0
- package/dist/line/fileRelay.js.map +1 -0
- package/dist/line/messages.js.map +1 -1
- package/dist/line/webhook.js +186 -8
- package/dist/line/webhook.js.map +1 -1
- package/dist/server.js +11 -2
- package/dist/server.js.map +1 -1
- package/dist/store/messageStore.js +2 -2
- package/dist/tools/ask.js +135 -4
- package/dist/tools/ask.js.map +1 -1
- package/dist/tools/gitReview-template.js +14 -4
- package/dist/tools/gitReview-template.js.map +1 -1
- package/dist/tools/gitReview.js +2 -1
- package/dist/tools/gitReview.js.map +1 -1
- package/dist/tools/navBrowser.js +625 -0
- package/dist/tools/navBrowser.js.map +1 -0
- package/dist/tools/renderMarkdown.js +7 -1
- package/dist/tools/renderMarkdown.js.map +1 -1
- package/package.json +4 -2
- package/templates/line-notification.instructions.md +1 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation Browser — server-side file viewer and directory browser.
|
|
3
|
+
*
|
|
4
|
+
* Provides `/nav/view/<path>` and `/nav/ls/<path>` GET routes that render
|
|
5
|
+
* workspace files and directories as HTML pages in LINE's in-app browser.
|
|
6
|
+
* All nav URLs are authenticated via HMAC-SHA256 signed tokens.
|
|
7
|
+
*/
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import crypto from "crypto";
|
|
11
|
+
import { marked } from "marked";
|
|
12
|
+
// ─── Token Auth ─────────────────────────────────────────────────────────────
|
|
13
|
+
const DEFAULT_NAV_TTL_MS = 2 * 60 * 60 * 1000; // 2 hours
|
|
14
|
+
const NAV_SESSION_TTL_MS = 12 * 60 * 60 * 1000; // 12 hours
|
|
15
|
+
/** In-memory nav session store. Sessions are ephemeral — server restart invalidates all. */
|
|
16
|
+
const navSessions = new Map(); // sessionId → expiresAt
|
|
17
|
+
/** Create a new nav session and return its ID. */
|
|
18
|
+
export function createNavSession() {
|
|
19
|
+
const sessionId = crypto.randomUUID();
|
|
20
|
+
navSessions.set(sessionId, Date.now() + NAV_SESSION_TTL_MS);
|
|
21
|
+
return sessionId;
|
|
22
|
+
}
|
|
23
|
+
/** Verify a nav session ID. Returns true if valid and not expired. */
|
|
24
|
+
export function verifyNavSession(sessionId) {
|
|
25
|
+
const expiresAt = navSessions.get(sessionId);
|
|
26
|
+
if (!expiresAt)
|
|
27
|
+
return false;
|
|
28
|
+
if (Date.now() > expiresAt) {
|
|
29
|
+
navSessions.delete(sessionId);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
/** Clean up expired sessions (called periodically). */
|
|
35
|
+
export function cleanupNavSessions() {
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
for (const [id, exp] of navSessions) {
|
|
38
|
+
if (now > exp)
|
|
39
|
+
navSessions.delete(id);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Build the Set-Cookie header value for a nav session. */
|
|
43
|
+
export function buildNavSessionCookie(sessionId) {
|
|
44
|
+
const maxAge = Math.floor(NAV_SESSION_TTL_MS / 1000);
|
|
45
|
+
return `nav_session=${sessionId}; HttpOnly; Secure; SameSite=Strict; Path=/nav/; Max-Age=${maxAge}`;
|
|
46
|
+
}
|
|
47
|
+
/** Extract nav_session value from a Cookie header. */
|
|
48
|
+
export function parseNavSessionCookie(cookieHeader) {
|
|
49
|
+
if (!cookieHeader)
|
|
50
|
+
return null;
|
|
51
|
+
const match = cookieHeader.match(/(?:^|;\s*)nav_session=([a-f0-9-]{36})/);
|
|
52
|
+
return match ? match[1] : null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate a signed URL token for a nav path.
|
|
56
|
+
* Token = HMAC-SHA256(secret, path + "|" + expiry)
|
|
57
|
+
*/
|
|
58
|
+
export function generateNavToken(secret, navPath, ttlMs = DEFAULT_NAV_TTL_MS) {
|
|
59
|
+
const exp = Date.now() + ttlMs;
|
|
60
|
+
const data = `${navPath}|${exp}`;
|
|
61
|
+
const token = crypto.createHmac("sha256", secret).update(data).digest("hex");
|
|
62
|
+
return { token, exp };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Verify a signed URL token. Returns true if valid and not expired.
|
|
66
|
+
*/
|
|
67
|
+
export function verifyNavToken(secret, navPath, token, exp) {
|
|
68
|
+
if (Date.now() > exp)
|
|
69
|
+
return false;
|
|
70
|
+
const data = `${navPath}|${exp}`;
|
|
71
|
+
const expected = crypto.createHmac("sha256", secret).update(data).digest("hex");
|
|
72
|
+
return crypto.timingSafeEqual(Buffer.from(token), Buffer.from(expected));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build a full nav URL with signed token query params.
|
|
76
|
+
* Used only for entry URLs sent via LINE messages.
|
|
77
|
+
*/
|
|
78
|
+
export function buildSignedNavUrl(baseUrl, routePath, secret, ttlMs) {
|
|
79
|
+
const { token, exp } = generateNavToken(secret, routePath, ttlMs);
|
|
80
|
+
return `${baseUrl}${routePath}?token=${token}&exp=${exp}`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Build a plain nav URL without tokens (for internal links in rendered pages).
|
|
84
|
+
* Browser session cookie provides auth for subsequent navigations.
|
|
85
|
+
*/
|
|
86
|
+
export function buildPlainNavUrl(baseUrl, routePath) {
|
|
87
|
+
return `${baseUrl}${routePath}`;
|
|
88
|
+
}
|
|
89
|
+
// ─── Path Validation ────────────────────────────────────────────────────────
|
|
90
|
+
/** File extensions renderable by /nav/view/ */
|
|
91
|
+
export const VIEWABLE_EXTENSIONS = new Set([
|
|
92
|
+
".ts", ".js", ".tsx", ".jsx", ".mjs", ".cjs",
|
|
93
|
+
".md", ".mdx",
|
|
94
|
+
".json", ".jsonc",
|
|
95
|
+
".py",
|
|
96
|
+
".txt", ".log",
|
|
97
|
+
".yaml", ".yml",
|
|
98
|
+
".html", ".htm", ".css", ".scss",
|
|
99
|
+
".sh", ".bash", ".zsh", ".fish",
|
|
100
|
+
".toml", ".ini", ".cfg",
|
|
101
|
+
".xml", ".svg",
|
|
102
|
+
".sql",
|
|
103
|
+
".env", ".env.local", ".env.example",
|
|
104
|
+
".gitignore", ".dockerignore",
|
|
105
|
+
".rs", ".go", ".java", ".kt", ".swift", ".c", ".cpp", ".h",
|
|
106
|
+
".rb", ".php", ".lua", ".r", ".jl",
|
|
107
|
+
".tf", ".hcl",
|
|
108
|
+
".graphql", ".gql",
|
|
109
|
+
".proto",
|
|
110
|
+
".csv",
|
|
111
|
+
]);
|
|
112
|
+
/** Directories excluded from /nav/ls/ listings */
|
|
113
|
+
const EXCLUDED_DIRS = new Set([
|
|
114
|
+
".git", ".hg", ".svn",
|
|
115
|
+
"node_modules", "__pycache__", ".cache",
|
|
116
|
+
".DS_Store",
|
|
117
|
+
]);
|
|
118
|
+
/** Files excluded from /nav/ls/ listings (secrets, credentials) */
|
|
119
|
+
const EXCLUDED_PATTERNS = [
|
|
120
|
+
/^\.env(\.|$)/, // .env, .env.local, .env.production, etc.
|
|
121
|
+
/\.(pem|key|p12|pfx|jks|keystore)$/i,
|
|
122
|
+
/^id_rsa/,
|
|
123
|
+
/\.secret$/i,
|
|
124
|
+
/^credentials\.json$/i,
|
|
125
|
+
];
|
|
126
|
+
/** Check if a filename matches any exclusion pattern */
|
|
127
|
+
function isExcludedFile(name) {
|
|
128
|
+
return EXCLUDED_PATTERNS.some(p => p.test(name));
|
|
129
|
+
}
|
|
130
|
+
/** Max file size for rendering (200KB source) */
|
|
131
|
+
const MAX_VIEW_SIZE = 200 * 1024;
|
|
132
|
+
/** Check first 8KB for null bytes to detect binary files */
|
|
133
|
+
function isBinaryFile(filePath) {
|
|
134
|
+
const fd = fs.openSync(filePath, "r");
|
|
135
|
+
try {
|
|
136
|
+
const buf = Buffer.alloc(8192);
|
|
137
|
+
const bytesRead = fs.readSync(fd, buf, 0, 8192, 0);
|
|
138
|
+
for (let i = 0; i < bytesRead; i++) {
|
|
139
|
+
if (buf[i] === 0)
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
fs.closeSync(fd);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** Max directory entries */
|
|
149
|
+
const MAX_DIR_ENTRIES = 100;
|
|
150
|
+
/**
|
|
151
|
+
* Validate and resolve a nav path against the workspace root.
|
|
152
|
+
* Returns the resolved absolute path or an error string.
|
|
153
|
+
*/
|
|
154
|
+
export function resolveNavPath(workspacePath, navPath) {
|
|
155
|
+
// Reject null bytes
|
|
156
|
+
if (navPath.includes("\0")) {
|
|
157
|
+
return { error: "Invalid path", status: 400 };
|
|
158
|
+
}
|
|
159
|
+
// Normalize and resolve
|
|
160
|
+
const cleaned = path.normalize(navPath);
|
|
161
|
+
const resolved = path.resolve(workspacePath, cleaned);
|
|
162
|
+
// Must be within workspace
|
|
163
|
+
if (!resolved.startsWith(workspacePath + path.sep) && resolved !== workspacePath) {
|
|
164
|
+
return { error: "Path outside workspace", status: 403 };
|
|
165
|
+
}
|
|
166
|
+
// Check for symlink escapes
|
|
167
|
+
try {
|
|
168
|
+
const real = fs.realpathSync(resolved);
|
|
169
|
+
if (!real.startsWith(workspacePath + path.sep) && real !== workspacePath) {
|
|
170
|
+
return { error: "Path outside workspace", status: 403 };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// File doesn't exist
|
|
175
|
+
return { error: "Not found", status: 404 };
|
|
176
|
+
}
|
|
177
|
+
return { resolved };
|
|
178
|
+
}
|
|
179
|
+
// ─── HTML Rendering ─────────────────────────────────────────────────────────
|
|
180
|
+
function escapeHtml(text) {
|
|
181
|
+
return text
|
|
182
|
+
.replace(/&/g, "&")
|
|
183
|
+
.replace(/</g, "<")
|
|
184
|
+
.replace(/>/g, ">")
|
|
185
|
+
.replace(/"/g, """);
|
|
186
|
+
}
|
|
187
|
+
/** Map file extensions to highlight.js language names */
|
|
188
|
+
function langFromExt(ext) {
|
|
189
|
+
const map = {
|
|
190
|
+
".ts": "typescript", ".tsx": "typescript",
|
|
191
|
+
".js": "javascript", ".jsx": "javascript", ".mjs": "javascript", ".cjs": "javascript",
|
|
192
|
+
".py": "python",
|
|
193
|
+
".json": "json", ".jsonc": "json",
|
|
194
|
+
".yaml": "yaml", ".yml": "yaml",
|
|
195
|
+
".html": "html", ".htm": "html",
|
|
196
|
+
".css": "css", ".scss": "scss",
|
|
197
|
+
".sh": "bash", ".bash": "bash", ".zsh": "bash", ".fish": "bash",
|
|
198
|
+
".sql": "sql",
|
|
199
|
+
".xml": "xml", ".svg": "xml",
|
|
200
|
+
".toml": "toml", ".ini": "ini",
|
|
201
|
+
".rs": "rust", ".go": "go", ".java": "java", ".kt": "kotlin",
|
|
202
|
+
".swift": "swift", ".c": "c", ".cpp": "cpp", ".h": "c",
|
|
203
|
+
".rb": "ruby", ".php": "php", ".lua": "lua", ".r": "r",
|
|
204
|
+
".graphql": "graphql", ".gql": "graphql",
|
|
205
|
+
".proto": "protobuf",
|
|
206
|
+
".tf": "hcl", ".hcl": "hcl",
|
|
207
|
+
".csv": "plaintext",
|
|
208
|
+
};
|
|
209
|
+
return map[ext] || "plaintext";
|
|
210
|
+
}
|
|
211
|
+
/** Shared CSS for all nav pages */
|
|
212
|
+
const NAV_CSS = `
|
|
213
|
+
* { box-sizing: border-box; }
|
|
214
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; max-width: 900px; margin: 0 auto; padding: 16px; color: #333; background: #fff; }
|
|
215
|
+
.breadcrumbs { font-size: 0.85em; padding: 8px 12px; background: #f5f7fa; border-radius: 6px; margin-bottom: 16px; overflow-x: auto; white-space: nowrap; }
|
|
216
|
+
.breadcrumbs a { color: #0969da; text-decoration: none; }
|
|
217
|
+
.breadcrumbs a:hover { text-decoration: underline; }
|
|
218
|
+
.breadcrumbs .sep { color: #888; margin: 0 4px; }
|
|
219
|
+
.breadcrumbs .current { color: #333; font-weight: 600; }
|
|
220
|
+
pre { background: #f5f5f5; padding: 12px; border-radius: 6px; overflow-x: auto; font-size: 0.85em; line-height: 1.5; }
|
|
221
|
+
code { font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace; }
|
|
222
|
+
pre code { background: none; padding: 0; }
|
|
223
|
+
.dir-list { list-style: none; padding: 0; margin: 0; }
|
|
224
|
+
.dir-list li { border-bottom: 1px solid #f0f0f0; }
|
|
225
|
+
.dir-list li:last-child { border-bottom: none; }
|
|
226
|
+
.dir-list a { display: block; padding: 10px 12px; color: #333; text-decoration: none; font-size: 0.95em; }
|
|
227
|
+
.dir-list a:hover { background: #f5f7fa; }
|
|
228
|
+
.dir-list .icon { margin-right: 8px; }
|
|
229
|
+
.dir-list .size { float: right; color: #888; font-size: 0.85em; }
|
|
230
|
+
.readme-section { margin-top: 24px; padding-top: 16px; border-top: 2px solid #e8e8e8; }
|
|
231
|
+
.readme-section h3 { font-size: 0.85em; color: #888; margin-bottom: 12px; }
|
|
232
|
+
.truncated { padding: 12px; background: #fff3e0; border-radius: 6px; color: #e65100; font-size: 0.85em; margin-top: 12px; }
|
|
233
|
+
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
|
|
234
|
+
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; white-space: nowrap; }
|
|
235
|
+
th { background: #f5f5f5; }
|
|
236
|
+
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 1em 0; }
|
|
237
|
+
.table-wrap table { margin: 0; }
|
|
238
|
+
img { max-width: 100%; }
|
|
239
|
+
blockquote { border-left: 4px solid #ddd; margin: 0; padding: 0 1em; color: #666; }
|
|
240
|
+
.mermaid { text-align: center; margin: 1em 0; }
|
|
241
|
+
h1, h2, h3 { margin-top: 1.5em; }
|
|
242
|
+
|
|
243
|
+
`;
|
|
244
|
+
function wrapNavPage(opts) {
|
|
245
|
+
const cdnStyles = [];
|
|
246
|
+
const cdnScripts = [];
|
|
247
|
+
if (opts.hasCode) {
|
|
248
|
+
cdnStyles.push('<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/styles/github.min.css">');
|
|
249
|
+
cdnScripts.push('<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/highlight.min.js"></script>', `<script>document.querySelectorAll('pre code${opts.hasMermaid ? ":not(.language-mermaid)" : ""}').forEach(el => hljs.highlightElement(el));</script>`);
|
|
250
|
+
}
|
|
251
|
+
if (opts.hasMermaid) {
|
|
252
|
+
cdnScripts.push(`<script type="module">
|
|
253
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
254
|
+
mermaid.initialize({ startOnLoad: false, theme: 'default' });
|
|
255
|
+
document.querySelectorAll('pre > code.language-mermaid').forEach(el => {
|
|
256
|
+
const pre = el.parentElement;
|
|
257
|
+
const div = document.createElement('div');
|
|
258
|
+
div.className = 'mermaid';
|
|
259
|
+
div.textContent = el.textContent;
|
|
260
|
+
pre.replaceWith(div);
|
|
261
|
+
});
|
|
262
|
+
await mermaid.run();
|
|
263
|
+
</script>`);
|
|
264
|
+
}
|
|
265
|
+
if (opts.hasMath) {
|
|
266
|
+
cdnStyles.push('<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16/dist/katex.min.css">');
|
|
267
|
+
cdnScripts.push('<script src="https://cdn.jsdelivr.net/npm/katex@0.16/dist/katex.min.js"></script>', '<script src="https://cdn.jsdelivr.net/npm/katex@0.16/dist/contrib/auto-render.min.js"></script>', `<script>renderMathInElement(document.body, {delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false}]});</script>`);
|
|
268
|
+
}
|
|
269
|
+
const cspSources = ["'self'", "cdn.jsdelivr.net"];
|
|
270
|
+
return `<!DOCTYPE html>
|
|
271
|
+
<html lang="en">
|
|
272
|
+
<head>
|
|
273
|
+
<meta charset="utf-8">
|
|
274
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
275
|
+
<meta name="referrer" content="no-referrer">
|
|
276
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src ${cspSources.join(" ")} 'unsafe-inline'; style-src ${cspSources.join(" ")} 'unsafe-inline'; img-src * data:; font-src ${cspSources.join(" ")}; connect-src 'none';">
|
|
277
|
+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
278
|
+
<title>${escapeHtml(opts.title)}</title>
|
|
279
|
+
<style>${NAV_CSS}</style>
|
|
280
|
+
${cdnStyles.join("\n")}
|
|
281
|
+
</head>
|
|
282
|
+
<body>
|
|
283
|
+
${opts.breadcrumbsHtml}
|
|
284
|
+
${opts.bodyHtml}
|
|
285
|
+
${cdnScripts.join("\n")}
|
|
286
|
+
</body>
|
|
287
|
+
</html>`;
|
|
288
|
+
}
|
|
289
|
+
function buildBreadcrumbs(opts) {
|
|
290
|
+
const parts = opts.navPath.split("/").filter(Boolean);
|
|
291
|
+
const crumbs = [];
|
|
292
|
+
// Root link
|
|
293
|
+
const rootUrl = buildPlainNavUrl(opts.baseUrl, "/nav/ls/");
|
|
294
|
+
crumbs.push(`<a href="${escapeHtml(rootUrl)}">📁 root</a>`);
|
|
295
|
+
// Directory segments
|
|
296
|
+
for (let i = 0; i < parts.length; i++) {
|
|
297
|
+
const isLast = i === parts.length - 1;
|
|
298
|
+
const segmentPath = parts.slice(0, i + 1).join("/");
|
|
299
|
+
if (isLast && opts.isFile) {
|
|
300
|
+
crumbs.push(`<span class="current">${escapeHtml(parts[i])}</span>`);
|
|
301
|
+
}
|
|
302
|
+
else if (isLast) {
|
|
303
|
+
crumbs.push(`<span class="current">📁 ${escapeHtml(parts[i])}</span>`);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const url = buildPlainNavUrl(opts.baseUrl, `/nav/ls/${segmentPath}`);
|
|
307
|
+
crumbs.push(`<a href="${escapeHtml(url)}">📁 ${escapeHtml(parts[i])}</a>`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return `<nav class="breadcrumbs">${crumbs.join('<span class="sep">/</span>')}</nav>`;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Render a file for /nav/view/<path>.
|
|
314
|
+
*/
|
|
315
|
+
export async function renderNavView(workspacePath, navPath, baseUrl) {
|
|
316
|
+
const result = resolveNavPath(workspacePath, navPath);
|
|
317
|
+
if ("error" in result) {
|
|
318
|
+
return { html: errorPage(result.error), status: result.status };
|
|
319
|
+
}
|
|
320
|
+
const { resolved } = result;
|
|
321
|
+
// Must be a file
|
|
322
|
+
let stat;
|
|
323
|
+
try {
|
|
324
|
+
stat = fs.statSync(resolved);
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
return { html: errorPage("Not found"), status: 404 };
|
|
328
|
+
}
|
|
329
|
+
if (stat.isDirectory()) {
|
|
330
|
+
// Redirect: /nav/view/dir → /nav/ls/dir
|
|
331
|
+
return { html: "", status: 301 };
|
|
332
|
+
}
|
|
333
|
+
if (!stat.isFile()) {
|
|
334
|
+
return { html: errorPage("Not a regular file"), status: 400 };
|
|
335
|
+
}
|
|
336
|
+
const ext = path.extname(resolved).toLowerCase();
|
|
337
|
+
// Reject secret files
|
|
338
|
+
if (isExcludedFile(path.basename(resolved))) {
|
|
339
|
+
return { html: errorPage("File not accessible"), status: 403 };
|
|
340
|
+
}
|
|
341
|
+
// Image files: render inline via /nav/raw/
|
|
342
|
+
const IMAGE_EXTS = new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".ico"]);
|
|
343
|
+
if (IMAGE_EXTS.has(ext)) {
|
|
344
|
+
if (stat.size > 5 * 1024 * 1024) {
|
|
345
|
+
return { html: errorPage("Image too large (>5MB)"), status: 413 };
|
|
346
|
+
}
|
|
347
|
+
const breadcrumbsHtml = buildBreadcrumbs({ navPath, isFile: true, baseUrl });
|
|
348
|
+
const imgUrl = buildPlainNavUrl(baseUrl, `/nav/raw/${navPath}`);
|
|
349
|
+
const body = `<div style="text-align:center;"><img src="${escapeHtml(imgUrl)}" alt="${escapeHtml(path.basename(navPath))}" style="max-width:100%;border-radius:8px;"></div>`;
|
|
350
|
+
return {
|
|
351
|
+
html: wrapNavPage({ title: path.basename(navPath), breadcrumbsHtml, bodyHtml: body }),
|
|
352
|
+
status: 200,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
// Reject binary files (check first 8KB for null bytes)
|
|
356
|
+
if (isBinaryFile(resolved)) {
|
|
357
|
+
return { html: errorPage("Binary file — not viewable"), status: 415 };
|
|
358
|
+
}
|
|
359
|
+
// Check size
|
|
360
|
+
let truncated = false;
|
|
361
|
+
let content;
|
|
362
|
+
if (stat.size > MAX_VIEW_SIZE) {
|
|
363
|
+
const buffer = Buffer.alloc(MAX_VIEW_SIZE);
|
|
364
|
+
const fd = fs.openSync(resolved, "r");
|
|
365
|
+
try {
|
|
366
|
+
fs.readSync(fd, buffer, 0, MAX_VIEW_SIZE, 0);
|
|
367
|
+
}
|
|
368
|
+
finally {
|
|
369
|
+
fs.closeSync(fd);
|
|
370
|
+
}
|
|
371
|
+
content = buffer.toString("utf-8");
|
|
372
|
+
truncated = true;
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
content = fs.readFileSync(resolved, "utf-8");
|
|
376
|
+
}
|
|
377
|
+
const breadcrumbsHtml = buildBreadcrumbs({ navPath, isFile: true, baseUrl });
|
|
378
|
+
// Markdown files: render as HTML
|
|
379
|
+
if (ext === ".md" || ext === ".mdx") {
|
|
380
|
+
const rawHtml = await marked.parse(content);
|
|
381
|
+
const hasMermaid = /```mermaid/i.test(content);
|
|
382
|
+
const hasCode = /```\w+/i.test(content);
|
|
383
|
+
const hasMath = /\$\$[\s\S]+?\$\$|\$[^$\n]+?\$/m.test(content);
|
|
384
|
+
// Replace internal links with nav links
|
|
385
|
+
let bodyHtml = replaceInternalLinks(rawHtml, navPath, baseUrl);
|
|
386
|
+
// Wrap tables for horizontal scrolling on mobile
|
|
387
|
+
bodyHtml = bodyHtml.replace(/<table\b/g, '<div class="table-wrap"><table')
|
|
388
|
+
.replace(/<\/table>/g, '</table></div>');
|
|
389
|
+
let body = bodyHtml;
|
|
390
|
+
if (truncated) {
|
|
391
|
+
body += `\n<div class="truncated">⚠️ File truncated at ${(MAX_VIEW_SIZE / 1024).toFixed(0)}KB. Full file is ${(stat.size / 1024).toFixed(0)}KB.</div>`;
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
html: wrapNavPage({
|
|
395
|
+
title: path.basename(navPath),
|
|
396
|
+
breadcrumbsHtml,
|
|
397
|
+
bodyHtml: body,
|
|
398
|
+
hasCode,
|
|
399
|
+
hasMermaid,
|
|
400
|
+
hasMath,
|
|
401
|
+
}),
|
|
402
|
+
status: 200,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
// Code files: syntax highlighted
|
|
406
|
+
const lang = langFromExt(ext);
|
|
407
|
+
let body = `<pre><code class="language-${lang}">${escapeHtml(content)}</code></pre>`;
|
|
408
|
+
if (truncated) {
|
|
409
|
+
body += `\n<div class="truncated">⚠️ File truncated at ${(MAX_VIEW_SIZE / 1024).toFixed(0)}KB. Full file is ${(stat.size / 1024).toFixed(0)}KB.</div>`;
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
html: wrapNavPage({
|
|
413
|
+
title: path.basename(navPath),
|
|
414
|
+
breadcrumbsHtml,
|
|
415
|
+
bodyHtml: body,
|
|
416
|
+
hasCode: true,
|
|
417
|
+
}),
|
|
418
|
+
status: 200,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
// ─── List Handler ───────────────────────────────────────────────────────────
|
|
422
|
+
/**
|
|
423
|
+
* Render a directory listing for /nav/ls/<path>.
|
|
424
|
+
*/
|
|
425
|
+
export async function renderNavList(workspacePath, navPath, baseUrl) {
|
|
426
|
+
const dirToList = navPath || ".";
|
|
427
|
+
const result = resolveNavPath(workspacePath, dirToList);
|
|
428
|
+
if ("error" in result) {
|
|
429
|
+
return { html: errorPage(result.error), status: result.status };
|
|
430
|
+
}
|
|
431
|
+
const { resolved } = result;
|
|
432
|
+
let stat;
|
|
433
|
+
try {
|
|
434
|
+
stat = fs.statSync(resolved);
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
return { html: errorPage("Not found"), status: 404 };
|
|
438
|
+
}
|
|
439
|
+
if (!stat.isDirectory()) {
|
|
440
|
+
return { html: "", status: 301 }; // redirect to /nav/view/
|
|
441
|
+
}
|
|
442
|
+
let entries;
|
|
443
|
+
try {
|
|
444
|
+
entries = fs.readdirSync(resolved, { withFileTypes: true });
|
|
445
|
+
}
|
|
446
|
+
catch {
|
|
447
|
+
return { html: errorPage("Cannot read directory"), status: 500 };
|
|
448
|
+
}
|
|
449
|
+
// Filter and sort
|
|
450
|
+
const filtered = entries.filter(e => {
|
|
451
|
+
if (EXCLUDED_DIRS.has(e.name))
|
|
452
|
+
return false;
|
|
453
|
+
if (isExcludedFile(e.name))
|
|
454
|
+
return false;
|
|
455
|
+
return true;
|
|
456
|
+
});
|
|
457
|
+
const dirs = filtered.filter(e => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
|
|
458
|
+
const files = filtered.filter(e => e.isFile()).sort((a, b) => a.name.localeCompare(b.name));
|
|
459
|
+
const sorted = [...dirs, ...files].slice(0, MAX_DIR_ENTRIES);
|
|
460
|
+
const breadcrumbsHtml = buildBreadcrumbs({ navPath: navPath || "", isFile: false, baseUrl });
|
|
461
|
+
// Build list HTML
|
|
462
|
+
const listItems = sorted.map(entry => {
|
|
463
|
+
const entryPath = navPath ? `${navPath}/${entry.name}` : entry.name;
|
|
464
|
+
const isDir = entry.isDirectory();
|
|
465
|
+
const route = isDir ? `/nav/ls/${entryPath}` : `/nav/view/${entryPath}`;
|
|
466
|
+
const url = buildPlainNavUrl(baseUrl, route);
|
|
467
|
+
const icon = isDir ? "📁" : "📄";
|
|
468
|
+
let sizeHtml = "";
|
|
469
|
+
if (!isDir) {
|
|
470
|
+
try {
|
|
471
|
+
const fileStat = fs.statSync(path.join(resolved, entry.name));
|
|
472
|
+
sizeHtml = `<span class="size">${formatSize(fileStat.size)}</span>`;
|
|
473
|
+
}
|
|
474
|
+
catch { /* ignore */ }
|
|
475
|
+
}
|
|
476
|
+
return `<li><a href="${escapeHtml(url)}"><span class="icon">${icon}</span>${escapeHtml(entry.name)}${sizeHtml}</a></li>`;
|
|
477
|
+
}).join("\n");
|
|
478
|
+
let bodyHtml = `<ul class="dir-list">\n${listItems}\n</ul>`;
|
|
479
|
+
if (filtered.length > MAX_DIR_ENTRIES) {
|
|
480
|
+
bodyHtml += `\n<div class="truncated">⚠️ Showing first ${MAX_DIR_ENTRIES} of ${filtered.length} entries.</div>`;
|
|
481
|
+
}
|
|
482
|
+
// README auto-append (D5)
|
|
483
|
+
const readmeResult = await renderReadmeIfPresent(resolved, navPath, baseUrl);
|
|
484
|
+
if (readmeResult) {
|
|
485
|
+
bodyHtml += readmeResult;
|
|
486
|
+
}
|
|
487
|
+
return {
|
|
488
|
+
html: wrapNavPage({
|
|
489
|
+
title: navPath ? path.basename(navPath) : "root",
|
|
490
|
+
breadcrumbsHtml,
|
|
491
|
+
bodyHtml,
|
|
492
|
+
hasMermaid: readmeResult?.includes("language-mermaid") ?? false,
|
|
493
|
+
hasCode: readmeResult != null,
|
|
494
|
+
hasMath: false,
|
|
495
|
+
}),
|
|
496
|
+
status: 200,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
// ─── README Auto-Append ─────────────────────────────────────────────────────
|
|
500
|
+
async function renderReadmeIfPresent(dirPath, navPath, baseUrl) {
|
|
501
|
+
const candidates = ["README.md", "readme.md", "Readme.md", "index.md", "INDEX.md"];
|
|
502
|
+
let readmeName = null;
|
|
503
|
+
for (const name of candidates) {
|
|
504
|
+
const fullPath = path.join(dirPath, name);
|
|
505
|
+
if (fs.existsSync(fullPath)) {
|
|
506
|
+
readmeName = name;
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (!readmeName)
|
|
511
|
+
return null;
|
|
512
|
+
try {
|
|
513
|
+
const content = fs.readFileSync(path.join(dirPath, readmeName), "utf-8");
|
|
514
|
+
// Limit readme rendering to 50KB
|
|
515
|
+
const trimmed = content.length > 50000 ? content.slice(0, 50000) : content;
|
|
516
|
+
const rawHtml = await marked.parse(trimmed);
|
|
517
|
+
const readmePath = navPath ? `${navPath}/${readmeName}` : readmeName;
|
|
518
|
+
let bodyHtml = replaceInternalLinks(rawHtml, readmePath, baseUrl);
|
|
519
|
+
bodyHtml = bodyHtml.replace(/<table\b/g, '<div class="table-wrap"><table')
|
|
520
|
+
.replace(/<\/table>/g, '</table></div>');
|
|
521
|
+
return `\n<div class="readme-section">
|
|
522
|
+
<h3>📖 ${escapeHtml(readmeName)}</h3>
|
|
523
|
+
${bodyHtml}
|
|
524
|
+
</div>`;
|
|
525
|
+
}
|
|
526
|
+
catch {
|
|
527
|
+
return null;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
// ─── Internal Link Replacement ──────────────────────────────────────────────
|
|
531
|
+
/**
|
|
532
|
+
* Replace relative links in rendered HTML with signed /nav/ URLs.
|
|
533
|
+
*/
|
|
534
|
+
function replaceInternalLinks(html, currentNavPath, baseUrl) {
|
|
535
|
+
const dirPath = path.dirname(currentNavPath);
|
|
536
|
+
// Replace relative <a href="..."> with signed nav URLs
|
|
537
|
+
let result = html.replace(/<a\b([^>]*?)href="([^"]+)"([^>]*)>/gi, (_match, pre, href, post) => {
|
|
538
|
+
const trimmed = href.trim();
|
|
539
|
+
// Only transform relative links
|
|
540
|
+
if (!trimmed.startsWith("./") && !trimmed.startsWith("../") && !trimmed.startsWith("#") && !trimmed.match(/^[a-zA-Z][\w-]*\.[a-zA-Z]+$/)) {
|
|
541
|
+
return `<a${pre}href="${escapeHtml(href)}"${post}>`;
|
|
542
|
+
}
|
|
543
|
+
// Skip anchor links
|
|
544
|
+
if (trimmed.startsWith("#")) {
|
|
545
|
+
return `<a${pre}href="${escapeHtml(href)}"${post}>`;
|
|
546
|
+
}
|
|
547
|
+
// Resolve relative path
|
|
548
|
+
const targetPath = path.normalize(path.join(dirPath, trimmed));
|
|
549
|
+
// Determine if target is a directory or file
|
|
550
|
+
const isDir = trimmed.endsWith("/") || !path.extname(trimmed);
|
|
551
|
+
const route = isDir ? `/nav/ls/${targetPath}` : `/nav/view/${targetPath}`;
|
|
552
|
+
const url = buildPlainNavUrl(baseUrl, route);
|
|
553
|
+
return `<a${pre}href="${escapeHtml(url)}"${post}>`;
|
|
554
|
+
});
|
|
555
|
+
// Replace relative <img src="..."> with signed /nav/raw/ URLs
|
|
556
|
+
result = result.replace(/<img\b([^>]*?)src="([^"]+)"([^>]*?)>/gi, (_match, pre, src, post) => {
|
|
557
|
+
const trimmed = src.trim();
|
|
558
|
+
// Only transform relative paths (skip absolute URLs and data URIs)
|
|
559
|
+
if (trimmed.startsWith("http://") || trimmed.startsWith("https://") ||
|
|
560
|
+
trimmed.startsWith("data:") || trimmed.startsWith("//")) {
|
|
561
|
+
return `<img${pre}src="${escapeHtml(src)}"${post}>`;
|
|
562
|
+
}
|
|
563
|
+
// Resolve relative path
|
|
564
|
+
const targetPath = path.normalize(path.join(dirPath, trimmed));
|
|
565
|
+
if (targetPath.startsWith("..")) {
|
|
566
|
+
return `<img${pre}src="${escapeHtml(src)}"${post}>`;
|
|
567
|
+
}
|
|
568
|
+
const url = buildPlainNavUrl(baseUrl, `/nav/raw/${targetPath}`);
|
|
569
|
+
return `<img${pre}src="${escapeHtml(url)}"${post}>`;
|
|
570
|
+
});
|
|
571
|
+
return result;
|
|
572
|
+
}
|
|
573
|
+
// ─── Raw File Serving ───────────────────────────────────────────────────────
|
|
574
|
+
const MIME_TYPES = {
|
|
575
|
+
".svg": "image/svg+xml",
|
|
576
|
+
".png": "image/png",
|
|
577
|
+
".jpg": "image/jpeg",
|
|
578
|
+
".jpeg": "image/jpeg",
|
|
579
|
+
".gif": "image/gif",
|
|
580
|
+
".webp": "image/webp",
|
|
581
|
+
".ico": "image/x-icon",
|
|
582
|
+
".css": "text/css",
|
|
583
|
+
".js": "text/javascript",
|
|
584
|
+
".json": "application/json",
|
|
585
|
+
".woff": "font/woff",
|
|
586
|
+
".woff2": "font/woff2",
|
|
587
|
+
".ttf": "font/ttf",
|
|
588
|
+
};
|
|
589
|
+
/**
|
|
590
|
+
* Serve a raw file from the workspace with correct Content-Type.
|
|
591
|
+
* Used for images/assets referenced in markdown.
|
|
592
|
+
*/
|
|
593
|
+
export function renderNavRaw(navPath, workspacePath) {
|
|
594
|
+
const pathResult = resolveNavPath(workspacePath, navPath);
|
|
595
|
+
if ("error" in pathResult) {
|
|
596
|
+
return pathResult;
|
|
597
|
+
}
|
|
598
|
+
const resolved = pathResult.resolved;
|
|
599
|
+
if (!fs.statSync(resolved).isFile()) {
|
|
600
|
+
return { error: "Not found", status: 404 };
|
|
601
|
+
}
|
|
602
|
+
const ext = path.extname(resolved).toLowerCase();
|
|
603
|
+
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
604
|
+
// Size limit for raw files: 5MB
|
|
605
|
+
const stat = fs.statSync(resolved);
|
|
606
|
+
if (stat.size > 5 * 1024 * 1024) {
|
|
607
|
+
return { error: "File too large", status: 413 };
|
|
608
|
+
}
|
|
609
|
+
return { data: fs.readFileSync(resolved), contentType, status: 200 };
|
|
610
|
+
}
|
|
611
|
+
function formatSize(bytes) {
|
|
612
|
+
if (bytes < 1024)
|
|
613
|
+
return `${bytes}B`;
|
|
614
|
+
if (bytes < 1024 * 1024)
|
|
615
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
616
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
617
|
+
}
|
|
618
|
+
function errorPage(message) {
|
|
619
|
+
return `<!DOCTYPE html>
|
|
620
|
+
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
621
|
+
<title>Error</title>
|
|
622
|
+
<style>body { font-family: -apple-system, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 80vh; color: #666; } .err { text-align: center; } .err h1 { font-size: 1.5em; color: #c62828; }</style>
|
|
623
|
+
</head><body><div class="err"><h1>⚠️ ${escapeHtml(message)}</h1></div></body></html>`;
|
|
624
|
+
}
|
|
625
|
+
//# sourceMappingURL=navBrowser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navBrowser.js","sourceRoot":"","sources":["../../src/tools/navBrowser.ts"],"names":[],"mappings":"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"}
|