generated from nhcarrigan/template
feat: display ConfigChange hook events in terminal
Detects [ConfigChange Hook] lines in stderr and emits them as config-change line type with [config] prefix in purple. Closes #151
This commit is contained in:
@@ -761,18 +761,21 @@ fn handle_stderr(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Worktree hook events are informational — emit with a distinct type
|
// Hook events are informational — emit with distinct types instead of error
|
||||||
let is_worktree_event = line.contains("[WorktreeCreate Hook]")
|
let line_type = if line.contains("[WorktreeCreate Hook]")
|
||||||
|| line.contains("[WorktreeRemove Hook]");
|
|| line.contains("[WorktreeRemove Hook]")
|
||||||
|
{
|
||||||
|
"worktree"
|
||||||
|
} else if line.contains("[ConfigChange Hook]") {
|
||||||
|
"config-change"
|
||||||
|
} else {
|
||||||
|
"error"
|
||||||
|
};
|
||||||
|
|
||||||
let _ = app.emit(
|
let _ = app.emit(
|
||||||
"claude:output",
|
"claude:output",
|
||||||
OutputEvent {
|
OutputEvent {
|
||||||
line_type: if is_worktree_event {
|
line_type: line_type.to_string(),
|
||||||
"worktree".to_string()
|
|
||||||
} else {
|
|
||||||
"error".to_string()
|
|
||||||
},
|
|
||||||
content: line,
|
content: line,
|
||||||
tool_name: None,
|
tool_name: None,
|
||||||
conversation_id: conversation_id.clone(),
|
conversation_id: conversation_id.clone(),
|
||||||
|
|||||||
@@ -100,6 +100,8 @@
|
|||||||
return "terminal-compact-prompt";
|
return "terminal-compact-prompt";
|
||||||
case "worktree":
|
case "worktree":
|
||||||
return "terminal-worktree";
|
return "terminal-worktree";
|
||||||
|
case "config-change":
|
||||||
|
return "terminal-config-change";
|
||||||
default:
|
default:
|
||||||
return "terminal-default";
|
return "terminal-default";
|
||||||
}
|
}
|
||||||
@@ -121,6 +123,8 @@
|
|||||||
return "[rate-limit]";
|
return "[rate-limit]";
|
||||||
case "worktree":
|
case "worktree":
|
||||||
return "[worktree]";
|
return "[worktree]";
|
||||||
|
case "config-change":
|
||||||
|
return "[config]";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -394,6 +398,10 @@
|
|||||||
color: var(--terminal-worktree, #34d399);
|
color: var(--terminal-worktree, #34d399);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.terminal-config-change {
|
||||||
|
color: var(--terminal-config-change, #a78bfa);
|
||||||
|
}
|
||||||
|
|
||||||
.compact-action-btn {
|
.compact-action-btn {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ function getLineClass(type: string): string {
|
|||||||
return "terminal-compact-prompt";
|
return "terminal-compact-prompt";
|
||||||
case "worktree":
|
case "worktree":
|
||||||
return "terminal-worktree";
|
return "terminal-worktree";
|
||||||
|
case "config-change":
|
||||||
|
return "terminal-config-change";
|
||||||
default:
|
default:
|
||||||
return "terminal-default";
|
return "terminal-default";
|
||||||
}
|
}
|
||||||
@@ -63,6 +65,8 @@ function getLinePrefix(type: string): string {
|
|||||||
return "[rate-limit]";
|
return "[rate-limit]";
|
||||||
case "worktree":
|
case "worktree":
|
||||||
return "[worktree]";
|
return "[worktree]";
|
||||||
|
case "config-change":
|
||||||
|
return "[config]";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -124,6 +128,10 @@ describe("getLineClass", () => {
|
|||||||
expect(getLineClass("worktree")).toBe("terminal-worktree");
|
expect(getLineClass("worktree")).toBe("terminal-worktree");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("returns terminal-config-change for config-change lines", () => {
|
||||||
|
expect(getLineClass("config-change")).toBe("terminal-config-change");
|
||||||
|
});
|
||||||
|
|
||||||
it("returns terminal-default for unknown line types", () => {
|
it("returns terminal-default for unknown line types", () => {
|
||||||
expect(getLineClass("unknown")).toBe("terminal-default");
|
expect(getLineClass("unknown")).toBe("terminal-default");
|
||||||
expect(getLineClass("")).toBe("terminal-default");
|
expect(getLineClass("")).toBe("terminal-default");
|
||||||
@@ -164,6 +172,10 @@ describe("getLinePrefix", () => {
|
|||||||
expect(getLinePrefix("worktree")).toBe("[worktree]");
|
expect(getLinePrefix("worktree")).toBe("[worktree]");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("returns [config] for config-change lines", () => {
|
||||||
|
expect(getLinePrefix("config-change")).toBe("[config]");
|
||||||
|
});
|
||||||
|
|
||||||
it("returns empty string for thinking lines (no prefix)", () => {
|
it("returns empty string for thinking lines (no prefix)", () => {
|
||||||
expect(getLinePrefix("thinking")).toBe("");
|
expect(getLinePrefix("thinking")).toBe("");
|
||||||
});
|
});
|
||||||
|
|||||||
+4
-2
@@ -332,7 +332,8 @@ export async function initializeTauriListeners() {
|
|||||||
| "thinking"
|
| "thinking"
|
||||||
| "rate-limit"
|
| "rate-limit"
|
||||||
| "compact-prompt"
|
| "compact-prompt"
|
||||||
| "worktree",
|
| "worktree"
|
||||||
|
| "config-change",
|
||||||
content,
|
content,
|
||||||
tool_name || undefined,
|
tool_name || undefined,
|
||||||
costData,
|
costData,
|
||||||
@@ -350,7 +351,8 @@ export async function initializeTauriListeners() {
|
|||||||
| "thinking"
|
| "thinking"
|
||||||
| "rate-limit"
|
| "rate-limit"
|
||||||
| "compact-prompt"
|
| "compact-prompt"
|
||||||
| "worktree",
|
| "worktree"
|
||||||
|
| "config-change",
|
||||||
content,
|
content,
|
||||||
tool_name || undefined,
|
tool_name || undefined,
|
||||||
costData,
|
costData,
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ export interface TerminalLine {
|
|||||||
| "thinking"
|
| "thinking"
|
||||||
| "rate-limit"
|
| "rate-limit"
|
||||||
| "compact-prompt"
|
| "compact-prompt"
|
||||||
| "worktree";
|
| "worktree"
|
||||||
|
| "config-change";
|
||||||
content: string;
|
content: string;
|
||||||
timestamp: Date;
|
timestamp: Date;
|
||||||
toolName?: string;
|
toolName?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user