返回 ViMax
workspaceMeta.ts
根目录 / ui / src / workspaceMeta.ts
1 export type WorkspaceMeta = {
2 workspacePath: string;
3 sessionId: string;
4 stage: string;
5 compactionUsed: number;
6 compactionTarget: number;
7 };
8
9 export function compactTargetFromEnv(env: Record<string, string | undefined>): number {
10 const contextWindow = parsePositiveInt(env.VIMAX_CONTEXT_WINDOW_TOKENS, 200000);
11 const ratio = parsePositiveFloat(env.VIMAX_AUTO_COMPACT_RATIO, 0.9);
12 const threshold = parsePositiveInt(env.VIMAX_AUTO_COMPACT_TOKEN_THRESHOLD, Math.round(contextWindow * Math.min(1, Math.max(0, ratio))));
13 const buffer = parsePositiveInt(env.VIMAX_AUTO_COMPACT_BUFFER_TOKENS, 20000);
14 return Math.max(0, threshold - buffer);
15 }
16
17 export function compactionBar(used: number, target: number, width = 18): string {
18 const safeWidth = Math.max(4, width);
19 if (target <= 0) return '░'.repeat(safeWidth);
20 const ratio = Math.min(1, Math.max(0, used / target));
21 const filled = Math.round(ratio * safeWidth);
22 return '█'.repeat(filled) + '░'.repeat(safeWidth - filled);
23 }
24
25 export function compactionLabel(used: number, target: number): string {
26 if (target <= 0) return 'Compaction disabled';
27 const safeUsed = Math.max(0, Math.round(used));
28 const percent = Math.min(999, Math.max(0, Math.round((safeUsed / target) * 100)));
29 return `Compaction [${compactionBar(safeUsed, target)}] ${safeUsed}/${target} (${percent}%)`;
30 }
31
32 export function resolveWorkspacePath(_repoRoot: string, workingDir?: string): string {
33 const normalized = String(workingDir ?? '').trim();
34 if (!normalized) return '.working_dir';
35 const relative = normalized.replace(/^.*\/\.working_dir\//, '.working_dir/').replace(/^\.\//, '');
36 if (relative.startsWith('.working_dir/')) return relative;
37 if (relative === '.working_dir') return relative;
38 return `.working_dir/${relative.replace(/^\/+/, '')}`;
39 }
40
41 function parsePositiveInt(value: string | undefined, fallback: number): number {
42 if (!value) return fallback;
43 const parsed = Number.parseInt(value, 10);
44 if (!Number.isFinite(parsed) || parsed < 0) return fallback;
45 return parsed;
46 }
47
48 function parsePositiveFloat(value: string | undefined, fallback: number): number {
49 if (!value) return fallback;
50 const parsed = Number.parseFloat(value);
51 if (!Number.isFinite(parsed) || parsed < 0) return fallback;
52 return parsed;
53 }
54
54 lines TYPESCRIPT