+
    „WÝjàW  ã                  ób   € R t ^ RIHt ^ RIHt ^ RIHt ^ RIHtH	t	 R t
R tR R ltR	 R
 ltR# )z&``hermes sessions`` subcommand parser.)Úannotations)ÚPath)ÚCallable)Úadd_json_flagÚadd_yes_flagc               ó2   € V P                   ! VR RRV/VB  R# )ÚactionÚ
store_trueÚhelpN)Úadd_argument)Úparserr
   ÚnamesÚkws   &$*,ÚSC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\subcommands\sessions.pyÚ_flagr      s   € Ø
×Ò˜ÐE |ÐE¸$ÐEÀ"ÔEó    c                ó    € ^ RI Hp V! V 3/ VB # )zP``hermes sessions`` handler; sessions_cmd imports only when the subcommand runs.)Úcmd_sessions)Úhermes_cli.sessions_cmdr   )ÚargsÚkwargsr   s   &, r   Úcmd_sessions_lazyr      s   € å4á˜Ñ' Ñ'Ð'r   c               ó   € V ^8„  d   QhRR/# )é   ÚreturnÚNone© )Úformats   "r   Ú__annotate__r      s   € ÷ ,ñ ,°Dñ ,r   c                ó–   € V P                  R RR7      pVP                  RRR7       VP                  RRRR7       ^ R	IHp V! V 4       R
# )ÚrenamezSet or change a session's title©r
   Ú
session_idzSession ID to renameÚtitleÚ+zNew title for the session©Únargsr
   )Úadd_discard_parserN)Ú
add_parserr   Úhermes_cli.sessions_discardr'   )Úsessions_subparsersÚsessions_renamer'   s   &  r   Ú_add_rename_and_discardr,      sS   € Ø)×4Ñ4ØÐ8ð 5ó :€Oà× Ñ  Ð4JÐ ÔKØ× Ñ  °Ð:UÐ ÔVÝ>ÙÐ*Ö+r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r   r   )r   s   "r   r   r      s   € ÷ r:ñ r:°xð r:ÀDñ r:r   c               ó”  aa€ V P                  RRRR7      pVP                  RR7      pVP                  RRR	7      pVP                  R
RR	7       VP                  R\        ^RR7       VP                  RRRR7       R\	        RRR7      3R\	        RRR7      3R\	        RRR7      3R
\	        RR	7      3R\	        RR	7      3R\	        RR	7      3R \	        R!R	7      3R"\	        \        R#R$7      3R%\	        \        R&R$7      3R'\	        R(R	7      3R)\	        R*R	7      3R+\	        R,R	7      3R-\	        R.R	7      3R/\	        R0R	7      3R1\	        R2R	7      3R3\	        \        R4R$7      3R5\	        \        R6R$7      3R7\	        \
        R8R$7      3R9\	        \
        R:R$7      3R;\	        \        R<R$7      3R=\	        \        R>R$7      3R?\	        R@RARB7      33oV3RC lpVP                  RDRER	7      pVP                  RFRGRHRIRJ7       VP                  RK. RïORLRMRN7       \        VRORPR	7       \        VRQRRR	7       \        VRSRTR	7       VP                  RURV.RWRX7       VP                  RYRZR	7       V! VR[4       \        VR\R]R	7       VP                  R^R_R`.R_RaRN7       \        VRbRcR	7       \        VRdReR	7       VP                  RfRgR	7      pVP                  RhRiR	7       \        VRj4       VP                  RkRlR	7      pV! VRm4       \        VRnRoR	7       \        VRpRqR	7       \        VRrRsR	7       \        VRdRtR	7       VP                  RuRvR	7      p	V! V	Rw4       \        V	RxRyR	7       VP                  RzR{R	7      p
\        V
RdR|R	7       VP                  R}R~RR7      p\        VR?R€R�R‚7       \        VRƒR€R„R‚7       VP                  R…R†R‡R7      p\        VRˆR€R‰R‚7       \        VRŠR‹R€RŒR‚7       \        VRdR|R	7       VP                  R�RŽR�R7      p\        VR�R‘R	7       \        VRƒR’R	7       VP                  R“R”R•R7      pVP                  R–RðR—RX7       VP                  R˜R™RšR›Rœ7       \        VRdR�R	7       VP                  RžRŸR R7      p\        VR¡R¢R	7       VP                  R£\
        R™R¤R7       VP                  R¥R¦R§R7      p\        VR¡R¨R	7       \        VR©RªR	7       \        VRŠR‹R€R«R‚7       VP                  R¬RñR­R®RN7       VP                  R¯R°R±R7      p\        VR¡R²R	7       \        VR©R³R	7       VP                  RhRGR™R´Rµ7       VP                  R¶R·R¸R7      pVP                  R
\        R¹RºR»7       VP                  R¼\        R½R$7       \        VR¾R¿R	7       VP                  RÀ\        RÁR$7       VP                  RÂ\        RÃRÄR7       \        VRÅRÆR	7       VP                  RÇ\        RÈR$7       VP                  RÉRÊR	7       \        V4       VP                  RËRÌRÍR7      pVP                  RÎRÏRÐRÑ7       VP                  RÒRÓR	7      pVP                  RÎRÏRÔRÑ7       VP                  RÕRÖR	7      p\        VR×4       VP                  RØRÙRÚR7      p\        VR¡RÛR	7       VP                  R\        ^ÈRÜR7       VP                  RÝRÞR	7      pVP                  R
RR	7       VP                  R\        RßRàR7       VP                  RáRâRãR7      pVP                  RäRåRæRç.RèRé7       VP                  RêRGRëRÑ7       RìV/V3Rí llpVP                  VRî7       R™# )òz5Attach the ``sessions`` subcommand to ``subparsers``.Úsessionsz<Manage session history (list, rename, export, prune, delete)z(View and manage the SQLite session store)r
   ÚdescriptionÚsessions_action)ÚdestÚlistzList recent sessionsr!   z--sourcez/Filter by source (cli, telegram, discord, etc.)z--limitzMax sessions to show)ÚtypeÚdefaultr
   z--workspaceÚNEEDLEzgOnly sessions in one workspace: a git repo root or project dir (matched by path substring or basename).©Úmetavarr
   z--newer-thanÚAGEzZOnly match sessions active within the last AGE (e.g. '5h', '2d') or after an ISO timestampz--beforeÚTIMEzjOnly match sessions started before TIME (duration ago like '5h', or ISO timestamp like '2026-07-05 14:30')z--afterzTOnly match sessions started at/after TIME (duration ago like '5h', or ISO timestamp)z$Only match sessions from this sourcez--titlez7Only match sessions whose title contains this substringz--end-reasonz(Only match sessions with this end reasonz--cwdz>Only match sessions whose working directory is under this pathz--min-messagesz&Only match sessions with >= N messages)r4   r
   z--max-messagesz&Only match sessions with <= N messagesz--modelz_Only match sessions whose model name contains this substring (e.g. 'sonnet', 'gpt-5', 'hermes')z
--providerzSOnly match sessions billed through this provider (e.g. openrouter, anthropic, nous)z--userz%Only match sessions from this user IDz	--chat-idz-Only match sessions from this chat/channel IDz--chat-typez8Only match sessions with this chat type (e.g. dm, group)z--branchz<Only match sessions whose git branch contains this substringz--min-tokensz9Only match sessions with >= N total tokens (input+output)z--max-tokensz9Only match sessions with <= N total tokens (input+output)z
--min-costz:Only match sessions costing >= N USD (actual or estimated)z
--max-costz:Only match sessions costing <= N USD (actual or estimated)z--min-tool-callsz(Only match sessions with >= N tool callsz--max-tool-callsz(Only match sessions with <= N tool callsz	--dry-runr	   z0List matching sessions without changing anything)r   r
   c                ó„   <€ V P                  R RVR7       S F  w  r#V P                   ! V3/ VB  K  	  \        V R4       R# )z--older-thanr9   r7   úSkip confirmationN)r   r   )ÚpÚdefault_older_helpÚflagr   Ú_filter_argss   &&  €r   Ú_add_session_filter_argsÚ7build_sessions_parser.<locals>._add_session_filter_argsO   s>   ø€ Ø	�‰�~¨uÐ;MˆÔNÛ$‰HˆDØ�NŠN˜4Ñ& 2Ô&ñ %ä�QÐ+Ö,r   Úexportz*Export sessions to JSONL, Markdown, or QMDÚoutputÚ?ÚOUTPUTa  Where to write. jsonl/html/trace: a file path, or a directory (existing, or ending in /) to write a default-named file into; - for stdout (jsonl/trace only; jsonl requires OUTPUT). md/qmd: a directory, one file per session (default: <hermes home>/session-exports))r&   r8   r
   z--formatÚjsonlzgExport format (default: jsonl). 'trace' emits Claude Code JSONL for the Hugging Face Agent Trace Viewer)Úchoicesr5   r
   z--uploadzgtrace only: upload to your Hugging Face traces dataset instead of writing a local file (needs HF_TOKEN)z--publiczFtrace --upload only: create/update a public dataset instead of privatez--no-redactzJtrace only: skip the forced secret redaction; only use after manual reviewz--onlyzuser-promptszhExport only a filtered view (user-prompts: one prompt record per line for jsonl, headed sections for md))rH   r
   z--session-idz%Session ID or unique prefix to exportzØOnly export sessions older than AGE (duration like '5h'/'2d', bare number of days, or an ISO timestamp). Filtered exports include pinned and archived sessions, so they back up everything a matching prune could deletez--redactzDRedact secrets (API keys, tokens, credentials) from exported contentz	--lineageÚsingleÚlogicalz6md/qmd only: export one row or its compression lineagez--delete-after-verifiedzTmd/qmd only: after verified single-session export, delete that session (needs --yes)z--forcez.md/qmd only: overwrite an existing export fileÚdeletezDelete a specific sessionr"   zSession ID to deleter<   ÚprunezCDelete old sessions (filterable by time window, source, title, ...)u¼   Delete sessions older than AGE â€” days if bare number, or a duration like '5h'/'2d'/'1w', or an ISO timestamp (bare prune with no filters defaults to 90 days; any filter matches all ages)z--include-archivedz3Also delete archived sessions (excluded by default)z--include-pinneduH   Also delete pinned sessions (excluded by default â€” pin is a keep flag)z--never-activeuö   Instead of ended sessions, delete keyed gateway rows that were opened and never used (no messages, tokens, tool calls or title) and are older than AGE (default 30 days). Ordinary prune can never reach these â€” it only ever selects ended sessionsu  With no gateway running: run even while another Hermes process (Desktop, dashboard, cron) holds state.db â€” rewriting the store under a live writer can leave every agent refusing turns until all writers are stopped. With the gateway running, prune always goes through itÚarchiveuB   Bulk-archive (soft-hide) sessions matching filters â€” no deletionzeOnly archive sessions older than AGE (duration like '5h'/'2d', bare number of days, or ISO timestamp)z--include-openz5Also archive never-ended sessions, e.g. Desktop chatsÚoptimizezAReclaim disk space: merge FTS5 segments + VACUUM (no data change)uÇ   Run even while another Hermes process (gateway, Desktop, dashboard, cron) holds state.db â€” rewriting the store under a live writer can leave every agent refusing turns until all writers are stoppedzclean-markerszTPermanently clear stale tool-call marker content left by sessions from before #78148uß  Before the #78148 fix, a local tool-call template could persist a bare bracketed marker (e.g. "[memory]") as an assistant turn's content instead of real text. This is already repaired in memory on every session load, so running this is optional â€” it rewrites the affected rows once, in place, so long-lived sessions stop re-scanning/re-repairing the same rows on every resume. Only the content column is touched; tool_calls and every other column on the row are left untouched.Fz-Report the affected row count without writing)r5   r
   z--no-backupzKSkip the timestamped state.db backup taken before writing (not recommended)zoptimize-storagezOMigrate the search index to the compact v23 layout (reclaims disk on large DBs)uÏ  Rebuild the full-text search index in the compact v23 external-content layout. On large databases this reclaims a large fraction of state.db (the old layout stored duplicate copies of every message and indexed tool output). Runs foreground with a progress bar, throttles so a running gateway stays responsive, and VACUUMs at the end. Safe to interrupt and re-run â€” it resumes where it left off. No conversation data is changed; only the search index is rebuilt.z--no-vacuumzgSkip the final VACUUM (index is rebuilt but freed pages aren't returned to the OS until a later VACUUM)z--yesz-yz'Skip the disk-space confirmation promptÚrepairz>Repair a malformed state.db schema so hidden sessions reappearzóRecover a state.db whose schema is malformed (e.g. 'table messages_fts already exists'), which makes Desktop/Dashboard show no sessions. A backup is made first; sessions and messages are preserved and the FTS search index is rebuilt if needed.z--check-onlyz@Only report whether the database opens cleanly; do not modify itz2Skip the timestamped backup copy (not recommended)zset-journal-modezSConvert state.db between journal_mode=WAL and DELETE offline (every holder stopped)aˆ  Switch the on-disk journal mode of the session store. Hermes never live-downgrades a WAL database at startup (other processes may hold uncheckpointed commits), so `database.journal_mode: delete` cannot self-apply to an existing WAL store. Run this with the gateway, dashboard and every CLI stopped: it refuses while any process holds the file, switches the mode, and verifies the file header.ÚmodezTarget journal modez--dbNÚPATHzVConvert another Hermes SQLite store (e.g. kanban.db) instead of the profile's state.db)r5   r8   r
   z§Proceed when the holder scan itself fails (cannot prove the store is quiet) after stopping every Hermes process yourself; a process the scan does find is still refusedzrepair-routingz:Re-stamp gateway sessions that lost their routing identityuÆ  Find gateway conversations stranded in session rows whose routing identity (session_key/chat_id/origin) was never written â€” the damage a corrupt state.db write path leaves behind (#82616). Such a row is invisible to restart recovery, so the chat resumes an older session instead. Re-stamps each orphan from the keyed predecessor it continues, and only when that predecessor is unambiguous. Reports without touching the database unless --apply is given.z--applyz,Perform the adoptions (default: report only)z--max-gap-secondsz‚Window between a keyed predecessor's last activity and an orphan's start for them to count as the same conversation (default: 900)zrepair-profilesz@Settle session/routing state that landed under the wrong profilea2  Scan every profile's state.db (and the gateway's voice-mode / sessions.json files) for durable state crossed between profiles: rows whose profile_name disagrees with their session key, rows sitting in another profile's store, parent links crossing namespaces, routing rows outside the default store or for a profile that no longer exists, and Telegram topic / voice-mode entries missing their bot's profile. Reports without touching anything unless --apply is given; --apply refuses while a gateway is running, snapshots every store first, and is safe to re-run.z*Perform the repairs (default: report only)z--jsonzMachine-readable reportzSkip the confirmation promptz--legacy-mainÚreportuA  What to do with agent:main rows found inside a named profile's store: 'rekey' them to that profile (a standalone gateway's own history, e.g. after multiplexing was switched on), 'move' them to the default store (a default chat that leaked in), or 'report' (default) â€” the rows themselves cannot tell the two cases apartzrepair-promptszIReport or clear stored system prompts degraded to a reduced-toolset builda²  Repair session rows degraded by the pre-#122822 gateway hygiene/compress bug. Automatic repair requires positive tools[] evidence; rows without a readable pin are reported as unverifiable and never changed by a scan. Clearing a prompt makes the next turn rebuild and persist healthy bytes. Reports without touching anything unless --apply is given; a session_id is an explicit destructive override and can clear even a healthy prompt.z1Clear the verified prompts (default: report only)zPMachine-readable output; with --apply, apply without an interactive confirmationzODestructive override: clear this session even when its stored prompt is healthy)r&   r5   r
   Úrecoverz=Rebuild canonical session data into a separate clean databasea5  Offline, non-destructive recovery for a damaged state.db. The source database and its WAL/SHM/rollback-journal sidecars are copied before SQLite opens anything. Canonical rows are rebuilt into a new output database; derived search indexes are recreated and the active database is never replaced automatically.Tz6Source state.db or preserved backup to inspect/recover)r4   Úrequiredr
   z--outputz;New recovery database path (required unless --inspect-only)z--inspect-onlyzIOnly report canonical table readability; do not create an output databasez
--work-dirzNExisting directory for the disposable source copy (defaults beside the output)z--chunk-sizeiè  z1Rows committed per recovery batch (default: 1000)z--allow-partialznBest-effort salvage across damaged row ranges; the output remains separate and every skipped range is recordedz--reportz5JSON report path (defaults to <output>.recovery.json)ÚstatszShow session store statisticsÚpinu>   Pin session(s) â€” durable keep flag, exempt from auto-archiveuý   Set the durable 'keep' flag on one or more sessions. Pinned sessions are exempt from the sessions.auto_archive stale sweep and always appear in listings. The same flag drives the Desktop sidebar's Pinned section â€” pin from either surface, both see it.Úsession_idsr$   z)Session ID(s) or unique prefix(es) to pinr%   Úunpinz2Remove the pin (durable keep flag) from session(s)z+Session ID(s) or unique prefix(es) to unpinÚpinnedzList pinned sessionsz9Emit machine-readable JSON (for backup/restore scripting)zretitle-skillsz@Re-title sessions whose auto-title came from a /skill's own textu  Sessions opened with a /skill were auto-titled from the expanded message, which embeds the whole skill body â€” so the title describes the SKILL, not the request. This regenerates those titles from what the user actually typed. Lists what it would change unless --apply is passed.z'Write the new titles (default: dry run)z*Maximum sessions to examine (default: 200)ÚbrowseuB   Interactive session picker â€” browse, search, and resume sessionsiô  z#Max sessions to load (default: 500)Úimportz5Import a Claude Code or Codex CLI session into HermeszáPull a conversation started in Claude Code (~/.claude/projects) or Codex CLI (~/.codex/sessions) into the Hermes session store so it can be resumed with 'hermes --resume <id>'. The foreign files are only read, never modified.z--fromÚfrom_sourceÚclaudeÚcodexz5Which tool to import from (default: pick across both))r2   rH   r
   Úpathz8Path to a specific session JSONL file (skips the picker)Úsessions_parserc               ó   <€ S! WR 7      # ))r`   r   )Ú_argsr`   r   s   &$€r   Ú_dispatch_sessionsÚ1build_sessions_parser.<locals>._dispatch_sessionsN  s   ø€ Ù˜EÔCÐCr   )Úfunc)rG   ÚmdÚqmdÚhtmlÚtrace)rK   Úwal)rR   ÚrekeyÚmove)r(   Úadd_subparsersr   ÚintÚdictÚfloatr   r   r   r,   r   Úset_defaults)Ú
subparsersr   r`   r*   Úsessions_listrA   Úsessions_exportÚsessions_deleteÚsessions_pruneÚsessions_archiveÚsessions_optimizeÚsessions_clean_markersÚsessions_optimize_storageÚsessions_repairÚsessions_set_journal_modeÚsessions_repair_routingÚsessions_repair_profilesÚsessions_repair_promptsÚsessions_recoverÚsessions_pinÚsessions_unpinÚsessions_pinnedÚsessions_retitleÚsessions_browseÚsessions_importrc   r@   s   &d                        @r   Úbuild_sessions_parserr‡      s¿	  ù€ à ×+Ñ+ØÐWØ>ð ,ó @€Oð *×8Ñ8Ð>OÐ8ÓPÐà'×2Ñ2°6Ð@VÐ2ÓW€MØ×Ñ˜zÐ0aÐÔbØ×Ñ˜y¬s¸BÐE[ÐÔ\Ø×Ñ˜}°hð3ð ô 4ð
 
œ eð 3:ô ;ð 	<à	”T &ð 0Qô Rð 	Sà	”D ð /9ô :ð 	;à	”TÐEÔFÐGØ	”DÐWÔXÐYØ	œÐ#MÔNÐOØ	”$Ð\Ô]Ð^Ø	œ4¤SÐ/WÔXÐYØ	œ4¤SÐ/WÔXÐYØ	”Dð 1ô 2ð 	3à	”tð "1ô 2ð 	3à	”4ÐDÔEÐFØ	”dÐ OÔPÐQØ	œÐ"\Ô]Ð^Ø	”TÐ]Ô^Ð_Ø	œ¤3ØLôNð 	Oà	œ¤3ØLôNð 	Oà	”t¤ØMôOð 	Pà	”t¤ØMôOð 	Pà	œT¤sÐ1[Ô\Ð]Ø	œT¤sÐ1[Ô\Ð]Ø	”d ,ØCôEð 	Fð? G€LõD-ð *×4Ñ4ØÐCð 5ó E€Oà× Ñ  °¸hðað !ô bð × Ñ ØÒCÈWð6ð !ô 7ô 
ˆ/˜:ð7õ8ô 
ˆ/˜:ØUõWä	ˆ/˜=ØZõ]à× Ñ  °NÐ3Cð:ð !ô ;ð × Ñ  Ð6]Ð Ô^ÙØð MôNô 
ˆ/˜:ØSõUà× Ñ  °xÀÐ6KÐU]ØEð !ô Gä	ˆ/Ð4Øcõeä	ˆ/˜9Ð+[Õ\à)×4Ñ4°XÐD_Ð4Ó`€OØ× Ñ  Ð4JÐ ÔKÜ�Ð"5Ô6à(×3Ñ3ØÐ[ð 4ó ]€NáØð <ô=ô 
ˆ.Ð.ØBõDä	ˆ.Ð,ØWõYä	ˆ.Ð*ðHõIô
 
ˆ.˜)ð _õ`ð +×5Ñ5ØÐ\ð 6ó ^ÐáÐ-ð 0Fô Gä	Ð
Ð,Ð3jÕkà+×6Ñ6ØÐ\ð 7ó ^Ðä	Ð
˜Yð WõXð 1×;Ñ;¸OØcð*ð <ó 	+Ðô 
Ð
  +°uØ<õ>ä	Ð
  -¸ØZõ\ð !4× >Ñ >Ð?QØ^ð9ð !?ó 	!:Ðô 
Ð
# ]¸EØvõxä	Ð
# W¨d¸EØ6õ8ä	Ð
# Yð WõXð *×4Ñ4ØÐWðGð 5ó H€Oô 
ˆ/˜>ØOõQä	ˆ/˜=Ð/cÕdà 3× >Ñ >ØÐ!vðIð !?ó !JÐð ×*Ñ*¨6Ð;LÐShÐ*ÔiØ×*Ñ*¨6¸4ÈØeð +ô gä	Ð
# YðUõVð 2×<Ñ<ØÐ[ð0ð =ó 	1Ðô 
Ð
! 9Ð3aÕbØ×(Ñ(Ð)<Ä5ÐRVðð )ô ð
  3×=Ñ=ØÐ bðð  >ó 	 Ðô 
Ð
" IÐ4`ÕaÜ	Ð
" HÐ3LÕMÜ	Ð
" G¨T¸5ÐGeÕfØ×)Ñ)ØÐ!<ÀhðYð *ô Zð 2×<Ñ<ØÐjðnð =ó oÐô 
Ð
! 9Ð3fÕgÜ	Ð
! 8Ø_õaà×(Ñ(¨¸SÈ$Ø^ð )ô `ð +×5Ñ5ØÐWðGð 6ó HÐð ×!Ñ! *´4À$ØEð "ô Gà×!Ñ!ØœÐ$að "ô cä	Ð
Ð,ØXõZà×!Ñ! ,´TØ]ð "ô _à×!Ñ! .´sÀDØ@ð "ô Bä	Ð
Ð-ð;õ<ð ×!Ñ!ØœÐ$[ð "ô ]ð ×"Ñ" 7Ð1PÐ"ÔQÜÐ/Ô0à&×1Ñ1ØÐTðQð 2ó R€Lð ×ÑØ˜SÐ'Rð ô Tð )×3Ñ3ØÐJð 4ó L€Nà×ÑØ˜SÐ'Tð  ô Vð *×4Ñ4°XÐDZÐ4Ó[€OÜ�/Ð#^Ô_à*×5Ñ5ØÐað/ð 6ó 0Ðô 
Ð
˜IÐ,UÕVØ×!Ñ!Øœ SÐ/[ð "ô ]ð *×4Ñ4ØÐ[ð 5ó ]€Oà× Ñ  Ð2cÐ ÔdØ× Ñ Øœ SÐ/Tð !ô Vð *×4Ñ4ØÐNð3ð 5ó 4€Oð × Ñ  °ÈÐRYÐGZØDð !ô Fà× Ñ Ø�cÐ Zð !ô \ðD°_÷ Dð × Ñ Ð&8Ð Ö9r   N)Ú__doc__Ú
__future__r   Úpathlibr   Útypingr   Úhermes_cli.subcommands._sharedr   r   r   r   r,   r‡   r   r   r   Ú<module>r�      s*   ðÙ ,å "å Ý ç FòFò(õ,÷r:r   