fix: show empty work preview without invoking the Agent
This commit is contained in:
48
electron/coding-runtime/work-presence.ts
Normal file
48
electron/coding-runtime/work-presence.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { lstat, opendir, realpath } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
export type WorkPresence = 'empty' | 'possible' | 'unknown';
|
||||
|
||||
// Only prove absence. Unknown project formats must retain the existing startup
|
||||
// path; a missing root index.html or an offline server does not prove emptiness.
|
||||
const IGNORED_DIRECTORIES = new Set(['.git', '.makelore', '.vscode', '.idea', 'node_modules']);
|
||||
const IGNORED_FILES = new Set(['.ds_store', 'thumbs.db', '.git', '.gitignore', '.gitattributes', '.editorconfig', 'license', 'readme']);
|
||||
const MATERIAL_EXTENSIONS = new Set([
|
||||
'.md', '.txt', '.pdf', '.doc', '.docx', '.ppt', '.pptx', '.xls', '.xlsx', '.csv',
|
||||
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.ico', '.bmp', '.avif',
|
||||
'.mp3', '.wav', '.ogg', '.m4a', '.mp4', '.webm', '.mov',
|
||||
'.woff', '.woff2', '.ttf', '.otf',
|
||||
]);
|
||||
const MAX_ENTRIES = 2_000;
|
||||
const MAX_DEPTH = 8;
|
||||
|
||||
/** Inspect names/types only, without reading contents, following links or running a model. */
|
||||
export async function inspectWorkPresence(projectPath: string): Promise<WorkPresence> {
|
||||
try {
|
||||
const root = await realpath(projectPath);
|
||||
const pending = [{ directory: root, depth: 0 }];
|
||||
let visited = 0;
|
||||
while (pending.length) {
|
||||
const { directory, depth } = pending.pop()!;
|
||||
// Revalidate queued directories in case a project edit replaced one with a link.
|
||||
if ((await lstat(directory)).isSymbolicLink() || await realpath(directory) !== directory) return 'unknown';
|
||||
const entries = await opendir(directory);
|
||||
for await (const entry of entries) {
|
||||
if (++visited > MAX_ENTRIES) return 'unknown';
|
||||
const name = entry.name.toLowerCase();
|
||||
if (entry.isSymbolicLink()) return 'unknown';
|
||||
if (entry.isDirectory()) {
|
||||
if (IGNORED_DIRECTORIES.has(entry.name) || (depth === 0 && entry.name === 'knowledge')) continue;
|
||||
if (depth >= MAX_DEPTH) return 'unknown';
|
||||
pending.push({ directory: path.join(directory, entry.name), depth: depth + 1 });
|
||||
} else if (entry.isFile()) {
|
||||
if (!IGNORED_FILES.has(name) && !MATERIAL_EXTENSIONS.has(path.extname(name))) return 'possible';
|
||||
} else return 'unknown';
|
||||
}
|
||||
}
|
||||
return 'empty';
|
||||
} catch {
|
||||
// Unreadable, removed or changing directories are not evidence of no work.
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user