diff --git a/cmd/chat.go b/cmd/chat.go index 4d3e6ac6..058d5f94 100644 --- a/cmd/chat.go +++ b/cmd/chat.go @@ -291,7 +291,7 @@ func newChatModel(ref *progRef, systemPrompt string, settings hawkconfig.Setting if home, err := os.UserHomeDir(); err == nil { dagPath := filepath.Join(home, ".hawk", "sessions", "convo.db") if dag, err := storage.NewDAG(dagPath, sid); err == nil { - sess.ConvoDAG = dag + sess.SetConvoDAG(dag) } } startup.EndPhase("newChatModel:dag") @@ -446,19 +446,19 @@ func newChatModel(ref *progRef, systemPrompt string, settings hawkconfig.Setting (saved == nil || len(saved.Messages) == 0) // Wire permission system - sess.PermissionFn = func(req engine.PermissionRequest) { + sess.PermSvc().SetPermissionFn(func(req engine.PermissionRequest) { ref.Send(permissionAskMsg{req: req}) - } + }) // High-risk action gate (network, destructive bash) — additive layer on top // of the permission engine; falls back to AskUserFn for confirmation. - sess.Approval = &engine.ApprovalGate{ + sess.SetApproval(&engine.ApprovalGate{ Enabled: true, MaxAutoApprove: engine.AutonomySemi, - } + }) // Wire ask_user tool (5-minute timeout matches permission prompts). - sess.AskUserFn = func(question string) (string, error) { + sess.SetAskUserFn(func(question string) (string, error) { resp := make(chan string, 1) ref.Send(askUserMsg{question: question, response: resp}) select { @@ -467,7 +467,7 @@ func newChatModel(ref *progRef, systemPrompt string, settings hawkconfig.Setting case <-time.After(5 * time.Minute): return "", fmt.Errorf("question timed out") } - } + }) if saved != nil { for _, sm := range saved.Messages { diff --git a/cmd/chat_commands.go b/cmd/chat_commands.go index 1eeef6c2..7fe70f50 100644 --- a/cmd/chat_commands.go +++ b/cmd/chat_commands.go @@ -4,25 +4,12 @@ import ( "context" "fmt" "os" - "os/exec" - "path/filepath" - "strconv" "strings" - "time" tea "github.com/charmbracelet/bubbletea" - hawkconfig "github.com/GrayCodeAI/hawk/internal/config" "github.com/GrayCodeAI/hawk/internal/engine" - "github.com/GrayCodeAI/hawk/internal/engine/project" - "github.com/GrayCodeAI/hawk/internal/feature/shellmode" - "github.com/GrayCodeAI/hawk/internal/home" - "github.com/GrayCodeAI/hawk/internal/intelligence/memory" "github.com/GrayCodeAI/hawk/internal/multiagent/parallel" - analytics "github.com/GrayCodeAI/hawk/internal/observability" - "github.com/GrayCodeAI/hawk/internal/plugin" - "github.com/GrayCodeAI/hawk/internal/recipe" - "github.com/GrayCodeAI/hawk/internal/tool" "github.com/GrayCodeAI/hawk/internal/ui/icons" ) @@ -289,1315 +276,30 @@ func (m *chatModel) handleCommand(text string) (tea.Model, tea.Cmd) { return m.handleNamespacedSkill(cmd, text) } - switch cmd { - case "/quit", "/exit": - return m.handleSessionCommand(cmd, parts, text) - case "/add-dir": - if len(parts) < 2 { - m.messages = append(m.messages, displayMsg{role: "error", content: "Usage: /add-dir "}) - return m, nil - } - dirArg := strings.TrimSpace(strings.TrimPrefix(text, "/add-dir")) - abs, contextBlock, err := additionalDirContext(dirArg) - if err != nil { - m.messages = append(m.messages, displayMsg{role: "error", content: err.Error()}) - return m, nil - } - if !hasString(addDirs, abs) { - addDirs = append(addDirs, abs) - m.session.AppendSystemContext(contextBlock) - m.session.SetAllowedDirs(addDirs) - } - m.messages = append(m.messages, displayMsg{role: "system", content: "Added directory to context: " + abs}) - return m, nil - case "/branch": - m.messages = append(m.messages, displayMsg{role: "system", content: branchSummary()}) - return m, nil - case "/clear": - return m.handleSessionCommand(cmd, parts, text) - case "/compact": - return m.handleSessionCommand(cmd, parts, text) - case "/diff": - stat, _ := gitOutput("diff", "--stat") - diff, _ := gitOutput("diff") - if strings.TrimSpace(diff) == "" { - stat, _ = gitOutput("diff", "--cached", "--stat") - diff, _ = gitOutput("diff", "--cached") - } - if strings.TrimSpace(diff) == "" { - m.messages = append(m.messages, displayMsg{role: "system", content: "No changes detected."}) - return m, nil - } - output := stat + "\n\n" + diff - if len(output) > 10000 { - output = stat + "\n\n(diff too large, showing stat only)" - } - m.messages = append(m.messages, displayMsg{role: "system", content: output}) - return m, nil - case "/help", "/commands": - help := `/add-dir — Add a directory to context -/agents — List active agents/teammates -/branch — Show git branch/status -/bughunter — Ask hawk to hunt for bugs -/clear — Clear display -/color — Set agent color -/compact — Compact conversation (LLM summary) -/commit — Auto-commit changes -/config — Show settings -/commands — List available slash commands -/context — Show current context -/copy — Copy chat or input (all|input|last|assistant) -/cost — Token usage and cost -/cron — List scheduled cron jobs -/diff — Review changes -/doctor — Run diagnostics -/dream — Run memory consolidation -/away — Generate session recap -/effort — Set reasoning effort (low/medium/high) -/env — Show provider environment status -/export — Export session to JSON -/fast — Toggle fast mode -/feedback — Submit feedback (saved to ~/.hawk/feedback/) -/files — Show modified files -/help — This help message -/history — List saved sessions -/hooks — Show configured hooks -/init — Analyze project -/keybindings — Show keybindings -/loop — Run a command on interval -/mcp — Show MCP status -/memory — Show loaded project instructions -/metrics — Show collected metrics -/model — Show current model -/models — List available models -/output-style — Set output verbosity -/permissions — Show tier, sandbox, mode, rules, and effective behavior -/permissions tier — Set the autonomy tier -/permissions mode — Set the advanced permission mode -/permissions allow — Add an allow rule -/permissions deny — Add a deny rule -/permissions save — Persist the current permission policy -/plugins — List installed plugins -/pr-comments — Ask hawk to handle PR comments -/release-notes — Draft release notes -/rename — Rename current session -/resume — Resume session -/review — Ask hawk to review changes -/rewind — Undo last exchange -/security-review — Ask hawk to review security risks -/select — Pause TUI for native text selection -/mouse — Toggle mouse capture (off = click-drag copy) -/share — Share session -/learn — LLM-powered skill advisor (deep, update) -/skills — List, search, install, remove skills -/stale — Show stale rules that may need removal -/stats — Session statistics -/status — Session status -/summary — Summarize the current session -/tag