feat: add configurable CLI command and UI improvements

Add support for alternative CLI commands via CLI_COMMAND environment
variable, allowing users to use CLIs other than 'claude' (e.g., 'glm').
This change affects all server services and the main CLI launcher.

Key changes:

- Configurable CLI command via CLI_COMMAND env var (defaults to 'claude')
- Configurable Playwright headless mode via PLAYWRIGHT_HEADLESS env var
- Pin claude-agent-sdk version to <0.2.0 for stability
- Use tail -500 for progress notes to avoid context overflow
- Add project delete functionality with confirmation dialog
- Replace single-line input with resizable textarea in spec chat
- Add coder agent configuration for code implementation tasks
- Ignore issues/ directory in git

Files modified:
- client.py: CLI command and Playwright headless configuration
- server/main.py, server/services/*: CLI command configuration
- start.py: CLI command configuration and error messages
- .env.example: Document new environment variables
- .gitignore: Ignore issues/ directory
- requirements.txt: Pin SDK version
- .claude/templates/*: Use tail -500 for progress notes
- ui/src/components/ProjectSelector.tsx: Add delete button
- ui/src/components/SpecCreationChat.tsx: Auto-resizing textarea
- ui/src/components/ConfirmDialog.tsx: New reusable dialog
- .claude/agents/coder.md: New coder agent configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Auto
2026-01-10 13:19:49 +02:00
parent a0f7e72361
commit 117ca89f08
16 changed files with 496 additions and 49 deletions

View File

@@ -43,7 +43,7 @@ export function SpecCreationChat({
const [yoloEnabled, setYoloEnabled] = useState(false)
const [pendingAttachments, setPendingAttachments] = useState<ImageAttachment[]>([])
const messagesEndRef = useRef<HTMLDivElement>(null)
const inputRef = useRef<HTMLInputElement>(null)
const inputRef = useRef<HTMLTextAreaElement>(null)
const fileInputRef = useRef<HTMLInputElement>(null)
const {
@@ -98,6 +98,10 @@ export function SpecCreationChat({
sendMessage(trimmed, pendingAttachments.length > 0 ? pendingAttachments : undefined)
setInput('')
setPendingAttachments([]) // Clear attachments after sending
// Reset textarea height after sending
if (inputRef.current) {
inputRef.current.style.height = 'auto'
}
}
const handleKeyDown = (e: React.KeyboardEvent) => {
@@ -355,11 +359,15 @@ export function SpecCreationChat({
<Paperclip size={18} />
</button>
<input
<textarea
ref={inputRef}
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onChange={(e) => {
setInput(e.target.value)
// Auto-resize the textarea
e.target.style.height = 'auto'
e.target.style.height = `${Math.min(e.target.scrollHeight, 200)}px`
}}
onKeyDown={handleKeyDown}
placeholder={
currentQuestions
@@ -368,8 +376,9 @@ export function SpecCreationChat({
? 'Add a message with your image(s)...'
: 'Type your response... (or /exit to go to project)'
}
className="neo-input flex-1"
className="neo-input flex-1 resize-none min-h-[46px] max-h-[200px] overflow-y-auto"
disabled={(isLoading && !currentQuestions) || connectionStatus !== 'connected'}
rows={1}
/>
<button
onClick={handleSendMessage}
@@ -386,7 +395,7 @@ export function SpecCreationChat({
{/* Help text */}
<p className="text-xs text-[var(--color-neo-text-secondary)] mt-2">
Press Enter to send. Drag & drop or click <Paperclip size={12} className="inline" /> to attach images (JPEG/PNG, max 5MB).
Press Enter to send, Shift+Enter for new line. Drag & drop or click <Paperclip size={12} className="inline" /> to attach images (JPEG/PNG, max 5MB).
</p>
</div>
)}