Fix prompt truncation edge case and harden global state handling
Correct list truncation logic to avoid eliding prompts that already fit, and gracefully handle narrow terminals. Sanitize project entries on load, deduplicate registration through a shared registerPaths helper, and simplify scanAndRegister by reusing it.
This commit is contained in:
parent
da7adc674d
commit
4574749cde
|
|
@ -31,7 +31,7 @@ function renderSessions(
|
||||||
const status = statusMap.get(s) ?? "idle"
|
const status = statusMap.get(s) ?? "idle"
|
||||||
const { icon, color: bc } = styles[status]
|
const { icon, color: bc } = styles[status]
|
||||||
const maxPrompt = cols - prefixWidth
|
const maxPrompt = cols - prefixWidth
|
||||||
const truncated = maxPrompt < 1 ? "" : maxPrompt > 3 && prompt.length > maxPrompt ? prompt.slice(0, maxPrompt - 3) + "..." : prompt
|
const truncated = maxPrompt < 1 ? "" : prompt.length <= maxPrompt ? prompt : maxPrompt > 3 ? prompt.slice(0, maxPrompt - 3) + "..." : prompt.slice(0, maxPrompt)
|
||||||
console.log(`${icon} ${bc}${s.branch.padEnd(branchWidth)}${reset} ${dim}${truncated}${reset}`)
|
console.log(`${icon} ${bc}${s.branch.padEnd(branchWidth)}${reset} ${dim}${truncated}${reset}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
42
src/state.ts
42
src/state.ts
|
|
@ -101,7 +101,7 @@ async function loadGlobal(): Promise<GlobalState> {
|
||||||
if (await file.exists()) {
|
if (await file.exists()) {
|
||||||
try {
|
try {
|
||||||
const data = await file.json()
|
const data = await file.json()
|
||||||
if (data && Array.isArray(data.projects)) return data
|
if (data && Array.isArray(data.projects)) return { projects: data.projects.filter((p: unknown) => typeof p === "string") }
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
return { projects: [] }
|
return { projects: [] }
|
||||||
|
|
@ -117,18 +117,27 @@ export function normalizePath(dir: string): string {
|
||||||
return resolve(dir.replace(/^~(?=\/|$)/, homedir()))
|
return resolve(dir.replace(/^~(?=\/|$)/, homedir()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Register a project directory in the global state. */
|
async function registerPaths(paths: string[]): Promise<void> {
|
||||||
export async function registerProject(repoRoot: string): Promise<void> {
|
if (paths.length === 0) return
|
||||||
const normalized = normalizePath(repoRoot)
|
|
||||||
await withGlobalLock(async () => {
|
await withGlobalLock(async () => {
|
||||||
const gs = await loadGlobal()
|
const gs = await loadGlobal()
|
||||||
if (!gs.projects.includes(normalized)) {
|
const existing = new Set(gs.projects)
|
||||||
gs.projects.push(normalized)
|
let changed = false
|
||||||
await saveGlobal(gs)
|
for (const p of paths) {
|
||||||
|
if (!existing.has(p)) {
|
||||||
|
gs.projects.push(p)
|
||||||
|
changed = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (changed) await saveGlobal(gs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Register a project directory in the global state. */
|
||||||
|
export async function registerProject(repoRoot: string): Promise<void> {
|
||||||
|
await registerPaths([normalizePath(repoRoot)])
|
||||||
|
}
|
||||||
|
|
||||||
/** Remove a project directory from the global state. */
|
/** Remove a project directory from the global state. */
|
||||||
export async function unregisterProject(dir: string): Promise<boolean> {
|
export async function unregisterProject(dir: string): Promise<boolean> {
|
||||||
const target = normalizePath(dir)
|
const target = normalizePath(dir)
|
||||||
|
|
@ -165,26 +174,11 @@ export async function scanAndRegister(dir: string, maxDepth = 5): Promise<string
|
||||||
}
|
}
|
||||||
|
|
||||||
const children = entries.filter(e => e.isDirectory() && !e.isSymbolicLink() && !e.name.startsWith(".") && e.name !== "node_modules")
|
const children = entries.filter(e => e.isDirectory() && !e.isSymbolicLink() && !e.name.startsWith(".") && e.name !== "node_modules")
|
||||||
await Promise.all(children.map(entry => walk(join(d, entry.name), depth + 1)))
|
for (const entry of children) await walk(join(d, entry.name), depth + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
await walk(root, 0)
|
await walk(root, 0)
|
||||||
|
await registerPaths(found)
|
||||||
if (found.length > 0) {
|
|
||||||
await withGlobalLock(async () => {
|
|
||||||
const gs = await loadGlobal()
|
|
||||||
const existing = new Set(gs.projects)
|
|
||||||
let changed = false
|
|
||||||
for (const p of found) {
|
|
||||||
if (!existing.has(p)) {
|
|
||||||
gs.projects.push(p)
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changed) await saveGlobal(gs)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user