Tui rewrite - #3
Merged
Merged
Conversation
- MessageStore with subscribe/notify pattern for reactive state - MessageInstance type with id, type, content, component, timestamp - VirtualMessageList implementing pi-tui Component interface - Typed message creators: createUserMessage, createAssistantMessage, createSystemMessage, createInProgressMessage - Message row factory for rendering different message types Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Routes CLI stderr output through a callback instead of console.error, enabling proper message handling in the TUI. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Extends CommandContext with createUserMessage, createAssistantMessage, createSystemMessage, createInProgressMessage, and removeMessageById for type-safe message handling in commands. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Uses createUserMessage, createInProgressMessage, createAssistantMessage, and removeMessageById instead of direct tui.children manipulation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds setTui() call to connect VirtualMessageList to the TUI instance, enabling requestRender() on message store updates. Also refactors message creation to use typed message creators through the store. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
timestamp field now serves as startTime for in-progress messages, enabling a single source of truth for elapsed time calculation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- InProgressMessage tracks startTime and renders phrase + elapsed seconds - Parens timer is dim grey, phrase is yellow - createMessageComponent accepts optional startTime for in-progress type Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
scheduleTick() now reschedules after each tick, firing every second to update the live timer display until the in-progress message is removed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Removes duplicate startTime tracking — elapsed now derives from the in-progress message's timestamp for consistency. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
LoopResult now includes usage field, and AgentLoop accumulates input/output tokens across all turns for accurate total counts. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
InProgressMessage now shows live timer + token counts (↓↑) and optional context bar [current/limit]. createInProgressMessage accepts token and context parameters. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Shows token counts and context bar in in-progress message - Shows token info in elapsed system message - Brief pause before removing in-progress to show final state Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Shows token counts and context bar in in-progress message - Shows token info in elapsed system message - Brief pause before removing in-progress to show final state Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
OpenAI, Anthropic, and Gemini providers were not passing `tools` to generateText(), causing result.toolCalls to be undefined and no tool UI to display. Now transforms and passes tools as ToolSet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…reaming AgentLoop now emits tool events via onToolEvent callback when tools are executed. Server wires these to stdout immediately for TUI streaming. Supports both batch mode and streaming IPC responses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Defines StreamEvent union type with tool_start, tool_output, tool_complete, text, done, and error event variants. Used by core to emit events and TUI to consume them for real-time tool UI rendering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
IPC client now supports streaming mode via sessionSendStreaming which accepts an onEvent callback to handle StreamEvent messages as they arrive. Events are parsed from stdout lines that don't have jsonrpc field. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ToolProgressMessage shows animated spinner during tool execution with output lines. ToolResultMessage shows success/failure status after completion. Both truncate output to terminal width and support updating output during execution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MessageType now includes 'tool' type for tool progress/result messages. Components index exports createToolProgressMessage and createToolResultMessage factory functions used by handleToolEvent in index.ts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
InProgressMessage.render() now uses truncateToWidth to ensure the full status line doesn't exceed terminal width, preventing crashes when context bar or model info is added. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
index.ts now handles tool_start/tool_output/tool_complete events to show live tool progress and results. handleToolEvent creates ToolProgressMessage on tool_start, updates it on tool_output, replaces with ToolResultMessage on tool_complete. Commands updated to use sessionSendStreaming with event callback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Central session storage at ~/.freecode/, JSONL message streaming, interrupt handling with resume, URL-based remote sync. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7 tasks covering SessionStore (JSONL), SessionManager integration, agent loop streaming, Ctrl+C interrupt handling, resume picker TUI, session IPC handlers, and URL-based remote sync. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Converts project paths to safe directory names for sessions. Format: /home/ayande/Project → home__ayande__Project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sessions now stored at ~/.freecode/sessions/{projectDir}/{sessionId}/
Adds projectDir parameter to all session store methods.
Adds getMetaBySessionId for formatted dir lookup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>SessionManager now uses list() to find meta then uses projectPath directly for subsequent calls. Fixes resume/switch/fork failures with new project-based storage structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds projectPath field to SessionState interface for use in session store operations throughout the agent loop. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AgentLoop now passes this.state.projectPath to all appendMessage calls in session store. Ensures messages are written to correct project-based directory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replaces LLM-based title generation with generateTitleFromPrompt() using stop-word filtering (no extra API call) - Session IDs now use randomUUID() instead of counter - Uses SESSION_BASE_DIR constant Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New module for session title generation: - generateTitleFromPrompt(): Uses stop-word filtering on first prompt - generateSessionTitle(): LLM-based approach (kept for future Haiku option) - extractSmallModel(): Helper to extract fast model names No extra API call needed - titles extracted from prompt directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Uh oh!
There was an error while loading. Please reload this page.
ayan-de added a commit
that referenced
this pull request
Sep 5, 2026
All six P1 items are closed. Each entry says what was wrong, what was built, and — where it matters more — what was deliberately not built: no shared settings loader (the three-merge-rules gap stays open and is not what made a typo invisible), no wire type for the raw config, no validation stricter than the handler it guards. Step 5 of the path to 1.0 is now the eval gate. P1 #2 and #3 both change what the model sees after a compaction, so that run is the measurement, not a formality.
ayan-de added a commit
that referenced
this pull request
Sep 5, 2026
I wrote that a moved judged suite would point at the compaction changes. That is wrong: compaction fires at ~107k input tokens, the longest eval prompt is ~65 tokens, and every case runs a single turn — so no case has ever compacted or can. The transcript from P1 #3 reaches the model only through the summary (loop.ts:1446 reads .summary, not recentMessages), so with no compaction the prompt is byte-identical before and after. The gate is a pre-tag regression check here, not a measurement. Recorded the harness gap in TODO.md, with the cheap fix (a FREECODE_COMPACT_TARGET_TOKENS override in the runner) noted over the expensive one (multi-turn replay cases).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.