feat(ui): add customizable status line

Allow users to configure a custom shell command to display in the UI footer status line.
This commit is contained in:
wenshao 2026-04-06 07:10:50 +08:00
parent 6785a8d908
commit 6784f0c02c
10 changed files with 116 additions and 13 deletions

View file

@ -0,0 +1,63 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { useState, useEffect } from 'react';
import { exec } from 'child_process';
import { useSettings } from '../contexts/SettingsContext.js';
import { isShellCommandReadOnlyAST } from '@qwen-code/qwen-code-core';
export function useStatusLine(): string | null {
const settings = useSettings();
const statusLineCommand = settings.merged.ui?.statusLine;
const [output, setOutput] = useState<string | null>(null);
useEffect(() => {
if (!statusLineCommand) {
setOutput(null);
return;
}
let isMounted = true;
const executeCommand = async () => {
try {
const isReadOnly = await isShellCommandReadOnlyAST(statusLineCommand);
if (!isReadOnly) {
if (isMounted) setOutput('⚠️ Sandbox: Command must be read-only');
return;
}
exec(
statusLineCommand,
{ timeout: 5000, maxBuffer: 1024 * 10 },
(error, stdout) => {
if (!isMounted) return;
if (!error && stdout) {
setOutput(stdout.trim().split('\n')[0] || null);
} else {
setOutput(null);
}
},
);
} catch {
if (isMounted) setOutput('⚠️ Sandbox: Verification failed');
}
};
// Execute immediately
executeCommand();
// Poll every 5 seconds
const interval = setInterval(executeCommand, 5000);
return () => {
isMounted = false;
clearInterval(interval);
};
}, [statusLineCommand]);
return output;
}