refactor: enhance artifact system, security, and terminal command handling
- Add basic HTTP authentication (express-basic-auth) - Improve artifact tool with better source type handling (command_output, file, text) - Update agent prompt with clearer artifact usage patterns - Refactor tmux command execution to use execFile for safer argument handling - Add UI cancellation capability for in-progress operations - Switch session dumps to use util.inspect for better formatting - Update artifact tool schema to require title parameter first 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -380,6 +380,14 @@
|
||||
background-color: #f59e0b;
|
||||
}
|
||||
|
||||
.send-button.cancelling {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
|
||||
.send-button.cancelling:hover:not(:disabled) {
|
||||
background-color: #dc2626;
|
||||
}
|
||||
|
||||
.send-button:disabled {
|
||||
background-color: #444;
|
||||
color: #999;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { Mic, Send, Radio } from "lucide-react";
|
||||
import { Mic, Send, Radio, X } from "lucide-react";
|
||||
import { useWebSocket } from "./hooks/useWebSocket";
|
||||
import { createAudioPlayer } from "./lib/audio-playback";
|
||||
import { createAudioRecorder, type AudioRecorder } from "./lib/audio-capture";
|
||||
@@ -399,12 +399,47 @@ function App() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = async () => {
|
||||
console.log("[App] Cancelling operations...");
|
||||
|
||||
// Stop audio playback
|
||||
audioPlayerRef.current.stop();
|
||||
setIsPlayingAudio(false);
|
||||
|
||||
// Clear streaming state
|
||||
setCurrentAssistantMessage("");
|
||||
|
||||
// Reset processing state
|
||||
setIsProcessingAudio(false);
|
||||
|
||||
// Send abort request to server
|
||||
ws.send({
|
||||
type: "session",
|
||||
message: {
|
||||
type: "abort_request",
|
||||
},
|
||||
});
|
||||
|
||||
addLog("info", "Operations cancelled");
|
||||
};
|
||||
|
||||
// Compute if we're processing an already sent request (not including recording)
|
||||
const isInProgress =
|
||||
isProcessingAudio || isPlayingAudio || currentAssistantMessage.length > 0;
|
||||
|
||||
const handleButtonClick = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (userInput.trim()) {
|
||||
if (isRecording) {
|
||||
// Stop recording and send the audio
|
||||
await handleToggleRecording();
|
||||
} else if (isInProgress) {
|
||||
// Cancel processing/playback of already sent request
|
||||
await handleCancel();
|
||||
} else if (userInput.trim()) {
|
||||
handleSendMessage();
|
||||
} else {
|
||||
// Start recording
|
||||
await handleToggleRecording();
|
||||
}
|
||||
};
|
||||
@@ -649,15 +684,15 @@ function App() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleButtonClick}
|
||||
disabled={!ws.isConnected || isProcessingAudio}
|
||||
className={`send-button ${isRecording ? "recording" : ""} ${
|
||||
isProcessingAudio ? "processing" : ""
|
||||
disabled={!ws.isConnected}
|
||||
className={`send-button ${isInProgress ? "cancelling" : ""} ${
|
||||
isRecording ? "recording" : ""
|
||||
} ${userInput.trim() ? "has-text" : ""}`}
|
||||
>
|
||||
{isRecording ? (
|
||||
{isInProgress ? (
|
||||
<X size={20} />
|
||||
) : isRecording ? (
|
||||
<span className="recording-indicator" />
|
||||
) : isProcessingAudio ? (
|
||||
<span className="processing-indicator" />
|
||||
) : userInput.trim() ? (
|
||||
<Send size={20} />
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user