agent-Specialization/cli/legacy-ink-src/format.ts
JOJO d97c1423b1 feat(cli): rewrite CLI on opentui with Gateway host Bearer channel
- replace Ink implementation with opentui + React 19 (old version kept at cli/legacy-ink-src/ for field reference)
- all traffic goes through Gateway host Bearer token; workspace bound via X-Astrion-Workspace-Id header
- auto-spawn server only when no instance is alive (never kill/restart running ones); stale server without token is detected
- astrion launcher (bin/astrion, symlink-aware, --version/--help fast-exit)
- slash menu panels (session/model/mode/permission/path/context/approvals...) with shared selector component
- backend: host workspace list/create dual-channel endpoints, host token generated at startup
- i18n reads OS locale at startup (zh/en)

Co-authored-by: Astrion powered by Kimi-K3 <astrion-agent@users.noreply.github.com>
2026-09-11 17:27:53 +08:00

30 lines
954 B
TypeScript

import { homedir } from 'node:os';
export function shortPath(path: string): string {
const home = homedir();
return path.startsWith(home) ? `~${path.slice(home.length)}` : path;
}
export function formatContext(used: number, limit: number): string {
if (!limit || limit <= 0) return formatTokens(used);
const left = Math.max(0, limit - used);
const pct = limit > 0 ? Math.round((left / limit) * 100) : 0;
return `${pct}% left ${formatTokens(used)} / ${formatTokens(limit)}`;
}
export function formatTokens(value: number): string {
if (value >= 1000) {
const rounded = Math.round((value / 1000) * 10) / 10;
return `${rounded}K`;
}
return String(value);
}
export function nowSessionId(): string {
return globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
}
export function lastLines(lines: string[], limit = 5): string[] {
return lines.slice(Math.max(0, lines.length - limit));
}