diff --git a/src/utils/statusline.ts b/src/utils/statusline.ts
index b61da1e..deb2f2a 100644
--- a/src/utils/statusline.ts
+++ b/src/utils/statusline.ts
@@ -10,6 +10,7 @@ export interface StatusLineModuleConfig {
text: string;
color?: string;
background?: string;
+ scriptPath?: string; // 用于script类型的模块,指定要执行的Node.js脚本文件路径
}
export interface StatusLineThemeConfig {
@@ -132,11 +133,58 @@ function getColorCode(colorName: string): string {
// 变量替换函数,支持{{var}}格式的变量替换
function replaceVariables(text: string, variables: Record): string {
- return text.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
- return variables[varName] || match;
+ return text.replace(/\{\{(\w+)\}\}/g, (_match, varName) => {
+ return variables[varName] || "";
});
}
+// 执行脚本并获取输出
+async function executeScript(scriptPath: string, variables: Record): Promise {
+ try {
+ // 检查文件是否存在
+ await fs.access(scriptPath);
+
+ // 使用require动态加载脚本模块
+ const scriptModule = require(scriptPath);
+
+ // 如果导出的是函数,则调用它并传入变量
+ if (typeof scriptModule === 'function') {
+ const result = scriptModule(variables);
+ // 如果返回的是Promise,则等待它完成
+ if (result instanceof Promise) {
+ return await result;
+ }
+ return result;
+ }
+
+ // 如果导出的是default函数,则调用它
+ if (scriptModule.default && typeof scriptModule.default === 'function') {
+ const result = scriptModule.default(variables);
+ // 如果返回的是Promise,则等待它完成
+ if (result instanceof Promise) {
+ return await result;
+ }
+ return result;
+ }
+
+ // 如果导出的是字符串,则直接返回
+ if (typeof scriptModule === 'string') {
+ return scriptModule;
+ }
+
+ // 如果导出的是default字符串,则返回它
+ if (scriptModule.default && typeof scriptModule.default === 'string') {
+ return scriptModule.default;
+ }
+
+ // 默认情况下返回空字符串
+ return "";
+ } catch (error) {
+ console.error(`执行脚本 ${scriptPath} 时出错:`, error);
+ return "";
+ }
+}
+
// 默认主题配置 - 使用Nerd Fonts图标和美观配色
const DEFAULT_THEME: StatusLineThemeConfig = {
modules: [
@@ -490,9 +538,9 @@ export async function parseStatusLineData(input: StatusLineInput): Promise
-): string {
+): Promise {
const modules = theme.modules || DEFAULT_THEME.modules;
const parts: string[] = [];
@@ -542,19 +590,30 @@ function renderDefaultStyle(
const color = module.color ? getColorCode(module.color) : "";
const background = module.background ? getColorCode(module.background) : "";
const icon = module.icon || "";
- const text = replaceVariables(module.text, variables);
- // 如果text为空且不是usage类型,则跳过该模块
- if (!text && module.type !== "usage") {
+ // 如果是script类型,执行脚本获取文本
+ let text = "";
+ if (module.type === "script" && module.scriptPath) {
+ text = await executeScript(module.scriptPath, variables);
+ } else {
+ text = replaceVariables(module.text, variables);
+ }
+
+ // 构建显示文本
+ let displayText = "";
+ if (icon) {
+ displayText += `${icon} `;
+ }
+ displayText += text;
+
+ // 如果displayText为空,或者只有图标没有实际文本,则跳过该模块
+ if (!displayText || !text) {
continue;
}
// 构建模块字符串
let part = `${background}${color}`;
- if (icon) {
- part += `${icon} `;
- }
- part += `${text}${COLORS.reset}`;
+ part += `${displayText}${COLORS.reset}`;
parts.push(part);
}
@@ -701,10 +760,10 @@ function segment(text: string, textFg: string, bgColor: string, nextBgColor: str
}
// 渲染Powerline风格的状态行
-function renderPowerlineStyle(
+async function renderPowerlineStyle(
theme: StatusLineThemeConfig,
variables: Record
-): string {
+): Promise {
const modules = theme.modules || POWERLINE_THEME.modules;
const segments: string[] = [];
@@ -714,11 +773,13 @@ function renderPowerlineStyle(
const color = module.color || "white";
const backgroundName = module.background || "";
const icon = module.icon || "";
- const text = replaceVariables(module.text, variables);
- // 如果text为空且不是usage类型,则跳过该模块
- if (!text && module.type !== "usage") {
- continue;
+ // 如果是script类型,执行脚本获取文本
+ let text = "";
+ if (module.type === "script" && module.scriptPath) {
+ text = await executeScript(module.scriptPath, variables);
+ } else {
+ text = replaceVariables(module.text, variables);
}
// 构建显示文本
@@ -728,6 +789,11 @@ function renderPowerlineStyle(
}
displayText += text;
+ // 如果displayText为空,或者只有图标没有实际文本,则跳过该模块
+ if (!displayText || !text) {
+ continue;
+ }
+
// 获取下一个模块的背景色(用于分隔符)
let nextBackground: string | null = null;
if (i < modules.length - 1) {
diff --git a/ui/src/components/StatusLineConfigDialog.tsx b/ui/src/components/StatusLineConfigDialog.tsx
index 9f341d2..0a47895 100644
--- a/ui/src/components/StatusLineConfigDialog.tsx
+++ b/ui/src/components/StatusLineConfigDialog.tsx
@@ -50,6 +50,7 @@ const MODULE_TYPES = [
{ label: "gitBranch", value: "gitBranch" },
{ label: "model", value: "model" },
{ label: "usage", value: "usage" },
+ { label: "script", value: "script" },
];
// ANSI颜色代码映射
@@ -675,6 +676,15 @@ export function StatusLineConfigDialog({
color: "bright_magenta",
};
break;
+ case "script":
+ newModule = {
+ type: "script",
+ icon: "📜",
+ text: "Script Module",
+ color: "bright_cyan",
+ scriptPath: "",
+ };
+ break;
default:
newModule = { ...DEFAULT_MODULE, type: moduleType };
}
@@ -920,6 +930,31 @@ export function StatusLineConfigDialog({
+ {/* Script Path 输入框 - 仅在type为script时显示 */}
+ {selectedModule.type === "script" && (
+
+
+
+ handleModuleChange(
+ selectedModuleIndex,
+ "scriptPath",
+ e.target.value
+ )
+ }
+ placeholder="例如: /path/to/your/script.js"
+ />
+
+ 输入Node.js脚本文件的绝对路径
+
+
+ )}
+
+