Detailed changes
@@ -49,6 +49,8 @@ type Service interface {
Deny(permission PermissionRequest)
Request(opts CreatePermissionRequest) bool
AutoApproveSession(sessionID string)
+ SetSkipRequests(skip bool)
+ SkipRequests() bool
SubscribeNotifications(ctx context.Context) <-chan pubsub.Event[PermissionNotification]
}
@@ -210,6 +212,14 @@ func (s *permissionService) SubscribeNotifications(ctx context.Context) <-chan p
return s.notificationBroker.Subscribe(ctx)
}
+func (s *permissionService) SetSkipRequests(skip bool) {
+ s.skip = skip
+}
+
+func (s *permissionService) SkipRequests() bool {
+ return s.skip
+}
+
func NewPermissionService(workingDir string, skip bool, allowedTools []string) Service {
return &permissionService{
Broker: pubsub.NewBroker[PermissionRequest](),
@@ -263,6 +263,9 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
Attachment: attachment,
})
+ case commands.ToggleYoloModeMsg:
+ m.setEditorPrompt()
+ return m, nil
case tea.KeyPressMsg:
cur := m.textarea.Cursor()
curIdx := m.textarea.Width()*cur.Y + cur.X
@@ -368,6 +371,14 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Batch(cmds...)
}
+func (m *editorCmp) setEditorPrompt() {
+ if m.app.Permissions.SkipRequests() {
+ m.textarea.SetPromptFunc(4, yoloPromptFunc)
+ return
+ }
+ m.textarea.SetPromptFunc(4, normalPromptFunc)
+}
+
func (m *editorCmp) completionsPosition() (int, int) {
cur := m.textarea.Cursor()
if cur == nil {
@@ -416,6 +427,9 @@ func (m *editorCmp) View() string {
} else {
m.textarea.Placeholder = m.readyPlaceholder
}
+ if m.app.Permissions.SkipRequests() {
+ m.textarea.Placeholder = "Yolo mode!"
+ }
if len(m.attachments) == 0 {
content := t.S().Base.Padding(1).Render(
m.textarea.View(),
@@ -529,31 +543,47 @@ func (c *editorCmp) HasAttachments() bool {
return len(c.attachments) > 0
}
-func New(app *app.App) Editor {
+func normalPromptFunc(info textarea.PromptInfo) string {
t := styles.CurrentTheme()
- ta := textarea.New()
- ta.SetStyles(t.S().TextArea)
- ta.SetPromptFunc(4, func(info textarea.PromptInfo) string {
- if info.LineNumber == 0 {
- return " > "
- }
+ if info.LineNumber == 0 {
+ return " > "
+ }
+ if info.Focused {
+ return t.S().Base.Foreground(t.GreenDark).Render("::: ")
+ }
+ return t.S().Muted.Render("::: ")
+}
+
+func yoloPromptFunc(info textarea.PromptInfo) string {
+ t := styles.CurrentTheme()
+ if info.LineNumber == 0 {
if info.Focused {
- return t.S().Base.Foreground(t.GreenDark).Render("::: ")
+ return fmt.Sprintf("%s ", t.YoloIconFocused)
} else {
- return t.S().Muted.Render("::: ")
+ return fmt.Sprintf("%s ", t.YoloIconBlurred)
}
- })
+ }
+ if info.Focused {
+ return fmt.Sprintf("%s ", t.YoloDotsFocused)
+ }
+ return fmt.Sprintf("%s ", t.YoloDotsBlurred)
+}
+
+func New(app *app.App) Editor {
+ t := styles.CurrentTheme()
+ ta := textarea.New()
+ ta.SetStyles(t.S().TextArea)
ta.ShowLineNumbers = false
ta.CharLimit = -1
ta.SetVirtualCursor(false)
ta.Focus()
-
e := &editorCmp{
// TODO: remove the app instance from here
app: app,
textarea: ta,
keyMap: DefaultEditorKeyMap(),
}
+ e.setEditorPrompt()
e.randomizePlaceholders()
e.textarea.Placeholder = e.readyPlaceholder
@@ -69,6 +69,7 @@ type (
ToggleCompactModeMsg struct{}
ToggleThinkingMsg struct{}
OpenExternalEditorMsg struct{}
+ ToggleYoloModeMsg struct{}
CompactMsg struct {
SessionID string
}
@@ -362,6 +363,14 @@ func (c *commandDialogCmp) defaultCommands() []Command {
}
return append(commands, []Command{
+ {
+ ID: "toggle_yolo",
+ Title: "Toggle Yolo Mode",
+ Description: "Toggle yolo mode",
+ Handler: func(cmd Command) tea.Cmd {
+ return util.CmdHandler(ToggleYoloModeMsg{})
+ },
+ },
{
ID: "toggle_help",
Title: "Toggle Help",
@@ -300,7 +300,11 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
return p, tea.Batch(cmds...)
-
+ case commands.ToggleYoloModeMsg:
+ // update the editor style
+ u, cmd := p.editor.Update(msg)
+ p.editor = u.(editor.Editor)
+ return p, cmd
case pubsub.Event[history.File], sidebar.SessionFilesMsg:
u, cmd := p.sidebar.Update(msg)
p.sidebar = u.(sidebar.Sidebar)
@@ -45,6 +45,7 @@ func NewCharmtoneTheme() *Theme {
Blue: charmtone.Malibu,
Yellow: charmtone.Mustard,
+ Citron: charmtone.Citron,
Green: charmtone.Julep,
GreenDark: charmtone.Guac,
@@ -65,5 +66,10 @@ func NewCharmtoneTheme() *Theme {
t.ItemErrorIcon = t.ItemOfflineIcon.Foreground(charmtone.Coral)
t.ItemOnlineIcon = t.ItemOfflineIcon.Foreground(charmtone.Guac)
+ t.YoloIconFocused = lipgloss.NewStyle().Foreground(charmtone.Oyster).Background(charmtone.Citron).Bold(true).SetString(" ! ")
+ t.YoloIconBlurred = t.YoloIconFocused.Foreground(charmtone.Pepper).Background(charmtone.Squid)
+ t.YoloDotsFocused = lipgloss.NewStyle().Foreground(charmtone.Zest).SetString(":::")
+ t.YoloDotsBlurred = t.YoloDotsFocused.Foreground(charmtone.Squid)
+
return t
}
@@ -62,6 +62,7 @@ type Theme struct {
// Yellows
Yellow color.Color
+ Citron color.Color
// Greens
Green color.Color
@@ -83,6 +84,12 @@ type Theme struct {
ItemErrorIcon lipgloss.Style
ItemOnlineIcon lipgloss.Style
+ // Editor: Yolo Mode
+ YoloIconFocused lipgloss.Style
+ YoloIconBlurred lipgloss.Style
+ YoloDotsFocused lipgloss.Style
+ YoloDotsBlurred lipgloss.Style
+
styles *Styles
}
@@ -174,6 +174,8 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return a, util.CmdHandler(dialogs.OpenDialogMsg{
Model: quit.NewQuitDialog(),
})
+ case commands.ToggleYoloModeMsg:
+ a.app.Permissions.SetSkipRequests(!a.app.Permissions.SkipRequests())
case commands.ToggleHelpMsg:
a.status.ToggleFullHelp()
a.showingFullHelp = !a.showingFullHelp