
    Yffjv                    0   d Z ddlmZ ddlZddlZddlmZmZ ddlmZ ddl	m
Z
 d'dZd(dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd*dZd)dZd)dZd)dZd)d Zd)d!Zd+d$Zd,d)d%Zed&k    r ej          e                       dS dS )-u0  CLI subcommand: `hermes curator <subcommand>`.

Thin shell around agent/curator.py and tools/skill_usage.py. Renders a status
table, triggers a run, pauses/resumes, and pins/unpins skills.

This module intentionally has no side effects at import time — main.py wires
the argparse subparsers on demand.
    )annotationsN)datetimetimezone)Path)OptionaltsOptional[str]returnstrc                   | sdS 	 t          j        |           }n&# t          t          f$ r t	          |           cY S w xY w|j         |                    t          j                  }t          j	        t          j                  |z
  }t          |                                          }|dk     r| dS |dk     r|dz   dS |dk     r|dz   dS |dz   d	S )
Nnevertzinfo<   zs agoi  zm agoiQ zh agozd ago)r   fromisoformat	TypeError
ValueErrorr   r   replacer   utcnowinttotal_seconds)r   dtdeltasecss       8/home/thesage/.hermes/hermes-agent/hermes_cli/curator.py_fmt_tsr      s    w#B''z"   2ww	yZZx|Z,,L&&+Eu""$$%%Dbyy~~~d{{"*####e||$,%%%%em""""s     >>Nonec                 d   ddl m}  	 |                                 }n# t          $ r Y dS w xY w|sdS t	          d |D                       }t          |          |z
  }t          dt          |           d           t          d|            t          d|            t          d	           dS )
u  Report curation-eligible skills that carry no provenance marker.

    A skill only becomes curator-managed once ``created_by: agent`` lands on
    its usage record, which happens ONLY for background-review creations.
    Skills predating that marker, plus every foreground
    ``skill_manage(create)``, are eligible but unmanaged — no automatic
    transition ever considers them. Printing just the managed count made a
    large library look fully curated while a big slice was untouchable.
    r   skill_usageNc              3  D   K   | ]}|                     d           dV  dS )has_provenance_key   Nget).0rs     r   	<genexpr>z+_print_unmanaged_summary.<locals>.<genexpr>9   s4      IIqQUU3G-H-HIIIIIII    z#
unmanaged (no provenance marker): z totalz  pre-dates marker    z  foreground-created  uP     never auto-staled or archived — `hermes curator adopt <name>` hands one over)toolsr!   unmanaged_report	Exceptionsumlenprint)r!   	unmanagedlegacy
foregrounds       r   _print_unmanaged_summaryr4   '   s     "!!!!!0022		    IIIIIIIIFY&(J	
GY
G
G
GHHH	
+6
+
+,,,	
/:
/
/000		7    s    
++r   c                (   ddl m} ddlm} |                                }|                                }|                    dd          }|                    d          }|                    d          pd}|                    d	d          }|r|sd
n|rdnd}	t          d|	            t          d|            t          dt          |                      d|v r@|	                                ^}
}t          d|
            |D ]}t          d|            nt          d|            |                    d          }|r9t          |                                          rdnd}t          d| |            |                                }|dz  dk    r|dk    r|dz   dn| d}t          d|            t          d|                                 d           t          d|                                 d           t          d|                                rdnd  |                                rdnd!            |                                }|st          d"           t#                       dS g g g d#}g }d}d}|D ]}|                    d$d%          }|                    |g                               |           |                    d&          r|                    |d'                    |                    d(d)          }|d)k    r|d*z  }|d+k    r|d*z  }t          d,t)          |           d-| d.| d/           d#D ];}|                    |g           }t          d0|d1d2t)          |                      <|r5t          d3t)          |           d4d5                    |                      t#                       t-          |                    d%g           d6 7          d d8         }|rt          d9           |D ]}t          |                    d:                    }t          d0|d'         d;d<|                    d=d          d>d?|                    d@d          d>dA|                    dBd          d>dC|                    dDd          d>dE|            |                    d%g           }|rt-          |dF dGH          d d8         }|r|d                             d=          pddk    rt          dI           |D ]}t          |                    d:                    }t          d0|d'         d;d<|                    d=d          d>d?|                    d@d          d>dA|                    dBd          d>dC|                    dDd          d>dE|            t-          |dJ 7          d d8         }|rt          dK           |D ]}t          |                    d:                    }t          d0|d'         d;d<|                    d=d          d>d?|                    d@d          d>dA|                    dBd          d>dC|                    dDd          d>dE|            dS )LNr   curatorr    pausedFlast_run_atlast_run_summaryz(none)	run_countENABLEDPAUSEDDISABLED	curator: z  runs:           z  last run:       
z  last summary:   z                  last_report_path z
 (missing)z  last report:       dhz  interval:       every z  stale after:    zd unusedz  archive after:  z  consolidate:    onoffz$ (prune-only; LLM merge pass opt-in)z
no curator-managed skills)activestalearchivedstaterH   pinnedname
provenanceagentr$   bundledz
curator-managed skills: z total  (agent-created=
  bundled=)  10s z	
pinned (z): z, c                Z    |                      d          p|                      d          pdS )Nlast_activity_at
created_atrB   r%   r(   s    r   <lambda>z_cmd_status.<locals>.<lambda>   s)    aee.//L1553F3FL" r*   key   z
least recently active (top 5):rW   40sz  activity=activity_count3dz  use=	use_countz  view=
view_countz
  patches=patch_count  last_activity=c                ^    |                      d          pd|                      d          pdfS Nr_   r   rW   rB   r%   rY   s    r   rZ   z_cmd_status.<locals>.<lambda>   0    155!1227a?Q9R9R9XVXY r*   Tr\   reversez
most active (top 5):c                ^    |                      d          pd|                      d          pdfS rf   r%   rY   s    r   rZ   z_cmd_status.<locals>.<lambda>   rg   r*   z
least active (top 5):)rO   r7   r+   r!   
load_state
is_enabledr&   r0   r   
splitlinesr   existsget_interval_hoursget_stale_after_daysget_archive_after_daysget_consolidatecurated_reportr4   
setdefaultappendr/   joinsorted)argsr7   r!   rK   enabledr8   last_runsummaryrunsstatus_linefirstrestline_reportsuffix_ih_interval_labelrowsby_staterL   agent_countbundled_countr(   
state_nameprovbucketrH   last
active_allmost_activeleast_actives                                  r   _cmd_statusr   D   s   !!!!!!  E  ""GYYx''Fyy''Hii*++7xG99[!$$D  	V 			 	 
 

#k
#
#$$$	
%t
%
%&&&	
2wx00
2
2333 w))++*5**+++ 	/ 	/D-t--....	/ 	,7,,---ii*++G 6G}}++--?<474F44555

$
$
&
&C8q==SBYY3"9YYY  

6_
6
6777	
Gw;;==
G
G
GHHH	
Iw==??
I
I
IJJJ		YW%<%<%>%>ITTE 	Y((**V220V	Y 	Y  
 %%''D +,,, """qrr::HFKM 	 	UU7H--
J++22155555?? 	%MM!F)$$$uu\7++7??1KKYQM	 Ds4yy D D'D D3@D D D E E E5 3 3
j"--1:111CKK112222 @>3v;;>>499V+<+<>>??? 
 Xr""LL   	qb
F  0111 		 		A155!34455D(QvY& ( (EE"2A66=( (uu[!,,3( ( lA..5( ( 55229	( (
 "&( (    h++J "YY
 
 
 1"	
  	KN../?@@EAJJ*+++  	 	quu%78899,6* , , !&6 : :A, ,55a007, , EE,229, ,  !uu]A66=	, ,
 &*, ,    YY
 
 
 1"  	+,,,! 	 	quu%78899,6* , , !&6 : :A, ,55a007, , EE,229, ,  !uu]A66=	, ,
 &*, ,    1r*   c                   ddl m} |                                st          d           dS t	          t          | dd                    }t	          t          | dd                    }t	          t          | dd                    p| }t	          t          | d	d                    rd
nd }|rt          d           nt          d           |#|                                st          d           d"d}|                    ||||          }|                    di           }|r|r(t          d|                    dd           d           nkt          d|                    dd           d|                    dd           d|                    dd           d|                    dd                      |st          d           |r!|rt          d            nt          d!           dS )#Nr   r6   zAcurator: disabled via config; enable with `curator.enabled: true`r$   dry_runF
backgroundsynchronousconsolidateTz7curator: running DRY-RUN (report only, no mutations)...zcurator: running review pass...u   curator: consolidation is off — running prune-only (deterministic stale/archive). Pass --consolidate or set `curator.consolidate: true` to enable the LLM merge pass.msgr   r
   r   c                $    t          |            d S N)r0   )r   s    r   _on_summaryz_cmd_run.<locals>._on_summary   s    c




r*   )
on_summaryr   r   r   auto_transitionszauto (preview): checkedu9    candidate skill(s) — no transitions applied in dry-runzauto: checked=z stale=marked_stalez
 archived=rJ   z reactivated=reactivateduF   llm pass running in background — check `hermes curator status` laterzzdry-run: no changes applied. Read the report with `hermes curator status` and run `hermes curator run` (no flag) to apply.zdry-run: no changes applied. When the report lands, read it with `hermes curator status` and run `hermes curator run` (no flag) to apply.)r   r   r
   r   )	rO   r7   rl   r0   boolgetattrrr   run_curator_reviewr&   )	rx   r7   dryr   r   r   r   resultautos	            r   _cmd_runr      s    QRRRq
wtY..
/
/CgdL%8899Jwt]E::;;M:~K wt]EBBCCM$$K
 1GHHHH/0007#:#:#<#<H	
 	
 	
    ''	 (  F ::("--D  	8488Iq#9#9 8 8 8   
 <)Q!7!7 < <.!44< < HHZ33< <  $xxq99< <    XVWWW
 
 		[   
 [   1r*   c                Z    ddl m} |                    d           t          d           dS )Nr   r6   Tzcurator: pausedrO   r7   
set_pausedr0   rx   r7   s     r   
_cmd_pauser     s<    t	
1r*   c                Z    ddl m} |                    d           t          d           dS )Nr   r6   Fzcurator: resumedr   r   s     r   _cmd_resumer     s<    u	
1r*   c                    ddl m} |                    | j                  st	          d| j         d           dS |                    | j        d           t	          d| j         d           dS )	Nr   r    
curator: 'u`   ' is bundled or hub-installed — cannot pin (only agent-created skills participate in curation)r$   Tzcurator: pinned 'z ' (will bypass auto-transitions)r+   r!   is_agent_createdskillr0   
set_pinnedrx   r!   s     r   _cmd_pinr   "  s    !!!!!!''
33 B B B B	
 	
 	
 q4:t,,,	
Jdj
J
J
JKKK1r*   c                    ddl m} |                    | j                  st	          d| j         d           dS |                    | j        d           t	          d| j         d           dS )	Nr   r    r   ue   ' is bundled or hub-installed — there's nothing to unpin (curator only tracks agent-created skills)r$   Fzcurator: unpinned ''r   r   s     r   
_cmd_unpinr   /  s    !!!!!!''
33 R R R R	
 	
 	
 q4:u---	
-

-
-
-...1r*   c                   ddl m} |                                }|st          d           dS t          dt	          |           d           t          |d           D ]v}|                    d          rd	nd
}t          |                    d                    }t          d|d         dd|                    dd          dd|dd| d	           wt          d           dS )zList curation-eligible skills that carry no provenance marker.

    The same population `status` summarizes, itemized. Useful before deciding
    what to hand over with `adopt`.
    r   r    u@   curator: no unmanaged skills — every eligible skill is managedzunmanaged skills (z):c                    | d         S NrM    )xs    r   rZ   z%_cmd_list_unmanaged.<locals>.<lambda>J  s
    &	 r*   r[   r#   zcreated_by:nullz	no markerrW   rS   rM   44sz
 activity=r_   4drd   14sz  (rR   za
adopt one with `hermes curator adopt <name>`, or all with `hermes curator adopt --all-unmanaged`)r+   r!   r,   r0   r/   rw   r&   r   )rx   r!   r   r(   whyr   s         r   _cmd_list_unmanagedr   <  sM    "!!!!!''))D PQQQq	
,s4yy
,
,
,---D11222 
 
#$55)=#>#>OKquu/00116!  .229 !)    	
 	
 	
 	
 
 ? @ @ @1r*   c                D   ddl m} t          t          | dd          pg           }t	          t          | dd                    }|r:|rt          d           dS |                                }|st          d	           dS |st          d
           dS t	          t          | dd                    }|r9t          dt          |           d           |D ]}t          d|            dS |rt	          t          | dd                    st          dt          |           d           t          d           	 t          d          	                                
                                }n# t          t          f$ r d}Y nw xY w|dvrt          d           dS d}|D ]3}|                    |          \  }}	t          d|	            |s|dz  }4t          |          dk    r2t          dt          |          |z
   dt          |                      |rdndS )u  Hand unmanaged skills to the curator by explicit user declaration.

    Provenance cannot be inferred from telemetry: a high patch count proves
    the agent MAINTAINS a skill, not that it AUTHORED it (the agent edits
    user-written skills on the user's behalf constantly). So adoption is never
    automatic — the user names what they're handing over, or passes
    ``--all-unmanaged`` to hand over every eligible skill at once.
    r   r    r   Nall_unmanagedFz=curator: pass either skill names or --all-unmanaged, not bothr$   z%curator: no unmanaged skills to adoptz7curator: name a skill to adopt, or pass --all-unmanagedr   zcurator: would adopt z skill(s) (dry run):z  + yeszcurator: adopt z, unmanaged skill(s) into curator management?z9  they become eligible for automatic staleness + archivalz  proceed? [y/N] rB   >   yr   curator: abortedr?   zcurator: adopted /)r+   r!   listr   r   r0   list_unmanaged_skill_namesr/   inputstriplowerEOFErrorKeyboardInterruptadopt_skill)
rx   r!   names	adopt_allr   nreplyfailedokr   s
             r   
_cmd_adoptr   X  s    "!!!!!w--344EWT?E::;;I  	QRRR16688 	9:::1 GHHHq74E2233G Fc%jjFFFGGG 	 	A***q  	gdE599:: 	XE

XXXYYYIJJJ	-..4466<<>>EE+, 	 	 	EEE	$$$%%%1F  ))!,,C#    	aKF
5zzA~~D#e**v"5DDE

DDEEE11As   =3E1 1FFc                x    ddl m} |                    | j                  \  }}t	          d|            |rdndS )Nr   r    r?   r$   )r+   r!   restore_skillr   r0   rx   r!   r   r   s       r   _cmd_restorer     sR    !!!!!!''
33GB	
c

>11r*   c                   ddl m} |                    | j                                      d          r"t          d| j         d| j         d           dS |                    | j                  \  }}t          d|            |rdndS )	zManually archive an agent-created skill. Refuses if pinned.

    The auto-curator archives stale skills on its own schedule; this verb is
    for the user who wants to archive *now* without waiting for a run.
    r   r    rL   r   u7   ' is pinned — unpin first with `hermes curator unpin `r$   r?   )r+   r!   
get_recordr   r&   r0   archive_skillr   s       r   _cmd_archiver     s     "!!!!!dj))--h77 3 3 3%)Z3 3 3	
 	
 	
 q''
33GB	
c

>11r*   recorddictOptional[int]c                   |                      d          p|                      d          }|sdS 	 t          j        t          |                    }n# t          t
          f$ r Y dS w xY w|j         |                    t          j	                  }t          dt          j        t          j	                  |z
  j                  S )u  Days since the skill's last activity (view / use / patch).

    Falls back to ``created_at`` so a skill that was authored but never used
    can still be pruned — otherwise never-touched skills would be immortal.
    Returns None only when both fields are missing or unparseable.
    rW   rX   Nr   r   )r&   r   r   r   r   r   r   r   r   r   maxr   days)r   r   r   s      r   
_idle_daysr     s     
&	'	'	C6::l+C+CB t#CGG,,z"   tt	yZZx|Z,,q8<--28999s   !A A'&A'c                8   ddl m} t          | dd          }|dk     r!t          d| dt          j                   d	S t          t          | d
d                    }t          t          | dd                    }g }|                                D ]l}|                    d          r|                    d          |j	        k    r7t          |          }|||k     rO|                    |d         |f           m|st          d| d           dS |                    d            t          dt          |           d| d           |D ]\  }}t          d|dd| d           |rt          d           dS |s	 t          dt          |           d                                                                          }	n'# t"          t$          f$ r t          d           Y dS w xY w|	d vrt          d!           dS d}
g }|D ]<\  }}|                    |          \  }}|r|
dz  }
%|                    ||f           =t          d"|
 d#t          |                      |r.t          d$           |D ]\  }}t          d| d%|            dS dS )&a  Bulk-archive curator-managed skills idle for >= N days.

    Pinned skills are exempt. Already-archived skills are skipped. Default
    ``--days 90`` matches a conservative read of the curator's own archive
    threshold; adjust with ``--days``. Use ``--dry-run`` to preview.
    r   r    r   Z   r$   z"curator: --days must be >= 1 (got rR   )file   r   Fr   rL   rK   NrM   z6curator: nothing to prune (no unpinned skills idle >= zd)c                    | d          S )Nr$   r   )cs    r   rZ   z_cmd_prune.<locals>.<lambda>  s    1Q4% r*   r[   r?   z skill(s) idle >= zd:rS   r^   z idle rD   u   
(dry run — no changes made)z	
Archive z skill(s)? [y/N] z
curator: aborted>   r   r   r   z
curator: archived r   z	failures:z: )r+   r!   r   r0   sysstderrr   rs   r&   STATE_ARCHIVEDr   ru   sortr/   r   r   r   r   r   r   )rx   r!   r   r   skip_confirm
candidatesr(   idlerM   r   rJ   failures_r   r   s                  r   
_cmd_pruner     sG    "!!!!!4$$Daxx:4:::LLLLq74E2233GeU3344LJ'')) - -55?? 	55>>[777!}}<4$;;1V9d+,,,, OtOOOPPPqOOO(((	
Ac*oo
A
A
A
A
ABBB  , ,
d*4***4***++++ /000q 	Is:IIIJJPPRRXXZZEE+, 	 	 	&'''11	 $$$%%%1HH ) )a++D11C 	)MHHOOT3K((((	
=
=
=C
OO
=
=>>> k! 	& 	&ID#$t$$s$$%%%%q1s   AG	 	 G-,G-c                   ddl m} |                                st          d           dS t	          | dd          pd}|                    |          }|t          d	           dS t          d
|j                    dS )zuTake a manual snapshot of the skills tree. Same mechanism as the
    automatic pre-run snapshot, just user-initiated.r   curator_backupzacurator: backups are disabled via config (`curator.backup.enabled: false`); re-enable to snapshotr$   reasonNmanual)r   uE   curator: snapshot failed — check logs (backup disabled or IO error)z?curator: snapshot created at ~/.hermes/skills/.curator_backups/)rO   r   rl   r0   r   snapshot_skillsrM   )rx   r   r   snaps       r   _cmd_backupr      s     %$$$$$$$&& G	
 	
 	
 qT8T**6hF)))88D|UVVVq	
WDI
W
WXXX1r*   c                   ddl m} t          | dd          r#t          |                                           dS t          | dd          }|                    |          }||                                }|st          d           nWt          d|rd	t          |          z   nd
 d           t          d           t          |                                           dS |                    |          }t          d|j	                    |rt          d|
                    dd                      t          d|
                    dd                      t          d|
                    dd                      |
                    d          pi }t          |t                    rf|
                    d          r(t          d|
                    dd           d           n)|
                    dd          }t          d| d           t          d           t          | dd          sq	 t          d                                                                           }n'# t           t"          f$ r t          d!           Y dS w xY w|d"vrt          d#           dS |                    |j	        $          \  }	}
}|	rt          d%|
            dS t          d&|
            dS )'a7  Restore the skills tree from a snapshot. Defaults to newest.

    ``--list`` prints available snapshots and exits. ``--id <stamp>`` picks
    a specific one. Without ``-y``, prompts for confirmation. A safety
    snapshot of the current tree is always taken first, so rollbacks are
    themselves undoable.
    r   r   r   F	backup_idNzhcurator: no snapshots exist yet. Take one with `hermes curator backup` or wait for the next curator run.zcurator: no snapshot matching zid z
your query.z
Available:r$   zRollback target: z  reason:      r   ?z  created_at:  rX   z  skill files: skill_files	cron_jobs	backed_upz  cron jobs:   
jobs_countz. (will be restored for skill-link fields only)znot capturedz   cron jobs:   not in snapshot (rR   a  
This will replace the current ~/.hermes/skills/ tree (a safety snapshot of the current state is taken first so this is undoable). Cron jobs that still exist will have their skills/skill fields restored from the snapshot; all other cron fields are left alone.r   zProceed? [y/N] z

cancelled>   r   r   	cancelled)r   r?   u   curator: rollback failed — )rO   r   r   r0   summarize_backups_resolve_backuplist_backupsrepr_read_manifestrM   r&   
isinstancer   r   r   r   r   r   rollback)rx   r   r   target_pathr   manifestcronr   ansr   r   r   s               r   _cmd_rollbackr    s}    %$$$$$tVU## n..00111qk400I 00;;K**,, 	6L   
 M.7I54	??**\M M M   ,.2244555q,,[99H	
0k.
0
0111 D=Xs ; ;==>>>A\3 ? ?AABBBB]C @ @BBCCC||K((.BdD!! 	Dxx$$ DEdhh|Q&?&? E E E   
 (N;;BBBBCCC		L   4&& 	)**002288::CC+, 	 	 	-   11	 l""+1((;3C(DDJBQ	 #   q	
/#
/
/0001s   63I* * JJc                    ddl m} |                                }|st          d           dS |D ]}t          |           dS )z#List archived (recoverable) skills.r   r    zcurator: no archived skills)r+   r!   list_archived_skill_namesr0   )rx   r!   r   rM   s       r   _cmd_list_archivedr  \  sb    !!!!!!1133E +,,,q  d1r*   c                   ddl }ddlm} |                                }t	          | dd          rfd|D             }t	          | dd          }|dk    r|                    d	 
           n7|dk    r|                    d d           n|                    d d           t	          | dd          r't          |                    |dd                     dS |st          d           dS dddd}|D ]F}|                    |                    dd          d          dz   ||                    dd          <   Gt          dt          |           d|d          d|d          d|d          d	           t                       t          dd d!dd"d#dd$d%dd&d%dd'd(dd)d%d*           |D ]}t          |                    d+                    }t          d|d         dd,         d!d|                    dd          d#d|                    d-d          d.d|                    d/d          d.d|                    d0d          d1d|                    d2d          d.d|            dS )3u  Show usage telemetry for ALL skills, with provenance.

    Unlike `status` (curator-scoped to curated candidates), this lists
    every skill on disk — bundled built-ins and hub-installed included — so you
    can see how often each is actually used regardless of curation.
    r   Nr    rN   c                F    g | ]}|                     d           k    |S )rN   r%   )r'   r(   prov_filters     r   
<listcomp>z_cmd_usage.<locals>.<listcomp>v  s/    FFFa155#6#6+#E#E#E#E#Er*   r   activityrM   c                    | d         S r   r   rY   s    r   rZ   z_cmd_usage.<locals>.<lambda>z  s
    &	 r*   r[   recentc                0    |                      d          pdS )NrW   rB   r%   rY   s    r   rZ   z_cmd_usage.<locals>.<lambda>}  s    &8 9 9 ?R r*   Trh   c                .    |                      dd          S )Nr_   r   r%   rY   s    r   rZ   z_cmd_usage.<locals>.<lambda>  s    &6 : : r*   jsonFr   )indentensure_asciizcurator: no skills foundrO   rP   hubrO   r$   zskills: z total  (agent=rQ   rP   z  hub=r$  rR   rS   r   r^   origin8susez>4sviewpatchz>5sactz  last_activityrW   (   ra   z>4drb   rc   z>5dr_   )r   r+   r!   usage_reportr   r   r0   dumpsr&   r/   r   )	rx   _jsonr!   r   sort_keycountsr(   r   r  s	           @r   
_cmd_usager1  h  s    !!!!!!##%%D$d33K GFFFF4FFFtVZ00H6		))	****	X				??	NNNN		::D	IIItVU## ekk$quk==>>>q ()))q Qq11F _ _/5zz!%%g:V:VXY/Z/Z]^/^quu\7++,,		W3t99 	W 	W/	W 	W-3I->	W 	WFLUm	W 	W 	W   
GGG		PW+ 	P 	PH+ 	P 	PO	P 	PO	P 	P&-O	P 	P5:O	P 	P 	P    

 

quu/001163B3'  uu\7++2 uu[!$$,  uu\1%%-  uu]A&&.	 
 uu%q))1   	
 	
 	
 	
 1r*   parentargparse.ArgumentParserc                t
                           fd                                d          }|                    dd          }|                     t                     |                    dd	          }|                    d
ddd           |                    dddd           |                    ddd           |                     t
                     |                    dd          }|                    ddddd           |                    dddd            |                    d!d"dd#           |                    d$d%dd&           |                     t                     |                    d'd(          }|                     t                     |                    d)d*          }|                     t                     |                    d+d,          }|                    d-d.           |                     t                     |                    d/d0          }|                    d-d.           |                     t                     |                    d1d2                               t                     |                    d3d4          }	|	                    d-d5d67           |	                    d8dd9           |	                    d!dd:           |	                    d;dd<           |	                     t                     |                    d=d>          }
|
                    d-d.           |
                     t                     |                    d?d@                               t                     |                    dAdB          }|                    d-d.           |                     t                     |                    dCdD          }|                    dEt           dFdGH           |                    dId;ddJ           |                    d!d"ddK           |                     t"                     |                    dLdM          }|                    dNddOP           |                     t$                     |                    dQdR          }|                    dSddT           |                    dUdVddWX           |                    dId;ddY           |                     t&                     dS )ZzAttach `curator` subcommands to *parent*.

    main.py calls this with the ArgumentParser returned by
    ``subparsers.add_parser("curator", ...)``.
    c                <                                     dfd         S )Nr   r$   )
print_help)ar2  s    r   rZ   zregister_cli.<locals>.<lambda>  s    (9(9(;(;Q'?'B r*   )funccurator_command)deststatusz#Show curator status and skill stats)helpusagezJShow usage telemetry for ALL skills (built-in, hub, agent) with provenancez--sort)r  r  rM   r  zlSort order: activity (most-used first, default), recent (most-recently-active first), or name (alphabetical))choicesdefaultr<  z--provenancer#  NzOnly show skills of this originz--json
store_truez/Emit the full report as JSON instead of a table)actionr<  runzTrigger a curator review nowz--syncz--synchronousr   z@Wait for the LLM review pass to finish (default for manual runs))r:  rA  r<  z--backgroundr   zGStart the LLM review pass in a background thread and return immediatelyz	--dry-runr   uk   Report only — no state changes, no archives, no consolidation (use this to preview what curator would do)z--consolidater   zForce the LLM umbrella-building consolidation pass on for this run, overriding the config default (off). Without this flag the run is prune-only unless `curator.consolidate: true` is set.pausezPause the curator until resumedresumezResume a paused curatorpinz4Pin a skill so the curator never auto-transitions itr   z
Skill nameunpinzUnpin a skillzlist-unmanagedz7List curation-eligible skills with no provenance markeradoptzGHand unmanaged skills to the curator (provenance is a user declaration)*z8Skill name(s) to adopt. Omit when using --all-unmanaged.)nargsr<  z--all-unmanagedzAAdopt every curation-eligible skill that has no provenance markerz3List what would be adopted without writing anythingz--yesz0Skip the confirmation prompt for --all-unmanagedrestorezRestore an archived skillzlist-archivedzList archived skillsarchivezBManually archive a skill (move to .archive/, excluded from prompt)prunezCBulk-archive curator-managed skills idle for >= N days (default 90)z--daysr   z5Archive skills idle for at least N days (default: 90))typer?  r<  z-yzSkip the confirmation promptz,Show what would be archived without doing itbackupzoTake a manual tar.gz snapshot of ~/.hermes/skills/ (curator also does this automatically before every real run)z--reasonz;Free-text label stored in manifest.json (default: 'manual'))r?  r<  r  zJRestore ~/.hermes/skills/ from a curator snapshot (defaults to the newest)z--listz3List available snapshots and exit without restoringz--idr   z6Snapshot id to restore (see `--list`); default: newest)r:  r?  r<  zSkip confirmation prompt)set_defaultsadd_subparsers
add_parserr   add_argumentr1  r   r   r   r   r   r   r   r   r  r   r   r   r   r  )r2  subsp_statusp_usagep_runp_pausep_resumep_pinp_unpinp_adopt	p_restore	p_archivep_prunep_backup
p_rollbacks   `              r   register_clira    sh    BBBBCCC  &7 88Dx.STTH{+++ooY   G 8*D    
  ;T.     >     j)))OOE(FOGGE	/lO     
\,V     
)L;    
 
mLL     
H%%%oog,MoNNGj)))x.GHHH{+++OOE(^O__E	w\222	H%%%oogOo<<G|444j)))OOF    l+l,,,ooV   G sG     ,P     LB     ?     j)))	0KLLI7666---OOO*@OAA	-	.	.	.Q    I 7666---ooR   G sBD     gl+     )L;     j)))L   H
 DJ     {+++( !  J
 B     [$E     gl'     /////r*   c                    t          j        d          }t          |           |                    |           }t	          |dd          }||                                 dS t           ||          pd          S )z>Standalone entry (also usable by hermes_cli.main fallthrough).zhermes curator)progr8  Nr   )argparseArgumentParserra  
parse_argsr   r6  r   )argvparserrx   fns       r   cli_mainrj  E  s~    $*:;;;FT""D	vt	$	$B	zqrr$xx}1r*   __main__)r   r	   r
   r   )r
   r   )r
   r   )r   r   r
   r   )r2  r3  r
   r   r   )!__doc__
__future__r   rd  r   r   r   pathlibr   typingr   r   r4   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r1  ra  rj  __name__exitr   r*   r   <module>rr     sP    # " " " " "  



 ' ' ' ' ' ' ' '            # # # #(   :N N N Nb< < < <~      
 
 
 

 
 
 
   85 5 5 5p      $: : : :&A A A AH   &F F F FR	 	 	 	9 9 9 9@Z0 Z0 Z0 Z0z	 	 	 	 	 zCHXXZZ r*   