返回 DeepSeek-Reasonix
chat_tui_slash_fallback.go
根目录 / internal / cli / chat_tui_slash_fallback.go
1 package cli
2
3 import (
4 "fmt"
5 "strings"
6
7 tea "charm.land/bubbletea/v2"
8
9 "reasonix/internal/control"
10 "reasonix/internal/i18n"
11 "reasonix/internal/skill"
12 )
13
14 // runUnrecognizedSlash resolves slash input that is not a built-in command, in
15 // the order a name must win: built-in docs pages, then a custom command, then
16 // a skill, then an extension action, and finally prose sent as a plain message.
17 // cmd is the canonicalized spelling used in the unknown-command notice.
18 func (m *chatTUI) runUnrecognizedSlash(input, typedCmd, cmd string) tea.Cmd {
19 if control.IsBuiltinDocsSlash(typedCmd, m.commands, m.skills) {
20 query := strings.TrimSpace(strings.TrimPrefix(input, typedCmd))
21 if query != "" {
22 return m.startControllerTurn(input, input, func(ctrl control.SessionAPI) { ctrl.SubmitDisplay(input, input) })
23 }
24 m.echoLocalCommand(input)
25 text, err := control.DocsCommandOverviewFor(typedCmd)
26 if err != nil {
27 m.notice("docs: " + err.Error())
28 } else {
29 m.commitLine(text)
30 }
31 return nil
32 }
33 // A custom command wins over a skill of the same name; both resolve to a turn.
34 if sent, ok := m.ctrl.CustomCommand(input); ok {
35 return m.startTurn(sent, input, input)
36 }
37 if _, ok := m.ctrl.RunSkill(input); ok {
38 fields := strings.Fields(input)
39 name := strings.TrimPrefix(fields[0], "/")
40 for _, sk := range m.ctrl.Skills() {
41 if sk.Name == name && sk.RunAs == skill.RunSubagent && len(fields) == 1 {
42 m.echoLocalCommand(input)
43 m.notice("usage: /" + name + " <task>")
44 return nil
45 }
46 }
47 return m.startControllerTurn(input, input, func(ctrl control.SessionAPI) { ctrl.SubmitDisplay(input, input) })
48 }
49 // An extension action (/<plugin>:<action>) resolves last, before the
50 // unknown-command fallback; the invocation is a sidecar round-trip, so it
51 // runs off the event loop and its result lands as a notice.
52 if action, ok := matchExtensionAction(m.ctrl, typedCmd); ok {
53 m.echoLocalCommand(input)
54 return m.runExtensionAction(action.Slash, parseExtensionActionArgs(strings.Fields(input)[1:]))
55 }
56 // Unknown slash input is prose more often than a typo — send it as a
57 // regular message (matching the controller's behavior for the other
58 // surfaces), with a notice so real typos stay visible (#5756).
59 m.notice(fmt.Sprintf("%s: %s — %s", i18n.M.SlashUnknown, cmd, i18n.M.SlashUnknownSentAsMessage))
60 return m.startTurn(input, input, input)
61 }
62
62 lines GO