+
    jHàj‚!  ã                  ó
  € R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t	 R R lt
R!R R	 lltR
 R ltR!R R lltRRRRRRRRRRRRRR/R R lltRRRRRRRRRRRR/R R lltRR/R R lltRR/R R llt^ R IHt R# )"a€  Board metadata (``board.json``) and board lifecycle management for the Kanban DB:
read/write of per-board display metadata, board creation/discovery/archival, and the
``board.json``-as-identity-marker rule.

Split out of ``hermes_cli.kanban_db``; origin-resident helpers are reached
late-bound via ``_kb`` (import-cycle breaking) so monkeypatching
``kanban_db.<name>`` keeps working.
)ÚannotationsN)ÚAny)ÚOptional)ÚPathc               ó    € V ^8„  d   QhRRRR/# )é   Údr   ÚreturnÚbool© )Úformats   "Ú@/home/ubuntu/.hermes/hermes-agent/hermes_cli/kanban_db_boards.pyÚ__annotate__r      s   € ÷ 'ñ '˜ð ' ñ 'ó    c                ó0   € V R ,          P                  4       # )ú
board.json)Úexists)r   s   &r   Ú_dir_holds_boardr      s   € ð �Õ×$Ñ$Ó&Ð&r   c               ó    € V ^8„  d   QhRRRR/# )r   ÚboardúOptional[str]r	   r   r   )r   s   "r   r   r      s   € ÷ Eñ E˜}ð E¸ñ Er   c                ód   € \         P                  ! \         P                  ! V 4      4      R,          # )uR   ``board.json`` path â€” display metadata only; the directory slug is the identity.r   )Ú_kbÚ	board_dirÚ_slug_or_default©r   s   &r   Úboard_metadata_pathr      s!   € ä�=Š=œ×-Ò-¨eÓ4Ó5¸ÕDÐDr   c               ó    € V ^8„  d   QhRRRR/# )r   ÚslugÚstrr	   r   )r   s   "r   r   r   !   s   € ÷ eñ e cð e¨cñ er   c                ó„   € RP                  R V P                  RR4      P                  R4       4       4      ;'       g    T # )z%``atm10-server`` -> ``Atm10 Server``.Ú c              3  óT   "  € T F  q'       g   K  VP                  4       x € K   	  R # 5i©N)Ú
capitalize)Ú.0Úparts   & r   Ú	<genexpr>Ú._default_board_display_name.<locals>.<genexpr>#   s"   é € Ð\Ñ2S¨$ÓW[Ô%�D—O‘O×%Ð%Ó2Sùs   ‚	(�(Ú_Ú-)ÚjoinÚreplaceÚsplit)r   s   &r   Ú_default_board_display_namer.   !   s6   € à�8‰8Ñ\°$·,±,¸sÀCÓ2H×2NÑ2NÈsÔ2SÓ\Ó\×dÐdÐ`dÐdr   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r	   Údictr   )r   s   "r   r   r   &   s   € ÷ ñ ˜}ð ¸ñ r   c                óØ  € \         P                  ! V 4      pRVR\        V4      RRRRRRRRR	RR
RRR/	p \        V4      pVP	                  4       '       dR   \
        P                  ! VP                  RR7      4      p\        V\        4      '       d   WR&   VP                  V4       \        \         P                  ! T4      4      TR&   T#   \        \
        P                  3 d     LAi ; i)u‹   ``board.json`` merged over defaults, plus ``slug`` and ``db_path``. Never
raises â€” a missing/malformed file yields the synthesized entry.r   ÚnameÚdescriptionÚ ÚiconÚcolorÚdefault_workdirNÚ
project_idÚ
created_atÚarchivedFz	utf-8-sig©ÚencodingÚdb_path)r   r   r.   r   r   ÚjsonÚloadsÚ	read_textÚ
isinstancer0   ÚupdateÚOSErrorÚJSONDecodeErrorr   Úkanban_db_path)r   r   ÚmetaÚpÚraws   &    r   Úread_board_metadatarI   &   sâ   € ô ×Ò Ó&€Dà�ØÔ+¨DÓ1Ø�rØ�Ø�Ø˜4à�dØ�dØ�Eð€Dð
Ü Ó%ˆØ�8‰8�:Š:Ü—*’*˜QŸ[™[°+˜[Ó>Ó?ˆCÜ˜#œt×$Ò$ð #�F‘Ø—‘˜CÔ ô œ#×,Ò,¨TÓ2Ó3€Dˆ�OØ€Køô ”T×)Ñ)Ð*ô Ùðús   µA2C ÃC)Ã(C)r2   r3   r5   r6   r:   r7   r8   c               ó<   € V ^8„  d   QhRRRRRRRRRRRRR	RR
RRR/	# )r   r   r   r2   r3   r5   r6   r:   zOptional[bool]r7   r8   r	   r0   r   )r   s   "r   r   r   E   s[   € ÷ ñ ØðØ#0ðØFSðà
ðà'4ðàGUðð #ðð 8Eðð 
ñ	r   c               ó0  € \         P                  ! 4        \         P                  ! V 4      p\        V4      p	V	P	                  RR4       Ve0   \        V4      P                  4       ;'       g    \        V4      V	R&   RV3RV3RV33 F  w  r«Vf   K  \        V4      Wš&   K  	  Ve   \        V4      V	R&   RV3R	V33 F"  w  r«Vf   K  V'       d   \        V4      MRWš&   K$  	  V	P                  R
4      '       g"   \        \        P                  ! 4       4      V	R
&   \        V4      pVP                  P                  RRR7       VP                  \         P"                  ! V	^RR7      R,           RR7       \        \         P$                  ! V4      4      V	R&   V	# )zÏCreate/update ``board.json``; unmentioned fields are preserved, ``created_at``
set on first write. ``project_id``/``default_workdir``: ``None`` = unchanged,
"" = clear (``project_id`` is not validated here).r=   Nr2   r3   r5   r6   r:   r7   r8   r9   T©ÚparentsÚexist_okF)ÚindentÚensure_asciiÚ
zutf-8r;   )r   Ú$_assert_not_delegated_child_mutationr   rI   Úpopr   Ústripr.   r
   ÚgetÚintÚtimer   ÚparentÚmkdirÚ
write_textr>   ÚdumpsrE   )r   r2   r3   r5   r6   r:   r7   r8   r   rF   ÚkeyÚvalueÚpaths   &$$$$$$$     r   Úwrite_board_metadatar_   E   si  € ô ×,Ò,Ô.Ü×Ò Ó&€DÜ˜tÓ$€Dà‡H�HˆY˜ÔØÒÜ˜4“y—‘Ó(×MÐMÔ,GÈÓ,MˆˆV‰Ø% {Ð3°f¸d°^ÀgÈuÐEUÓV‰
ˆØÔÜ˜E›
ˆD‹Iñ Wð ÒÜ ›>ˆˆZÑØ)¨?Ð;¸lÈJÐ=WÓX‰
ˆØÔß&+œ˜Eœ
°ˆD‹Iñ Yð �8‰8�L×!Ò!Ü ¤§¢£Ó-ˆˆ\ÑÜ˜tÓ$€DØ‡K�K×Ñ˜d¨TÐÔ2Ø‡O�OÜ�
Š
�4 °Ô6¸Õ=Èð ô ô œ#×,Ò,¨TÓ2Ó3€Dˆ�OØ€Kr   c               ó8   € V ^8„  d   QhRRRRRRRRRRRRR	RR
R/# )r   r   r   r2   r   r3   r5   r6   r7   r8   r	   r0   r   )r   s   "r   r   r   g   sP   € ÷ ñ Ø
ðØ%ðØ;Hðà
ðà'4ðàN[ðð ðð 
ñ	r   c               ó€   € \         P                  ! V 4      p\        WqW#VWVRR7      p\         P                  ! VR7       V# )z_Create board dir + DB + metadata (``mkdir -p`` semantics: existing board returns its metadata).F©r2   r3   r5   r6   r7   r8   r:   r   )r   Ú_require_slugr_   Úinit_db)	r   r2   r3   r5   r6   r7   r8   ÚnormedrF   s	   &$$$$$$  r   Úcreate_boardrf   g   s?   € ô ×Ò˜tÓ$€Fô  Ø {ÀUØ'Èô€Dô
 ‡K‚K�fÕØ€Kr   Úinclude_archivedTc               ó    € V ^8„  d   QhRRRR/# )r   rg   r
   r	   z
list[dict]r   )r   s   "r   r   r   z   s   € ÷ ñ  Tð °Zñ r   c                ól  € \        \        P                  4      .p\        P                  0p\        P                  ! 4       pVP	                  4       '       dÌ   \        VP                  4       R R7       F«  pVP	                  4       '       g   K   \        P                  ! VP                  4      pT'       d   YR9   g   \        T4      '       g   K]  \        T4      pTP                  R4      '       d   T '       g   K‰  TP                  T4       TP                  T4       K­  	  V#   \         d     K¿  i ; i)z�Metadata for every board: ``default`` first (always present), then
``boards/<slug>/`` dirs holding a ``kanban.db`` or ``board.json``, sorted.c                ó6   € V P                   P                  4       # r#   )r2   Úlower)rG   s   &r   Ú<lambda>Úlist_boards.<locals>.<lambda>�   s   € ¸!¿&¹&¿,¹,¼.r   )r\   r:   )rI   r   ÚDEFAULT_BOARDÚboards_rootÚis_dirÚsortedÚiterdirÚ_normalize_board_slugr2   Ú
ValueErrorr   rU   ÚappendÚadd)rg   ÚentriesÚseenÚrootÚchildre   rF   s   $      r   Úlist_boardsr{   z   så   € ô #¤3×#4Ñ#4Ó5Ð6€GÜ×ÑÐ€DÜ�?Š?Ó€DØ‡{�{‡}‚}Ü˜DŸL™L›NÑ0H×IˆEØ—<‘<—>’>ÙðÜ×2Ò2°5·:±:Ó>�÷ ˜Vœ^Ô3CÀE×3JÒ3JÙÜ& vÓ.ˆDØ�x‰x˜
×#Ò#×,<ÙØ�N‰N˜4Ô Ø�H‰H�VÖñ Jð €Nøô ô Úðús   Â D$Ä$D3Ä2D3Úarchivec               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r|   r
   r	   r0   r   )r   s   "r   r   r   ’   s&   € ÷ 1Añ 1A�sð 1A¨ð 1A¸ñ 1Ar   c               ó‚  € \         P                  ! 4        \         P                  ! V 4      pV\         P                  8X  d   \	        R4      h\         P
                  ! V4      pVP                  4       '       g   \	        RV: R24      h\         P                  ! 4       V8X  d   \         P                  ! 4        \         P                  P                  \        VR,          P                  4       4      4       V'       Ed(   \        V4      p\         P                  ! 4       R,          pVP                  RRR7       \!        \"        P"                  ! 4       4      pWR RV 2,          p^pVP                  4       '       d   WR RV RV 2,          pV^,          pK1  VP%                  V4       \'        VVP)                  R	4      VP)                  R
4      VP)                  R4      VP)                  R4      VP)                  R4      VP)                  R4      RR7       RVRRR\        V4      /# ^ RIp	V	P-                  V4       RVRRRR/# )zŒArchive (to ``boards/_archived/<slug>-<ts>/``) or delete a board;
``default`` cannot be removed. Returns ``{"slug", "action", "new_path"}``.z%the 'default' board cannot be removedzboard z does not existz	kanban.dbÚ	_archivedTrL   r*   r2   r3   r5   r6   r7   r8   rb   r   Úactionr:   Únew_pathNÚdeletedr4   )r   rR   rc   rn   rt   r   r   Úget_current_boardÚclear_current_boardÚ_INITIALIZED_PATHSÚdiscardr   ÚresolverI   ro   rY   rV   rW   Úrenamer_   rU   ÚshutilÚrmtree)
r   r|   re   r   Ú
prior_metaÚarchive_rootÚtsÚtargetÚsuffixr‰   s
   &$        r   Úremove_boardr�   ’   sØ  € ô ×,Ò,Ô.Ü×Ò˜tÓ$€FØ”×"Ñ"Ô"ÜÐ@ÓAÐAÜ�Š�fÓ€AØ�8‰8�:Š:Ü˜6 &¡¨?Ð;Ó<Ð<ô ×ÒÓ &Ô(Ü×ÒÔ!ô ×Ñ×"Ñ"¤3¨¨K­×'@Ñ'@Ó'BÓ#CÔDç€wô )¨Ó0ˆ
Ü—’Ó(¨;Õ6ˆØ×Ñ 4°$ÐÔ7Ü”—’“ÓˆØ (¨!¨B¨4Ð 0Õ0ˆØˆØ�m‰m�oŠoØ! h¨a°¨t°1°V°HÐ$=Õ=ˆFØ�a�KŠFØ	�‰�Ôô
 	ØØ—‘ Ó'Ø"Ÿ™ }Ó5Ø—‘ Ó'Ø—.‘. Ó)Ø&ŸN™NÐ+<Ó=Ø!—~‘~ lÓ3Øõ		
ð ˜ ¨*°jÄ#ÀfÃ+ÐNÐNÛØ
‡M�M�!ÔØ�F˜H i°¸RÐ@Ð@r   )Ú	kanban_dbr#   )Ú__doc__Ú
__future__r   r>   rW   Útypingr   r   Úpathlibr   r   r   r.   rI   r_   rf   r{   r�   Ú
hermes_clir‘   r   r   r   r   Ú<module>r—      sÏ   ðñõ #ã Û Ý Ý Ý õ'÷Eõ
e÷
ð>Ø37ðØVZðàðà7;ðàX\ðð &*ðð HL÷ðDØ(,ðØKOðàðà7;ðà^bðð !%÷ð&¨D÷ ð01A¨t÷ 1A÷l (r   