
    ,j!                       d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m	Z	 ddl
mZ ddlmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZmZmZ  G d d          ZdS )u  Slash-command handlers for the interactive CLI (god-file decomposition Phase 4).

This module hosts the ``_handle_*_command`` slash-command handlers lifted out of
``cli.py``'s ``HermesCLI`` class. ``HermesCLI`` inherits ``CLICommandsMixin`` so
every ``self.<handler>`` call resolves unchanged via the MRO — behavior-neutral.

Import discipline (mirrors gateway/slash_commands.py, PR #41886):
  * Neutral, non-cyclic deps are imported at module top-level below.
  * cli.py-internal symbols (the ``_cprint``/``_ACCENT``/``save_config_value``…
    module-level helpers and constants) are imported LAZILY inside each handler
    via ``from cli import ...`` — that resolves at call time when ``cli`` is fully
    loaded, so the mixin module never imports ``cli`` at top level (no cycle).
    )annotationsN)datetime)urlparse)box)escape)Panel)display_hermes_home	is_termux)DEFAULT_BROWSER_CDP_URLis_browser_debug_readymanual_chrome_debug_commandc                  (   e Zd ZdZd0dZd0dZd Zd Zd Zd1dZ	d2dZ
d3dZd Zd4dZd1dZd1dZd1dZd1dZd3dZd3dZd3dZd3dZd3dZd3dZd3dZd3dZd5d!Zd3d"Zd6d#Zd3d$Zd6d%Zd6d&Zd3d'Z d1d(Z!d3d)Z"d3d*Z#d3d+Z$d, Z%d7d-Z&d0d.Z'd/S )8CLICommandsMixinzMixin holding the interactive-CLI slash-command handlers.

    All methods use only ``self`` state plus the imports above and per-method
    lazy ``from cli import ...`` lines, so they compose cleanly onto
    ``HermesCLI`` via the MRO.
    commandstrc           	        ddl m} t          | d          r| j        st	          d           dS | j        j        }|j        s/t	          d           t	          d           t	          d           dS t          j        d	t          j	                              }|
                                }t          |          d
k    r
|d
d         ng }|s0|                    |          }t	           |||                     dS |d                                         dk    rt          |          dk     rt	          d           dS |                    |          }|st	          d|            dS |                     |d
         |          }|sdS |                    ||          }	|	d         r|	                    dd          }
|	                    dd          }|
s|st	          d           n|
rt	          d|
            |r|                                }t          |          dk    rNt	          d                    |dd                              t	          dt          |          dz
   d           n+t	          d|            nt	          d|	d                     dS |                    |          }|st	          d|            dS |                     |d         |          }|sdS t          |          d
k    r|d
         nd}|                    |||          }	|	d         r|r%t	          d| d|	d          d|	d                     n!t	          d|	d          d|	d                     t	          d            | j        r'|                     d!"           t	          d#           dS dS t	          d|	d                     dS )$u  Handle /rollback — list, diff, or restore filesystem checkpoints.

        Syntax:
            /rollback                 — list checkpoints
            /rollback <N>             — restore checkpoint N (also undoes last chat turn)
            /rollback diff <N>        — preview changes since checkpoint N
            /rollback <N> <file>      — restore a single file from checkpoint N
        r   )format_checkpoint_listagentz  No active agent session.Nz  Checkpoints are not enabled.z#  Enable with: hermes --checkpointsz3  Or in config.yaml: checkpoints: { enabled: true }TERMINAL_CWD   diff   z  Usage: /rollback diff <N>z  No checkpoints found for successstat z#  No changes since this checkpoint.
P   z
  ... (z more lines, showing first 80)u     ❌ error)	file_pathu     ✅ Restored z from checkpoint restored_to: reasonu     ✅ Restored to checkpoint z2  A pre-rollback snapshot was saved automatically.F)prefillz0  Chat turn undone to match restored file state.)tools.checkpoint_managerr   hasattrr   print_checkpoint_mgrenabledosgetenvgetcwdsplitlenlist_checkpointslower_resolve_checkpoint_refr   get
splitlinesjoinrestoreconversation_history	undo_last)selfr   r   mgrcwdpartsargscheckpointstarget_hashresultr   r   
diff_linesr   s                 B/home/ubuntu/.hermes/hermes-agent/hermes_cli/cli_commands_mixin.py_handle_rollback_commandz)CLICommandsMixin._handle_rollback_command.   sL    	DCCCCCtW%% 	TZ 	.///Fj({ 	23337888GHHHFi	44JJNNuQRRyy 	..s33K((c::;;;F 7==??f$$4yy1}}3444..s33K 9C99:::66tAwLLK XXc;//Fi  2zz&"--zz&"-- /D /?@@@@ +k4kk*** /%)__%6%6
z??R//!$))JssO"<"<===!"bc*oo.B"b"b"bcccc!+t++...0vg00111F **3// 	555666F2247KHH 	F  #4yy1}}DGG$	S+CC) 	. co	ooF=DYoo]cdl]mooppppaf]6KaavV^O_aabbbFGGG ( Ju---HIIIIIJ J ,6'?,,-----    c                T   ddl m}m}m}m} ddlm} |                                }t          |          dk    r|d         	                                nd}|dv r0 |            }	|	s t          d           t          d           d	S t          d
 |             d           t          dddddddddddddd 
           t          dd dd dd dd dd 
           t          |	d          D ]\  }
}|                    dd          }|dk     r| d}n|dk     r
|dz  d d!}n|dz  dz  d"d#}|                    d$          pd%}t          d|
d&d|d'         dd|                    d(d          dd|dd| 
           d	S |d)k    ret          |          d*k    rd                    |d*d	                   nd	} ||+          }|rt          d,|            d	S t          d-           d	S |d.v rt          |          d/k     r=t          d0            |d1          }	|	rt          d2|	d         d'                     d	S |d*         }	 t          |          } |            }	d|cxk    rt          |	          k    rn n|	|dz
           d'         }n"t          d3t          |	           d4           d	S n# t          $ r Y nw xY w ||          r#t          d5|            t          d6           d	S t          d7|            d	S |d8k    rpd9}t          |          d*k    r7	 t          |d*                   }n # t          $ r t          d:           Y d	S w xY w ||;          }t          d<| d=| d>           d	S t          d?|            t          d@           d	S )Auu  Handle /snapshot — lightweight state snapshots for Hermes config/state.

        Syntax:
            /snapshot                  — list recent snapshots
            /snapshot create [label]   — create a snapshot
            /snapshot restore <id>     — restore state from snapshot
            /snapshot prune [N]        — prune to N snapshots (default 20)
        r   )create_quick_snapshotlist_quick_snapshotsrestore_quick_snapshotprune_quick_snapshotsr	   r   list>   lsrI   z  No state snapshots yet.z&  Create one: /snapshot create [label]Nz  State snapshots (z/state-snapshots/):
  #z>3IDz<35 Filesz>5Sizez>10Labelu	   ───ui   ───────────────────────────────────u   ─────u   ──────────u<   ────────────────────
total_sizei   z Bi   z.0fz KBz.1fz MBlabelr   3id
file_countcreater   )rS   z  Snapshot created: z#  No state files found to snapshot.>   rewindr4      z(  Usage: /snapshot restore <snapshot-id>limitz  Most recent: z!  Invalid snapshot number. Use 1-.z  Restored state from: z:  Restart recommended for state.db changes to take effect.z  Snapshot not found: prune   z%  Usage: /snapshot prune [keep-count])keepz	  Pruned z old snapshot(s) (keeping ).z  Unknown subcommand: z?  Usage: /snapshot [list|create [label]|restore <id>|prune [N]])hermes_cli.backuprD   rE   rF   rG   hermes_constantsr	   r,   r-   r/   r&   	enumerater1   r3   int
ValueError)r7   r   rD   rE   rF   rG   r	   r:   subcmdsnapsissizesize_strrS   snap_ididxr_   deleteds                      r@   _handle_snapshot_commandz)CLICommandsMixin._handle_snapshot_command   s/   	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	988888%(ZZ!^^q!!!^##((**E 1222>???T(;(;(=(=TTTUUUOsOOOOOOGOOOOOOgOOPPPLwLL(LLWLLxLL(LLMMM!%++ 	d 	d1uu\1--$;;"&{{{HHK''"&+6666HH"&+"4====Hg,"b1bbb!D'bbblA0F0FbbbHbbb[`bbcccc	d 	d x+.u::>>CHHU122Y'''tE++%888G =6W6677777;<<<<<,,,5zzA~~@AAA,,1555 ><E!HTN<<===AhG	'll,,..))))s5zz)))))#C!GnT2GGKc%jjKKKLLLF     %%g.. :999:::RSSSSS8w8899999wD5zzA~~uQx==DD!   ABBBFF ,+666GIgIIIIIJJJJJ 3633444STTTTTs%   A(J? ?
KK-M M M c                   ddl m} |                                }d |D             }|st          d           dS t          dt	          |           d           |                                }t          d| d	           dS )
u   Handle /stop — kill all running background processes.

        Inspired by OpenAI Codex's separation of interrupt (stop current turn)
        from /stop (clean up background processes). See openai/codex#14602.
        r   )process_registryc                D    g | ]}|                     d           dk    |S statusrunningr1   .0ps     r@   
<listcomp>z9CLICommandsMixin._handle_stop_command.<locals>.<listcomp>   ,    HHH155??i+G+G1+G+G+GrB   z"  No running background processes.Nz  Stopping z background process(es)...u     ✅ Stopped z process(es).)tools.process_registryrq   list_sessionsr&   r-   kill_all)r7   rq   	processesru   killeds        r@   _handle_stop_commandz%CLICommandsMixin._handle_stop_command   s     	<;;;;;$2244	HHiHHH 	6777FDCLLDDDEEE!**,,4v44455555rB   c           	        ddl m} ddlm}m} |                                }d |D             }d |D             } |dt          |                      |D ]g}|                    dd          d	d
         } ||                    dd                    }	 |d|                    dd           d|	 d|            h|r |dt          |                      t          | dd          }
 |d|
rdnd            d	S )u>   Handle /agents — show background processes and agent status.r   _cprint)format_uptime_shortrq   c                D    g | ]}|                     d           dk    |S rs   rv   rw   s     r@   rz   z;CLICommandsMixin._handle_agents_command.<locals>.<listcomp>   r{   rB   c                D    g | ]}|                     d           dk    |S rs   rv   rw   s     r@   rz   z;CLICommandsMixin._handle_agents_command.<locals>.<listcomp>   s,    III!AEE(OOy,H,HA,H,H,HrB   z  Running processes: r   r   Nr   uptime_seconds    
session_id?u    · z  Recently finished: _agent_runningFz	  Agent: ru   idle)	clir   r|   r   rq   r}   r-   r1   getattr)r7   r   r   rq   r   ru   finishedry   cmdupagent_runnings              r@   _handle_agents_commandz'CLICommandsMixin._handle_agents_command   si   PPPPPPPP$2244	HHiHHHIIyIII6G66777 	H 	HA%%	2&&ss+C$$QUU+;Q%?%?@@BGF155s33FFFFFFGGGG 	=G;CMM;;<<<&6>>DBIIFDDEEEEErB   c                N   ddl m}m}m}m} t                      r |d| d |             |            dS ddlm}  |            rL|                                 r%t          | j
                  } |d| d           dS  |d| d	|            dS  |d| d
|            dS )u   Handle /paste — explicitly check clipboard for an image.

        This is the reliable fallback for terminals where BracketedPaste
        doesn't fire for image-only clipboard content (e.g., VSCode terminal,
        Windows Terminal with WSL2).
        r   )_DIM_RSTr   _termux_example_image_pathrK   uh   Clipboard image paste is not available on Termux — use /image <path> or paste a local image path like N)has_clipboard_imageu     📎 Image #z attached from clipboardz2(>_<) Clipboard has an image but extraction failedz!(._.) No image found in clipboard)r   r   r   r   r   _is_termux_environmenthermes_cli.clipboardr   _try_attach_clipboard_imager-   _attached_images)r7   r   r   r   r   r   ns          r@   _handle_paste_commandz&CLICommandsMixin._handle_paste_command  s;    	HGGGGGGGGGGG!## 	G8T 8 8--//8158 8  
 F<<<<<<   	H//11 ]-..DDDDEEEEE[T[[UY[[\\\\\GFFFFFGGGGGrB   cmd_originalreturnNonec                   ddl m}m} |                    d          }t	          |          dk    r|d                                         nd}d | j        D             }|s |d           dS |rh	 t          |          dz
  }n# t          $ r  |d	           Y dS w xY w|dk     s|t	          |          k    r |d
t	          |           d           dS n~t	          |          dz
  }|dk    rS |||         	                    d                    s/|dz  }|dk    r$ |||         	                    d                    /|dk     r |d           dS  |||         	                    d                    }|s |d           dS 	 | 
                    |            |d|dz    d           dS # t          $ r}	 |d|	            Y d}	~	dS d}	~	ww xY w)u=   Handle /copy [number] — copy assistant output to clipboard.r   )_assistant_copy_textr   r   maxsplitr   c                D    g | ]}|                     d           dk    |S )role	assistantrv   rx   ms     r@   rz   z9CLICommandsMixin._handle_copy_command.<locals>.<listcomp>+  s,    ZZZ1QUU6]]k=Y=YQ=Y=Y=YrB   z  Nothing to copy yet.Nz  Usage: /copy [number]z!  Invalid response number. Use 1-r\   contentz-  Nothing to copy in assistant responses yet.z-  Nothing to copy in that assistant response.z  Copied assistant response #z to clipboardz  Clipboard copy failed: )r   r   r   r,   r-   stripr5   rd   re   r1   _write_osc52_clipboard	Exception)
r7   r   r   r   r:   argr   rm   textes
             r@   _handle_copy_commandz%CLICommandsMixin._handle_copy_command%  s}   55555555""A".."%e**q..eAhnnbZZ 9ZZZ	 	G,---F 	#hhl   1222 Qww#Y//MC	NNMMMNNN 0 i..1$C((#7#7	#8J8J98U8U#V#V(q ((#7#7	#8J8J98U8U#V#V(QwwGHHH##IcN$6$6y$A$ABB 	GCDDDF	5''---GJC!GJJJKKKKK 	5 	5 	5G333444444444	5s*   1B BB
'F3 3
G=GGc                   ddl m}m}m}m}m}m}m} d|v r.|                    dd          d         	                                nd}	|	s/t                      r
 |            nd}
 |d| d	|
 |            dS  ||	          \  }} ||          }| |d| d
| |            dS |j                                        |vr |d| d|j         |            dS | j                            |            |d|j                    |r |d| d| |            dS t                      r$ |d| d ||j                   d|            dS dS )uG   Handle /image <path> — attach a local image file for the next prompt.r   )r   _IMAGE_EXTENSIONSr   r   _resolve_attachment_path_split_path_inputr   rN   Nr   r   z/path/to/image.pngrK   z"Usage: /image <path>  e.g. /image z(>_<) File not found: z"(._.) Not a supported image file: u     📎 Attached image: z<Now type your prompt (or use --image in single-query mode): z;Tip: type your next message, or run hermes chat -q --image z "What do you see?")r   r   r   r   r   r   r   r   r,   r   r   suffixr/   namer   append)r7   r   r   r   r   r   r   r   r   raw_argshint
path_token
_remainder
image_paths                 r@   _handle_image_commandz&CLICommandsMixin._handle_image_commandL  s    	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H  	H>A\>Q>QL&&tQ//288:::WY 	3I3K3Ke--///QeDGMMMMtMMNNNF!2!28!<!<
J--j99
GGGGZGGGHHHF""$$,===GXXXXRVXXYYYF$$Z000;*/;;<<< 	dGmmm[emgkmmnnnnn#%% 	dG  c  c  cZtZtu  vE  [F  [F  c  c  ]a  c  c  d  d  d  d  d	d 	drB   r   c                J    ddl m}m}m}m ddl}ddlm} ddlm	 ddl
m ddlm d$ fd}	 |                    |          }n$# t          $ r |                                }Y nw xY wt!          |          dk    r|d         nd}	|	dvr                                  dS |	dk    r | |dd                     dS |dd         }
|
s;t%          d|	 d           t%          d|	 d           t%          d|	 d           dS |	dk    rdnd}d                    |
          } | | d| d|             | ||	|
d                      dd!lm} dd"lm}  | |            d           _                                           | d#|            dS )%a`  Handle /tools [list|disable|enable] slash commands.

        /tools (no args) shows the tool list.
        /tools list shows enabled/disabled status per toolset.
        /tools disable/enable saves the change to config and resets
        the session so the new tool set takes effect cleanly (no
        prompt-cache breakage mid-conversation).
        r   )_ACCENTr   r   r   N)	Namespace)redirect_stdout)StringIO)tools_disable_enable_commandnsr   r   r   c                8   t          dd           |            dS  G d d          } |            } |          5   |            ddd           n# 1 swxY w Y   |                                                                D ]} |           dS )a  Run tools_disable_enable_command, routing its ANSI-colored
            print() output through _cprint when inside the interactive TUI
            so escapes aren't mangled by patch_stdout's StdoutProxy into
            garbled '?[32m...?[0m' text.

            Outside the TUI (standalone mode, tests), call straight through
            so real stdout / pytest capture works as expected.
            _appNc                      e Zd ZddZdS )MCLICommandsMixin._handle_tools_command.<locals>._run_capture.<locals>._TTYBufr   boolc                    dS )NT )r7   s    r@   isattyzTCLICommandsMixin._handle_tools_command.<locals>._run_capture.<locals>._TTYBuf.isatty  s    4rB   Nr   r   )__name__
__module____qualname__r   r   rB   r@   _TTYBufr     s(                   rB   r   )r   getvaluer2   )	r   r   bufliner   r   r   r7   r   s	       r@   _run_capturez<CLICommandsMixin._handle_tools_command.<locals>._run_captureu  s    tVT**2,,R000
         (       '))C %% 1 1,,R0001 1 1 1 1 1 1 1 1 1 1 1 1 1 11133   s   AA"Ar   r   >   rI   enabledisablerI   r   )tools_actionplatformr   z(._.) Usage: /tools z <name> [name ...]z  Built-in toolset:  /tools z webz  MCP tool:          /tools z github:create_issuer   	DisablingEnabling, rN   ...)r   namesr   )_get_platform_toolsload_configz0Session reset. New tool configuration is active.)r   r   r   r   )r   r   r   r   r   shlexargparser   
contextlibr   ior   hermes_cli.tools_configr   r,   re   r-   
show_toolsr&   r3   r   hermes_cli.configr   enabled_toolsetsnew_session)r7   r   r   r   r   r   r   r   r:   
subcommandr   verbrS   r   r   r   r   r   r   s   `              @@@@r@   _handle_tools_commandz&CLICommandsMixin._handle_tools_commande  s    	544444444444&&&&&&......HHHHHH	 	 	 	 	 	 	 	 	 	6	 KK$$EE 	  	  	 IIKKEEE	  "%UaU1XXR
:::OOFLGGGHHHFabb	 	GGGGHHHAAAABBBQQQQRRRF
 )I55{{:		%  73D33533T33444YYJeeTTTUUU 	@?????111111 3 3KKMM5 I I4OOOOPPPPPs   A A0/A0c                    ddl m} ddlm}  |            } |            }t	                       t	          d|            t	          d|            t	                       dS )z/Display active profile name and home directory.r   rH   )get_active_profile_namez  Profile: z  Home:    N)rb   r	   hermes_cli.profilesr   r&   )r7   r	   r   displayprofile_names        r@   _handle_profile_commandz(CLICommandsMixin._handle_profile_command  s    888888??????%%''..00*L**+++%G%%&&&rB   r   c           	     	   ddl m} ddlm} |                    d          }t          |          dk     s|d                                         s# |d            |d            |d	           d
S |d                                                                         }	 ddlm	}m
} n&# t          $ r} |d|            Y d}~d
S d}~ww xY w	  ||          }	n'# t          t          f$ r  |d| d           Y d
S w xY w	  |            }
n&# t          $ r} |d|            Y d}~d
S d}~ww xY w|
j                            |	          }|r|j        s |d| d           d
S |
                    |	          }|r|j        s |d| d            |d           d
S t'          | dd          r |d           d
S | j        s'	 ddlm}  |            | _        n# t          $ r Y nw xY w| j        s |d |                        d
S 	 | j                            | j                  }|s2d| j        dd          }| j                            | j        |           n&# t          $ r} |d|            Y d}~d
S d}~ww xY wd}	 | j                            | j                  }|r|                    d          pd}n# t          $ r Y nw xY w|s| j        dd         }| j                            | j        |          }|s |d           d
S  |d | d!| d"|j         d#            |d$           ddl}|                                d%z   }d&}|                                |k     r	 | j                            | j                  }n# t          $ r d}Y nw xY w|pi                     d'          pd&}||k    r|d(k    r |d)           |}|d*k    r< |d            |d+| d            |d,|             |d           d
| _        dS |d-k    r4|pi                     d.          pd/} |d0|             |d1           d
S |                    d2           |                                |k     	 | j                            | j        d3           n# t          $ r Y nw xY w |d4            |d5           d
S )6u  Handle ``/handoff <platform>`` — transfer this CLI session to a gateway platform.

        Flow:
          1. Validate platform name + the gateway has a home channel for it.
          2. Reject if the agent is currently running (the in-flight turn
             would race with the gateway's switch_session).
          3. Write ``handoff_state='pending'`` on this session row.
          4. Block-poll ``state.db`` for terminal state (timeout 60s).
          5. On ``completed`` → print resume hint and signal CLI exit by
             returning False (the caller honors that like ``/quit``).
          6. On ``failed`` / timeout → print error and return True so the
             user keeps their CLI session.

        Returns:
            False to signal CLI exit, True to keep going.
        r   r   format_session_db_unavailabler   r   r   z  Usage: /handoff <platform>z@  Hands the current session off to that platform's home channel.z:  The CLI session ends here; resume it later with /resume.T)load_gateway_configPlatformz!  Could not load gateway config: Nz  Unknown platform 'z'.z  Platform 'z+' is not configured/enabled in the gateway.z!  No home channel configured for r\   z6  Set one with /sethome on the destination chat first.r   FzJ  Agent is busy. Wait for the current turn to finish, then retry /handoff.)	SessionDBrK   zhandoff-   z,  Could not ensure session row in state.db: r   titlezN  Session is already in flight for handoff. Wait for it to settle, then retry.z  Queued handoff of 'u   ' → z (home: r`   z*  Waiting for the gateway to pick it up...g      N@pendingstateru   z'  Gateway picked it up; transferring...	completedu5     ↻ Handoff complete. The session is now active on z,  Resume it on this CLI later with: /resume failedr   zunknown errorz  Handoff failed: zV  Your CLI session is intact. Try /handoff again, or /resume on the platform manually.      ?ztimed out waiting for gatewayzA  Timed out waiting for the gateway. Is `hermes gateway` running?z  Your CLI session is intact.) r   r   hermes_stater   r,   r-   r   r/   gateway.configr   r   r   re   KeyError	platformsr1   r(   get_home_channelchat_idr   _session_dbr   get_sessionr   set_session_titlerequest_handoffr   timeget_handoff_state_should_exitsleepfail_handoff)r7   r   r   r   r:   platform_namer   r   excr   	gw_configpcfghomer   rowplaceholder_titlesession_titleok_timedeadline
last_state	state_rowcurrenterrs                           r@   _handle_handoff_commandz(CLICommandsMixin._handle_handoff_command  s   " 	 >>>>>>""A"..u::>>q!1!1>G2333GVWWWGPQQQ4a((..00	DDDDDDDDD 	 	 	G===>>>44444		x..HHH% 	 	 	G<=<<<===44		++--II 	 	 	G===>>>44444	 "&&x00 	4< 	G]=]]]^^^4))(33 	4< 	GHHHHIIIGMNNN4 4)511 	G`aaa4  	222222#,9;;      	G:6688::;;;4	"..t??C W
 %Etrr/B$D$D! 224?DUVVV 	 	 	GH3HHIII44444	
 	"..t??C 7 # 0 0 6B 	 	 	D	 	0 OBQB/M --do}MM 	Gdeee4aaa]aaTXT]aaabbb=>>> 	::<<$&
jjllX%%! ,>>tOO		 ! ! ! 			! B++G44A	G*$$i''GEFFF$
+%%`P]```aaaV}VVWWW$(!u("" B++G44G2S22333pqqqtKK/ jjllX%%4	))$/;Z[[[[ 	 	 	D	STTT/000ts    B) )
C3CCC  D ?D 
D 
D2D--D2	G 
G,+G,AI# #
J-JJ8K 
KK1N N N   R! !
R.-R.c                "
   ddl m}m} |                    dd          }t	          |          dk    r|d                                         nd}t	          |          dk    r||d         dk    r|d         d	k    sH|d         d
k    r|d         dk    s0|d         dk    r|d         dk    s|d         dk    r(|d         dk    r|dd                                         }|sK |d           |                     d          r|                     d          | _        dS  |d           dS d| _        | j	        sddl
m}  |d |                        dS |                                rn|                     d          }t          |          }|dk     s|t	          |          k    r |d| d            |d           dS ||dz
           }	|	d         }
nddlm}  ||          }|p|}
| j	                            |
          }|s |d|             |d           dS 	 | j	                            |
          }n# t$          $ r |
}Y nw xY w|r8||
k    r2 |d|
 d| d           |}
| j	                            |
          }|r|}|
| j        k    r |d            dS | j        }	 | j	                            | j        d!           n# t$          $ r Y nw xY w|
| _        d"| _        d| _         ||
           | j	                            |
          }d# |pg D             }|| _        	 | j	                            |
           n# t$          $ r Y nw xY w| j        r|
| j        _        | j                                         t9          | j        d$          rt	          | j                  | j        _        t9          | j        d%          r,	 dd&lm}  |            | j        _         n# t$          $ r Y nw xY wt9          | j        d'          r| j        !                                 	 tE          | j        d(d          }||#                    |
|pdd)d*           n# t$          $ r Y nw xY w|$                    d+          rd,|d+          dnd}t	          d- | j        D                       }| j        rJ |d.|
 | d/| d0|dk    rd1nd d2t	          | j                   d3
           | %                                 dS  |d.|
 | d4           dS )5uW   Handle /resume <session_id_or_title> — switch to a previous session mid-conversation.r   r   _sync_process_session_idNr   r   r   <>[]"'z-  Usage: /resume <number|session_id_or_title>resumer"   
   rZ   zA  Tip:   Use /history or `hermes sessions list` to find sessions.r   rK   z  Resume index z is out of range.z:  Use /resume with no arguments to see available sessions.rU   )_resolve_session_by_name_or_idz  Session not found: zC  Use /history or `hermes sessions list` to see available sessions.z
  Session z was compressed into z/; resuming the descendant with your transcript.z  Already on that session.resumed_otherTc                D    g | ]}|                     d           dk    |S )r   session_metarv   r   s     r@   rz   z;CLICommandsMixin._handle_resume_command.<locals>.<listcomp>  s,    SSS!155==N3R3RA3R3R3RrB   _last_flushed_db_idx_todo_store	TodoStore_invalidate_system_prompt_memory_managerFparent_session_idresetr"   r   z "c                D    g | ]}|                     d           dk    |S r   userrv   r   s     r@   rz   z;CLICommandsMixin._handle_resume_command.<locals>.<listcomp>  -    YYYqvRXAXAXAXAXAXrB   u     ↻ Resumed session  ( user messageri   r   z total)u!    — no messages, starting fresh.)&r   r   r%  r,   r-   r   _show_recent_sessions_list_recent_sessions_pending_resume_sessionsr
  r  r   isdigitrd   hermes_cli.mainr0  r  resolve_resume_session_idr   r   end_session_resumed_pending_titleget_messages_as_conversationr5   reopen_sessionr   reset_session_stater%   r4  tools.todo_toolr7  r5  r8  r   on_session_switchr1   _display_resumed_history)r7   r   r   r%  r:   targetr   sessionsindexselected	target_idr0  resolvedr3  resolved_idresolved_metaold_session_idrestoredr7  _mm
title_part	msg_counts                         r@   _handle_resume_commandz'CLICommandsMixin._handle_resume_commandY  s   99999999""4++%(ZZ!^^q!!! v;;!AY#&*"3"3q	S  VBZ3%6%6q	S  VBZ3%6%6q	S  VBZ3%6%6AbD\''))F 	GCDDD)))::  150J0JQS0J0T0T-GWXXXF )-% 	BBBBBBG:6688::;;;F >> 	+111;;HKKEqyyECMM11B%BBBCCCTUUU	*H IIFFFFFF55f==H *FI'33I>> 	G4F44555GYZZZF	$*DDYOOKK 	$ 	$ 	$#KKK	$ 	-;)33GAY A A[ A A A   $I ,88CCM -,''G0111F	((/JJJJ 	 	 	D	 $"  +++ #@@KKSSBSSS$,!	++I6666 	 	 	D	 : 	$-DJ!J**,,,tz#9:: Q25d6O2P2P
/tz=11 999999-6Y[[DJ**    Dtz#>?? 7
44666
dj*;TBB?))!*8*>B#'	 *        9E8H8H8Q8QY4<04444WY
YYD$=YYYZZ	$ 	gG< <J < << <4=NNSS< <122< < <  
 ))+++++GeYe
eeefffffsZ   %I   II, K 
KK-M 
MMO) )
O65O6(3Q 
Q)(Q)c                   ddl m} |                    dd          }t          |          dk    r|d                                         nd}|                                }|r|dv rH| j        sddlm}  |d |                        dS | 	                    d	
          s |d           dS | 
                    d|            dS )u&  Handle /sessions [list|<id_or_title>] — browse or resume previous sessions.

        Without arguments, prints the same recent-sessions table that /resume
        shows when called without a target, and tells the user how to resume.
        With an explicit subcommand or target, delegates to the resume flow so
        ``/sessions <id>`` and ``/resume <id>`` behave identically.

        The TUI ships an interactive picker overlay for this command; the
        classic CLI prints an inline list because there is no equivalent
        overlay primitive here. Without this handler the canonical name
        ``sessions`` falls through ``process_command``'s elif chain and
        prints ``Unknown command: sessions`` even though the command is
        registered in the central COMMAND_REGISTRY.
        r   r   Nr   r   >   rJ   rI   browser   rK   rS  r.  z!  (._.) No previous sessions yet.z/resume )r   r   r,   r-   r   r/   r
  r  r   rC  r_  )r7   r   r   r:   r   subr   s          r@   _handle_sessions_commandz)CLICommandsMixin._handle_sessions_command  s    	 ""4++"%e**q..eAhnnbiikk  	c555# FFFFFF>::<<>>???--Z-@@ =;<<<F 	##$4s$4$455555rB   c                   ddl m}m} | j        s |d           dS | j        sddlm}  |d |                        dS |                    dd          }t          |          dk    r|d         	                                nd}t          j                    }|                    d	          }t          j                    j        dd
         }	| d|	 }
|r|}nFd}| j        r| j                            | j                  }|pd}| j                            |          }| j        }	 | j                            | j        d           n# t(          $ r Y nw xY w	 | j                            |
t,          j                            dd          | j        | j        | j        |d|           n&# t(          $ r} |d|            Y d}~dS d}~ww xY w| j        D ]}	 | j                            |
|                    dd          |                    d          |                    d          p|                    d          |                    d          |                    d          |                    d                     # t(          $ r Y w xY w	 | j                            |
|           n# t(          $ r Y nw xY w|                     | j        |
           |
| _        || _        d| _         d| _!         ||
           | j"        r|
| j"        _        || j"        _        | j"        #                                 tI          | j"        d          rt          | j                  | j"        _%        tI          | j"        d          r,	 ddl&m'}  |            | j"        _(        n# t(          $ r Y nw xY wtI          | j"        d           r| j"        )                                 	 tU          | j"        d!d          }||+                    |
|pdd"d#           n# t(          $ r Y nw xY wt          d$ | j        D                       } |d%| d&| d'|dk    rd(nd d)            |d*|             |d+|
            dS ),u*  Handle /branch [name] — fork the current session into a new independent copy.

        Copies the full conversation history to a new session so the user can
        explore a different approach without losing the original session state.
        Inspired by Claude Code's /branch command.
        r   r$  u5     No conversation to branch — send a message first.Nr   rK   r   r   z%Y%m%d_%H%M%S   _branchbranchedHERMES_SESSION_SOURCEr   )max_iterationsreasoning_config_branched_from)r   sourcemodelmodel_configr;  z#  Failed to create branch session: r   r?  r   	tool_namer   
tool_callstool_call_id	reasoning)r   r   r   rp  rq  rr  rs  Tr4  r5  r6  r8  r9  Fr:  c                D    g | ]}|                     d           dk    |S r>  rv   r   s     r@   rz   z;CLICommandsMixin._handle_branch_command.<locals>.<listcomp>  r@  rB   u     ⑂ Branched session "z" (rB  ri   )z  Original session: z  Branch session:   ),r   r   r%  r5   r
  r  r   r,   r-   r   r   nowstrftimeuuiduuid4hexget_session_titler   get_next_title_in_lineagerI  r   create_sessionr)   environr1   rn  	max_turnsrk  append_messager  _transfer_session_yolosession_startrK  rJ  r   rN  r%   r4  rO  r7  r5  r8  r   rP  )r7   r   r   r%  r   r:   branch_namerv  timestamp_str
short_uuidnew_session_idbranch_titlecurrent_titlebaser;  r   msgr7  r\  r^  s                       r@   _handle_branch_commandz'CLICommandsMixin._handle_branch_command  s    	:9999999( 	GKLLLF 	BBBBBBG:6688::;;;F""4++*-e**q..eAhnn&&&b lnn_55Z\\%bqb)
)88J88  	L&LL !M T $ 0 B B4? S S ,HD+EEdKKL !O	((*EEEE 	 	 	D		++)z~~&=uEEj&*n(,(=&7 
 #4 , 
 
 
 
  	 	 	G=!==>>>FFFFF	
 , 	 	C //-00GGI..!ggk22Ecggfoo"ww|44!$!8!8!ggk22 0        	..~|LLLL 	 	 	D	 	##DO^DDD( "  000 : 	$2DJ!'*DJ$J**,,,tz#9:: Q25d6O2P2P
/tz=11 999999-6Y[[DJ**    Dtz#>?? 7
44666
dj*;TBB?))&*;*Ar#'	 *        YYD$=YYYZZ	J J JJ J09QBJ J J	
 	
 	
 	:'8::;;;7~7788888st   ) E
 

EEAF, ,
G6G

GB)J
JJJ3 3
K ?K N" "
N/.N/!3P 
P"!P"c           	     *   	 ddl m}m}m} ddlm}m} n1# t          $ r$}|                     d| d           Y d}~dS d}~ww xY w	  |            }nA# |$ r9}|                     d| d           |                     d           Y d}~dS d}~ww xY w |            }	|	r|	j	        nd	pd	}
	  |||

          }n+# |$ r#}|                     d|            Y d}~dS d}~ww xY w|s|                     d           dS |
                    d            |                                  |                     d|
pd d           |                                  |D ]}t          dt          d|j                            }d}t          t          ||z                      }d|z  d||z
  z  z   }t          |dz            dd}|j        }|j        r|d|j         dz  }|                     d|dd| d|            |                                  dS )zIShow Google Gemini Code Assist quota usage for the current OAuth account.r   )get_valid_access_tokenGoogleOAuthErrorload_credentials)retrieve_user_quotaCodeAssistErrorz#  [red]Gemini modules unavailable: [/]Nz
  [yellow]zB  Run [bold]/model[/] and pick 'Google Gemini (OAuth)' to sign in.r   )
project_idz  [red]Quota lookup failed:[/] zN  [dim]No quota buckets reported (account may be on legacy/unmetered tier).[/]c                    | j         | j        fS N)model_id
token_type)bs    r@   <lambda>z9CLICommandsMixin._handle_gquota_command.<locals>.<lambda>  s    AJ#= rB   )keyz/  [bold]Gemini Code Assist quota[/]  (project: z(auto / free-tier)ru  g              ?r^   u   ▓u   ░d   3d%z [r*  r   40srK   )agent.google_oauthr  r  r  agent.google_code_assistr  r  ImportError_console_printr  sortmaxminremaining_fractionrd   roundr  r  )r7   r   r  r  r  r  r  r  access_tokencredsr  bucketsr  pctwidthfilledbarpct_strheaders                      r@   _handle_gquota_commandz'CLICommandsMixin._handle_gquota_command  s   	eeeeeeeeeeUUUUUUUUU 	 	 	 Nc N N NOOOFFFFF		1133LL 	 	 	 5S 5 5 5666 deeeFFFFF	
 ! ""*/7e&&R>B
	)),:NNNGG 	 	 	 G# G GHHHFFFFF	  	 pqqqF 	==>>>sjNp\psssttt 		G 		GAc3sA$899::CEsU{++,,F&.5EFN#;;CS3Y----GZF| /.q|.... Ev E E ES E EG E EFFFFsB    
A>A
A B.BB+B9 9C!>CC!c                   ddl m} |                    d          }t          |          dk    ru|d                                                                         }|dv rJd| _        d| _         |dd          rt          d	           nt          d
           t          d           dS || j	        v r| 
                    | j	        |                   | _        d| _         |d| j                  rt          d| d           nt          d| d           t          d| j        dd          t          | j                  dk    rdnd d           dS t          d|            t          dd                    | j	                                                              dS t                       t          d           t          d           t          d           t                       t          dddd           | j	                                        D ]{\  }}t          |t                    r4|                    d          p|                    dd          dd         }nt#          |          dd         }t          d|dd |            |t                       t          d!           t                       dS )"z@Handle the /personality command to set predefined personalities.r   save_config_valuer   r   >   nonedefaultneutralr   Nzagent.system_promptz,(^_^)b Personality cleared (saved to config)z((^_^) Personality cleared (session only)u7     No personality overlay — using base agent behavior.z(^_^)b Personality set to '' (saved to config)z(^_^) Personality set to '' (session only)z  "<   r   r+  z(._.) Unknown personality: z  Available: none, r   z4+--------------------------------------------------+z1|            (^o^)/ Personalities               |rK   r  <12z - (no personality overlay)descriptionsystem_prompt2   z - z  Usage: /personality <name>)r   r  r,   r-   r   r/   r  r   r&   personalities_resolve_personality_promptr3   keysitems
isinstancedictr1   r   )r7   r   r  r:   personality_namer   promptpreviews           r@   _handle_personality_commandz,CLICommandsMixin._handle_personality_command  s   ))))))		1	%%u::>>$Qx~~//5577#AAA%'"!
$$%:B?? FHIIIIDEEEOPPPPP!T%777%)%E%EdFXYiFj%k%k"!
$$%:D<NOO []8H]]]^^^^Y7GYYYZZZgT/4gs4CU?V?VY[?[?[eeacggghhhhhF4DFFGGGRDIId6H6M6M6O6O,P,PRRSSSSS GGG&'''JKKK&'''GGG>v>>>>??? $ 2 8 8 : : 3 3ffd++ /$jj77_6::oWY;Z;Z[^\^[^;_GG!&kk#2#.G14111112222GGG0111GGGGGrB   c           
        ddl m} ddl}ddlm fd}d }d }|                    |          }t          |          dk    rat                       t          d	           t          d
           t          d	           t                       t          d           t          d           t          d           t          d           t          d           t          d           t          d           t          d           t          d           t          d           t          d           t                        |d          }|                    d          r|                    dg           ng }	|	r
t          d           t          d           |	D ]}
|
                    dd          }t          d|
d         dd          d!d"|
d#         d$d"|d%           |
                    d&          r+t          d'd(	                    |
d&                               t          d)|
                    d*d+                      |
                    d,          rt          d-|
d,                     t                       nt          d.           t                       dS |d         
                                } ||d/d                   }|dS |dk    r |d|d0         1          }|                    d          r|                    dg           ng }	|	st          d2           dS t                       t          d3           t          d4           |	D ]h}
t          d5|
d                     t          d6|
d7                     t          d8|
                    d9d                      t          d:|
d#          d;|
                    dd           d<           t          d=|
                    d,d>                      |
                    d&          r+t          d?d(	                    |
d&                               t          d@|
                    d*d+                      |
                    dA          r0t          dB|
dA          d;|
                    dCd           d<           t                       jdS |dDv rc|dE         }|st          dF           dS |d#         p|d         }|dG         pdH	                    |dd                   } ||d&                   }|s|st          dI           dS  |dJ||pd|d7         |dK         |d         |pdL          }|                    d          rt          dM|d                     t          d:|d#                     |                    d&          r+t          d?d(	                    |d&                               t          d=|d,                     n%t          dN|                    dO                      dS |dPk    r|dE         }|st          dQ           dS |d         } ||          }|st          dR|            dS d} ||d&                   } ||dS                   }t           ||dT                             t          |                    d&          p,|                    dU          sg n|                    dU          g          }|dV         rg }n5|r|}n0|sr,fdW|D             }|D ]}||vr|                    |            |dX||d#         |dG         |d7         |dK         |d         |Y          }|                    d          r|dZ         }
t          d[|
d                     t          d:|
d#                     |
                    d&          r,t          d?d(	                    |
d&                               n5t          d\           n%t          d]|                    dO                      dS |d^v r{|dE         }|st          d_| d`           dS |d         }|dav rdbn|} ||||dck    rddnde          }|                    d          s*t          df| dg|                    dO                      dS |dck    r#t          dh|dZ         d7          d;| d<           n|dik    rNt          dj|dZ         d7          d;| d<           t          d=|dZ                             d,                      nx|dkk    r2t          dl|dZ         d7          d;| d<           t          dm           n@|                    dni           }t          do|                    d7|           d;| d<           dS t          dp|            t          dq           dS )rz3Handle the /cron command to manage scheduled tasks.r   )get_jobN)cronjobc                 8    t          j         di |           S )Nr   )jsonloads)kwargscronjob_tools    r@   	_cron_apiz8CLICommandsMixin._handle_cron_command.<locals>._cron_api  s#    :ll44V44555rB   c                    g }| D ]@}t          |pd                                          }|r||vr|                    |           A|S )Nr   )r   r   r   )values
normalizedvaluer   s       r@   _normalize_skillsz@CLICommandsMixin._handle_cron_command.<locals>._normalize_skills  s`    J , ,5;B''--// ,D
22%%d+++rB   c                   d d d g g g ddd d g d}d}|t          |           k     rS| |         }|dk    r+|dz   t          |           k     r| |dz            |d<   |dz  }n|dk    r+|dz   t          |           k     r| |dz            |d	<   |dz  }n|d
k    rZ|dz   t          |           k     rD	 t          | |dz                      |d<   n # t          $ r t          d           Y d S w xY w|dz  }nu|dk    rA|dz   t          |           k     r+|d                             | |dz                       |dz  }n.|dk    r@|dz   t          |           k     r*|d                             | |dz                       |dz  }n|dk    r@|dz   t          |           k     r*|d                             | |dz                       |dz  }n|dk    rd|d<   |dz  }n|dk    rd|d<   |dz  }n|dk    r*|dz   t          |           k     r| |dz            |d<   |dz  }nP|dk    r*|dz   t          |           k     r| |dz            |d<   |dz  }n |d                             |           |dz  }|t          |           k     S|S )NF)r   deliverrepeatskills
add_skillsremove_skillsclear_skillsallr  schedulepositionalsr   z--namer   r   r   z	--deliverr  z--repeatr  z!(._.) --repeat must be an integerz--skillr  z--add-skillr  z--remove-skillr  z--clear-skillsTr  z--allr  z--promptr  z
--scheduler  r  )r-   rd   re   r&   r   )tokensoptsrh   tokens       r@   _parse_flagsz;CLICommandsMixin._handle_cron_command.<locals>._parse_flags  s    !# % ! D Ac&kk//q	H$$QV)<)<#)!a%=DLFAAk))a!ec&kk.A.A&,QUmDOFAAj((QUS[[-@-@$),VAE]););X% $ $ $ABBB#tt$ FAAi''AECKK,?,?N))&Q-888FAAm++AF0C0C&--fQUm<<<FAA...1q53v;;3F3F)00A???FAA...+/D(FAAg%%"&DKFAAj((QUS[[-@-@%+AE]DNFAAl**q1us6{{/B/B'-a!e}D$FAA'..u555FAM c&kk//N Ks   ,C C%$C%r   zF+--------------------------------------------------------------------+zD|                      (^_^) Scheduled Tasks                       |z  Commands:z    /cron listzD    /cron add "every 2h" "Check server status" [--skill blogwatcher]zA    /cron edit <job_id> --schedule "every 4h" --prompt "New task"z8    /cron edit <job_id> --skill blogwatcher --skill mapsz2    /cron edit <job_id> --remove-skill blogwatcherz&    /cron edit <job_id> --clear-skillsz    /cron pause <job_id>z    /cron resume <job_id>z    /cron run <job_id>z    /cron remove <job_id>rI   )actionr   jobsz  Current Jobs:zA  ---------------------------------------------------------------r  r   r   job_id   r  z | r  z<15z<8r  z      Skills: r   z      prompt_previewr   next_run_atz      Next: z3  No scheduled jobs. Use '/cron add' to create one.r   r  )r  include_disabledz(._.) No scheduled jobs.zScheduled Jobs:zP--------------------------------------------------------------------------------z  ID: z  Name: r   z	  State: r   z  Schedule: rA  ru  z  Next run: zN/Az
  Skills: z
  Prompt: last_run_atz  Last run: last_status>   addrW   r  z*(._.) Usage: /cron add <schedule> <prompt>r  rN   z3(._.) Please provide a prompt or at least one skillrW   r  )r  r  r  r   r  r  r  z(^_^)b Created job: z(x_x) Failed to create job: r   editzN(._.) Usage: /cron edit <job_id> [--schedule ...] [--prompt ...] [--skill ...]z(._.) Job not found: r  r  skillr  c                    g | ]}|v|	S r   r   )rx   r  r  s     r@   rz   z9CLICommandsMixin._handle_cron_command.<locals>.<listcomp>  s$    aaa%eS`F`F`F`F`F`rB   update)r  r  r  r  r   r  r  r  jobz(^_^)b Updated job: z  Skills: nonez(x_x) Failed to update job: >   rmrunpausedeleteremover-  z(._.) Usage: /cron z	 <job_id>>   r  r  r  r  r  zpaused from /cron)r  r  r"   z(x_x) Failed to z job: z(^_^)b Paused job: r-  z(^_^)b Resumed job: r  z(^_^)b Triggered job: z)  It will run on the next scheduler tick.removed_jobz(^_^)b Removed job: z(._.) Unknown cron command: z8  Available: list, add, edit, pause, resume, run, remove)r   r  r   tools.cronjob_toolsr  r,   r-   r&   r1   r3   r/   setrI   r   )r7   r   r  r   r  r  r  r  r>   r  r  
repeat_strr   r  r  r  r  r  r  existingfinal_skillsreplacement_skillsr  existing_skillsr  r  removedr  r  s                              @@r@   _handle_cron_commandz%CLICommandsMixin._handle_cron_command  s   ??????	6 	6 	6 	6 	6	 	 	6	 6	 6	p S!!v;;!GGG&'''KLLL&'''GGG-   "###XYYYUVVVLMMMFGGG:;;;,----...*+++-...GGGYf---F-3ZZ	-B-BJ6::fb)))D M'(((o&&&  C!$3!7!7JcXss!3cccC
OcccT^cccdddwwx(( KItyyX/G/GIIJJJB377+;R#@#@BBCCCww}-- CAS-?AABBBGGGG KLLLGGGFAY__&&
|F122J''<FYftE{KKKF-3ZZ	-B-BJ6::fb)))D 0111GGG#$$$(OOO  .s8}..///.V..///9#'''3"7"799:::QS_QQ#8N8NQQQRRRDSWW]E%B%BDDEEE778$$ CAtyyX'?'?AABBBB377+;R#@#@BBCCC77=)) _]]);]]sww}VY?Z?Z]]]^^^F***}-K BCCCJ'9;q>H(^@sxxABB'@'@F&&tH~66F & KLLLY!~&\YH~~  F zz)$$ L?VH-=??@@@9VJ%799:::::h'' FDtyy1A'B'BDDEEE<VM%:<<====JVZZ5H5HJJKKKF}-K fggg ^FwvH 6f66777L!2!24>!B!B**4+=>>J 1 1$2G H HIIM"8<<#9#9#{U\H]H]>zbbdldpdpqxdydycz||ON# 3!# 31 3} 3aaaa?aaa' 3 3EL00$++E222Yj)H~&\YH~#	 	 	F zz)$$ 	LUm<S]<<===6S_66777778$$ ,AtyyX'?'?AABBBB*++++JVZZ5H5HJJKKKFMMM}-K AJAAABBB ^F!+/I!I!IXXzFYfV[ael[l[lDWDWrvwwwF::i(( LLLvzz'7J7JLLMMM  NF5M&,ANNVNNNOOOO8##OVE]6-BOOfOOOPPPGVE]%6%6}%E%EGGHHHH5Qve}V/DQQQQQRRRABBBB **]B77UW[[-H-HUUFUUUVVVF9Z99:::HIIIIIrB   c                b   ddl }	 |r|                    |          dd         ng }n.# t          $ r! |pd                                dd         }Y nw xY wd                    |          }	 ddlm}  ||          }n# t          $ r}d| }Y d}~nd}~ww xY w|                     |           dS )u  Handle /suggestions — review/accept/dismiss suggested automations.

        Delegates to the shared handler so CLI and gateway never drift. CLI
        origin is the local platform so an accepted job's "origin" delivery
        resolves to a configured home channel.
        r   Nr   r   rN   )handle_suggestions_commandzSuggestions command failed: )r   r,   re   r3   hermes_cli.suggestions_cmdr  r   r  )r7   r   r   r  r;   r  outputr   s           r@   _handle_suggestions_commandz,CLICommandsMixin._handle_suggestions_command  s     		--08U[[%%abb))bFF 	- 	- 	-iR&&((,FFF	-xx	8MMMMMM//55FF 	8 	8 	87A77FFFFFF	8F#####s'   !( (AA,A> >
BBBc                   ddl 	 |r                    |          dd         ng }n.# t          $ r! |pd                                dd         }Y nw xY wd                    fd|D                       }	 ddlm}  ||          }n0# t          $ r#}|                     d|            Y d}~dS d}~ww xY w|                     |j                   t          |d	d          }|r	|| _
        dS dS )
u  Handle /blueprint — set up an automation from a blueprint template.

        Delegates to the shared handler. A bare ``/blueprint`` lists the
        catalog; ``/blueprint <name>`` name-matches a blueprint and seeds the
        agent to ask the user for each value conversationally (the result's
        ``agent_seed``); ``/blueprint <name> slot=val …`` creates the job
        directly. When a seed is returned it is stashed as a one-shot pending
        message the interactive loop runs as the next agent turn.
        r   Nr   r   rN   c              3  B   K   | ]}                     |          V  d S r  )quote)rx   tr   s     r@   	<genexpr>z=CLICommandsMixin._handle_blueprint_command.<locals>.<genexpr>  s-      771A777777rB   )handle_blueprint_commandzCron blueprint command failed: 
agent_seed)r   r,   re   r3   hermes_cli.blueprint_cmdr  r   r  r   r   _pending_agent_seed)	r7   r   r  r;   r  r>   r   seedr   s	           @r@   _handle_blueprint_commandz*CLICommandsMixin._handle_blueprint_command  sY    		--08U[[%%abb))bFF 	- 	- 	-iR&&((,FFF	-xx777777777	IIIIII--d33FF 	 	 	 E! E EFFFFFFFF	 	FK(((v|T22 	, (,D$$$	, 	,s'   !) (AA9B 
B8B33B8c                    ddl }|r|                    |          dd         ng }|sdg}	 ddlm}  ||           dS # t          $ r Y dS t
          $ r}t          d|            Y d}~dS d}~ww xY w)zHandle /curator slash command.

        Delegates to hermes_cli.curator so the CLI and the `hermes curator`
        subcommand share the same handler set.
        r   Nr   rt   )cli_mainz(._.) curator: )r   r,   hermes_cli.curatorr  
SystemExitr   r&   )r7   r   r   r  r  r  s         r@   _handle_curator_commandz(CLICommandsMixin._handle_curator_command  s     	),4S!!!""%%" 	 ZF	+333333HV 	 	 	 DD 	+ 	+ 	+)C))*********	+s   ? 
A2	A2A--A2c                   ddl m} |                                }|                    d          r|                    d          }|                    d          r)|t          d          d                                         }	  ||          }n# t          $ r}d| }Y d}~nd}~ww xY w|rt          |           dS dS )u#  Handle the /kanban command — delegate to the shared kanban CLI.

        The string form passed here is the user's full ``/kanban ...``
        including the leading slash; we strip it and hand the remainder
        to ``kanban.run_slash`` which returns a single formatted string.
        r   )	run_slash/kanbanNz(._.) kanban error: )hermes_cli.kanbanr  r   
startswithlstripr-   r   r&   )r7   r   r  restr  r  s         r@   _handle_kanban_commandz'CLICommandsMixin._handle_kanban_command3  s     	0/////yy{{??3 	$;;s##D??8$$ 	1H'..00D	2Yt__FF 	2 	2 	21C11FFFFFF	2 	&MMMMM	 	s   B 
B)B$$B)c                x    ddl m} |                                                                }t	          |          dk    r
|dd         ng }|rQ|d                                         dv r5ddlm} ddlm	}  ||j
        | fd	          }|t          |           dS dd
lm}  || |                       dS )uD   Handle /skills slash command — delegates to hermes_cli.skills_hub.r   )ChatConsoler   N>	   denyr   dropmodeapplyrejectapprover   approvalhandle_pending_subcommandwrite_approvalc                0                         d|           S )Nr  _save_write_approvalr(   r7   s    r@   r  z9CLICommandsMixin._handle_skills_command.<locals>.<lambda>U  s    D,E,EhPW,X,X rB   )set_mode_fn)handle_skills_slash)r   r#  r   r,   r-   r/   "hermes_cli.write_approval_commandsr,  toolsr.  SKILLSr&   hermes_cli.skills_hubr4  )	r7   r   r#  r:   r;   r,  waoutr4  s	   `        r@   _handle_skills_commandz'CLICommandsMixin._handle_skills_commandH  s   ###### 		!!##JJNNuQRRyy 
	DGMMOO (T T TTTTTTT222222++	4XXXX  C c


======C/////rB   c                P    ddl m} ddlm} |                                                                }t          |          dk    r
|dd         ng }t           dd          rt           j        dd          nd} ||j	        || fd	          }|d
}t          |           dS )uG   Handle /memory slash command — pending review + approval-gate toggle.r   r+  r-  r   Nr   _memory_storec                0                         d|           S )Nmemoryr0  r2  s    r@   r  z9CLICommandsMixin._handle_memory_command.<locals>.<lambda>g  s    (A(A(G(T(T rB   )memory_storer3  zWUnknown /memory subcommand. Use: pending, approve <id>, reject <id>, approval <on|off>.)r5  r,  r6  r.  r   r,   r-   r   r   MEMORYr&   )r7   r   r,  r9  r:   r;   storer:  s   `       r@   _handle_memory_commandz'CLICommandsMixin._handle_memory_command]  s    PPPPPP......		!!##JJNNuQRRyy>EdGUY>Z>Zd
OT:::`d''ItTTTT
 
 

 ;QCc




rB   	subsystemr(   c                J    ddl m}  || dt          |                     dS )zLPersist <subsystem>.write_approval to config (for /memory|/skills approval).r   r  z.write_approvalN)r   r  r   )r7   rD  r(   r  s       r@   r1  z%CLICommandsMixin._save_write_approvaln  s<    ))))))Y777gGGGGGrB   c                   	
 ddl mmmmm	m
mmm	 |
                                                    d          }t          |          dk     s|d         
                                s# d            d            d           d	S |d         
                                 xj        dz  c_         j        d
t          j                                        d           dt#          j                    j        d	d                                           s d           d	S  d dd	d          t                    dk    rdnd d            d             d                                          	
 fd}t-          j        |dd           }| j        <   |                                 d	S )u  Handle /background <prompt> — run a prompt in a separate background session.

        Spawns a new AIAgent in a background thread with its own session.
        When it completes, prints the result to the CLI without modifying
        the active session's conversation history.
        r   )	AIAgentr#  _accent_hexr   _maybe_remap_for_light_mode_render_final_assistant_contentset_approval_callbackset_secret_capture_callbackset_sudo_password_callbackr   r   r   z  Usage: /background <prompt>z9  Example: /background Summarize the top HN stories todayzI  The task runs in a separate session and results display here when done.Nbg_z%H%M%Srf  re  z;  (>_<) Cannot start background task: no valid credentials.u     🔄 Background task #z started: "r  r   r   r+  z  Task ID: u?     You can continue chatting — results will appear when done.
c                     j                     j                   	  j                   n# t          $ r Y nw xY w	  dKi dd         dd                             d          dd                             d          dd                             d          dd                             d          dd                             d          d	d                             d
          dd                             d          dj        dj        ddddddddj        dj        dj	        d                    d          dj
        dj        dj        dj        dj        dj        dj        d j        } d! | _        dLfd&}|| _        |                     '          }|r|                    d(d)          nd)}|s"|r |                    d*          rd+|d*          }j        r-j                                         t/          j        d,           t3                                                        d-              d.d/ d0            d1 d2            d3d d4          t5                    d4k    rd5nd) d6                                            d-              d.d/ d0           |r	 d7d8lm}  |            }|                    d9d:          } |                    d;d<                    } |                    d=d>                    }n# t          $ r	 d:}d<}d>}Y nw xY w             }	|	                    t?           |j         ?          d-| d@| dA dBdC||tB          j"        dD#                                E                     n dF           j$        r=tJ          j&        '                    dG           tJ          j&        (                                 nj# t          $ r]}
j        r-j                                         t/          j        d,           t3                        dH dI|
            Y d }
~
nd }
~
ww xY w	  d             d             d            n# t          $ r Y nw xY wj)        *                    d            j+        sd)_,        j        r-                    d7J           d S d S # 	  d             d             d            n# t          $ r Y nw xY wj)        *                    d            j+        sd)_,        j        r-                    d7J           w w xY w)MNrn  api_keyruntimebase_urlproviderapi_modeacp_commandr   acp_argsr;   
max_tokensrj  r   
quiet_modeTverbose_loggingFr   r   r   
session_dbrk  service_tierrequest_overridesproviders_allowedproviders_ignoredproviders_orderprovider_sortprovider_require_parametersprovider_data_collectionopenrouter_min_coding_scorefallback_modelc                     d S r  r   )_a_kws     r@   r  zUCLICommandsMixin._handle_background_command.<locals>.run_background.<locals>.<lambda>  s     rB   r   r   r   r   c                l    j         s)| _        j        rj                                         d S d S d S r  )r   _spinner_textr   
invalidate)r   r7   s    r@   _bg_thinkingzYCLICommandsMixin._handle_background_command.<locals>.run_background.<locals>._bg_thinking  sN    . 3-1*9 3 I00222223 33 3rB   )user_messagetask_idfinal_responser   r   zError: g?r)  r*  ux   ────────────────────────────────────────r  u     ✅ Background task #z	 completez  Prompt: "r  r   r+  r   )get_active_skinresponse_labelu
   ⚕ Hermesresponse_borderz#CD7F32banner_textz#FFF8DC)r&  z bold]z (background #z)[/]left)r      )r   title_alignborder_stylestyler   paddingr  z  (No response generated)u     ❌ Background task #z	 failed: )min_intervalr   )r   r   r   r   )._sudo_password_callback_approval_callback_secret_capture_callbackr   r1   r  r   r
  rk  r[  _providers_only_providers_ignore_providers_order_provider_sort_provider_require_params_provider_data_collection_openrouter_min_coding_score_fallback_model	_print_fnthinking_callbackrun_conversationr   rj  r  r  r&   r-   hermes_cli.skin_enginero  get_branding	get_colorr   final_response_markdownrich_boxHORIZONTALS_scrollback_box_widthbell_on_completesysstdoutwriteflush_background_taskspopr   ri  _invalidate)bg_agentrk  r>   responsero  _skinrS   _resp_color
_resp_text_chat_consoler   rG  r#  rH  r   rI  rJ  r  r7   rK  rL  rM  rm  task_num
turn_routes              r@   run_backgroundzCCLICommandsMixin._handle_background_command.<locals>.run_background  s   &&t'CDDD!!$"9:::++D,IJJJJ   o5"7   $W--&y155i@@@ (	266zBBB (	266zBBB	
 (	266zBBB !+9 5 9 9) D D D (	266v>>>  *)488FFF $(>> &*%:%:  $t %*E  'w #U  $//  &*%:%:!" "&!2!2#$ '1nn5H&I&I&I%& '+&:&:'( '+&<&<)* %)$9$9+, #'"5"5-. 150M0M/0 .2-K-K12 150Q0Q34 $(#7#75: &=%<"3 3 3 3 3 3 .:*!22!'# 3  
 @FM6::&6;;;2 ;F ;vzz'/B/B ;:::H
 9 %I((***Jt$$$##$G$G$G
$G$G$GHHHE(EEEFFFYvcrc{YS[[2=M=MEESUYYYZZZ##$G$G$G
$G$G$GHHH 9	/JJJJJJ / 1 1 % 2 23C\ R R&A&A%//RcenBoBo&p&p%@%@Q^`iAjAj%k%k

$ / / / ,&/%.


/
 %0KMMM!''77tGcdddX+XXUXX(XXX$*%0($0 &"88::	) 	) 	) 	 	 	 	 G7888 ( 'J$$T***J$$&&& J J J9 %I((***Jt$$$H(HHQHHIIIIIIIIJ..t444))$/////5555    D&**7D999* ,)+D&9 5$$!$444445 5..t444))$/////5555    D&**7D999* ,)+D&9 5$$!$44445s   4 
A AJ P &A$M 
P MP MB=P T 
R&AQ>9T >RT !R) )
R65R6U?!T'&U?'
T41U?3T44AU?Tzbg-task-)rR  daemonr   )r   rG  r#  rH  r   rI  rJ  rK  rL  rM  r   r,   r-   _background_task_counterr   rv  rw  rx  ry  rz  _ensure_runtime_credentials_resolve_turn_agent_config	threadingThreadr  start)r7   r   r:   r  threadrG  r#  rH  r   rI  rJ  r  rK  rL  rM  rm  r  r  s   `    @@@@@@@@@@@@@r@   _handle_background_commandz+CLICommandsMixin._handle_background_commands  s    	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q  	Q		!!1!--u::>>q!1!1>G3444GOPPPG_```Fq!!%%*%%0R//99RRDJLL<LRaR<PRR //11 	GQRRRFs8sssWZ[aWbWbegWgWgeemosssttt'g''(((RSSS44V<<
v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5 v	5p !K_V]K_K_```*0w'rB   c                   ddl m}m}m}m}m}m} 	 ddlm}m	}	 n(# t          $ r}
 |d|
 |            Y d}
~
dS d}
~
ww xY w |            }|s9 |d            |d| d|             |d| d	 |	             |            dS  |d
| d| dt          |           d           |D ]}t          |                    dg                     }|                    d          pd| d} |                                d |             d|d         ddt          |           d| d	           |                    dg           D ]0} |                                dt          |           d           1 |d| d|            dS )u  In-session ``/bundles`` — show installed skill bundles.

        Mirrors ``hermes bundles list`` but renders inside the running
        CLI so users can discover what's available without dropping out
        of their session. Bundles are loaded via ``/<bundle-name>``.
        r   )r#  _BOLDr   r   rH  r   )list_bundles_bundles_dirz%[1;31mBundle subsystem unavailable: Nz  No skill bundles installed.rK   zGCreate one with: hermes bundles create <name> --skill <s1> --skill <s2>zDirectory: u   
  ▣ zSkill BundlesrA  z installed):r  r  zLoad z skillsz
    [bold z]/slugz<20z[/] [dim]-[/] z [dim](z skills)[/]u           [dim]· r  z
  z;Invoke a bundle with /<slug>. Manage with `hermes bundles`.)r   r#  r  r   r   rH  r   agent.skill_bundlesr  r  r   r-   r1   r&   _escape)r7   r   r#  r  r   r   rH  r   r  r  r  bundlesinfoskill_countdescri   s                   r@   _handle_bundles_commandz(CLICommandsMixin._handle_bundles_command  s    	MLLLLLLLLLLLLLLL	FFFFFFFFF 	 	 	GJsJDJJKKKFFFFF	 ,.. 	G3444G:T : :37: :   G@@@,,..@$@@AAAFQ5QQtQQs7||QQQRRR 	H 	HDdhhx4455K88M**J.Jk.J.J.JDKMML[[]] L Ld6lD L L$T]]L L3>L L L   XXh++ H H##$Fwqzz$F$F$FGGGGH34 3 3,03 3	
 	
 	
 	
 	
s    
A ;A c                l   ddl }|                                                    dd          }t          |          dk    r,|d                                                                         nd}t
          }t          j                            dd                                          }|	                    d          r|                                                    dd          }t          |          dk    r|d                                         n|}t          d	|v r|nd
|           }	|	j        dvr8t                       t          d|	j        pd d           t                       dS 	 |	j        p|	j        dv rdnd}
n?# t          $ r2 t                       t          d|            t                       Y dS w xY w|	j        s0t                       t          d|            t                       dS |	j        }|	j        	                    d          r|	                                }n+|	                    dddd                                          }	 ddlm}  |             n# t*          $ r Y nw xY wt                       t-          |d          }|rt          d|
            n/||k    rt          d           |                     |
|                                          }|rst3          d          D ]+}t-          |d          rd} nt5          j        d           ,|rt          d|
            nt          d|
 d            t          d!           n|t          d"           |                                }t9          |
|          }|r"t          d#           t          d$|            n%t          d%           nt          d&|
 d'|            |s-t                       t          d(           t                       dS |t          j        d<   	 dd)lm}  |d*           n# t*          $ r Y nw xY wt                       t          d+           t          d,|            t                       t=          | d-          r| j                             d.           dS dS |d/k    r|rt          j        !                    dd           	 dd0lm}m"}  |d*            |             n# t*          $ r Y nw xY wt                       t          d1           t          d2           t                       t=          | d-          r| j                             d3           dS dS t                       t          d4           t                       dS |dk    r/t                       |rt          d5           t          d,|            d6}
	 tG          |$                    d7d          d8                             d9          d                   }
n# t          tJ          f$ r Y nw xY w	 ddl&}|&                    |j'        |j(                  }|)                    d           |*                    d:|
f           |+                                 t          d;           n# tX          t*          f$ r t          d<           Y nw xY w	 dd=lm-}  |            }n# t*          $ r d}Y nw xY w|&t          d>|.                                 d?           n}	 dd@lm/}  |            }n# t*          $ r dA}Y nw xY w|dBk    r.t          dC           t          dD           t          dE           n%|dFk    rt          dG           nt          dH           t                       t          dI           t          dJ           t                       dS t                       t          dK           t                       t          dL           t          dM           t          dN           t                       dS )OuY   Handle /browser connect|disconnect|status — manage live Chromium-family CDP connection.r   Nr   rt   BROWSER_CDP_URLr   connectr   z://zhttp://>   wswsshttphttpsu'      ⚠ Unsupported browser url scheme: z	(missing)z( (expected one of: http, https, ws, wss)>   r  r  i  r   u$      ⚠ Invalid port in browser url: u$      ⚠ Missing host in browser url: z/devtools/browser/)pathparamsqueryfragment)cleanup_all_browsersr  )timeoutu<      ✓ Chromium-family browser is already listening on port uZ      Chromium-family browser isn't running with remote debugging — attempting to launch...r/  Tr  u>      ✓ Chromium-family browser launched and listening on port u!      ⚠ Browser launched but port z isn't responding yetuL        Try again in a few seconds — the debug instance may still be startingu6      ⚠ Could not auto-launch a Chromium-family browserz/     Launch a Chromium-family browser manually:z     zN     No supported Chromium-family browser executable found in this environmentu      ⚠ Port z is not reachable at uj   Browser not connected — start a Chromium-family browser with remote debugging and retry /browser connect)_ensure_cdp_supervisorr  u>   🌐 Browser connected to live Chromium-family browser via CDPz   Endpoint: _pending_inputa  [System note: The user invoked /browser connect and connected your browser tools to a Chromium-family dev/debug browser via Chrome DevTools Protocol. Your browser_navigate, browser_snapshot, browser_click, and other browser tools now control that CDP browser. The command itself is a signal that using browser tools for their current browser-related request is expected; do not wait for separate permission just because CDP is connected. This is typically a Hermes-managed isolated debug profile, not the user's main everyday browser. It is still user-visible and may contain pages, logged-in sessions, or cookies in that debug profile, so avoid destructive actions, closing tabs, or navigating away unless the user's task calls for it.]
disconnect)r  _stop_cdp_supervisoru;   🌐 Browser disconnected from live Chromium-family browserzL   Browser tools reverted to default mode (local headless or cloud provider)z[System note: The user has disconnected the browser tools from their live Chromium-family browser. Browser tools are back to default mode (headless local browser or cloud provider).]zWBrowser is not connected to a live Chromium-family browser (already using default mode)u?   🌐 Browser: connected to live Chromium-family browser via CDPi$  :r'  r  z	127.0.0.1u      Status: ✓ reachableu9      Status: ⚠ not reachable (browser may not be running))_get_cloud_provideru   🌐 Browser: z (cloud))_get_browser_engineauto
lightpandauB   🌐 Browser: local Lightpanda (agent-browser --engine lightpanda)u;      ⚡ Lightpanda: faster navigation, no screenshot supportzB   Automatic Chromium fallback for screenshots and failed commandschromeuE   🌐 Browser: local headless Chromium (agent-browser --engine chrome)u5   🌐 Browser: local headless Chromium (agent-browser)uI      /browser connect      — connect to your live Chromium-family browseru.      /browser disconnect   — revert to defaultz)Usage: /browser connect|disconnect|statuszR   connect      Connect browser tools to your live Chromium-family browser sessionz1   disconnect   Revert to default browser backendz)   status       Show current browser mode)0r   r   r,   r-   r/   r   r)   r~  r1   r  r   schemer&   portre   hostnamer  geturl_replacetools.browser_toolr  r   r   _try_launch_chrome_debugsystemranger  r  r   r  r%   r  putr  r  rd   rsplit
IndexErrorsocketAF_INETSOCK_STREAM
settimeoutr  closeOSErrorr  provider_namer  )r7   r   _platr:   rb  _DEFAULT_CDPr   connect_partscdp_url
parsed_cdp_port_hostr  _already_open	_launched_waitsys_name
chrome_cmdr  r  r  ri   r  rS  r  engines                             r@   _handle_browser_commandz(CLICommandsMixin._handle_browser_command5  s	       		!!$***-e**q..eAhnn$$&&&h.*..!2B77==??>>)$$ @	IIKK--dA66M25m2D2Dq2H2HmA&,,...lG!Ug-=-=''CVWCVCVWWJ (FFF>j>O>^S^ > > >   "a:3DHX3X3XCC^`   FWFFGGG	
 & FWFFGGG'E))*>?? $++--$--	 .  
 &(( CCCCCC$$&&&&    GGG 37CHHHM L\UZ\\]]]]L((rsss 99%PP	 p!&r ( (1'3GGG ",0M!E
3$ nf_dffgggg^%^^^___lmmmmRSSS$||~~H!<UH!M!MJ! pPQQQ2j223333nooooJUJJJJKKK    C  D  D  D,3BJ()EEEEEE&&y1111   GGGRSSS+'++,,,GGG t-.. #'']
 
 
 
 
  L   
0$777]]]]]]]]((333((****    DSTTTdeee4!122 '++n      opppH__GGG )WWXXX/g//000sA 6 6r : @ @ E Ea HIIEE"J/   DW!MMMfnf6HIIALLOOOII{E2333GGIII45555+ W W WUVVVVVW$FFFFFF2244HH  $ $ $#HHH$ 'M8+A+A+C+CMMMNNNN(JJJJJJ!4!4!6!6$ ( ( (!'(--bccc[\\\bcccc8++effffUVVVGGG]^^^BCCCGGGGG GGG=>>>GGGfgggEFFF=>>>GGGGGs   .F 8F?>F?I, ,
I98I9P1 1
P>=P>S3 3
T ?T AX X+*X+/A3Z# # [[
[ [*)[*\' '\65\6c                   ddl m}m}m} |pd                                                    dd          }t          |          dk    r|d                                         nd}|                                 }| |d| d|            dS |                                }|r|dk    r" |d|	                                            dS |d	k    r?|
                    d
          }	|	 |d| d|            n |d|	j                    dS |dk    rN|                                }	|	 |d| d|            n$ |d|	j                     |d| d|            dS |dv rI|                                }
|                                 |
r |d           n |d| d|            dS 	 |                    |          }	n&# t           $ r} |d|            Y d}~dS d}~ww xY w |d|	j         d|	j                     |d| d|            	 | j                            |	j                   dS # t(          $ r Y dS w xY w)zBDispatch /goal subcommands: set / status / pause / resume / clear.r   r   r   r   r   Nr   rK   &Goals unavailable (no active session).rt   r  zuser-pausedr.  zNo goal set.u     ⏸ Goal paused: r-  zNo goal to resume.u     ▶ Goal resumed: z`Send any message (or press Enter on an empty prompt is a no-op; type 'continue' to kick it off).>   donestopclearu     ✓ Goal cleared.zNo active goal.z  Invalid goal: u     ⊙ Goal set (z-turn budget): zAfter each turn, a judge model will check if the goal is done. Hermes keeps working until it is, you pause/clear it, or the budget is exhausted. Use /goal status, /goal pause, /goal resume, /goal clear.)r   r   r   r   r   r,   r-   _get_goal_managerr/   status_liner  goalr-  has_goalr  r  re   r  r  r  r   )r7   r   r   r   r   r:   r   r8   r/   r   hadr  s               r@   _handle_goal_commandz%CLICommandsMixin._handle_goal_command  sX   ++++++++++!!##))$22"%e**q..eAhnnb$$&&;GKKKTKKLLLF		  	ex''G,**,,---FGII]I33E}5T55t556666:ej::;;;FHJJLLE};T;;T;;<<<<;uz;;<<<J J JCGJ J   F---,,..CIIKKK :-....8T88$88999F	GGCLLEE 	 	 	G,s,,---FFFFF	 	O5?OO5:OOPPPZ Z ZSWZ Z	
 	
 	
	##EJ///// 	 	 	DD	s*   2G 
G+G&&G+H< <
I
	I
c                   ddl m}m}m} |pd                                                    dd          }t          |          dk    r/d                    |dd                                                   nd}|                                 }| |d| d	|            dS |	                                s |d| d
|            dS |sB |d|
                                             |d|                                            dS |                    dd          }|d                                         }	t          |          dk    r|d                                         nd}
|	dk    r|
s |d           dS 	 t          |
                                d                   }n# t          $ r  |d           Y dS w xY w	 |                    |          }n-# t           t"          f$ r} |d|            Y d}~dS d}~ww xY w |d| d|            dS |	dk    rl	 |                                }n&# t"          $ r} |d|            Y d}~dS d}~ww xY w|r |d| d|dk    rdnd d           n |d| d|            dS 	 |                    |          }n-# t          t"          f$ r} |d|            Y d}~dS d}~ww xY w|j        rt          |j        j                  nd} |d| d|            dS )u  Dispatch /subgoal subcommands.

        Forms:
          /subgoal                              show current subgoals
          /subgoal <text>                       append a criterion
          /subgoal remove <n>                   drop subgoal n (1-based)
          /subgoal clear                        wipe all subgoals

        Subgoals are extra criteria the user adds mid-loop. They get
        appended to both the judge prompt (verdict must consider them)
        and the continuation prompt (agent sees them) on the next turn
        boundary. No special kick — the running turn finishes, the next
        judge call includes them.
        r   r  r   Nr   r   rN   rK   r  z*No active goal. Set one with /goal <text>.r  z  Usage: /subgoal remove <n>z:  /subgoal remove: <n> must be an integer (1-based index).z  /subgoal remove: u     ✓ Removed subgoal r!   r  z  /subgoal clear: u     ✓ Cleared z subgoalri   r\   zNo subgoals to clear.z  /subgoal: u     ✓ Added subgoal )r   r   r   r   r   r,   r-   r3   r  r  r  render_subgoalsr/   rd   re   remove_subgoalr  RuntimeErrorclear_subgoalsadd_subgoalr   subgoals)r7   r   r   r   r   r:   r   r8   r  r   r   rm   r  r  prevr   s                   r@   _handle_subgoal_commandz(CLICommandsMixin._handle_subgoal_commandD  s    	,+++++++++!!##))$22-0ZZ!^^chhuQRRy!!'')))$$&&;GKKKTKKLLLF||~~ 	GOOOOOPPPF  	G,**,,---G0,,..00111F4##ay  $'KK!OOvay   8 6777$**,,q/**   TUUU,,S11-   3c33444 G=S==G==>>>F7??))++   2S22333  @RRRdaiissRRRRSSSS>T>>>>???F	??3''DDL) 	 	 	G(3(()))FFFFF	 *-9c#)$%%%4s44d4455555sZ   'F* *GGG H.HH$H9 9
IIIJ& &K7KKc                   ddl m}m} 	 ddlm}m}m} n # t          $ r t          d           Y dS w xY w|	                                
                    d          }t          |          dk     s|d         	                                s |            } |            }	t          d	|            t          d
           |	D ]R}
|
d         |k    rdnd}|
d         dk    rd|
d          dnd}t          d| d|
d          | d|
d                     St          d           t          dt                       d           dS |d         	                                                                }d  |            D             }||vrFt          d|            t          dd                    t          |                                dS  ||           |                                  |d|          rt          d| d            nt          d|            t          d!           |                                 rt          d"           dS dS )#u8   Handle /skin [name] — show or change the display skin.r   )r   r  )
list_skinsset_active_skinget_active_skin_namezSkin engine not available.Nr   r   r   z
  Current skin: z  Available skins:r   u    ●rK   rm  r?  rA  ru  r   z   rN   u    — r  z
  Usage: /skin <name>z$  Custom skins: drop a YAML file in z/skins/
c                    h | ]
}|d          S )r   r   )rx   ri   s     r@   	<setcomp>z8CLICommandsMixin._handle_skin_command.<locals>.<setcomp>  s    5551QvY555rB   z  Unknown skin: z  Available: r   zdisplay.skinz  Skin set to: z (saved)z8  Note: banner colors will update on next session start.z  Prompt + TUI colors updated.)r   r   r  r  r  r  r  r  r&   r   r,   r-   r	   r/   r3   sortedr<  _apply_tui_skin_style)r7   r   r   r  r  r  r  r:   r   skinsri   markerrm  new_skin	availables                  r@   _handle_skin_commandz%CLICommandsMixin._handle_skin_command  s   22222222	``````````` 	 	 	.///FF	 		!!1!--u::>>q!1!1>**,,GJLLE0w00111&''' Q Q#$V9#7#7T01(v0E0E,ak,,,,2OFOOQvYOOOQ}=MOOPPPP+,,,Y9L9N9NYYYZZZF8>>##))++55

555	9$$/X//000@$))F9,=,=">">@@AAAF!!! ^X66 	06H6667777.H..///HIII%%'' 	4233333	4 	4s   
 22c                t   ddl m}m} ddlm} ddlm} d}	 |pd                                                    dd          }t          |          dk    r,|d                                         
                                }n# t          $ r d}Y nw xY w |            pi }|                    d          pi                     d	          pi }	t          |	                    d
d                    }
|	                    d          pg d}|dv r<|
rdnd} |d|j         d|j         d| dd                    |                      dS |dv rd}n|dv rd}n|dk    r|
 }n |d           dS  |d|          r4|r|j         d|j         n|j         d|j         } |d|            dS  |d           dS )u   Toggle or inspect ``display.runtime_footer.enabled`` from the CLI.

        Usage:
            /footer           → toggle
            /footer on|off    → explicit
            /footer status    → show current state
        r   )r   r  r   )Colorsr   Nr   r   runtime_footerr(   Ffields)rn  context_pctr9   >   rt   r   ONOFFrK   zRuntime footer:rN   z
  Fields: r   >   1ontruer   T>   0offfalser   z   Usage: /footer [on|off|status]zdisplay.runtime_footer.enabledz  Runtime footer: z6  Failed to save runtime_footer setting to config.yaml)r   r   r  r   r   hermes_cli.colorsr  r   r,   r-   r/   r   r1   r   BOLDRESETr3   GREENDIM)r7   r   r   r  r   _Colorsr   r:   cfg
footer_cfgr   r  r   	new_states                 r@   _handle_footer_commandz'CLICommandsMixin._handle_footer_command  s    	32222222111111777777 	!'R..0066tQ??E5zzA~~Ahnn&&,,.. 	 	 	CCC	 kmm!rwwy))/R445EFFL"
z~~i7788))L-L-L-L/!!#.DDEG1W\ 1 1'- 1 1% 1 1!YYv..1 1   F///II444IIBYY#IIG6777F=yII 	N7@ 87=33GM3337777  G00011111GLMMMMMs   A)B BBc                b   ddl m}m}m}m}m}m} |                                                    d          }t          |          dk     r| j
        }	|	d}
n0|	                    d          d	u rd
}
n|	                    dd          }
| j        rdnd} |d| d|
 |             |d| d| |             |d| d|            dS |d                                                                         }|dv r\d| _        | j        r|                                 | j        _         |dd            |d| d|             |d| d|            dS |dv rKd	| _        | j        r|                                 | j        _         |dd	            |d| d|            dS  ||          }|7 |d| d| |             |d| d|             |d| d|            dS || _
        d| _         |d|          r |d| d| d|            dS  |d| d| d |            dS )!u  Handle /reasoning — manage effort level and display toggle.

        Usage:
            /reasoning              Show current effort level and display state
            /reasoning <level>      Set reasoning effort (none, minimal, low, medium, high, xhigh)
            /reasoning show|on      Show model thinking/reasoning in output
            /reasoning hide|off     Hide model thinking/reasoning from output
        r   )r   r   r   r   _parse_reasoning_configr  r   r   r   Nzmedium (default)r(   Fznone (disabled)effortmediumu   on ✓r  rK   zReasoning effort:  zReasoning display: z@Usage: /reasoning <none|minimal|low|medium|high|xhigh|show|hide>>   r  showTzdisplay.show_reasoningu!   ✓ Reasoning display: ON (saved)z>  Model thinking will be shown during and after each response.>   r  hideu"   ✓ Reasoning display: OFF (saved)(._.) Unknown argument: z5Valid levels: none, minimal, low, medium, high, xhighzDisplay:      show, hidezagent.reasoning_effortu   ✓ Reasoning effort set to 'r  r  )r   r   r   r   r   r(  r  r   r,   r-   rk  r1   show_reasoningr/   r   _current_reasoning_callbackreasoning_callback)r7   r   r   r   r   r   r(  r  r:   rcleveldisplay_stater   parseds                 r@   _handle_reasoning_commandz*CLICommandsMixin._handle_reasoning_command  sU    	a```````````````		!!1!--u::>>&Bz*	""e++)x22(,(;FHHMGBBBUBDBBCCCGJJJ]JDJJKKKGeee_ceefffFAhnn$$&& .  "&Dz S040P0P0R0R
-6===GIII4IIJJJGccc]accdddF/!!"'Dz S040P0P0R0R
-6>>>GJJJDJJKKKF )(-->GBBBsBDBBCCCGZZZTXZZ[[[G===t==>>>F &
5s;; 	\G]]]s]]W[]]^^^^^GZZZsZZTXZZ[[[[[rB   c                "   ddl m}m}m}m}m} |                                                    d          }t          |          dk     s0|d                                         	                                dk    r\ |d| d| j
         |            | j
        d	k    rd
}n| j
        dk    rd}nd} |d| d| |             |d| d|            dS |d                                         	                                }	|	dvr& |d| d|	 |             |d| d|            dS |	| _
         |d|	          r<|	d	k    rd}
n|	dk    rd}
nd}
 |d| d|	 d|             |d| |
 |            dS  |d| d|	 d|            dS )u  Handle /busy — control what Enter does while Hermes is working.

        Usage:
            /busy               Show current busy input mode
            /busy status        Show current busy input mode
            /busy queue         Queue input for the next turn instead of interrupting
            /busy steer         Inject Enter mid-run via /steer (after next tool call)
            /busy interrupt     Interrupt the current run on Enter (default)
        r   r   r   r   r   r  r   r   r   rt   rK   zBusy input mode: queuezqueues for next turnsteerz.steers into current run (after next tool call)zinterrupts current runzEnter while busy: z+Usage: /busy [queue|steer|interrupt|status]N>   r8  r9  	interruptr-  zdisplay.busy_input_modez6Enter will queue follow-up input while Hermes is busy.zNEnter will steer your message into the current run (after the next tool call).z:Enter will interrupt the current run while Hermes is busy.u   ✓ Busy input mode set to 'r  r  )r   r   r   r   r   r  r   r,   r-   r/   busy_input_mode)r7   r   r   r   r   r   r  r:   	_behaviorr   behaviors              r@   _handle_busy_commandz%CLICommandsMixin._handle_busy_command.  sb    	HGGGGGGGGGGGGG		!!1!--u::>>U1X^^--3355AAGOOO43GOOOPPP#w..2		%00L		4	GBBBBDBBCCCGPPP$PPQQQFAhnn$$&&555GBBBsBDBBCCCGPPP$PPQQQF"6<< 
	[g~~SkWG\\\c\\VZ\\]]]G//x///00000GYYYcYYSWYYZZZZZrB   c           
        ddl m}m}m}m}m} |                                 s |d           dS 	 ddlm} t          | dd          }t          |dd          pt          | dd          }	 ||	          rdnd	}
n# t          $ r d
}
Y nw xY w|                                                    d          }t          |          dk     s0|d                                                                         dk    r7| j        dk    rdnd} |d| |
 d| |             |d| d|            dS |d                                                                         }|dv rd| _        d}d}n6|dv rd| _        d}d}n& |d| d| |             |d| d|            dS d| _         |d|          r |d| d|
 d| d|            dS  |d| d|
 d| d|            dS )uU   Handle /fast — toggle fast mode (OpenAI Priority Processing / Anthropic Fast Mode).r   r7  zv  (._.) /fast is only available for models that support fast mode (OpenAI Priority Processing or Anthropic Fast Mode).N)_is_anthropic_fast_modelr   rn  zAnthropic Fast ModezPriority Processingz	Fast moder   r   r   rt   priorityfastnormalrK   r!   z!Usage: /fast [normal|fast|status]>   r  rB  FAST>   r  rC  NORMALr-  zagent.service_tieru   ✓ z set to z (saved to config)z (session only))r   r   r   r   r   r  _fast_command_availablehermes_cli.modelsr@  r   r   r   r,   r-   r/   r[  r   )r7   r   r   r   r   r   r  r@  r   rn  feature_namer:   rt   r   saved_valuerS   s                   r@   _handle_fast_commandz%CLICommandsMixin._handle_fast_commandY  s   GGGGGGGGGGGGGG++-- 	G  M  N  N  NF	'BBBBBBD'400EE7D11QWT7D5Q5QE4L4LU4S4Sn00YnLL 	' 	' 	'&LLL	' 		!!1!--u::>>U1X^^--3355AA#0J>>VVHFG@@,@@&@$@@AAAGFFFFFGGGFAhnn$$&&.   *D KEE%%% $D"KEEGBBBsBDBBCCCGFFFFFGGGF
1;?? 	ZG[[[l[[E[[UY[[\\\\\GXXXlXXEXXRVXXYYYYYs   AA: :B	B	c                P    ddl m} ddlm}  |ddd          } ||           dS )	uB   Handle /debug — upload debug report + logs and print paste URLs.r   )run_debug_share)SimpleNamespace      F)linesexpirelocalN)hermes_cli.debugrL  typesrM  )r7   rL  rM  r;   s       r@   _handle_debug_commandz&CLICommandsMixin._handle_debug_command  sR    444444))))))S%@@@rB   c                   ddl m}m}  |            rt          d |d                      dS ddg}|                     dd	|
          }|t          d           dS |                     ||          }|dk    rt          d           dS t                       t          d           t                       dg| _        dS )u  Handle /update — update Hermes Agent to the latest version.

        In the classic CLI this exits the session and relaunches as
        ``hermes update`` so the user sees update output directly and gets
        the new version on next launch.

        Returns ``True`` when the update was confirmed (caller should trigger
        app exit so the relaunch is deferred to the main thread after
        prompt_toolkit cleans up terminal modes).  Returns ``False`` / falsy
        when cancelled.
        r   )
is_managedformat_managed_messageu     ✗ zupdate Hermes AgentF)oncez
Update Nowz0exit the current session and update Hermes Agent)cancelCancelzkeep the current sessionu   ⚕  Update Hermes Agentz;This will exit the current session and run `hermes update`.)r   detailchoicesNu     🟡 /update cancelled.rY  u     ⚕ Launching update...r  T)r   rW  rX  r&   _prompt_text_input_modal_normalize_slash_confirm_choice_pending_relaunch)r7   rW  rX  r]  rawchoices         r@   _handle_update_commandz'CLICommandsMixin._handle_update_command  s
    	IHHHHHHH:<< 	J112GHHJJKKK5 W<
 ++,P , 
 

 ;-...555c7CCV-...5)*** #+trB   c                h   ddl m} |                                                    d          }t	          |          dk    r,|d                                                                         nd}|dk    r|                                  dS |dk    r|                                  dS |dk    r|                                  dS |d	k    r| 	                                 dS |dk    r3| j
        r|                                  dS |                                  dS  |d
|             |d           dS )z*Handle /voice [on|off|tts|status] command.r   r   r   r   r   r  r  ttsrt   zUnknown voice subcommand: z!Usage: /voice [on|off|tts|status]N)r   r   r   r,   r-   r/   _enable_voice_mode_disable_voice_mode_toggle_voice_tts_show_voice_status_voice_mode)r7   r   r   r:   r   s        r@   _handle_voice_commandz&CLICommandsMixin._handle_voice_command  sf   %%q%1114UaU1X^^%%++---R
##%%%%%5  $$&&&&&5  ""$$$$$8####%%%%%2 *((*****'')))))G===>>>G788888rB   N)r   r   )r   r   r   r   )r   r   )r   r   )r   r   r   r   )rD  r   r(   r   )r   r   r   r   r   )(r   r   r   __doc__rA   ro   r   r   r   r   r   r   r   r"  r_  rc  r  r  r  r  r  r  r  r!  r;  rC  r1  r  r  r  r  r  r  r&  r5  r>  rJ  rU  rc  rk  r   rB   r@   r   r   &   sE        \. \. \. \.|UU UU UU UUn6 6 6&F F F*H H H4%5 %5 %5 %5Nd d d d2NQ NQ NQ NQ`  U U U UnTg Tg Tg Tgl6 6 6 6BF9 F9 F9 F9P, , , ,\, , , ,\tJ tJ tJ tJl$ $ $ $*, , , ,<+ + + +,   *0 0 0 0*   "H H H H
Y Y Y Yv%
 %
 %
 %
NJ J J JXA A A AFJ6 J6 J6 J6X)4 )4 )4 )4V3N 3N 3N 3Nj<\ <\ <\ <\|)[ )[ )[ )[V*Z *Z *Z *ZX  2 2 2 2h9 9 9 9 9 9rB   r   )rl  
__future__r   r  r)   r  r  r  rx  r   urllib.parser   richr   r  rich.markupr   r  
rich.panelr   rb   r	   r
   r   hermes_cli.browser_connectr   r   r   r   r   rB   r@   <module>rs     s<    # " " " " "  				 



             ! ! ! ! ! !             ) ) ) ) ) )       U U U U U U U U         q"9 q"9 q"9 q"9 q"9 q"9 q"9 q"9 q"9 q"9rB   