45 Commits

Author SHA1 Message Date
Ed Zynda 78570d4188 remove dead code identified by audit
Removes ~600 lines of unreferenced code surfaced by deadcode + manual
audit (none of it reachable from production code paths or test setup):

- internal/models/pool.go: ProviderPool was never wired into kitsetup
  or the agent; the global pool singleton had zero callers.
- internal/ui/debug_logger.go: CLIDebugLogger was unreachable; debug
  routing goes through internal/tools/buffered_logger.go instead.
- internal/ui/tool_approval_input.go: tea.Model never instantiated;
  approvals are handled inline in model.go.
- internal/ui/cli.go: DisplayAssistantMessage / DisplayCancellation /
  GetDebugLogger had zero callers (the *WithModel variant is what
  event_handler.go uses).
- internal/ui/style/enhanced.go: Style{Card,Header,Subheader,Muted,
  Success,Error,Warning,Info} + Create{Separator,ProgressBar} — none
  used. CreateBadge stays (used by model.go).
- internal/ui/style/themes.go: RefreshThemeRegistry — never called.
- internal/ui/block_renderer.go: With{FullWidth,MarginTop,Padding{Left,
  Right},Background,Foreground,Width} — option helpers nobody calls.
- internal/ui/render/blocks.go: UserBlock, ToolBlock — replaced by
  inline rendering elsewhere; the test for UserBlock was rewritten to
  directly exercise HighlightFileTokens (which is what the test really
  cared about).
- internal/ui/commands/commands.go: GetAllCommandNames — no callers.
- internal/ui/message_items.go: NewTextMessageItem,
  NewSystemMessageItem + the entire SystemMessageItem type — model.go
  uses NewStyledMessageItem instead.
- internal/prompts/loader.go: Deduplicate — the loader does dedup
  internally; standalone helper was unused.
- internal/models/cache_options.go: mergeProviderOptions + its
  test-only consumer.
- internal/extensions/installer.go: Installer.GetInstalledPackages —
  intended for a 'kit ext list' command that was never built.
- internal/extensions/manifest.go: saveManifestToScope,
  saveManifestToPath, GetGlobalManifest, GetProjectManifest,
  addEntryToManifest, removeEntryFromManifest — package-level
  duplicates of *Installer methods. Tests rewritten to exercise the
  live Installer methods instead, which fixes a latent path-resolution
  inconsistency between manifestPathForScope and Installer.manifestPath
  (the former hard-coded paths, the latter respects projectGitRoot).
- internal/extensions/subagent.go: SpawnSubagent + helpers
  (generateSubagentID, findKitBinary, subagentJSONOutput). The
  subprocess-spawn implementation is unreachable; production code
  routes through kit.Kit.Subagent (in-process). Types
  (SubagentConfig/Result/Handle/etc.) and the SubagentHandle methods
  remain because they are exposed to extensions via Yaegi symbols and
  the Context.SpawnSubagent field.
- cmd/root.go: LoadConfigWithEnvSubstitution — one-line wrapper around
  kit.LoadConfigWithEnvSubstitution with zero callers.

go test -race ./... passes.
2026-05-07 12:20:08 +03:00
Ed Zynda 3ffc995f27 feat(sdk): add NewTool/NewParallelTool for dependency-free custom tools
- Add ToolOutput struct, TextResult/ErrorResult helpers, and
  ToolCallIDFromContext so SDK consumers can create custom tools
  without importing charm.land/fantasy
- Add NewTool (sequential) and NewParallelTool (concurrent) generic
  constructors with automatic JSON schema generation from struct tags
- Remove dead UpdateUsageFromResponse method and fantasy import from
  internal/ui/cli.go
- Update SDK skill, README, and www/ docs with custom tool examples
  and corrected hook signatures
2026-04-07 22:05:42 +03:00
Ed Zynda 28d2de8f39 Phase 1: Reorganize UI leaf utilities into subpackages
Moved leaf utility files to subpackages for better organization:
- events.go -> core/ (core message types)
- clipboard.go -> clipboard/ (clipboard operations)
- commands.go -> commands/ (slash commands)
- file_processor.go -> fileutil/ (file attachment processing)
- preferences.go -> prefs/ (theme/model preferences)
- enhanced_styles.go, styles.go, themes.go -> style/ (theming system)

Added exports.go to re-export commonly used types for backward
compatibility. External importers can still use ui.XXX without
changes.

All tests pass, basic smoke test successful.
2026-04-01 13:54:10 +03:00
Ed Zynda e7f11487b9 remove CompactRenderer and --compact flag
The compact display mode was purely a UI concern that added complexity
without providing unique value. Anyone wanting compact-style formatting
can implement it as an extension using the Renderer interface.

- Delete internal/ui/compact_renderer.go
- Remove renderToolBodyCompact and all compact tool body renderers from
  tool_renderers.go
- Simplify NewCLI(debug bool) — drop compact parameter
- Simplify NewStreamComponent(width, modelName) — drop compactMode parameter
- Remove CompactMode from AppModelOptions, app.Options, CLISetupOptions
- Remove Compact from internal/config/config.go
- Remove --compact flag, var, and viper binding from cmd/root.go
- Update format.go: remove CompactRenderer interface compile-time check
  and clean up comments
2026-03-31 13:01:30 +03:00
Ed Zynda 1f5c103667 fix: rock-solid token tracking - /new resets usage, remove estimation for costs
- /new command now properly resets usageTracker stats when starting fresh session
- Remove EstimateAndUpdateUsage fallback in updateUsageFromTurnResult()
- Remove EstimateAndUpdateUsage fallback in UpdateUsageFromResponse()
- Only use actual API-reported tokens for cost tracking (following opencode pattern)
- Estimation is inaccurate and should never be used for billing

Fixes issues with kimi-k2.5 and opencode token tracking where:
1. /new didn't reset token count/cost
2. Tokens never updated correctly due to estimation fallback
2026-03-28 12:15:45 +03:00
Ed Zynda bbf1106e27 Add OpenAI ChatGPT/Codex OAuth authentication alongside Anthropic auth
Implements OAuth authentication for OpenAI ChatGPT Plus/Pro (Codex) similar to pi:

- Add OpenAICredentials type with OAuth and API key support
- Add OpenAI OAuth client with correct endpoints (auth.openai.com)
- Implement PKCE-based OAuth flow with local callback server on :1455
- Add login/logout/status commands for openai provider
- Support both ChatGPT/Codex OAuth tokens (chatgpt.com/backend-api) and
  regular OpenAI API keys (api.openai.com)
- Extract and store ChatGPT account ID from JWT token
- Add custom HTTP transport with required Codex headers:
  - chatgpt-account-id, originator, OpenAI-Beta: responses=experimental
- Update provider selection to use correct endpoint based on auth type

Usage:
  kit auth login openai    # OAuth with ChatGPT account
  kit auth logout openai
  kit auth status

The implementation follows the same patterns as the existing Anthropic OAuth
support, with automatic token refresh and secure credential storage in
~/.config/.kit/credentials.json
2026-03-26 14:50:15 +03:00
Ed Zynda 13060a20f9 feat: add KITT-inspired theme system with unified markdown colors
Replace the Catppuccin color palette with a Knight Rider KITT-inspired
theme — scanner reds, amber dashboard glows, and dark cockpit tones.
No blues or bright greens; the entire palette stays in the warm
red/amber/gray family.

Unify the theme system by folding the standalone MarkdownTheme config
into the main Theme struct, eliminating the separate config path.
Replace all hardcoded lipgloss.Color() calls across input, overlay,
and CLI components with semantic theme references so every color
responds to theme customization.
2026-03-19 18:04:56 +03:00
Ed Zynda af486133a5 chore: remove dead code, unexport internal symbols, clean up stale comments
- Remove never-called functions: ListChildSessions, NewMessageEntryFromRaw,
  ProviderPool.Stats/PoolStats, CLI.DisplayToolCallMessage
- Remove deprecated ValidateModel (migrate callers to LookupModel)
- Remove deprecated colon-separated model format shim
- Unexport package-internal symbols: EstimateTokens, GetRequiredEnvVars,
  GeneratePKCE, ErrNoClipboardTool, ThinkingBudgetTokens, NewMessageRenderer
- Remove stale TAS-15/TAS-16 placeholder comments (both fully implemented)
- Fix misleading 'temporary approach' comment in clipboard_darwin.go
- Replace interface{} with any in extension examples
- Simplify auto-commit.go dead variable (CombinedOutput → Run)
2026-03-19 17:25:53 +03:00
Ed Zynda ad07086900 cleanup 2026-02-28 01:01:12 +03:00
Ed Zynda f42d487214 add Yaegi-based in-process extension system with event handlers, tool/command registration, and styled output
Implement a Pi-style extension system where plain .go files are loaded at
runtime via Yaegi. Extensions register typed event handlers against 13
lifecycle events (tool_call, tool_result, input, before_agent_start, etc.)
using concrete-type-only API methods to avoid Yaegi interface panics.

Key capabilities:
- Tool interception: block calls, modify results (wrapper pattern)
- Input handling: transform or fully handle user input (skip agent)
- System prompt injection via BeforeAgentStartResult
- Custom tool and slash command registration
- Styled output: ctx.Print, PrintInfo, PrintError, PrintBlock
- Legacy hooks.yml compatibility via adapter
- Auto-discovery from ~/.config/kit/extensions/ and .kit/extensions/
- CLI: kit extensions list|validate|init, --no-extensions, -e flags
- 58 unit tests covering runner, loader (Yaegi), wrapper, events
2026-02-27 00:08:48 +03:00
Ed Zynda a3bad94821 unify tool blocks into single header+result rendering
Core tools previously rendered two separate blocks: an 'Executing tool'
header block on ToolCallStartedEvent, then a separate result block on
ToolResultEvent. This merges them into a single unified block that
renders only when the result arrives.

The unified block shows a status icon (checkmark/cross), a friendly
tool display name, inline parameters, and the output body. Border
color indicates success (green) or error (red).
2026-02-26 17:59:45 +03:00
Ed Zynda 7fc94018a9 rename: fork mcphost to kit (github.com/mark3labs/kit)
Rename the entire project from mcphost to kit, including:
- Go module path and all import paths
- SDK type MCPHost -> Kit, file renames mcphost.go -> kit.go
- CLI command name, usage strings, UI labels (KIT in literature)
- Config paths (.mcphost -> .kit), env prefix (MCPHOST_ -> KIT_)
- Data/credential/hooks directory paths
- Remove legacy .mcp config fallbacks
- Session metadata field (mcphost_version -> kit_version)
- MCP client identity name
- Build output, goreleaser binary name
- All documentation, examples, scripts, and test files
2026-02-26 16:59:59 +03:00
Ed Zynda c5b75674a3 fix: token usage tracking with fantasy and sticky display across all visual modes
- Fix context percentage: use FinalResponse.Usage (last API call) instead of
  TotalUsage (sum of all tool-calling steps) which overstated context fill level
- Fix token count: display current context window tokens, not cumulative session
  total, so the number and percentage tell a consistent story
- Fix script mode double-counting: app.updateUsage already updates the shared
  tracker before sending StepCompleteEvent, so remove redundant
  UpdateUsageFromResponse call
- Add sticky usage display in TUI: render in View() layout between stream and
  separator instead of tea.Println so it updates in place
- Add usage display for non-interactive --prompt mode (non-quiet)
- Add SetContextTokens to UsageUpdater interface for separating billing tokens
  (TotalUsage) from context utilization (FinalResponse.Usage)
2026-02-26 16:10:43 +03:00
Ed Zynda 89b3adcc64 fix: unify script mode with app layer and fix broken display
Script mode had a duplicated agentic loop (runAgenticLoop/runAgenticStep)
that was copied from root.go during the Bubble Tea refactor but left with
broken streaming display and missing hooks integration. The streaming
callback silently accumulated chunks without rendering, and the final
response was skipped because it assumed streaming had already shown it.

- Refactor app.executeStep to accept a generic eventFn callback instead
  of a *tea.Program, decoupling the agent step from Bubble Tea
- Add app.RunOnceWithDisplay for non-TUI callers that need intermediate
  display events (spinner, tool calls, streaming chunks)
- Replace ~300 lines of duplicated code in script.go with a lightweight
  scriptEventHandler that routes app events to CLI display methods
- Fix agent.GenerateWithLoopAndStreaming to use the streaming path when
  any callbacks are provided (fantasy only exposes callbacks on Stream)
- Fix CLI displayContainer to match TUI output (remove extra padding)
- Remove premature usage display during CLI setup
2026-02-26 14:35:36 +03:00
Ed Zynda 69fba663ef fix(ui): use theme colors for spinner, remove text, persist during streaming
Spinner now uses theme.Primary/Muted/VeryMuted/MutedBorder instead of
hardcoded red. Removed 'Thinking...' label and message parameter from
NewSpinner/ShowSpinner/SpinnerFunc. Spinner keeps running alongside
streaming text and only hides on step complete via Reset().
2026-02-26 12:24:17 +03:00
Ed Zynda cf2c026182 refactor(ui): trim CLI to non-TUI helpers only
Remove methods that belonged to the old interactive loop and have no
external callers: HandleSlashCommand, SlashCommandResult, IsSlashCommand,
DisplayHelp, DisplayTools, DisplayServers, ClearMessages, UpdateUsage,
DisplayUsageStats, ResetUsageStats. Slash command dispatch is now owned
by InputComponent in the Bubble Tea TUI; usage tracking is handled
directly by the app layer.

Retain all display methods still needed by non-interactive paths
(cmd/root.go session replay, cmd/script.go, factory.go). Also drop the
now-unused "strings" import. cli.go shrinks from 509 to 329 lines.
2026-02-26 02:32:12 +03:00
Ed Zynda 154d693a8e refactor(ui): remove standalone tea.Program calls from CLI (TAS-27)
Delete GetPrompt, StartStreamingMessage, UpdateStreamingMessage,
GetToolApproval, and finishStreaming from CLI — these each spun up
their own tea.NewProgram and are superseded by the unified AppModel
TUI. Also remove the streamProgram/streamDone fields they relied on.

Update dead-code stubs in cmd/root.go to keep the build clean until
the legacy agentic-loop functions are deleted in TAS-28.
2026-02-26 01:58:25 +03:00
Ed Zynda 12bed9b515 feat(app): move usage tracking into app layer (TAS-8)
Add UsageUpdater interface to app/options.go to avoid circular imports,
wire *ui.UsageTracker via Options.UsageTracker in cmd/root.go, and call
updateUsage() after each successful step in both runPrompt() and RunOnce().
2026-02-26 01:45:24 +03:00
Ed Zynda 676a6b0e63 fix: replace manual ANSI escape sequences with Bubble Tea program for streaming display
Streaming text was flickering because displayContainer() used raw escape
sequences (\033[%dF) to move the cursor and fmt.Println to repaint on
every token. This bypassed Bubble Tea's synchronized output, cursor
hiding, and atomic flush.

Replace the manual approach with a dedicated tea.Program that runs for
the lifetime of each streaming response. BT's renderer now handles all
in-place updates flicker-free. One-shot messages (user, tool, system,
error) continue to use simple fmt.Println since they are never redrawn.
2026-02-26 00:07:27 +03:00
Ed Zynda 71bdc768be feat: replace catwalk with models.dev, auto-route openai-compatible providers, fix all lint issues
Replace catwalk dependency with direct models.dev integration (97 providers,
3039 models vs catwalk's 22/679). Auto-route @ai-sdk/openai-compatible
providers through fantasy's openaicompat using the api URL from models.dev,
eliminating the need for --provider-url. Add --all flag to 'mcphost models'
to show all providers vs just fantasy-compatible ones.

Fix all 74 golangci-lint issues: errcheck (53), staticcheck SA4006 (24),
SA9003 (2), ST1005 (5), ineffassign (3). Restructure styles.go color
handling into a colorScheme struct to eliminate SA4006 false positives
from new(x) syntax.
2026-02-25 22:51:45 +03:00
Ed Zynda 0703dd1602 fix: eliminate escape sequence leak from spinner tea.Program instances
Each spinner created a new tea.NewProgram which sent DECRQM queries for
synchronized output mode 2026. When the program exited and restored
cooked terminal mode, the terminal's DECRPM response leaked as visible
^[[?2026;2$y characters. Replace Bubble Tea spinner with a simple
goroutine animation loop writing directly to stderr via lipgloss.
2026-02-25 18:17:25 +03:00
Ed Zynda ce32cea7ee feat: upgrade charmbracelet libs to v2 (bubbletea, lipgloss, bubbles)
Migrate from github.com/charmbracelet/* v1 to charm.land/* v2 vanity imports.

Key changes:
- bubbletea: View() returns tea.View, KeyMsg -> KeyPressMsg, msg.String() matching
- lipgloss: AdaptiveColor replaced with cached dark-bg detection helper
- bubbles/textarea: Styles()/SetStyles() pattern, KeyMap.InsertNewline override
- bubbles/progress: SetWidth(), WithDefaultBlend(), typed Update return
- Input: enter always submits, ctrl+j/alt+enter insert newlines
- User message newlines preserved through glamour via \n -> \n\n conversion
- glamour stays at v1 (no v2 exists)
2026-02-25 17:07:09 +03:00
Darragh O'Reilly cab31935f1 Feat: Add option to require approval before tool execution (#140)
Adds a new CLI option, `--approve-tool-run` (or via config setting),
that when enabled, prompts the user to approve a tool's execution
before it runs.

This option is disabled by default to maintain existing behavior.
2025-12-09 18:28:41 +03:00
Ed Zynda 63704f55b5 godoc 2025-11-12 16:48:46 +03:00
Ed Zynda d3f9759eb4 refactor debug messages 2025-08-08 09:32:04 +03:00
Ed Zynda 5c041394b8 Autocomplete (#105)
* implement autocomplete

* fix

* fix

* remove useless history command

* fix spacing

* fix padding for goodbye

* cleanup
2025-07-09 17:49:13 +03:00
Ed Zynda 9159f226f4 Smooth UI (#104)
* draft: rewrite single message when streaming (not full terminal)

* having the spinner align better with dots in compact mode

* fix user messages

* handle usage display

* fix formatting

* bash highlighting

---------

Co-authored-by: Nate Woods <big.nate.w@gmail.com>
2025-07-09 00:41:35 +03:00
Ed Zynda 7b2592bbdc fmt 2025-06-27 16:31:01 +03:00
Ed Zynda 76dd18030a Compact mode (#91)
* compact mode

* tweaks

* tweaks

* tweaks

* fix streaming in tool calls
2025-06-27 15:56:09 +03:00
Ed Zynda 6a1b2f65d1 fix google/gemini 2025-06-27 11:40:11 +03:00
Ed Zynda acade83e37 fix token tracking 2025-06-27 11:33:44 +03:00
Ed Zynda ec620e4e88 Streaming (#87)
* basic streaming

* fix output

* update

* update

* fix display issue

* update readme

* fmt

* cleanup

* cleanup

* cleanup

* fix
2025-06-26 18:15:17 +03:00
Ed Zynda 30f720ef7b updates 2025-06-26 10:56:10 +03:00
Ed Zynda b3c26150c7 fix /clear 2025-06-26 10:49:39 +03:00
Ed Zynda 7d6abbf4a0 UI updates (#80)
* ui updates

* catppuccin

* fmt
2025-06-25 17:24:37 +03:00
Ed Zynda 1f407bf7fb streamable HTTP 2025-06-19 16:16:19 +03:00
Ed Zynda 3faf46ff44 better token tracking and support for more openai models 2025-06-18 15:19:04 +03:00
Ed Zynda cda80f1572 anthropic token tracking 2025-06-18 14:48:19 +03:00
Ed Zynda aa43421b81 rudimentary token tracking 2025-06-18 14:05:30 +03:00
Ed Zynda 45b9ad9d5c add cancellation 2025-06-18 10:29:47 +03:00
Ed Zynda ec5c1ef03e fix normal mode input 2025-06-11 13:27:15 +03:00
Ed Zynda 306fbdb3d0 Standardize (#67)
* Model generation params

* Standardize model URL

* standardize more flags and update max steps check

* fix system prompt handling

* standardize api key handling

* update readme
2025-06-11 11:45:55 +03:00
Ed Zynda 13ede07ea5 formatting 2025-06-10 01:21:17 +03:00
Ed Zynda 5d5cb58eb9 Do not buffer tool calls and responses (#61) 2025-06-09 16:34:55 +03:00
Ed Zynda 8645a8c36a Huge refactor (#58)
* overhaul

* fix ui glitch

* system messages

* use sonnet 4
2025-06-09 14:38:31 +03:00