
    PL
j81                   n   U 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
mZmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZ 	 ddlZn# e$ r dZY nw xY wdZd	Zd
ZdZdZh dZh dZdZ i ddddddddddddddddddddd d!d"dd#d$d%dd&d'd(dd)d*d+dd,d-d.dd/d0d1dd2d3d4dd5d6d7dd8d9d:dd;d<d=dd>d?d@ddAdBdCdi dDdEdFddGdHdIddJdKdLddMdNdOddPdQdRddSdTdUddVdWdXddYdZd[dd\d]d^dd_d`daddbdcddddedfdgddhdidjddkdldmddndodpddqdrdsddtdudvddwdxdydiZ!dze"d{<   h d| e#e!          d}Z$d~e"d<   dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,e G d d                      Z-ddZ.	 	 	 dddZ/ddZ0ddZ1ddZ2ddZ3dddZ4ddZ5ddZ6ddZ7ddZ8ddZ9 ej:        dej;                  df ej:        dej;                  df ej:        dej;                  dfgZ<de"d<   ddZ=ddZ>ddZ?ddZ@ddZAddZBdZCdZD ej:        dæ           ej:        dĦ           ej:        dŦ           ej:        dƦ           ej:        dǦ          fZEddɄZFdd˄ZGdd̄ZHdd̈́ZIddЄZJddӄZK G dԄ dզ          ZLddׄZMdd؄ZNeOdk    r eP eN                      dS )zOpenClaw -> Hermes migration helper.

This script migrates the parts of an OpenClaw user footprint that map cleanly
into Hermes Agent, archives selected unmapped docs for manual review, and
reports exactly what was skipped and why.
    )annotationsN)asdict	dataclassfield)datetime)Path)AnyDictListOptionalSequenceTupleu   
§
i  i_  zopenclaw-importsz+Skills migrated from an OpenClaw workspace.>   skiprename	overwrite>   OPENAI_API_KEYANTHROPIC_API_KEYELEVENLABS_API_KEYOPENROUTER_API_KEYTELEGRAM_BOT_TOKENVOICE_TOOLS_OPENAI_KEYz	AGENTS.mdsoulSOUL.mdz-Import the OpenClaw persona file into Hermes.)labeldescriptionworkspace-agentszWorkspace instructionszFCopy the OpenClaw workspace instructions file into a chosen workspace.memory	MEMORY.mdz5Import long-term memory entries into Hermes memories.user-profileUSER.mdz1Import user profile entries into Hermes memories.messaging-settingszMessaging settingszUImport Hermes-compatible messaging settings such as allowlists and working directory.secret-settingszAllowlisted secretszPImport the small allowlist of Hermes-compatible secrets when explicitly enabled.command-allowlistzCommand allowlistzDMerge OpenClaw exec approval patterns into Hermes command_allowlist.skillszUser skillsz=Copy OpenClaw skills into ~/.hermes/skills/openclaw-imports/.
tts-assetsz
TTS assetsz9Copy compatible workspace TTS assets into ~/.hermes/tts/.discord-settingszDiscord settingsz8Import Discord bot token and allowlist into Hermes .env.slack-settingszSlack settingsz;Import Slack bot/app tokens and allowlist into Hermes .env.whatsapp-settingszWhatsApp settingsz+Import WhatsApp allowlist into Hermes .env.signal-settingszSignal settingsz@Import Signal account, HTTP URL, and allowlist into Hermes .env.provider-keyszProvider API keyszMImport model provider API keys into Hermes .env (requires --migrate-secrets).model-configzDefault modelz9Import the default model setting into Hermes config.yaml.
tts-configzTTS configurationz?Import TTS provider and voice settings into Hermes config.yaml.shared-skillszShared skillszACopy shared OpenClaw skills from ~/.openclaw/skills/ into Hermes.daily-memoryzDaily memory fileszHMerge daily memory entries from workspace/memory/ into Hermes MEMORY.md.archivezArchive unmapped docsz=Archive compatible-but-unmapped docs for later manual review.mcp-serverszMCP serverszDImport MCP server definitions from OpenClaw into Hermes config.yaml.plugins-configzPlugins configurationzQArchive OpenClaw plugin configuration and installed extensions for manual review.	cron-jobszCron / scheduled taskszMImport cron job definitions. Archive for manual recreation via 'hermes cron'.hooks-configzHooks and webhookszRArchive OpenClaw hook configuration (internal hooks, webhooks, Gmail integration).agent-configz$Agent defaults and multi-agent setupzcImport agent defaults (compaction, context, thinking) into Hermes config. Archive multi-agent list.gateway-configzGateway configurationzTImport gateway port and auth settings. Archive full gateway config for manual setup.session-configzSession configurationzLImport session reset policies (daily/idle) into Hermes session_reset config.full-providerszFull model provider definitionszWImport custom model providers (baseUrl, apiType, headers) into Hermes custom_providers.deep-channelszDeep channel configurationzdImport extended channel settings (Matrix, Mattermost, IRC, group configs). Archive complex settings.browser-configzBrowser configurationz;Import browser automation settings into Hermes config.yaml.tools-configzTools configurationzQImport tool settings (exec timeout, sandbox, web search) into Hermes config.yaml.approvals-configzApproval ruleszIImport approval mode and rules into Hermes config.yaml approvals section.memory-backendzMemory backend configurationz[Archive OpenClaw memory backend settings (QMD, vector search, citations) for manual review.skills-configzSkills registry configurationzKArchive per-skill enabled/config/env settings from OpenClaw skills.entries.ui-identityzUI and identity settingszGArchive OpenClaw UI theme, assistant identity, and display preferences.logging-configzLogging and diagnosticsz7Archive OpenClaw logging and diagnostics configuration.zDict[str, Dict[str, str]]MIGRATION_OPTION_METADATA>!   r   r   r$   r/   r2   r%   r,   r0   r>   r4   r.   r3   r+   r:   r   r8   r-   r=   r9   r7   r5   r?   r<   r1   r6   r'   r)   r;   r&   r   r#   r(   r!   )z	user-datafullzDict[str, set[str]]MIGRATION_PRESETSmigratedarchivedskippedconflicterrorplanned'Target exists and overwrite is disabledz!blocked by earlier apply conflictc                  v    e Zd ZU ded<   ded<   ded<   ded<   dZded<    ee	          Zd
ed<   dZded<   dS )
ItemResultstrkindOptional[str]sourcedestinationstatus reason)default_factoryDict[str, Any]detailsFbool	sensitiveN)	__name__
__module____qualname____annotations__rS   r   dictrV   rX        k/home/kuhnn/.hermes/hermes-agent/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.pyrK   rK      s|         IIIKKKF#eD999G9999Ir_   rK   valuesOptional[Sequence[str]]return	List[str]c                    g }| pdD ]d}t          |                              d          D ]?}|                                                                }|r|                    |           @e|S )Nr^   ,)rL   splitstriplowerappend)ra   parsedvalueparts       r`   parse_selection_valuesrn      s}    F2 $ $JJ$$S)) 	$ 	$D::<<%%''D $d###	$ Mr_   includeexcludepresetrN   set[str]c                8   t          |           }t          |          }t          t                    }|pd                                                                }|rF|t
          vr=t          d|z   dz   d                    t          t
                              z             t          |          dhz
  |z
  t          |          dhz
  |z
  z  }|rXt          dd                    t          |                    z   dz   d                    t          |                    z             |rt          t
          |                   }n%|rd|v rt          |          }nt          |          }d|v r|	                                 |t          |          dhz
  z  }|S )NrR   zUnknown migration preset: z. Valid presets: , allzUnknown migration option(s): z. Valid options: )
rn   setr@   rh   ri   rB   
ValueErrorjoinsortedclear)	ro   rp   rq   include_valuesexclude_valuesvalidpreset_nameunknownselecteds	            r`   resolve_selected_optionsr   
  s   
 ,G44N+G44N)**E<R&&((..00K 
{*;;;(!" ii011223
 
 	
 >""eW,u4^9L9LPUw9VY^9^_G 
+iiw(()!" iiu&&'
 
 	
  '(566 'u66u::~&&^$$w./HOr_   pathr   rL   c                   t          j                    }|                     d          5 t          fdd          D ]}|                    |           	 d d d            n# 1 swxY w Y   |                                S )Nrbc                 .                          d          S )Ni   )read)fhs   r`   <lambda>zsha256_file.<locals>.<lambda>5  s    "''%.. r_   r_   )hashlibsha256openiterupdate	hexdigest)r   hchunkr   s      @r`   sha256_filer   2  s    A	4 B0000#66 	 	EHHUOOOO	               ;;==s   ,A##A'*A'c                .    |                      d          S Nutf-8encoding)	read_textr   s    r`   r   r   :  s    >>7>+++r_   textc                R    t          j        dd|                                           S )Nz\s+ )resubrh   )r   s    r`   normalize_textr   >  s    6&#tzz||,,,r_   Nonec                >    | j                             dd           d S )NTparentsexist_ok)parentmkdirr   s    r`   ensure_parentr   B  s#    KdT22222r_   rl   r	   envOptional[Dict[str, str]]c                   t          | t                    r~t          j        d|                                           }|r?|r=|                    |                    d          d                                          pdS |                                 pdS t          | t                    r`|                     dd          }|                     dd          }|dk    r.|r,|r*|                    |d                                          pdS dS )zResolve an OpenClaw SecretInput value to a plain string.

    SecretInput can be:
    - A plain string: "sk-..."
    - An env template: "${OPENROUTER_API_KEY}"
    - A SecretRef object: {"source": "env", "id": "OPENROUTER_API_KEY"}
    z^\$\{(\w+)\}$   rR   NrO   idr   )
isinstancerL   r   matchrh   getgroupr]   )rl   r   mrO   ref_ids        r`   resolve_secret_inputr   F  s     % %H%u{{}}55 	; 	;771771::r**0022:d:{{}}$$% 78R((4$$U??v?#?7762&&,,..6$64r_   rU   c                    t           |                                 si S t          j        |                     d                    }t	          |t
                    r|ni S r   )yamlexists	safe_loadr   r   r]   r   datas     r`   load_yaml_filer   ]  sN    |4;;==|	>$..'.::;;DdD))144r1r_   r   c                    t           t          d          t          |            |                     t          j        |dd          d           d S )Nz/PyYAML is required to update Hermes config.yamlF)	sort_keysallow_unicoder   r   )r   RuntimeErrorr   
write_text	safe_dumpr   s     r`   dump_yaml_filer   d  s`    |LMMM$OOtuEBBB      r_   Dict[str, str]c                p   |                                  si S i }|                     d                                          D ]t}|                                }|r|                    d          sd|vr2|                    d          \  }}}|                                ||                                <   u|S )Nr   r   #=)r   r   
splitlinesrh   
startswith	partition)r   r   raw_linelinekey_rl   s          r`   parse_env_filer   n  s    ;;== 	DNNGN44??AA * *~~ 	ts++ 	s$s++Q!KKMMSYY[[Kr_   c                    t          |            d |                                D             }|                     d                    |          |rdndz   d           d S )Nc                "    g | ]\  }}| d | S )r   r^   ).0r   rl   s      r`   
<listcomp>z!save_env_file.<locals>.<listcomp>}  s*    ===*#ue===r_   
rR   r   r   )r   itemsr   rx   )r   r   liness      r`   save_env_filer   {  sa    $==

===EOODIIe$$(=2>OQQQQQr_   backup_rootOptional[Path]c                d   |                                  sd S |                                 r.t          | j                  dk    rt	          | j        dd           n| }||z  }t          |           |                                 rt          j        | |d           nt          j	        | |           |S )Nr   Tdirs_exist_ok)
r   is_absolutelenpartsr   r   is_dirshutilcopytreecopy2)r   r   reldests       r`   backup_existingr     s    ;;== t#'#3#3#5#5
W#dj//A:M:M$
122

SWCD${{}} !d$77777T4   Kr_   z\bOpen[\s-]?Claw\bHermesz\bClawdBot\bz\bMoltBot\bzList[Tuple[re.Pattern, str]]_REBRAND_PATTERNSreplacementc                     d fd}|S )ug  Return a re.sub replacement fn that lowercases the result when the
    matched text was all-lowercase.

    Keeps ``OpenClaw`` → ``Hermes`` but maps ``openclaw`` → ``hermes`` so a
    filesystem path like ``~/.openclaw/config.yaml`` rewrites to
    ``~/.hermes/config.yaml`` (the real Hermes home) instead of the broken
    ``~/.Hermes/config.yaml``.
    r   're.Match[str]'rc   rL   c                    |                      d          }|r(|                                r                                S S )Nr   )r   islowerri   )r   matchedr   s     r`   _subz*_case_preserving_replacement.<locals>._sub  sC    ++a.. 	'w(( 	'$$&&&r_   )r   r   rc   rL   r^   )r   r   s   ` r`   _case_preserving_replacementr     s(         
 Kr_   c                f    t           D ](\  }}|                    t          |          |           } )| S )zReplace OpenClaw / ClawdBot / MoltBot brand names with Hermes.

    Preserves case so filesystem-path matches (lowercase) don't become
    capitalized directory names that don't exist.
    )r   r   r   )r   patternr   s      r`   rebrand_textr     s=     !2 L L{{7DDdKKKr_   c                    |                                  sg S t          |           }|                                sg S t          |v r$d |                    t                    D             S t          |          S )Nc                ^    g | ]*}|                                 |                                 +S r^   rh   )r   es     r`   r   z1parse_existing_memory_entries.<locals>.<listcomp>  s-    KKKaK		KKKr_   )r   r   rh   ENTRY_DELIMITERrg   extract_markdown_entries)r   raws     r`   parse_existing_memory_entriesr     sp    ;;== 	
D//C99;; 	#KK399_#=#=KKKK#C(((r_   c                   g g g dfddfd}d}|                                  D ]}|                                }|                                }|                    d          r| } |             N|rQt	          j        d|          }|r |             t          |                    d	                    }|                    d
                                          }t                    |k    r'                                 t                    |k    '	                    |           t	          j        d|          }	|	r[ |             |	                    d	                                          }
             }	                    |r| d|
 n|
           ~|s |             |                    d          r!|
                    d          r |             	                    |            |             g }t                      }D ]T}t          |          }|r||v r|                    |           |	                    |                                           U|S )Nrc   rL   c                 F    d D             } d                     |           S )Nc                V    g | ]&}|t          j        d |t           j                  $|'S )z0\b(MEMORY|USER|SOUL|AGENTS|TOOLS|IDENTITY)\.md\b)r   searchI)r   r   s     r`   r   zDextract_markdown_entries.<locals>.context_prefix.<locals>.<listcomp>  s6    }}}!1}RY?rtuwyw{5|5|}A}}}r_   z > )rx   )filteredheadingss    r`   context_prefixz0extract_markdown_entries.<locals>.context_prefix  s(    }}x}}}zz(###r_   r   c                     sd S d                     d D                                                       } g | sd S              }|r                    | d|             d S                     |            d S )Nr   c              3  >   K   | ]}|                                 V  d S Nr   )r   r   s     r`   	<genexpr>zDextract_markdown_entries.<locals>.flush_paragraph.<locals>.<genexpr>  s*      GGtdjjllGGGGGGr_   : )rx   rh   rj   )
text_blockprefixr   entriesparagraph_liness     r`   flush_paragraphz1extract_markdown_entries.<locals>.flush_paragraph  s     	FXXGGGGGGGMMOO
 	F!! 	'NNf44
4455555NN:&&&&&r_   Fz```z^(#{1,6})\s+(.*\S)\s*$r      z^\s*(?:[-*]|\d+\.)\s+(.*\S)\s*$r  |)rc   rL   rc   r   )r   rstriprh   r   r   r   r   r   poprj   endswithrv   r   add)r   r
  in_code_blockr   r   strippedheading_matchlevel
text_valuebullet_matchcontentr  dedupedseenentry
normalizedr   r  r   r	  s                   @@@@r`   r   r     s   GH!#O$ $ $ $ $ $' ' ' ' ' ' ' ' MOO%% %) %)  ::<<u%% 	 --MO 	!:HEE 	O++A..//E&,,Q//5577Jh--5(( h--5((OOJ'''x BDII 	O"((++1133G#^%%FNNVHf11111III 	Os## 	(9(9#(>(> 	Ox((((OG55D & &#E**
 	Z4//u{{}}%%%%Nr_   existingSequence[str]incominglimitint+Tuple[List[str], Dict[str, int], List[str]]c                \   t          |           }d | D             }t          |           dddd}g }|r't          t                              |                    nd}|D ]}t	          |          }	|	s|	|v r|dxx         dz  cc<   )|st          |          n&|t          t                    z   t          |          z   }
|
|k    r&|dxx         dz  cc<   |                    |           |                    |           |                    |	           |
}|dxx         dz  cc<   |||fS )Nc                T    h | ]%}|                                 t          |          &S r^   )rh   r   r   r  s     r`   	<setcomp>z merge_entries.<locals>.<setcomp>  s-    IIIe5;;==IN5!!IIIr_   r   )r  added
duplicates
overflowedr(  r   r)  r'  )listr   r   rx   r   rj   r  )r  r  r   mergedr  statsr)  current_lenr  r  candidate_lens              r`   merge_entriesr/    sq   
 (^^FIIxIIIDX!STUUEJ7=D#o**6223331K  #E**
 	,1$*0eE


kCDXDX6X[^_d[e[e6e5  ,1$e$$$e#g!5*$$r_   rootc                    	 t          |                     |                    S # t          $ r t          |           cY S w xY wr  )rL   relative_torw   )r   r0  s     r`   relative_labelr3  2  sP    4##D))***   4yys   !$ A A z
[redacted])accesstokenapikeyauthorizationbearertokenclientsecretcookie
credentialpassword
privatekeyrefreshtokensecretz\bBearer\s+[A-Za-z0-9._~+/=\-]+z\bsk-[A-Za-z0-9_\-]{8,}\bz\bgh[pousr]_[A-Za-z0-9_]{16,}\bz \bxox[abprs]-[A-Za-z0-9\-]{8,}\bz\bAIza[0-9A-Za-z_\-]{12,}\br   c                R    t          j        dd|                                           S )Nz	[^a-z0-9]rR   )r   r   ri   )r   s    r`   _normalize_secret_keyr@  ]  s    6,CIIKK000r_   rW   c                    t          |           dk    s                    d          rdS dv rdS t          fdt          D                       S )NtokenT>   authr6  c              3      K   | ]}|v V  	d S r  r^   )r   markerr  s     r`   r  z!_is_secret_key.<locals>.<genexpr>g  s(      FFv#FFFFFFr_   )r@  r  any_SECRET_KEY_MARKERS)r   r  s    @r`   _is_secret_keyrH  a  sh    &s++JW
 3 3G < <t...tFFFF2EFFFFFFr_   c                P    t           D ]}|                    t          |           } | S r  )_SECRET_VALUE_PATTERNSr   REDACTED_MIGRATION_VALUE)rl   r   s     r`   _redact_stringrL  j  s,    ) = =4e<<Lr_   c                :    t          | t                                S )az  Return a deep copy of ``value`` with secret-looking content replaced.

    Applied to every report written to disk.  Keys whose normalized form
    matches a credential marker get their value replaced wholesale.  Strings
    anywhere in the tree are scanned for common token patterns (sk-..., ghp_...,
    xox*-, AIza*, Bearer ...) and those substrings are replaced inline.
    )_redact_internalrv   )rl   s    r`   redact_migration_valuerO  p  s     E355)))r_   r  rv   c                   t          | t                    rt          |           S t          | t          t          f          rfd| D             S t          | t
                    rt          |           }|v rt          S                     |           i }| 	                                D ]G\  }}t          |t                    rt          |          rt          ||<   4t          |          ||<   H|S | S )Nc                0    g | ]}t          |          S r^   )rN  )r   r  r  s     r`   r   z$_redact_internal.<locals>.<listcomp>  s$    AAA% --AAAr_   )r   rL   rL  r*  tupler]   r   rK  r  r   rH  rN  )rl   r  obj_idoutr   r  s    `    r`   rN  rN  {  s    % %e$$$%$'' BAAAA5AAAA% ET>>++ ++-- 	9 	9JC#s## 9s(;(; 93C+E488C
Lr_   
output_dirreportc           	        |                      dd           t          |          }| dz                      t          j        |dd          dz   d	           i }|d
         D ]1}|                    |d         g                               |           2ddd|d          d|d          d|d          dd|d          ddddg	}|d                                         D ] \  }}|                    d| d|            !|                    d          pg }|r4|	                    g d           |D ]}	|                    d|	            |	                    g d           |                    dg           |                    dg           z   |                    d g           z   }
|
s|                    d!           nG|
D ]D}|d"         pd#}|d$         pd#}|d%         p|d         }|                    d&| d'| d(|            E|                    d)          pg }|r4|	                    g d*           |D ]}|                    d|            | d+z                      d
                    |          dz   d	           d S ),NTr   zreport.jsonr  Findentensure_asciir   r   r   r   rQ   z%# OpenClaw -> Hermes Migration ReportrR   z- Timestamp: 	timestampz- Mode: modez- Source: `source_root`z- Target: `target_rootz
## Summarysummaryz- r  warnings)rR   z## WarningsrR   )rR   z"## What Was Not Fully Brought OverrR   rE   rF   rG   zA- Nothing. All discovered items were either migrated or archived.rO   z(n/a)rP   rS   z- `z` -> `z`: 
next_steps)rR   z## Next StepsrR   z
summary.md)r   rO  r   jsondumps
setdefaultrj   r   r   extendrx   )rU  rV  redactedgroupeditemr   r   rl   ra  warningrE   rO   r   rS   rb  steps                   r`   write_reportrl    s0   TD111 &f--H-++
8AE:::TA ,   
 02G! < <4>2..55d;;;; 	0
/-//%8F#%%0h}-0000h}-000


E y)//11 * *
U(#(((())))||J''-2H ),,,--- 	) 	)GLLg((((	LL???@@@kk)R((7;;z2+F+FFU\^`IaIaaG @XYYYY 	@ 	@D(^.wF&1'D(^5tH~FLL>v>>T>>f>>????l++1rJ &.../// 	& 	&DLLd%%%%,**499U+;+;d+BW*UUUUUr_   c                  N   e Zd Z	 	 	 drdsdZdtdZ eh d          Z	 dudvd Zdwd"Zdxd#Z	dyd%Z
dzd&Zdyd'Zd{d+Zd{d,Zd|d.Zd}d1Z	 d~dd4Zdd5Zdd6Zdd9Zdd:Zdyd;Zdd=Zdd?Zd~ddBZd~ddCZddDZddGZeddJ            Zd~ddKZd~ddLZ d~ddMZ!d~ddNZ"d~ddOZ#ddPZ$d~ddQZ%d~ddRZ&ddSZ'ddVZ(ddWZ)ddXZ*	 d~dd[Z+dd\Z,dd]Z-d~dd^Z.d~dd_Z/d~dd`Z0d~ddaZ1d~ddbZ2d~ddcZ3d~dddZ4d~ddeZ5d~ddfZ6d~ddgZ7d~ddhZ8d~ddiZ9d~ddjZ:d~ddkZ;d~ddlZ<d~ddmZ=ddpZ>ddqZ?dS )MigratorNrR   r   r]  r   r_  executerW   workspace_targetr   r   migrate_secretsrU  selected_optionsOptional[set[str]]r~   rL   skill_conflict_modec                n   || _         || _        || _        || _        || _        || _        t          |pt                                                    | _	        |	
                                                                | _        |

                                                                pd| _        t          j                                        d          | _        |p|r|dz  dz  | j        z  nd | _        | j        r
| j        dz  nd | _        | j        r
| j        dz  nd | _        | j        r
| j        dz  nd | _        g | _        d| _        d | _        |                                 }|                    d	i                               d
i                               d          pd
                                }|rzt7          |                                                                          }|                                r3	 |                    | j                    n# t@          $ r
 || _        Y nw xY wtC          | j        dz            }tE          |                    d          tF                    r|                    di           ni }tI          |                    dtJ                              | _&        tI          |                    dtN                              | _(        | j        tR          vrBtA          d| j        z   dz   d*                    tW          tR                              z             d S )Nr   z%Y%m%dT%H%M%S	migrationopenclawr/   backupsoverflowFagentsdefaults	workspacerR   config.yamlr   memory_char_limituser_char_limitzUnknown skill conflict mode: z. Valid modes: rt   ),r]  r_  ro  rp  r   rq  rv   r@   keysrr  rh   ri   r~   rt  r   nowstrftimer[  rU  archive_dir
backup_diroverflow_dirr   _config_apply_blocked_custom_workspaceload_openclaw_configr   r   
expanduserresolver   r2  rw   r   r   r]   r!  DEFAULT_MEMORY_CHAR_LIMITmemory_limitDEFAULT_USER_CHAR_LIMIT
user_limitSKILL_CONFLICT_MODESrx   ry   )selfr]  r_  ro  rp  r   rq  rU  rr  r~   rt  	oc_configwsws_pathconfigmem_cfgs                   r`   __init__zMigrator.__init__  s    '& 0". #$4$X8Q8V8V8X8X Y Y&,,..4466#6#<#<#>#>#D#D#F#F#P& !00AA$ 
GNXK+%
2T^CCTX 	 ;?/S4?Y66t9=R$/I55d<@OUDOj88QU')
 ,1" 26--//	mmHb))--j"==AA+NNTRT[[]] 		52hh))++3355G ~~ 55''(89999! 5 5 5-4D***5   0= @AA.8H9M9Mt.T.T\&**Xr***Z\,?AZ [ [\\gkk*;=TUUVV#+???/*+#$ ))F#78899:   @?s   H H10H1	option_idrc   c                    || j         v S r  )rr  )r  r  s     r`   is_selectedzMigrator.is_selected  s    D111r_   >   r2   r,   r0   r>   r4   r3   r+   r:   r8   r=   r9   r7   r5   r?   r<   r1   r6   r;   r#   rM   rO   rP   rQ   rS   rV   r	   r   c                   t          |                    dd                    }| j                            t	          ||rt          |          nd |rt          |          nd ||||                     |t          t          hv rD|Dt          |          }|                    d          s|                    d          rd| _	        d S d S d S d S )NrX   F)rM   rO   rP   rQ   rS   rV   rX   r}  z
config.ymlT)
rW   r  r   rj   rK   rL   STATUS_CONFLICTSTATUS_ERRORr  r  )	r  rM   rO   rP   rQ   rS   rV   rX   dest_strs	            r`   recordzMigrator.record*  s     [%8899	
&,6s6{{{$0;EC,,,#  
	
 
	
 
	
 o|4449P;''H  // 283D3D\3R3R 2-1*** 549P9P2 2r_   relative_pathsc                n   |D ]}| j         |z  }|                                r|c S |                    d          rD|t          d          d          }dD ])}| j         |z  |z  }|                                r|c c S *}|                    d          r<|t          d          d          }| j         dz  |z  }|                                r|c S | j        r\|D ]Y}dD ]T}|                    |          r=|t          |          d          }| j        |z  }|                                r|c c S  nUZd S )N
workspace/)workspace-mainzworkspace-assistantworkspace.default/r  )r  r  )r]  r   r   r   r  )r  r  r   	candidatesuffixvariantaltr  s           r`   source_candidatezMigrator.source_candidateG  s   ! 	 	C(3.I!! !     ~~l++ 
S..//0H # #G*W4v=Czz|| #"




##  455 S!566778&)99FB::<< JJJ ! 
	% 	 	 C  F~~f-- !$S[[\\!2"4v=::<< '#&JJJJJ tr_   c                &   | j         dk    s|                                s|S d}|                    |j        |z             }d}|                                r:|                    |j         | d|           }|dz  }|                                :|S )Nr   z	-importedr  -r   )rt  r   	with_namename)r  rP   r  r  counters        r`   resolve_skill_destinationz"Migrator.resolve_skill_destinationl  s    #x//{7I7I7K7K/))+*:V*CDD	   	#--1A.U6.U.UG.U.UVVIqLG    	 r_   rU   c                8     j                                         s2                     d j         d dd                                            S                                                       d j                                        d j                                        d fd                                d fd	                                d
 fd                                d fd                                d fd                                d fd                                d fd                                d fd                                d fd                                d fd                                d fd                                d j                                        d j	                                        d j
                                        d j                                        d  fd!                                d" j                                        d# fd$                                d% fd&                                d' fd(                                d) fd*                                d+ fd,                                d- fd.                                d/ fd0                                d1 fd2                                d3 fd4                                d5 fd6                                d7 fd8                                d9 fd:                                d; fd<                                d= fd>                                d? fd@                                dA fdB                                                                              S )CNrO   rG   z!OpenClaw directory does not existr   r   r   c                 ~                                               dd           j        dz  dz   j        d          S )Nzworkspace/MEMORY.mdzworkspace.default/MEMORY.mdmemoriesr   r   rM   )migrate_memoryr  r_  r  r  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  sJ    D''%%&;=Z[[ :-;!	 (   r_   r   c                 ~                                               dd           j        dz  dz   j        d          S )Nzworkspace/USER.mdzworkspace.default/USER.mdr  r    r   r  )r  r  r_  r  r  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  sI    D''%%&9;VWW :-	9#	 (   r_   r!   c                 .                                    S r  )migrate_messaging_settingsr  r  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  s    4;Z;Z[a;b;b r_   r"   c                 .                                    S r  )handle_secret_settingsr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  s    8S8STZ8[8[ r_   r&   c                 .                                    S r  )migrate_discord_settingsr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>      9V9VW]9^9^ r_   r'   c                 .                                    S r  )migrate_slack_settingsr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>      t7R7RSY7Z7Z r_   r(   c                 .                                    S r  )migrate_whatsapp_settingsr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  s    $:X:XY_:`:` r_   r)   c                 .                                    S r  )migrate_signal_settingsr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  s    8T8TU[8\8\ r_   r*   c                 .                                    S r  )handle_provider_keysr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  s    d6O6OPV6W6W r_   r+   c                 .                                    S r  )migrate_model_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>      T5N5Nv5V5V r_   r,   c                 .                                    S r  )migrate_tts_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  s    43J3J63R3R r_   r#   r$   r-   r.   r%   c                 p                                               d           j        dz  dh d          S )Nzworkspace/ttsttsr%   >   .venv	generated__pycache__)rM   ignore_dir_names)copy_tree_non_destructiver  r_  r  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  sD    D22%%o66 5(!!F!F!F	 3   r_   r/   r0   c                 .                                    S r  )migrate_mcp_serversr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>      D4L4LV4T4T r_   r1   c                 .                                    S r  )migrate_plugins_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r2   c                 .                                    S r  )migrate_cron_jobsr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  s    $2H2H2P2P r_   r3   c                 .                                    S r  )migrate_hooks_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r4   c                 .                                    S r  )migrate_agent_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r5   c                 .                                    S r  )migrate_gateway_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r6   c                 .                                    S r  )migrate_session_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r7   c                 .                                    S r  )migrate_full_providersr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r8   c                 .                                    S r  )migrate_deep_channelsr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>      d6P6PQW6X6X r_   r9   c                 .                                    S r  )migrate_browser_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r:   c                 .                                    S r  )migrate_tools_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r;   c                 .                                    S r  )migrate_approvals_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r<   c                 .                                    S r  )migrate_memory_backendr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r=   c                 .                                    S r  )migrate_skills_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r>   c                 .                                    S r  )migrate_ui_identityr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   r?   c                 .                                    S r  )migrate_logging_configr  s   r`   r   z"Migrator.migrate.<locals>.<lambda>  r  r_   )r]  r   r  build_reportr  run_if_selectedmigrate_soulmigrate_workspace_agentsmigrate_command_allowlistmigrate_skillsmigrate_shared_skillsmigrate_daily_memoryarchive_docsgenerate_migration_notes)r  r  s   `@r`   migratezMigrator.migratex  sA   &&(( 	'KK$"2D'Cfggg$$&&&**,,VT%6777/1NOOO   	
 	
 	
 	   	
 	
 	
 	13b3b3b3b3bccc.0[0[0[0[0[\\\/1^1^1^1^1^___-/Z/Z/Z/Z/Z[[[02`2`2`2`2`aaa.0\0\0\0\0\]]]_.W.W.W.W.WXXX^-V-V-V-V-VWWW\+R+R+R+R+RSSS0$2PQQQXt':;;;_d.HIII^T-FGGG   	
 	
 	
 	Y(9::: 	],T,T,T,T,TUUU-/Z/Z/Z/Z/Z[[[[*P*P*P*P*PQQQ^-V-V-V-V-VWWW^-V-V-V-V-VWWW-/Z/Z/Z/Z/Z[[[-/Z/Z/Z/Z/Z[[[-/Z/Z/Z/Z/Z[[[_.X.X.X.X.XYYY-/Z/Z/Z/Z/Z[[[^-V-V-V-V-VWWW/1^1^1^1^1^___-/Z/Z/Z/Z/Z[[[_.X.X.X.X.XYYY],T,T,T,T,TUUU-/Z/Z/Z/Z/Z[[[ 	%%'''  """r_   c           	     F   |                      |          s0t          |         }|                     |d d dd|d                    d S | j        rJ| j        rC|| j        v r:t          |         }|                     |d d t          t          |d                    d S  |             d S )NrE   zNot selected for this runr   )option_label)r  r@   r  ro  r  _CONFIG_MUTATING_OPTIONSSTATUS_SKIPPED REASON_BLOCKED_BY_APPLY_CONFLICT)r  r  funcmetas       r`   r  zMigrator.run_if_selected  s    	** 	,Y7DKK	4y:UdhipdqKrrrF L	*	 T:::,Y7DKK0!']     Fr_   c                   dddddd}| j         D ](}|                    |j        d          dz   ||j        <   )| j        | j        rdndt          | j                  t          | j                  | j        rt          | j                  nd | j	        rt          | j	                  nd | j
        | j        pd | j        t          | j                  | j        pd | j        d t                                           D             d t                                            D             d|d	 | j         D             |                     |          |                     |          d
}| j	        rt'          | j	        |           |S )Nr   )rC   rD   rE   rF   rG   r   ro  zdry-runc                     g | ]\  }}d |i|S )r   r^   )r   r  r  s      r`   r   z)Migrator.build_report.<locals>.<listcomp>  s6       '	4 9--  r_   c                8    g | ]\  }}|t          |          d S ))r   r   )ry   )r   	preset_id
option_idss      r`   r   z)Migrator.build_report.<locals>.<listcomp>  s<       -	: %&2D2DEE  r_   )r   rq   rt  	availablepresetsc                ,    g | ]}t          |          S r^   )r   r   ri  s     r`   r   z)Migrator.build_report.<locals>.<listcomp>  s    :::tfTll:::r_   )r[  r\  r]  r_  rp  rU  rq  rq   rt  	selectionr`  r   ra  rb  )r   r   rQ   r[  ro  rL   r]  r_  rp  rU  rq  r~   rt  ry   rr  r@   rB   _build_warnings_build_next_stepsrl  )r  r`  ri  rV  s       r`   r  zMigrator.build_report  s   #
 #
 J 	C 	CD#*;;t{A#>#>#BGDK   !%<II9t/00t/00>B>S ]D$9 : : :Y]26/K#do...t#3&.$#'#;"4#899*2d'+'? +D+J+J+L+L   1B1H1H1J1J    ::tz:::,,W5500995
 
: ? 	2&111r_   r`  Dict[str, int]rd   c                   g }|                     dd          dk    r|                    d           |                     dd          dk    r|                    d           | j        r| j        r|                    d           t	          d | j        D                       }|r| j        s|                    d           |S )	u   Structured warnings surfaced on the report for downstream consumers.

        Modelled on OpenClaw's extensions/migrate-hermes/plan.ts warnings[].
        Keep the messages actionable — they show up in summary.md and the
        JSON report.
        rF   r   zfConflicts were found. Re-run with --overwrite to replace conflicting targets after item-level backups.rG   zZOne or more items failed. Inspect the report and re-run after fixing the underlying cause.zpA config.yaml write hit a conflict or error mid-apply; later config items were skipped to avoid a partial write.c              3  L   K   | ]}|j         d k    o|j        t          k    V   dS )r*   N)rM   rQ   r  r  s     r`   r  z+Migrator._build_warnings.<locals>.<genexpr>!  sI       $
 $
 I(JT[N-J$
 $
 $
 $
 $
 $
r_   zAPI keys and other credentials were detected but not imported. Re-run with --migrate-secrets to copy supported keys into the Hermes env file.)r   rj   r  ro  rF  r   rq  )r  r`  ra  provider_keys_skippeds       r`   r  zMigrator._build_warnings	  s
    !;;z1%%))OO4   ;;w""Q&&OO(   % 	$, 	OO?  
 !$ $
 $

$
 $
 $
 !
 !
 ! 	)= 	OO#  
 r_   c                *   | j         sddgS g }|                    dd          dk    r<|                    | j        rd| j         dnd           |                    d           |                    d	d          dk    r|                    d
           |S )z8Human-readable next-step guidance baked into the report.z0Re-run without --dry-run to apply the migration.zPPass --overwrite to resolve conflicts, or --migrate-secrets to include API keys.rC   r   zReview the migration report at z/summary.mdzReview the migration report.zFStart a new Hermes session (or /reset) to pick up the imported config.rF   zFRe-run with --overwrite to apply items that were blocked by conflicts.)ro  r   rj   rU  )r  r`  stepss      r`   r  zMigrator._build_next_steps-  s    | 	B$ 
 ;;z1%%))LL ?4 0?0 0 0 0 4	   LLX   ;;z1%%))LLX   r_   r   c                t    | j         r| j        r|                                sd S t          || j                  S r  )ro  r  r   r   )r  r   s     r`   maybe_backupzMigrator.maybe_backupF  s;    | 	4? 	$++-- 	4tT_555r_   r  r  c                    |r| j         sd S | j                             dd           |                    dd           d}| j         |z  }|                    d                    |          dz   d           |S )	NTr   r  r   z_overflow.txtr   r   r   )r  r   replacer   rx   )r  rM   r  filenamer   s        r`   write_overflow_entrieszMigrator.write_overflow_entriesK  s     	d/ 	4t<<<ll3,,;;; 8+		'**T1GDDDr_   	transformOptional[Any]c           	        |r|                                 sd S |                                 r_|s;t          |          t          |          k    r|                     |||dd           d S | j        s|                     |||dd           d S | j        r|                     |          }t          |           |rGt          |          } ||          }|                    |d           t          j
        ||           nt          j        ||           |                     |||d|rt          |          nd            d S |                     |||dd	           d S )
NrE   zTarget already matches sourcerF   rI   r   r   rC   )backupz
Would copy)r   r   r  r   ro  r  r   r   r   r   copystatr   rL   )r  rO   rP   rM   r  backup_pathr  s          r`   	copy_filezMigrator.copy_fileT  s    	V]]__ 	F 	 V!4!4K8P8P!P!PD&+yBabbb> D&+zClmmm< 	M++K88K+&&& 2#F++#)G,,&&w&AAA4444V[111KKfk:ZeFoc+FVFVFVkoKpppppKKfk:|LLLLLr_   c                    |                      dd          }|s#|                     dd | j        dz  dd           d S |                     || j        dz  dt                     d S )Nzworkspace/SOUL.mdzworkspace.default/SOUL.mdr   r   rE   zNo OpenClaw SOUL.md foundrM   r  )r  r  r_  r%  r   )r  rO   s     r`   r  zMigrator.migrate_soulo  sr    &&':<WXX 	KKd&6&BIOjkkkFvt/);&T`aaaaar_   c                *   |                      dt           dt                     }||                     ddddd           d S | j        s|                     d|d dd           d S | j        t          z  }|                     ||dt
          	           d S )
Nr  r  r   zworkspace/AGENTS.mdrR   rE   Source file not foundz No workspace target was providedr'  )r  WORKSPACE_INSTRUCTIONS_FILENAMEr  rp  r%  r   )r  rO   rP   s      r`   r  z!Migrator.migrate_workspace_agentsv  s    &&:8::B!@BB
 
 >KK*,A2yRijjjF$ 	KK*FD)EghhhF+.MMv{1C|\\\\\r_   r   r!  c           
        |r|                                 s|                     |d |dd           d S t          t          |                    }|s|                     |||dd           d S d |D             }t	          |          }t          |||          \  }}}	|d         |d         |d         |d         ||r't          t                              |                    nd	d
}
| 	                    ||	          }|t          |          |
d<   | j        r|d         d	k    r|	s | j        |||ddfi |
 d S |                     |          }t          |           |                    t                              |          |rdndz   d            | j        |||df|rt          |          nd|	d d         d|
 d S  | j        |||ddfd|	d d         i|
 d S )NrE   r)  zNo importable entries foundc                ,    g | ]}t          |          S r^   r   r%  s     r`   r   z+Migrator.migrate_memory.<locals>.<listcomp>  s     >>>EL''>>>r_   r  r'  r(  r)  r   )existing_entriesadded_entriesduplicate_entriesoverflowed_entries
char_limitfinal_char_countoverflow_fileNo new entries to importr   rR   r   r   rC      r"  overflow_previewzWould merge entriesr8  )r   r  r   r   r   r/  r   r   rx   r  rL   ro  r  r   r   )r  rO   rP   r   rM   r  r  r+  r,  r)  rV   r4  r$  s                r`   r  zMigrator.migrate_memory  s    	V]]__ 	KKdK<STTTF+If,=,=>> 	KKfk9>[\\\F>>X>>>0==$1(He$L$L!z %j 1"7^!&|!4"'"5EK RO$8$8$@$@ A A AQR
 
 33D*EE$'*='9'9GO$< 	BW~"":"D&+yB\hh`ghhh++K88K+&&&""?#7#7#?#?6CY44WY#Zel"mmmDK	
 ,7>s;'''B!+BQB       DKfk:?T  B  Bgqrtstrtgu  B  zA  B  B  B  B  Br_   c           	         | j         dz  }| j        dz  }|                                s|                     dd |dd           d S t          |                     d||dd           d S 	 t          j        |                    d	                    }n9# t
          j        $ r'}|                     d||dd
|            Y d }~d S d }~ww xY wg }|	                    di           }t          |t                    r|                                D ]w}t          |t                    r|	                    dg           ng }|D ]E}	t          |	t                    r|		                    d          nd }
|
r|                    |
           Fxt          t                              |                    }|s|                     d||dd           d S |                                s|                     d||dd           d S t!          |          }|	                    dg           t          t"                    sg t          t                              t#                    |z                       }fd|D             }|s|                     d||dd           d S | j        rX|                     |          }||d<   t)          ||           |                     d||d|rt+          |          nd|           d S |                     d||dd|           d S )Nzexec-approvals.jsonr}  r#   rE   z%No OpenClaw exec approvals file foundrG   PyYAML is not availabler   r   zInvalid JSON: rz  	allowlistr   zNo allowlist patterns foundz%Hermes config.yaml does not exist yetcommand_allowlistc                    g | ]}|v|	S r^   r^   )r   r   currents     r`   r   z6Migrator.migrate_command_allowlist.<locals>.<listcomp>  s#    IIIW'2H2H2H2H2Hr_   zAll patterns already presentrC   rR   )r"  added_patternszWould merge patterns)r?  )r]  r_  r   r  r   rc  loadsr   JSONDecodeErrorr   r   r]   ra   rj   ry   fromkeysr   r*  ro  r  r   rL   )r  rO   rP   r   excpatternsrz  
agent_datar;  r  r   r  r+  r'  r$  r>  s                  @r`   r  z"Migrator.migrate_command_allowlist  ss   !$99&6}} 	KK+T;	KrsssF<KK+V['KdeeeF	:f...@@AADD# 	 	 	KK+V['Ka\_KaKabbbFFFFF	 !(B''fd## 	1$mmoo 1 1
?I*VZ?[?[cJNN;;;;ac	& 1 1E6@6M6MWeii	222SWG 1 0001
 $--1122 	KK+V[)MjkkkF!!## 	KK+V[)MtuuuF,,**0"55'4(( 	Gd7mmh&>??@@IIIIIII 	KK+V[)MklllF< 	|++K88K*0F&';///KK#+6>s;'''B$       KK+V[*NduzK{{{{{s   ((B C CCc                    dD ]y}| j         |z  }|                                rY	 t          j        |                    d                    }t          |t                    r|ni c S # t          j        $ r Y uw xY wzi S )N)openclaw.jsonzclawdbot.jsonzmoltbot.jsonr   r   )r]  r   rc  r@  r   r   r]   rA  )r  r  config_pathr   s       r`   r  zMigrator.load_openclaw_config  s    F 	 	D*T1K!!## :k&;&;W&;&M&MNND#-dD#9#9A44rAAA+   H	 	s   A A''A98A9r   c                0    t          | j        dz            S )zJLoad the OpenClaw .env file for secrets that live there instead of config..env)r   r]  r  s    r`   load_openclaw_envzMigrator.load_openclaw_env  s    d.7888r_   	additionsc                   | j         dz  }t          |          }i }g }|                                D ]J\  }}	|                    |          }
|
|	k    r!|
r| j        s|                    |           @|	||<   |	||<   K|r|s|                     |||dd|           d S |s|s|                     |||dd           d S | j        rs|                     |          }t          ||           |                     |||d|rt          |          ndt          |                                          |	           d S |                     |||dd
t          |                                          |           d S )NrJ  rF   z-Destination .env already has different values)conflicting_keysrE   zAll env values already presentrC   rR   )r"  
added_keysrN  zWould merge env values)rO  rN  )r_  r   r   r   r   rj   r  ro  r  r   rL   ry   r  )r  rL  rM   rO   rP   env_datar'  	conflictsr   rl   r>  r$  s               r`   merge_env_valueszMigrator.merge_env_values  s   &/!+.. "!	#//++ 	 	JCll3''G% t~   %%%!HSME#JJ 	U 	KKfk:?n  BKK  L  L  LF 	 	KKfk9>^___F< 	++K88K+x000KK+6>s;'''B!%**,,//!*       KK(!%**,,//!*      r_   r  Optional[Dict[str, Any]]c                @   |p|                                  }i }|                    di                               di                               d          }t          |t                    r|                                r|                                }	 t          |                                                              | j                                                  }n# t          t          f$ r d}Y nw xY w|s||d<   | j        dz  dz  }|                                r	 t          j        |                    d	                    }|                    d
g           }t          |t                    r&d |D             }	|	rd                    |	          |d<   n6# t          j        $ r$ |                     d|| j        dz  dd           Y nw xY w|r!|                     |d| j        dz             d S |                     d| j        dz  | j        dz  dd           d S )Nrz  r{  r|  FMESSAGING_CWDcredentialsztelegram-default-allowFrom.jsonr   r   	allowFromc                    g | ]D}t          |                                          #t          |                                          ES r^   rL   rh   )r   users     r`   r   z7Migrator.migrate_messaging_settings.<locals>.<listcomp>H  s=    [[[4TIZIZ[SYY__..[[[r_   rf   TELEGRAM_ALLOWED_USERSr!   rJ  rG   z'Invalid JSON in Telegram allowlist filerG  rE   z-No Hermes-compatible messaging settings found)r  r   r   rL   rh   r   r  is_relative_tor]  rw   OSErrorr   rc  r@  r   r*  rx   rA  r  r_  rR  )
r  r  rL  r|  r  inside_sourceallowlist_path
allow_data
allow_fromuserss
             r`   r  z#Migrator.migrate_messaging_settings)  s   644466$&	 JJx$$SR  S 	
 i%% 	5)//*;*; 	5oo''G
& $W 5 5 7 7 F FtGWG_G_GaGa b b( & & & %&  5-4	/*)M9<]]  "" 
	N	N!Z(@(@'(@(R(RSS
 (^^K<<
j$// N[[:[[[E N>Ahhuoo	":; ' Q Q Q0.$BRU[B[]d  gP  Q  Q  Q  Q  QQ  	i!!)-A4CSVeCefffffKK,d.>.PRVRbekRkmv  yh  i  i  i  i  is%   AC   C65C6"(F 0GGc           
        |p|                                  }| j        r|                     |           d S | j        dz  }|                                r7|                     d|| j        dz  ddt          t                               d S |                     d|| j        dz  ddt          t                               d S )NrG  r"   rJ  rE   zWSecret migration disabled. Re-run with --migrate-secrets to import allowlisted secrets.supported_targetszOpenClaw config file not found)	r  rq  migrate_secret_settingsr]  r   r  r_  ry   SUPPORTED_SECRET_TARGETSr  r  rH  s      r`   r  zMigrator.handle_secret_settingsQ  s    644466 	((000F&8 	KK! 6)i"()A"B"B       KK! 6)0"()A"B"B      r_   c           
        i }|                     di                                di           }t          |t                    r|                     |d          nd }t          |t                    r+|                                r|                                |d<   |r!|                     |d| j        dz             d S |                     d| j        dz  | j	        dz  dd	t          t                    
           d S )NchannelstelegrambotTokenr   r"   rG  rJ  rE   z.No allowlisted Hermes-compatible secrets foundrd  )r   r   r]   _get_channel_fieldrL   rh   rR  r]  r  r_  ry   rg  )r  r  secret_additionstg_cfgtelegram_tokens        r`   rf  z Migrator.migrate_secret_settingsk  s   +-J++//
B??HRSY[_H`H`j00DDDfjnc** 	L~/C/C/E/E 	L5C5I5I5K5K12 
	!!"24EtGWZiGijjjjjKK! ?2 6)@"()A"B"B      r_   rl   rN   c                F    t          ||                                           S )z7Resolve a channel config value that may be a SecretRef.)r   rK  )r  rl   s     r`   _resolve_channel_secretz Migrator._resolve_channel_secret  s    #E4+A+A+C+CDDDr_   ch_cfgr   c                
   |                      |          }||S |                      d          }t          |t                    r?|                     d          }t          |t                    r|                     |          S dS )zPGet a field from channel config, checking both flat and accounts.default layout.Naccountsdefault)r   r   r]   )rs  r   valru  rv  s        r`   rm  zMigrator._get_channel_field  s|     jj?J::j))h%% 	*ll9--G'4(( *{{5)))tr_   c                   |p|                                  }i }|                    di                               di           }t          |t                    r|                     |d          }t          |t
                    r+|                                r|                                |d<   |                     |d          pg }t          |t                    r&d |D             }|rd                    |          |d<   |r!| 	                    |d	| j
        d
z             d S |                     d	| j
        d
z  | j        dz  dd           d S )Nrj  discordrB  DISCORD_BOT_TOKENrW  c                    g | ]D}t          |                                          #t          |                                          ES r^   rY  r   us     r`   r   z5Migrator.migrate_discord_settings.<locals>.<listcomp>  9    NNNAs1vv||~~NQNNNr_   rf   DISCORD_ALLOWED_USERSr&   rG  rJ  rE   zNo Discord settings foundr  r   r   r]   rm  rL   rh   r*  rx   rR  r]  r  r_  )r  r  rL  ry  rB  ra  rb  s          r`   r  z!Migrator.migrate_discord_settings  ss   644466$&	**Z,,00B??gt$$ 	I++GW==E%%% ?%++-- ?16	-.00+FFL"J*d++ INNNNN I9<%I56 	S!!)-?AQTcAcdddddKK*D,<,NPTP`ciPikt  wR  S  S  S  S  Sr_   c                J   |p|                                  }i }|                    di                               di           }t          |t                    r|                     |d          }t          |t
                    r+|                                r|                                |d<   |                     |d          }t          |t
                    r+|                                r|                                |d<   |                     |d          pg }t          |t                    r&d |D             }|rd	                    |          |d
<   |r!| 	                    |d| j
        dz             d S |                     d| j
        dz  | j        dz  dd           d S )Nrj  slackrl  SLACK_BOT_TOKENappTokenSLACK_APP_TOKENrW  c                    g | ]D}t          |                                          #t          |                                          ES r^   rY  r|  s     r`   r   z3Migrator.migrate_slack_settings.<locals>.<listcomp>  r~  r_   rf   SLACK_ALLOWED_USERSr'   rG  rJ  rE   zNo Slack settings foundr  )r  r  rL  r  	bot_token	app_tokenra  rb  s           r`   r  zMigrator.migrate_slack_settings  s   644466$&	

:r**..w;;eT"" 	G//zBBI)S)) Aioo.?.? A/8/@/@	+,//zBBI)S)) Aioo.?.? A/8/@/@	+,00DDJJ*d++ GNNNNN G7:xxI34 	O!!)-=t?ORa?abbbbbKK($*:_*LdN^agNgir  uN  O  O  O  O  Or_   c                   |p|                                  }i }|                    di                               di           }t          |t                    rS|                     |d          pg }t          |t
                    r&d |D             }|rd                    |          |d<   |r!|                     |d| j        dz             d S | 	                    d| j        dz  | j
        d	z  d
d           d S )Nrj  whatsapprW  c                    g | ]D}t          |                                          #t          |                                          ES r^   rY  r|  s     r`   r   z6Migrator.migrate_whatsapp_settings.<locals>.<listcomp>  r~  r_   rf   WHATSAPP_ALLOWED_USERSr(   rG  rJ  rE   zNo WhatsApp settings found)r  r   r   r]   rm  r*  rx   rR  r]  r  r_  )r  r  rL  r  ra  rb  s         r`   r  z"Migrator.migrate_whatsapp_settings  s*   644466$&	::j"--11*bAAh%% 	J00;GGM2J*d++ JNNNNN J:=((5//I67 	U!!)-@$BRUdBdeeeeeKK+T-=-OQUQadjQjlu  xT  U  U  U  U  Ur_   c                J   |p|                                  }i }|                    di                               di           }t          |t                    r|                     |d          }t          |t
                    r+|                                r|                                |d<   |                     |d          }t          |t
                    r+|                                r|                                |d<   |                     |d          pg }t          |t                    r&d |D             }|rd	                    |          |d
<   |r!| 	                    |d| j
        dz             d S |                     d| j
        dz  | j        dz  dd           d S )Nrj  signalaccountSIGNAL_ACCOUNThttpUrlSIGNAL_HTTP_URLrW  c                    g | ]D}t          |                                          #t          |                                          ES r^   rY  r|  s     r`   r   z4Migrator.migrate_signal_settings.<locals>.<listcomp>  r~  r_   rf   SIGNAL_ALLOWED_USERSr)   rG  rJ  rE   zNo Signal settings foundr  )r  r  rL  r  r  http_urlra  rb  s           r`   r  z Migrator.migrate_signal_settings  s   644466$&	J++//"==fd## 	H--fi@@G'3'' >GMMOO >.5mmoo	*+..vyAAH(C(( @X^^-=-= @/7~~/?/?	+,00EEKJ*d++ HNNNNN H8;I45 	Q!!)->@PSb@bcccccKK)4+;o+MtO_bhOhjs  vP  Q  Q  Q  Q  Qr_   c           
         |p|                                  }| j        sA| j        dz  }|                     d|| j        dz  ddt          t                               d S |                     |           d S )NrG  r*   rJ  rE   zUSecret migration disabled. Re-run with --migrate-secrets to import provider API keys.rd  )r  rq  r]  r  r_  ry   rg  migrate_provider_keysrh  s      r`   r  zMigrator.handle_provider_keys  s    644466# 
	*_<KKK 6)g"()A"B"B     F""6*****r_   c                &   i }|                                  }|                    di                               di           }t          |t                    r|                                D ]v\  }}t          |t                    s|                    d          }t          ||          }|s[t          |t                    rE|                    d          dv r.|                     d| j        dz  d dd	| d
|d          d           |                    dd          }	|                    dd          }
d }t          |	t                    rJd|		                                v rd}n1d|		                                v rd}nd|		                                v rd}|st          |
t                    r|
dk    rd}|s#|	                                }|dk    rd}nd|v rd}|r|||<   x|                    di                               di           }t          |t                    r |                    di           }t          |t                    rU|                    d          }t          |t                    r+|
                                r|
                                |d<   |                    di           }t          |t                    rU|                    d          }t          |t                    r+|
                                r|
                                |d<   |                                  }ddddddddd d!	}|                                D ]8\  }}|                    |d          
                                }|r	||vr|||<   9|                    d"          }t          |t                    r|                    d#          }|g}t          |t                    r|                    |           |D ]u}|                                D ]^\  }}|                    |          }t          |t                    r/|
                                r||vr|
                                ||<   _v| j        d$z  d%z  d&z  d'z  }|                                r	 t          j        |                    d()                    }t          |t                    r9t          |                    d*          t                    r|                    d*|          n|}|                                D ]\  }}t          |t                    s|                    d+d          p|                    dd          }t          |t                    r|
                                sq|	                                }d|v rd|vr|
                                |d<   d|v rd|vr|
                                |d<   d|v rd|vr|
                                |d<   n# t          j        t"          f$ r Y nw xY w|r!|                     |d| j        dz             d S |                     d| j        dz  | j        d,z  dd-t)          t*                    .           d S )/Nmodels	providersapiKeyrO   >   execfiler*   rG  rE   
Provider 'z	' uses a z\-backed SecretRef that cannot be auto-migrated. Add this key manually via: hermes config setbaseUrlrR   api
openrouterr   z
openai.comr   	anthropicr   anthropic-messagesopenaimessagesr  
elevenlabsr   r   r   DEEPSEEK_API_KEYGEMINI_API_KEYZAI_API_KEYMINIMAX_API_KEY)	r   r   r   r   r   r  r  r  r  r   varsrz  mainagentzauth-profiles.jsonr   r   profilesr   rJ  zNo provider API keys foundrd  )rK  r   r   r]   r   r   r  r]  rL   ri   rh   rj   r   rc  r@  r   rA  r]  rR  r_  ry   rg  )r  r  rn  openclaw_envr  provider_nameprovider_cfgraw_keyapi_keybase_urlapi_typeenv_var
name_lowerr  r  el_key
openai_ttsoai_keyenv_key_mappingoc_key
hermes_keyrw  json_envenv_varssourcessrcauth_profiles_pathr  profile_entriesprofile_nameprofile_datas                                  r`   r  zMigrator.migrate_provider_keys  sW   +- --//JJx,,00bAA	i&& -	8/8/@/@ ,8 ,8+|!,55 &**844.wEE !'400 W[[5J5JN^5^5^+ ,> %j j jAR j j j   '++Ir::'++E266 h,, 6#x~~'7'777"6%)9)999"2$(8(888"5  2:h#<#< 2MaAaAa1G  3!.!4!4!6!6J!\11"6!Z//"2 807$W- jjR((,,UB77c4   
	Qr22J*d++ L#11fc** Lv||~~ L=C\\^^$%9:2..J*d++ Q$..22gs++ Q QAH$%=> --//"6.!4"6"6 2.(0

 

 #2"7"7"9"9 	3 	3FJ""62..4466C 3z)999/2 ,
 ::e$$h%% 		C||F++HjG(D)) )x((( C C*9*?*?*A*A C C&FJ''&//C!#s++ C		 C
Rb@b@b7:yy{{(4C "-86AGKNbb$$&& 	:&8&B&BG&B&T&TUUh-- TLVW_WcWcdnWoWoquLvLv  'Ehll:x&H&H&H  }EO6E6K6K6M6M T T2l),== %$"."2"25""="="_AQAQRZ\^A_A_)'377 %w}} %$%1%7%7%9%9
':55:NVf:f:fEL]]__,-ABB%338HP`8`8`AH,-=>>(J66;NVf;f;fDKMMOO,-@A('2     
	!!"2OTEUXgEghhhhhKK ?2 6),"()A"B"B      s   E7X X.-X.c           	     <   |p|                                  }| j        dz  }| j        dz  }|                    di                               di                               d          }||                     d||dd           d S t          |t                    r|                    d	          }n|}t          |t                    r|                                s|                     d||dd
           d S |                                }|                    di                               di                               di           }t          |t                    r||vr|	                                D ]l\  }}t          |t                    st          |t                    r|                    d          |k    r|} n t          |t                    r
||k    r|} nmt          |                     d||dd           d S t          |          }	|	                    d          }
|
|k    r|                     d||dd           d S |
r%| j        s|                     d||dd|
|           d S | j        r|                     |          }|	                    d          }t          |t                    r||d<   nd|i|	d<   t          ||	           |                     d||d|rt          |          nd|           d S |                     d||dd|           d S )Nr}  rG  rz  r{  modelr+   rE   z)No default model found in OpenClaw configprimaryz'Default model value is empty or invalidr  aliasrG   r:  z#Model already set to the same valuerF   z+Model already set and overwrite is disabled)r>  r  rv  rC   rR   )r"  r  zWould set model)r  )r  r_  r]  r   r  r   r]   rL   rh   r   r   r   r   ro  r  r   )r  r  rP   source_pathmodel_value	model_strmodel_catalogapi_idr  hermes_configcurrent_modelr$  existing_models                r`   r  zMigrator.migrate_model_configu  s   644466&6&8jj2..22:rBBFFwOOKK[)MxyyyFk4(( 	$#	22II#I)S)) 	1B1B 	KK[)MvwwwFOO%%	 

8R0044ZDDHHSUVVmT** 		y/M/M!.!4!4!6!6  !&#.. eT** uyy/A/AY/N/N &IEeS)) ey.@.@ &IE<KK['KdeeeF&{33%))'22I%%KK[)MrsssF 	 	KK[*N{  FS  ^gK  h  h  hF< 
	r++K88K*..w77N.$// @,5y))*3Y)?g&;666KK[*itU|UXYdUeUeUez|  ENK  O  O  O  O  OKK[*N_gpKqqqqqr_   c                   |p|                                  }| j        dz  }| j        dz  }|                    di                               di           }t	          |t
                    r|s|                     d||dd           d S t          |                     d||dd	           d S i }|                    d
          }t	          |t                    r|dv r|dk    rdn||d
<   |                    d          pi }|p|                                                      d          pi }|                    d          pi }	t	          |                    d          t
                    r|                    d          pi nUt	          |	                    d          t
                    r|	                    d          pi n|                    d          pi }
t	          |
t
                    ri }|
                    d          p|                    d          }t	          |t                    r+|	                                r|	                                |d<   |
                    d          p|                    d          }t	          |t                    r+|	                                r|	                                |d<   |r||d<   t	          |                    d          t
                    r|                    d          pi nUt	          |	                    d          t
                    r|	                    d          pi n|                    d          pi }t	          |t
                    ri }|                    d          p|                    d          }t	          |t                    r+|	                                r|	                                |d<   |                    d          }t	          |t                    r+|	                                r|	                                |d<   |r||d<   t	          |                    d          t
                    s(t	          |                    d          t
                    r,|                    d          p|                    d          pi n+|                    d          p|                    d          pi }t	          |t
                    rW|                    d          }t	          |t                    r-|	                                rd|	                                i|d<   |s|                     d||dd           d S t          |          }|                    di           }t	          |t
                    si }| j        r|                     |          }t          |          }|                                D ]W\  }}t	          |t
                    r8t	          |                    |          t
                    ri ||         |||<   R|||<   X||d<   t          ||           |                     d||d|rt          |          ndt          |                                                     d S |                     d||ddt          |                                                     d S )Nr}  rG  r  r  r,   rE   z-No TTS configuration found in OpenClaw configrG   r:  provider>   edger  	microsoftr  r  r  r  talkr  voiceIdvoice_idmodelIdmodel_idr  r  voicez No compatible TTS settings foundrC   rR   )r"  settingszWould set TTS config)r  )r  r_  r]  r   r   r]   r  r   rL   rh   r   ro  r  r   r   r*  r  )r  r  rP   r  r  tts_datar  r  talk_cfgtalk_providersr  el_settingsr  r  r  oai_settings	oai_model	oai_voiceedge_tts
edge_voicer  existing_ttsr$  
merged_ttsr   rl   s                             r`   r  zMigrator.migrate_tts_config  s   644466&6&8jjR((,,UB77#t$$ 	C 	KKk;	Kz{{{F<KKk;IbcccF#%77:&&h$$ 	S5b)b)b-5-D-D66(HZ  GGK((.B	 9d7799>>vFFL"!k228b )--55t<<*Y]]<((.B .,,\::DAA*^--3WW\""(b 	 j$'' 		5*,K!~~i00KHLL4K4KH(C(( ;X^^-=-= ;*2..*:*:J'!~~i00KHLL4K4KH(C(( ;X^^-=-= ;*2..*:*:J' 5)4& )--11488&Y]]8$$* .,,X66==&^))/RWWX$" 	 j$'' 		2+-L"w//L:>>)3L3LI)S)) :ioo.?.? :(1(9(9W%"w//I)S)) :ioo.?.? :(1(9(9W% 2%1" )--//66<:DY]]S^E_E_ae:f:f<Y]]6""FimmK&@&@FBWWV__: 4 4: 	
 h%% 	A!g..J*c** Az/?/?/A/A A$+Z-=-=-?-?#@  	KKk;	KmnnnF&{33$((33,-- 	L< 	D++K88Kl++J&nn.. , ,
UeT** ,z*..:M:Mt/T/T ,&BC&BE&BJsOO&+JsOO#-M% ;666KKk;
grSzSVWbScScScxz  FJ  KS  KX  KX  KZ  KZ  F[  F[K  \  \  \  \  \KKk;
Lbmqrzrr  sB  sB  nC  nCK  D  D  D  D  Dr_   c                n   | j         dz  ddft          j                    dz  dz  ddf| j         dz  dz  dz  dd	f| j         d
z  dz  dz  dd	fg}d}|D ]3\  }}}|                                rd}|                     |||           4|s-| j        dz  t          z  }|                     dd |dd           d S d S )Nr$   r-   zmanaged skillsz.agentszpersonal-skillszpersonal cross-project skillsr|  zproject-skillszproject-level shared skillsworkspace.defaultFTrE   z+No shared OpenClaw skills directories found)r]  r   homer   _import_skill_directoryr_  SKILL_CATEGORY_DIRNAMEr  )r  skill_sources	found_anyr]  
kind_labeldescdestination_roots          r`   r  zMigrator.migrate_shared_skills  s    (/;KLY[[9$x/1BDcd+i7(BDTVst 33i?(JL\^{|	
 	-: 	L 	L)KT!!## L 	,,[*dKKK 	{#/(:=SSKK/?Lyzzzzz	{ 	{r_   r  r  c                   | j         dz  t          z  }d t          |                                          D             }|s|                     |||dd|            dS |D ]}||j        z  }|}|                                rE| j        dk    r|                     |||dd           H| j        d	k    r|                     |          }| j	        rd}	||k    r)|                                r| 
                    |          }	|j                            d
d
           ||k    r(|                                rt          j        |           t          j        ||           d|	rt!          |	          ndi}
||k    rt!          |          |
d<    | j        |||dfi |
 ?||k    r.|                     |||dd| dt!          |                     s|                     |||dd| d           |dz  }| j	        rS|j                            d
d
           |                                s!|                    t$          dz   d           dS dS |                                s|                     dd|dd           dS dS )zCImport skills from a single source directory into openclaw-imports.r$   c                h    g | ]/}|                                 |d z                                  -|0S zSKILL.mdr   r   r   ps     r`   r   z4Migrator._import_skill_directory.<locals>.<listcomp>3  =    kkkA!((**kRSV`R`QhQhQjQjkakkkr_   rE   z!No skills with SKILL.md found in Nr   rF    Destination skill already existsr   Tr   r"  rR   renamed_fromrC   zWould copy z! directory under a renamed folderr  z
 directoryDESCRIPTION.mdr   r   r   zshared-skill-category!Would create category description)r_  r  ry   iterdirr  r  r   rt  r  ro  r  r   r   r   rmtreer   rL   r   SKILL_CATEGORY_DESCRIPTION)r  r]  r  r  r  
skill_dirs	skill_dirrP   final_destinationr$  rV   	desc_paths               r`   r  z Migrator._import_skill_directory/  s'   +h69OOkk(;(;(=(=!>!>kkk
 	KK
K1A9NxrvNxNxyyyF#  	v  	vI*Y^;K +!!## T+v55KK
I{JPrsss+x77(,(F(F{(S(S%| v"$338J8J8L8L3"&"3"3K"@"@K!(..td.KKK$338J8J8L8L3M+...	+<===+35\S5E5E5EZ\*]$33.1+.>.>GN+J	3Dj\\T[\\\\$33KK"!)"MdMMM%(%5%5       KK
I7H*VtdhVtVtVtuuuu$'77	< 	s""4$"???##%% Z$$%?$%FQX$YYYYYZ Z!!## 	sKK/y*Nqrrrrr	s 	sr_   c                   |                      d          }| j        dz  dz  }|r|                                s|                     dd |dd           d S t	          d |                                D                       }|s|                     d||dd           d S g }|D ]3}t          t          |                    }|                    |           4|s|                     d||dd	           d S d
 |D             }t          |          }t          ||| j                  \  }}	}
t          |          |	d         |	d         |	d         |	d         | j        |r't          t                              |                    ndd}|                     d|
          }|t!          |          |d<   | j        r|	d         dk    r|
s | j        d||ddfi | d S |                     |          }t'          |           |                    t                              |          |rdndz   d            | j        d||df|rt!          |          nd|
d d         d| d S  | j        d||ddfd|
d d         i| d S )Nworkspace/memoryr  r   r.   rE   z$No workspace/memory/ directory foundc              3  X   K   | ]%}|                                 |j        d k    !|V  &dS )z.mdN)is_filer  r  s     r`   r  z0Migrator.migrate_daily_memory.<locals>.<genexpr>i  s<      __QYY[[_QXY^M^M^!M^M^M^M^__r_   z'No .md files found in workspace/memory/z1No importable entries found in daily memory filesc                ,    g | ]}t          |          S r^   r-  r%  s     r`   r   z1Migrator.migrate_daily_memory.<locals>.<listcomp>v  s     FFFU++FFFr_   r  r'  r(  r)  r   )source_filesr.  r/  r0  r1  r2  r3  r4  r5  r   rR   r   r   rC   r6  r7  z Would merge daily memory entriesr8  )r  r_  r   r  ry   r  r   r   rf  r   r/  r  r   r   rx   r  rL   ro  r  r   r   )r  
source_dirrP   md_filesall_incomingmd_filer  r  r+  r,  r)  rV   r4  r$  s                 r`   r  zMigrator.migrate_daily_memoryb  s\   **+=>>
&3kA 	!2!2!4!4 	KKk9FlmmmF__Z%7%7%9%9_____ 	KK
KLuvvvF"$ 	) 	)G.y/A/ABBG(((( 	KK
KL  A  A  AFFFFFF0==$1(L$J[$\$\!zMM %j 1"7^!&|!4"'"5+EK RO$8$8$@$@ A A AQR
 
 33NJOO$'*='9'9GO$< 	]W~"":"NJYPjvvnuvvv++K88K+&&&""?#7#7#?#?6CY44WY#Zel"mmmDK	
 ,7>s;'''B!+BQB       DK
KMo  ]  ]  CM  NP  OP  NP  CQ  ]  U\  ]  ]  ]  ]  ]r_   c                z   |                      d          }| j        dz  t          z  }|r|                                s|                     dd |dd           d S d t          |                                          D             }|s|                     d||dd           d S |D ]}||j        z  }|}|                                rE| j        dk    r|                     d||d	d
           H| j        dk    r| 	                    |          }| j
        rd }||k    r)|                                r|                     |          }|j                            dd           ||k    r(|                                rt          j        |           t          j        ||           d|rt#          |          ndi}||k    rt#          |          |d<    | j        d||dfi | ?||k    r*|                     d||ddt#          |                     o|                     d||dd           |dz  }	| j
        rS|	j                            dd           |	                                s!|	                    t&          dz   d           d S d S |	                                s|                     dd |	dd           d S d S )Nzworkspace/skillsr$   rE   z"No OpenClaw skills directory foundc                h    g | ]/}|                                 |d z                                  -|0S r  r  r  s     r`   r   z+Migrator.migrate_skills.<locals>.<listcomp>  r  r_   zNo skills with SKILL.md foundr   skillrF   r  r   Tr   r"  rR   r  rC   z1Would copy skill directory under a renamed folderr  zWould copy skill directoryr  r   r   r   zskill-categoryr  )r  r_  r  r   r  ry   r  r  rt  r  ro  r  r   r   r   r   r   rL   r   r  )
r  r]  r  r  r  rP   r  r$  rV   r  s
             r`   r  zMigrator.migrate_skills  sW   ++,>??+h69OO 	+"4"4"6"6 	KK$(8)EijjjFkk(;(;(=(=!>!>kkk
 	KK+/?LklllF#  	q  	qI*Y^;K +!!## T+v55KKKMoppp+x77(,(F(F{(S(S%| q"$338J8J8L8L3"&"3"3K"@"@K!(..td.KKK$338J8J8L8L3M+...	+<===+35\S5E5E5EZ\*]$33.1+.>.>GN+GY0A:YYQXYYYY$33KK!)"K%(%5%5       KK4EzSopppp$'77	< 	l""4$"???##%% Z$$%?$%FQX$YYYYYZ Z!!## 	lKK($	:Gjkkkkk	l 	lr_   r  r  c           
        r                                 s|                     |d |dd           d S pt                      fd                    d          D             }|s|                     ||dd           d S d}d}d}|D ]}	|	                              }
||
z  }|                                 rLt          |	          t          |          k    r|dz  }V| j        s|dz  }|                     ||	|dd	           || j        r9|                     |           t          |           t          j        |	|           |dz  }|rd
nd}d}|s|rd}d}n|sd}|                     |||||||           d S )NrE   zSource directory not foundc                    g | ]S}|                                 t          fd |                              j        dd         D                       Q|TS )c              3      K   | ]}|v V  	d S r  r^   )r   rm   r  s     r`   r  z@Migrator.copy_tree_non_destructive.<locals>.<listcomp>.<genexpr>  s)      &r&rDt/?'?&r&r&r&r&r&rr_   N)r	  rF  r2  r   )r   r  r  r]  s     r`   r   z6Migrator.copy_tree_non_destructive.<locals>.<listcomp>  sz     
 
 
yy{{
 $'&r&r&r&rAMMZeLfLfLlmpnpmpLq&r&r&r#r#r

 
 
r_   *zNo files foundr   r   rF   zDestination file already existsrC   rR   z>All candidate files conflicted with existing destination fileszNo new files to copy)copied_filesunchanged_filesrQ  )r   r  rv   rglobr2  r   r   ro  r  r   r   r   )r  r]  r  rM   r  filescopiedrE   rQ  rO   r   rP   rQ   rS   s    `  `         r`   r  z"Migrator.copy_tree_non_destructive  s!     	+"4"4"6"6 	KKd$4iA]^^^F+4suu
 
 
 
 
 &&s++
 
 

  	KKk+;YHXYYYF	 	 	F$$[11C*S0K!!## v&&+k*B*BBBqLG~ NIKKfk:Ghiii| 2!!+...k***V[111aKFF%49 	,) 	,FUFF 	,+FD+'7V\nu  BK  	L  	L  	L  	L  	Lr_   c                h   |                      dd          |                      dd          |                      dd          |                      dd          g}|D ]}|r|                     |d	
           dD ]7}| j        |z  }|                                r|                     |d	
           8ddg}|D ]<\  }}| j        |z  }|                                r|                     d|d d|           =g d}|D ]9}| j        |z  }|                                r|                     d|d dd           :d S )Nzworkspace/IDENTITY.mdzworkspace.default/IDENTITY.mdzworkspace/TOOLS.mdzworkspace.default/TOOLS.mdzworkspace/HEARTBEAT.mdzworkspace.default/HEARTBEAT.mdzworkspace/BOOTSTRAP.mdzworkspace.default/BOOTSTRAP.mdz8No direct Hermes destination; archived for manual review)rS   )zworkspace/.learningsr  )rG  zUSelected Hermes-compatible values were extracted; raw OpenClaw config was not copied.)z+credentials/telegram-default-allowFrom.jsonzVSelected Hermes-compatible values were extracted; raw credentials file was not copied.zraw-config-skiprE   )zmemory/main.sqliterV  devicesidentityzworkspace.zipzsensitive-skipz@Contains secrets, binary state, or product-specific runtime data)r  archive_pathr]  r   r  )r  
candidatesr  r   partially_extractedrS   skipped_sensitives          r`   r  zMigrator.archive_docs  s   !!"9;Z[[!!"68TUU!!":<\]]!!":<\]]	

 $ 	p 	pI p!!)4n!ooo? 	p 	pC(3.I!! p!!)4n!ooo w V
 / 	S 	SKC(3.I!! S-y$	6RRR
 
 
 % 	N 	NC(3.I!! N,iy  KM  N  N  N	N 	Nr_   c                l   | j         r| j         t          || j                  z  nd }| j        rm|kt	          |           |                                rt          j        ||d           nt          j        ||           | 	                    d||d|           d S | 	                    d||d|           d S )NTr   r/   rD   )
r  r3  r]  ro  r   r   r   r   r   r  )r  rO   rS   rP   s       r`   r   zMigrator.archive_path*  s    UYUeod&@P)Q)QQQko< 	LK3+&&&}} 24HHHHHV[111KK	6;
FKKKKKKK	6;
FKKKKKr_   c           	        |p|                                  }|                    d          pi                     d          pi }|s|                     dd d dd           d S | j        dz  }t	          |          }|                    d          pi }d}|                                D ]\  }}t          |t                    s||v r'| j        s |                     dd	| d
| dd           Gi }	|                    d          rk|d         |	d<   |                    d          r|d         |	d<   |                    d          r|d         |	d<   |                    d          r|d         |	d<   |                    d          rK|d         |	d<   |                    d          r|d         |	d<   |                    d          r|d         |	d<   |                    d          du rd|	d<   |                    d          r|d         |	d<   |                    d          r|d         |	d<   |                    d          pi }
|
                    d          s|
                    d          rQi |	d<   |
                    d          r|
d         |	d         d<   |
                    d          r|
d         |	d         d<   |                    d          }|rt          |t                    rd |                    d          |                    d          |                    d          p|                    d           |                    d          |                    d!          p|                    d"          d#                                D             |	d<   |	||<   |d$z  }|                     dd	| d%| d&|'           |dk    r3| j	        r.| 
                    |           ||d<   t          ||           d S d S d S )(Nmcpserversr0   rE   z'No MCP servers found in OpenClaw configr}  mcp_serversr   zmcp.servers.zmcp_servers.rF   z*MCP server already exists in Hermes configcommandargsr   cwdurlheadersrC  enabledFtimeoutconnectTimeoutconnect_timeouttoolsro   rp   samplingc                    i | ]
\  }}|||S r  r^   r   kvs      r`   
<dictcomp>z0Migrator.migrate_mcp_servers.<locals>.<dictcomp>n  s/     * * *!Q "# q "/r_   r  maxTokensCapmax_tokens_capmaxRpmmax_rpm)r.  r  r:  r/  r<  r   zconfig.yaml mcp_servers.rC   )servers_added)r  r   r  r_  r   r   r   r]   r   ro  r  r   )r  r  mcp_rawhermes_cfg_path
hermes_cfgexisting_mcpr'  r  srv
hermes_srv	tools_cfgr3  s               r`   r  zMigrator.migrate_mcp_servers7  sy   644466::e$$*//	::@b 	KKtT9>ghhhF*]:#O44
!~~m44:  8	9 8	9ID#c4(( |##DN#M+@$+@+@BWQUBWBWYcHJ J J)+Jwwy!! 3(+I
9%776?? 5),VJv&775>> 3(+E
Ju%775>> 3(+E
Ju%wwu~~ 5$'J
5!779%% ;,/	NJy)776?? 5),VJv&wwy!!U**(-
9%wwy!! 7(+I
9%ww'(( F034D0E
,-((.BI}}Y'' J9==+C+C J&(
7#==++ J5>y5IJw'	2==++ J5>y5IJw'	2wwz**H 	Jx66 	* *#+<<	#:#:!)g!6!6*2,,~*F*F*h(,,WgJhJh#+<<	#:#:#+<<#9#9#TX\\)=T=T& & egg* * *
:& ",LQJEKK'<d'<'<>_Y]>_>_"%  9 9 9 9 1999o...(4J}%?J77777 999r_   c                v   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        r| j        r|| j                            dd           | j        dz  }|                    t          j        |dd	
          dz   d           |                     ddt          |          dd           n"|                     ddd| j        sdndd           | j
        dz  }|                                rb| j        r[| j        dz  }| j        rt          j        ||d           |                     dt          |          t          |          dd           |                    d          pi }|                                D ]\  }}t          |t                     r||                    d          pi }	|                    d          }
|
rN| j        rGd|                                                    dd           d}|                     ||
d| d           d S ) Npluginsr1   rE   zNo plugins configuration foundTr   zplugins-config.jsonr  FrX  r   r   r   zopenclaw.json plugins.*rD   z)Plugins config archived for manual reviewzarchive/plugins-config.jsonrC   zWould archive plugins config
extensionsr   zExtensions directory archivedr  r   r  PLUGIN_r  r   _API_KEYzplugins.entries..apiKey)r  r   r  r  ro  r   r   rc  rd  rL   r]  r   r   r   r   r   r]   rq  upperr  _set_env_var)r  r  rF  r   ext_dirdest_extr  plugin_name
plugin_cfgr  r  env_keys               r`   r  zMigrator.migrate_plugins_config  s   644466**Y''-2 	KK($iAabbbF  	h 	h""4$"???#&;;DOODJwquMMMPTT_fOgggKK(*CSYYPZCE E E E KK(*CEb*.,F

JHfh h h "\1>> 	9 0 	9',6H| GFFFFKK(#g,,Hz79 9 9 ++i((.B'.}} 	a 	a#K*d++ a%>>%006B$..22 at3 aW(9(9(;(;(C(CC(M(MWWWG%%gw8_;8_8_8_```	a 	ar_   c                   |p|                                  }|                    d          pi }| j        dz  }d}|rd}| j        r| j        r|| j                            dd           | j        dz  }|                    t          j        |dd          dz   d	
           | 	                    ddt          |          dd           n| 	                    ddddd           |                                rd| j        r]d}| j        dz  }| j        rt          j        ||d           | 	                    dt          |          t          |          dd           |s| 	                    dd d dd           d S d S )NcronFTr   cron-config.jsonr  rX  r   r   r   r2   zopenclaw.json cron.*rD   zBCron config archived. Use 'hermes cron' to recreate jobs manually.zarchive/cron-config.jsonzWould archive cron config
cron-storer   zCron job store archivedrE   zNo cron configuration found)r  r   r]  r  ro  r   r   rc  rd  r  rL   r   r   r   )r  r  rS  
cron_storer  r   	dest_crons          r`   r  zMigrator.migrate_cron_jobs  s   644466zz&!!'R%.
	  
	EI EDL E &&td&CCC'*<<
4 N N NQU U`ghhhK)?TJ`b b b b K)?A[&(CE E E  	34#3 	3I(<7I| K
ITJJJJKKS__c)nnj13 3 3  	[KKT4<YZZZZZ	[ 	[r_   c                   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        r| j        r|| j                            dd           | j        dz  }|                    t          j        |dd	
          dz   d           |                     ddt          |          dd           n|                     ddddd           dD ]}| j
        |z  dz  }|                                re| j        r^| j        dz  }| j        rt          j        ||d           |                     dt          |          t          |          dd            d S d S )Nhooksr3   rE   zNo hooks configuration foundTr   zhooks-config.jsonr  FrX  r   r   r   zopenclaw.json hooks.*rD   z'Hooks config archived for manual reviewzarchive/hooks-config.jsonzWould archive hooks config)r|  r  zworkspace-hooksr   z"Workspace hooks directory archived)r  r   r  r  ro  r   r   rc  rd  rL   r]  r   r   r   )r  r  rY  r   ws_name	hooks_dir
dest_hookss          r`   r  zMigrator.migrate_hooks_config  s   644466

7##)r 	KKdI?]^^^F  	B 	B""4$"???#&99DOODJuQUKKKdR]dOeeeKK(?TJAC C C C KK(?A\"$@B B B : 	 	G(72W<I!! d&6 !-0AA
< OOIzNNNNNC	NNC
OOZ@B B B	 	r_   c           
     8   |p|                                  }|                    d          pi }|                    d          pi }|                    d          pg }|s|s|                     dd d dd           d S | j        dz  }t	          |          }d}|                    d	          pi }|                    d
          r	 |                    d          rt          |d         dz  d          |d<   d}|                    d          r|d         |d<   d}|                    d          r'|d         }	|	dv rd|d<   n|	dv rd|d<   n	|	dv rd|d<   d}|                    d          pi }
|
r|                    d          pi }|
                    d          dk    rd|d<   nd|d<   |
                    d          r	 |
                    d           r7|                    d!i           }|                    di           }|
d          |d <   ||d<   d}|                    d"          pi }|r|                    d#          pi }|                    d          p|                    d          rd$nd }|r|dk    r||d<   |                    d%          r|d%         |d&<   |                    d'          r|d'         |d(<   ||d#<   d}|                    d)          r|d)         |d*<   d}|                    d+          pi                     d,          pi }|ru|                    d-          pi }|                    d.          s|                    d          r/|                    d.          p|                    d          |d<   d}||d-<   |                    d/          pi }|rv|                    d0          d1k    r]|                    d-          pi }d1|d0<   |                    d1i                               d2          r|d1         d2         |d3<   ||d-<   d}|rJ||d	<   | j        r%|                     |           t          ||           |                     dd4d5d6d7           |r| j
        r\| j        rU| j
                            dd8           | j
        d9z  }|                    t          j        |d:d;          d<z   d=>           |                     dd?d@dAdBt          |           dC           |                    dD          pg }|r| j
        r\| j        rU| j
                            dd8           | j
        dEz  }|                    t          j        |d:d;          d<z   d=>           |                     ddFdGdAdHt          |           dI           d S d S )JNrz  r{  r*  r4   rE   zNo agent configuration foundr}  Fr  contextTokenstimeoutSeconds
      	max_turnsTverboseDefaultverbosethinkingDefault>   highxhighalwaysrf  reasoning_effort>   automediumadaptiverk  >   lowoffnoneminimalrm  
compactioncompressionr\  rn  r.  r/  r  	auxiliary
humanDelayhuman_delaynaturalminMsmin_msmaxMsmax_msuserTimezonetimezoner2  r  terminal
timeoutSecsandboxbackenddockerimagedocker_imagezopenclaw.json agents.defaultsz&config.yaml agent/compression/terminalrC   z&Agent defaults mapped to Hermes configr   zagents-list.jsonr  rX  r   r   r   zopenclaw.json agents.listzarchive/agents-list.jsonrD   zMulti-agent setup (z' agents) archived for manual recreationbindingszbindings.jsonzopenclaw.json bindingszarchive/bindings.jsonzAgent routing bindings (z rules) archived)r  r   r  r_  r   minre  ro  r  r   r  r   r   rc  rd  r   )r  r  rz  r{  
agent_listr?  r@  changes	agent_cfgthinkingrq  rr  auxaux_compru  hdhd_modeexec_cfgterminal_cfgr  r   r  s                         r`   r  zMigrator.migrate_agent_config  s   644466H%%+::j))/RZZ''-2
 	
 	KKdI?]^^^F*]:#O44
 NN7++1r	<<(( 	<<()) 	%(2B)Cr)I3%O%OIk"G<<()) 	#+,<#=Ii G<<)** 		 12H66606	,--;;;08	,-->>>05	,-G \\,//52
 	$..77=2K~~f%%..).I&&)-I&~~i(( ~~g&& 8 ++K<<>>-<<$.w$7!(3J}%G ll<006B 
	..4"B!oof--d{y?Y?Y2c))_cG %7e++$6
w'' 4*738w'' 4*738(*J}%G <<'' 	%-n%=Jz"G JJw''-2226::@b 	2%>>*55;L||L)) X\\)-D-D *2,,|*D*D*_U^H_H_Y'%1Jz" ,,y))/R 	w{{9--99%>>*55;L&.L#{{8R((,,W55 J/6x/@/I^,%1Jz"G 	N"+Jw| <!!/222
;;;KK(GIq"$LN N N  	t oDL o &&td&CCC'*<<
:ae T T TW[ [fmnnnKK(CE_"$r#j//$r$r$rt t t ::j))/R 	` mDL m &&td&CCC'/9
8AE R R RUY YdklllKK(@BY"$^s8}}$^$^$^` ` ` ` `	` 	`r_   c                :   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        r\| j        rU| j                            dd           | j        dz  }|                    t          j        |dd	
          dz   d           |                     ddddd           |                    d          pi }|                    d          r&| j	        r!| 
                    d|d         d           d S d S d S )Ngatewayr5   rE   zNo gateway configuration foundTr   zgateway-config.jsonr  FrX  r   r   r   zopenclaw.json gateway.*zarchive/gateway-config.jsonrD   z;Gateway config archived. Use 'hermes gateway' to configure.rC  rB  HERMES_GATEWAY_TOKENzgateway.auth.token)r  r   r  r  ro  r   r   rc  rd  rq  rL  )r  r  r  r   rC  s        r`   r  zMigrator.migrate_gateway_config^	  sc   644466**Y''-2 	KK($iAabbbF  	h 	h""4$"???#&;;DOODJwquMMMPTT_fOggg$&?A^ ]	_ 	_ 	_ {{6""(b88G 	[!5 	[4d7mEYZZZZZ	[ 	[ 	[ 	[r_   c                   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        dz  }t	          |          }|                    d          pi }d}|                    d          pi }|                    d	          p|                    d
          pg }|rx|                    dd          }	|	dk    rd|d<   n|	dk    rd|d<   n|	pd|d<   |                    d          |d         |d<   |                    d          r|d         |d<   d}n:t          |t                    r%|r#d|v }
d|v }|
r|rd|d<   n|
rd|d<   n|rd|d<   d}|rI||d<   | j        r%|                     |           t          ||           |                     dddd           h dfd|
                                D             }|r~| j        ry| j        rU| j                            dd           | j        dz  }|                    t          j        |dd          dz   d !           |                     dd"d#d$d%           d S d S d S )&Nsessionr6   rE   zNo session configuration foundr}  session_resetFresetresetTriggersreset_triggersr\  rR   dailyidlero  atHourat_houridleMinutesidle_minutesTbothz#openclaw.json session.resetTriggerszconfig.yaml session_resetrC   >   scope
sendPolicymaintenanceidentityLinksthreadBindingsc                (    i | ]\  }}|v 	|||S r^   r^   )r   r6  r7  complex_keyss      r`   r8  z3Migrator.migrate_session_config.<locals>.<dictcomp>	  s/    WWWDAqqL?P?PUV?P1a?P?P?Pr_   r   zsession-config.jsonr  rX  r   r   r   z openclaw.json session (advanced)zarchive/session-config.jsonrD   zJAdvanced session settings archived (identity links, thread bindings, etc.))r  r   r  r_  r   r   r*  ro  r  r   r   r  r   r   rc  rd  )r  r  r  r?  r@  srr  r  r  r\  	has_dailyhas_idlecomplex_sessionr   r  s                 @r`   r  zMigrator.migrate_session_configs	  s.   644466**Y''-2 	KK($iAabbbF*]:#O44
^^O,,2 G$$* _55\EU9V9V\Z\ 	99VR((Dw$6

#6

!^V6
yy"". %h9yy'' :%*=%9>"GG-- 
	. 
	>1I/H $X $#6

 $$6

 $#6
G 	A*,J'| <!!/222
;;;KK(*O3ZA A A a``WWWWGMMOOWWW 	ft/ 	f| t &&td&CCC'*??
?1SX Y Y Y\` `krsssKK(*L5zdf f f f f	f 	f 	f 	fr_   c           
        |p|                                  }|                    d          pi }|                    d          pi }|s|                     dd d dd           d S | j        dz  }t	          |          }|                    d          pg }d}h d	}|                                D ]\  }	}
t          |
t                    s|
                    d
          p|
                    d          }|rM| j        rF|		                                
                    dd           d}|                     ||d|	 d           |	                                |vr|
                    d          rd |D             }|	                                |v r)| j        s"|                     dd|	 ddd|	 d           |
                    d          p+|
                    d          p|
                    d          pd}dddddddd}|	|
d         d|                    |d          d}|                    |           |d z  }|                     dd|	 d!|	 d"d#           |dk    r1| j        r*|                     |           ||d<   t#          ||           |                    d$          pi                     d%          pi }|                    d          pi }|r| j        r\| j        rU| j                            d&d&'           | j        d(z  }|                    t+          j        |d)d*+          d,z   d-.           |                     dd/d0d1d2t/          |           d3           d S d S )4Nr  r  r7   rE   zNo model providers foundr}  custom_providersr   >   groqgoogler  deepseekr  r  r  r  r  r   rI  zmodels.providers.rJ  r  c                ^    h | ]*}|                     d d                                          +S )r  rR   )r   ri   r  s     r`   r&  z2Migrator.migrate_full_providers.<locals>.<setcomp>	  s2    !V!V!V!%%"3"3"9"9";";!V!V!Vr_   zconfig.yaml custom_providersrF   r  z' already existsapiTyper  typer  chat_completionsanthropic_messages)r  zopenai-completionszopenai-responsesr  r  zgoogle-generative-aicohererR   )r  r  r  api_moder   zconfig.yaml custom_providers[]rC   rz  r{  Tr   zmodel-aliases.jsonr  FrX  r   r   r   zagents.defaults.modelszarchive/model-aliases.jsonrD   zModel aliases/catalog ( entries) archived)r  r   r  r_  r   r   r   r]   rq  rK  r  rL  ri   r   rj   ro  r  r   r  r   r   rc  rd  r   )r  r  r  r  r?  r@  r  r'  
WELL_KNOWN	prov_nameprov_cfgr  rQ  existing_namesr  api_mode_mapr  agent_defaultsmodel_aliasesr   s                       r`   r  zMigrator.migrate_full_providers	  s2   644466H%%+JJ{++1r	 	KK($iA[\\\F*]:#O44
%>>*<==C YXX
#,??#4#4 '	V '	VIxh--  ll8,,GY0G0GG \4/ \&__..66sC@@JJJ!!'74Z	4Z4Z4Z[[[   
22x||I7N7N2!V!VEU!V!V!V??$$66t~6KK 02Qi2Q2Q >
 HY H H HJ J J #<<	22mhll56I6ImX\\Z`MaMamem0*<(:!5*>,>0    & ( 3! , 0 0;M N N	  !''...
,.M).M.MHIHHH*V V V 1999o...-=J)*?J777 !**X..4"99*EEK&**844: 	f rDL r &&td&CCC'*>>
=QV W W WZ^ ^ipqqqKK(*BD`"$dc->P>P$d$d$df f f f f	f 	fr_   c                t   |p|                                  }|                    d          pi }|s|                     dd d dd           d S ddddd	d
ddddddddddddidddiii ddddidddddd d!id"dd#id$d%	}|                                D ]\  }}|                    |          pi }|s |                    d&d'          }|                     ||          }|                    d(          r9|r7| j        r0|                     |d(         t          |          d)| d*|            |                     |d+          }	|                    d+          rd|	rbt          |	t                    rd,
                    d- |	D                       }	|                     |d+         t          |	          d)| d.           |                    d          pi                                 D ]\  }
}|                     ||
          }|rt          |t                    rd,
                    d/ |D                       }d0|
                                v p+d(|
                                v pd1|
                                v }|r| j        s|                     |t          |          d)| d*|
            Ȑ|                    d2          pi }|r| j        d3z  }t          |          }|                    d2          pi }d4}d5|v r|d5         |d6<   d7}|                    d8          |d8         |d9<   d7}|r| j        r||d2<   t          ||           i }|                                D ]@\  }}t          |t                     sd: |                                D             }|r|||<   A|r| j        r| j        rU| j                            d7d7;           | j        d<z  }|                    t)          j        |d=d4>          d?z   d@A           |                     ddBdCdDdEt-          |           dF           d S d S d S )GNrj  r8   rE   zNo channel configuration foundzMATRIX...OKENaccessTokenMATRIX_ALLOWED_USERSMATRIX_HOMESERVER_URLMATRIX_USER_ID)homeserverUrluserId)rB  
tokenFieldrW  extrasMATTERMOST_BOT_TOKENMATTERMOST_ALLOWED_USERSMATTERMOST_URLMATTERMOST_TEAM_ID)r,  teamId)rB  rW  r  r  
IRC_SERVERIRC_NICKIRC_CHANNELS)servernickrj  serviceAccountKeyPathGOOGLE_CHAT_SA_KEY_PATHBLUEBUBBLES_SERVERBLUEBUBBLES_PASSWORD)r  r;  MSTEAMS_BOT_TOKENMSTEAMS_ALLOWED_USERS)rB  rW  
NOSTR_NSECNOSTR_RELAYS)nsecrelaysTWITCH_BOT_TOKENTWITCH_CHANNELS)rB  r  )	matrix
mattermostirc
googlechatimessagebluebubblesmsteamsnostrtwitchr  rl  rB  z	channels..rW  rf   c              3  4   K   | ]}t          |          V  d S r  rL   r   xs     r`   r  z1Migrator.migrate_deep_channels.<locals>.<genexpr> 
  s(      (C(CAQ(C(C(C(C(C(Cr_   z
.allowFromc              3  4   K   | ]}t          |          V  d S r  r  r  s     r`   r  z1Migrator.migrate_deep_channels.<locals>.<genexpr>(
  s(      &;&;!s1vv&;&;&;&;&;&;r_   r;  r  ry  r}  FrequireMentionrequire_mentionT
autoThreadauto_threadc                .    i | ]\  }}|d vr	|r|dv||S )>   r.  r  rl  rW  >   r  r  r^   r5  s      r`   r8  z2Migrator.migrate_deep_channels.<locals>.<dictcomp>D
  sK     O O OTQ&VVV W$%-M$M$M q$M$M$Mr_   r   zchannels-deep-config.jsonr  rX  r   r   r   z*openclaw.json channels (advanced settings)z!archive/channels-deep-config.jsonrD   zDeep channel config for z channels archived)r  r   r  r   rm  rq  rL  rL   r   r*  rx   ri   r_  r   ro  r   r]   r  r   r   rc  rd  r   )r  r  rj  CHANNEL_ENV_MAPch_name
ch_mappingrs  token_fieldr  	allow_valr  rQ  rw  	is_secretdiscord_cfgr?  r@  discord_hermeschangedcomplex_archiver  r   s                         r`   r  zMigrator.migrate_deep_channels	  s   644466::j))/R 	KKtY@`aaaF !0}[q4KWg"h"hj j$:Ic-=I]%^%^` `zWeffg#&=?X%YZ$1ESi&j&jk!4CZ[[ P PQ 2zK\>]^^
 
 $3#8#8#:#: 	Y 	YGZ\\'**0bF  %..zBBK//DDI~~g&& G9 G9M G!!*W"5s9~~"Eg"E"E"E"EG G G//DDI~~k** Cy Ci.. D #(C(C(C(C(C C CI!!*["93y>>"Ag"A"A"AC C C %/NN8$<$<$B#I#I#K#K Y Y--ff== Y!#t,, <!hh&;&;s&;&;&;;; *fllnn < u6<<>>@Y u]cgmgsgsgugu]uI  !)= ! %%gs3xx9WW9W9Wv9W9WXXXY ll9--3 	<".>O'88J'^^I66<"NG;..4?@P4Q01|,,80;L0I}- <4< <(6
9%
;;; '~~// 	8 	8OGVfd++ O OV\\^^ O O OL  8+7( 	]t/ 	]| t &&td&CCC'*EE
?1SX Y Y Y\` `krsssKK)U;Z[33G3G[[[] ] ] ] ]	] 	] 	] 	]r_   c                Z   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        dz  }t	          |          }|                    d          pi }d}|                    d          r|d         |d<   d	}|                    d
          |d
         |d
<   d	}|rI||d<   | j        r%|                     |           t          ||           |                     dddd           d |                                D             }|r}| j	        rx| j        rU| j	        
                    d	d	           | j	        dz  }|                    t          j        |dd          dz   d           |                     dddd           d S d S d S )Nbrowserr9   rE   zNo browser configuration foundr}  FcdpUrlcdp_urlTheadlesszopenclaw.json browser.*zconfig.yaml browserrC   c                &    i | ]\  }}|d v	|||S )>   r  r  r^   r5  s      r`   r8  z3Migrator.migrate_browser_config.<locals>.<dictcomp>q
  s8     = = =TQ555!5 q555r_   r   zbrowser-config.jsonr  rX  r   r   r   z openclaw.json browser (advanced)zarchive/browser-config.jsonrD   )r  r   r  r_  r   ro  r  r   r   r  r   r   rc  rd  )	r  r  r  r?  r@  browser_hermesr  advancedr   s	            r`   r  zMigrator.migrate_browser_configT
  s"   644466**Y''-2 	KK($iAabbbF*]:#O44
#	228b ;;x   	(/(9N9%G;;z"".)0)<N:&G 	$$2Jy!| <!!/222
;;;KK(*CEZ"$ $ $= =W]]__ = = = 	C( 	C| m &&td&CCC'*??
8AE R R RUY YdklllKK(*L5zC C C C C	C 	C 	C 	Cr_   c                   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        dz  }t	          |          }d}|                    d          pi }|                    d          p|                    d	          }|r#|                    d
          pi }||d	<   ||d
<   d}|                    d          p|                    d          pi }	|	                    d          s|	                    d          p|	n|	d         }
|
                    d          pi }|                    d          p)|
                    d          p|	                    d          }|r3t          |t                    r| j        r|                     d|d           |rD| j	        r=| 
                    |           t          ||           |                     dddd           | j        rw| j	        rU| j                            dd           | j        dz  }|                    t          j        |dd          dz   d           |                     dddd d!           d S d S )"Nr2  r:   rE   zNo tools configuration foundr}  Fr  r~  r/  r}  Tweb	webSearchr   braver  braveApiKeyBRAVE_API_KEYztools.web.search.brave.apiKeyzopenclaw.json tools.*zconfig.yaml terminalrC   r   ztools-config.jsonr  rX  r   r   r   zopenclaw.json tools (full)zarchive/tools-config.jsonrD   z(Full tools config archived for reference)r  r   r  r_  r   r   rL   rq  rL  ro  r  r   r  r   r   rc  rd  )r  r  r2  r?  r@  r  r  timeout_valr  web_cfg
search_cfg	brave_cfg	brave_keyr   s                 r`   r  zMigrator.migrate_tools_config|
  s   644466

7##)r 	KKdI?]^^^F*]:#O44
 99V$$*ll<00KHLL4K4K 	%>>*55;L&1L#%1Jz"G ))E""Beii&<&<B=D[[=R=RiW[[**5gX_`hXi
NN7++1r	MM(++jz~~m/L/LjPWP[P[\iPjPj	 	[Is33 	[8L 	[oy:YZZZ 	$t| 	$o...?J777KK(?AW"$ $ $  	P| j &&td&CCC'*==
5 O O ORV VahiiiKK(DFa"$NP P P P P	P 	Pr_   c                   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        dz  }t	          |          }|                    d          pi }t          |t                    r|                    d          nd p)|                    d          p|                    d          }|rd	d
dd
d}|                    |d
          }||                    di           d<   | j        r%| 	                    |           t          ||           |                     ddddd| d| d           t          |          dk    r}| j        rx| j        rU| j                            dd           | j        dz  }	|	                    t          j        |dd          dz   d           |                     dddd           d S d S d S ) N	approvalsr;   rE   z No approvals configuration foundr}  r  r\  defaultModern  manualsmart)rj  rh  r  r  zopenclaw.json approvals.modezconfig.yaml approvals.moderC   zMapped 'z' -> ''r   Tr   zapprovals-config.jsonr  FrX  r   r   r   zopenclaw.json approvals (rules)zarchive/approvals-config.jsonrD   )r  r   r  r_  r   r   r]   re  ro  r  r   r   r  r   r   rc  rd  )
r  r  r  r?  r@  exec_approvalsr\  mode_maphermes_moder   s
             r`   r  z!Migrator.migrate_approvals_config
  sb   644466JJ{++1r	 	KK*D$	CefffF*]:#O44
 #v..4".8.N.NX""6***TX  S]f]j]jkq]r]r  Sv  wD  wD  ER  wS  wS 	i %GW_``H",,tX66K=HJ!!+r226:| <!!/222
;;;KK*,J4jBgTBgBgYdBgBgBgi i i y>>A$"2| n &&td&CCC'*AA
9QU S S SVZ ZelmmmKK*,M7E E E E E r_   c                   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        r\| j        rU| j                            dd           | j        dz  }|                    t          j        |dd	
          dz   d           |                     ddddd           d S )Nr   r<   rE   z%No memory backend configuration foundTr   zmemory-backend-config.jsonr  FrX  r   r   r   zopenclaw.json memory.*z"archive/memory-backend-config.jsonrD   zPMemory backend config (QMD, vector search, citations) archived for manual review	r  r   r  r  ro  r   r   rc  rd  )r  r  r   r   s       r`   r  zMigrator.migrate_memory_backend
  s    644466H%%+ 	KK($iAhiiiF 	g 	g""4$"???#&BBDOODJvaeLLLtS^eOfff$&>@d r	t 	t 	t 	t 	tr_   c           
        |p|                                  }|                    d          pi }|                    d          pi }|s|s|                     dd d dd           d S | j        r\| j        rU| j                            dd           | j        dz  }|                    t          j        |d	d
          dz   d           |                     dddddt          |           d           d S )Nr$   r  r=   rE   z&No skills registry configuration foundTr   zskills-registry-config.jsonr  FrX  r   r   r   zopenclaw.json skills.*z#archive/skills-registry-config.jsonrD   zSkills registry config (r  )
r  r   r  r  ro  r   r   rc  rd  r   )r  r  r$   r  r   s        r`   r  zMigrator.migrate_skills_config
  s$   644466H%%+**Y''-2 	v 	KKtY@hiiiF 	g 	g""4$"???#&CCDOODJvaeLLLtS^eOfffO%=?d [3w<< [ [ [	] 	] 	] 	] 	]r_   c                   |p|                                  }|                    d          pi }|s|                     dd d dd           d S | j        r\| j        rU| j                            dd           | j        dz  }|                    t          j        |dd	
          dz   d           |                     ddddd           d S )Nuir>   rE   z"No UI/identity configuration foundTr   zui-identity-config.jsonr  FrX  r   r   r   zopenclaw.json ui.*zarchive/ui-identity-config.jsonrD   z'UI theme and identity settings archivedr  )r  r  r  r   s       r`   r  zMigrator.migrate_ui_identity
  s    644466ZZ# 	KKtT9>bcccF 	c 	c""4$"???#&??DOODJr!%HHH4OZaObbbM#79Z I	K 	K 	K 	K 	Kr_   c                   |p|                                  }|                    d          pi }|                    d          pi }i }|r||d<   |r||d<   |s|                     dd d dd           d S | j        r\| j        rU| j                            dd           | j        dz  }|                    t          j        |d	d
          dz   d           |                     dddd           d S )Nloggingdiagnosticsr?   rE   z*No logging/diagnostics configuration foundTr   zlogging-diagnostics-config.jsonr  FrX  r   r   r   z!openclaw.json logging/diagnosticsz'archive/logging-diagnostics-config.jsonrD   r  )r  r  logging_cfgr   combinedr   s         r`   r  zMigrator.migrate_logging_config
  s4   644466jj++1rjj//52 	."-HY 	2&1H]# 	KK($iAmnnnF 	i 	i""4$"???#&GGDOODJxNNNQUU`gOhhh$&I=z	K 	K 	K 	K 	Kr_   r   source_labelc           	         | j         dz  }| j        rQt          |          }||v r)| j        s"|                     d|d| dd| d           d S |||<   t          ||           |                     d|d| d           d S )NrJ  zenv-varz.env rF   zEnv var z already setrC   )r_  ro  r   r   r  r   )r  r   rl   r#  env_pathrP  s         r`   rL  zMigrator._set_env_var  s    #f,< 	.%h//Hht~I|]S]]J8s888: : :!HSM(H---I|]S]]JGGGGGr_   c           	        | j         sd S g d}d | j        D             }|r^|                    g d           |D ]/}|                    d|j         d|j         d|j                    0|                    d           d | j        D             }|rV|                    g d	           |D ]'}|                    d|j         d
|j                    (|                    d           t          d | j        D                       }t          d | j        D                       }|                    g d           |r|                    d           n|r|                    d           t          d | j        D                       }|r|                    g d           t          d | j        D                       }|r|                    g d           |                    g d           | j        rS| j         	                    dd           | j         dz  
                    d                    |          dz   d           d S d S )N)
z$# OpenClaw -> Hermes Migration NotesrR   zHThis document lists items that require manual attention after migration.rR   z## PM2 / External ProcessesrR   zGYour PM2 processes (Discord bots, Telegram bots, etc.) are NOT affectedzDby this migration. They run independently and will continue working.z+No action needed for PM2-managed processes.rR   c                (    g | ]}|j         d k    |S )rD   rQ   r   is     r`   r   z5Migrator.generate_migration_notes.<locals>.<listcomp>)  s$    DDD!QX-C-CA-C-C-Cr_   )z(## Archived Items (Manual Review Needed)rR   zEThese OpenClaw configurations were archived because they don't have azEdirect 1:1 mapping in Hermes. Review each file and recreate manually:rR   z- **z**: `z` -- rR   c                (    g | ]}|j         d k    |S )rF   r(  r)  s     r`   r   z5Migrator.generate_migration_notes.<locals>.<listcomp>6  s$    EEE1ah*.D.DQ.D.D.Dr_   )z5## Conflicts (Existing Hermes Config Not Overwritten)rR   z>These items already existed in your Hermes config. Re-run withz*`--overwrite` to force, or merge manually:rR   z**: c              3     K   | ];}|j         d k    o+|j        dk    o |j        o|j                            d          V  <dS )r2   rD   rT  NrM   rQ   rP   r  r)  s     r`   r  z4Migrator.generate_migration_notes.<locals>.<genexpr>C  sh       &
 &
 Fk!}ah*&<}}STS`SiSij|S}S}&
 &
 &
 &
 &
 &
r_   c              3     K   | ];}|j         d k    o+|j        dk    o |j        o|j                            d          V  <dS )r2   rD   rU  Nr-  r)  s     r`   r  z4Migrator.generate_migration_notes.<locals>.<genexpr>G  sh       %
 %
 Fk!wah*&<wwSTS`SiSijvSwSw%
 %
 %
 %
 %
 %
r_   )z,## IMPORTANT: Archive the OpenClaw DirectoryrR   zLAfter migration, your OpenClaw directory still exists on disk with workspacezLstate files (todo.json, sessions, logs). If the Hermes agent discovers thesezKdirectories, it may read/write to them instead of the Hermes state, causingzTconfusion (e.g., cron jobs reading a different todo list than interactive sessions).rR   zJ**Strongly recommended:** Run `hermes claw cleanup` to rename the OpenClawzPdirectory to `.openclaw.pre-migration`. This prevents the agent from finding it.uH   The directory is renamed, not deleted — you can undo this at any time.rR   zLIf you skip this step and notice the agent getting confused about workspacesz3or todo lists, run `hermes claw cleanup` to fix it.rR   z## Hermes-Specific SetuprR   z!After migration, you may want to:zX- Run `hermes claw cleanup` to archive the OpenClaw directory (prevents state confusion)z8- Run `hermes setup` to configure any remaining settingszE- Run `hermes mcp list` to verify MCP servers were imported correctlyzN- Run `hermes cron` to recreate scheduled tasks (see archive/cron-config.json)zI- Run `hermes cron` to recreate scheduled tasks (see archived cron-store)c              3  B   K   | ]}|j         d k    o
|j        dk    V  dS )r$   rC   NrM   rQ   r)  s     r`   r  z4Migrator.generate_migration_notes.<locals>.<genexpr>i  s5      [[18+FJ0F[[[[[[r_   )rR   z## Imported SkillsrR   zFImported skills require a new session to take effect. After migration,zBrestart your agent or start a new chat session, then run `/skills`z to verify they loaded correctly.rR   c              3  B   K   | ]}|j         d k    o
|j        dk    V  dS )r(   rC   Nr0  r)  s     r`   r  z4Migrator.generate_migration_notes.<locals>.<genexpr>v  s7      hhXY16%88SQX=Shhhhhhr_   )rR   z## WhatsApp Requires Re-PairingrR   zCWhatsApp uses QR-code pairing, not token-based auth. Your allowlistz9was migrated, but you must re-pair the device by running:rR   z    hermes whatsapprR   )z>- Run `hermes gateway install` if you need the gateway servicez4- Review `~/.hermes/config.yaml` for any adjustmentsrR   Tr   zMIGRATION_NOTES.mdr   r   r   )rU  r   rf  rj   rM   rP   rS   rF  ro  r   r   rx   )	r  notesrD   ri  rQ  has_cron_config_archivehas_cron_store_archive
has_skillshas_whatsapps	            r`   r  z!Migrator.generate_migration_notes  sP    	F
 
 
 EDtzDDD 
	LL       ! Z ZXDIXXD4DXX4;XXYYYYLLEE
EEE	 
	LL       " B B@DI@@4;@@AAAALL"% &
 &
Z&
 &
 &
 #
 #
 "% %
 %
Z%
 %
 %
 "
 "

 	 
 
 
 	 	 	. # 	fLLijjjj# 	fLLdeee [[PTPZ[[[[[
 		LL       hh]a]ghhhhh 
	LL 	 	 	 	 	 	 	 
 
 
 	 	 	 < 	O!!$!>>>_33??		%  4'' @     	 	r_   )NrR   r   )r]  r   r_  r   ro  rW   rp  r   r   rW   rq  rW   rU  r   rr  rs  r~   rL   rt  rL   )r  rL   rc   rW   )rR   )rM   rL   rO   r   rP   r   rQ   rL   rS   rL   rV   r	   rc   r   )r  rL   rc   r   )rP   r   rc   r   )rc   rU   )r  rL   rc   r   )r`  r  rc   rd   )r   r   rc   r   )rM   rL   r  r  rc   r   r  )
rO   r   rP   r   rM   rL   r  r   rc   r   r  )
rO   r   rP   r   r   r!  rM   rL   rc   r   )rc   r   )rL  r   rM   rL   rO   r   rc   r   )r  rS  rc   r   )r  rU   rc   r   )rl   r	   rc   rN   )rs  rU   r   rL   rc   r	   )r]  r   r  rL   r  rL   rc   r   )
r]  r   r  r   rM   rL   r  rs  rc   r   )rO   r   rS   rL   rc   r   )r   rL   rl   rL   r#  rL   rc   r   )@rY   rZ   r[   r  r  	frozensetr  r  r  r  r  r  r  r  r  r  r  r%  r  r  r  r  r  rK  rR  r  r  rf  rr  staticmethodrm  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rL  r  r^   r_   r`   rn  rn    se        04#)C C C C CJ2 2 2 2  )y * * *    8 2 2 2 2 2:# # # #J
 
 
 
H# H# H# H#T   4+ + + +Z" " " "H   26 6 6 6
    .2M M M M M6b b b b] ] ] ]*B *B *B *BX9| 9| 9| 9|v
 
 
 
9 9 9 9, , , ,\&i &i &i &i &iP    4   (E E E E 
 
 
 \
S S S S S$O O O O O*U U U U UQ Q Q Q Q*+ + + + +I I I IVCr Cr Cr Cr CrJbD bD bD bD bDH{ { { {"1s 1s 1s 1sf6] 6] 6] 6]p4l 4l 4l 4lv 043L 3L 3L 3L 3Lj#N #N #N #NJ
L 
L 
L 
LI8 I8 I8 I8 I8X#a #a #a #a #aL[ [ [ [ [@    <t` t` t` t` t`n[ [ [ [ [*<f <f <f <f <f~Gf Gf Gf Gf GfTU] U] U] U] U]p%C %C %C %C %CP)P )P )P )P )PXE E E E EBt t t t t] ] ] ] ] K K K K KK K K K K*
H 
H 
H 
Ht t t t t tr_   rn  argparse.Namespacec                 B   t          j        d          } |                     dt          t	          j                    dz            d           |                     dt          j                            d          p"t          t	          j                    d	z            d
           |                     dd           |                     ddd           |                     ddd           |                     ddd           |                     dt          t                    dd           |                     dt          t                    d           |                     ddg dd                     t          t                               !           |                     d"dg d#d                     t          t                               !           |                     d$d%           |                     d&dd'd()           |                                 S )*Nz.Migrate OpenClaw user state into Hermes Agent.)r   z--sourcez	.openclawzOpenClaw home directory)rv  helpz--targetHERMES_HOMEz.hermeszHermes home directoryz--workspace-targetzNOptional workspace root where the workspace instructions file should be copied)r;  z	--execute
store_truez,Apply changes instead of reporting a dry run)actionr;  z--overwritez7Overwrite existing Hermes targets after backing them upz--migrate-secretszOImport a narrow allowlist of Hermes-compatible secrets into the target env filez--skill-conflictr   z_How to handle imported skill directory conflicts: skip, overwrite, or rename the imported copy.)choicesrv  r;  z--presetzpApply a named migration preset. 'user-data' excludes allowlisted secrets; 'full' includes all compatible groups.)r?  r;  z	--includerj   zKComma-separated migration option ids to include (default: all). Valid ids: rt   )r>  rv  r;  z	--excludez9Comma-separated migration option ids to skip. Valid ids: z--output-dirz1Where to write report, backups, and archived docsz--jsonjson_outputzPrint the migration report as JSON on stdout (redacted). Combine with no --execute for a safe plan-only machine-readable preview.)r>  r   r;  )argparseArgumentParseradd_argumentrL   r   r  osenvironr   ry   r  rB   rx   r@   
parse_args)parsers    r`   rF  rF    s   $1abbbF

C	k0I,J,JQjkkk

BJNN=,I,I,iSQUQZQ\Q\_hQhMiMi  qH  I  I  I
]     L?mnnn
lAz{{{
^    
 +,,n	     ())    
 J99V,E%F%FGGJ J	     J99V,E%F%FGGJ J	     -`aaa
X	     r_   c                    t                      } 	 t          | j        | j        | j                  }nK# t
          $ r>}t          t          j        dt          |          idd                     Y d }~dS d }~ww xY wt          t          t          j                            | j                                                            t          t          j                            | j                                                            t%          | j                  | j        rCt          t          j                            | j                                                            nd t%          | j                  t%          | j                  | j        rCt          t          j                            | j                                                            nd || j        pd| j        
  
        }|                                }t5          | dd          r3t          t          j        t7          |          dd                     d	S |d
         }|d         }| j        sdnd}t9          |                                          }t                       t          d           t          d|dd           t          d           t          dt          |d                   d d         dd           t          dt          |d                   d d         dd           t          d           t          d|                    dd	          dd|                    dd	          dd           t          d |                    d!d	          dd"|                    d#d	          dd           t          d$|                    dd	          dd%|dd           t          d&           d' |D             }	|	rt                       t          d(           t?                      }
|	D ]}|d)         }||
v r|
                     |           |                    d*          pd}|!                    t          |d                             r0d+|tE          t          |d                             d,z   d          z   }tF                              |i           }|                    d-|          }t          d.|d/d0|            d1 |D             }|rt                       t          d2           t?                      }
|D ]}|d)         }||
v r|
                     |           |                    d3d          }tF                              |i           }|                    d-|          }tE          |          d4k    r|d d4         d5z   n|}t          d6|d/d7|            d8 |D             }|rQt                       t          d9           |D ]1}t          d:|d)          d;|                    d3d                      2d< |D             }|rQt                       t          d=           |D ]1}t          d>|d)          d;|                    d3d                      2t                       t          d?           | j        rt                       t          d@           t          dA           t          dB           tI          dC |D                       rt          dD           |                    dE          rt          dF|dE          dG           n$| j        st                       t          dH           t                       t          j%                            dI          r$t          t          j        |dd                     |                    dd	          d	k    rd	nd,S )JN)rq   rG   r  FrX  rR   )
r]  r_  ro  rp  r   rq  rU  rr  r~   rt  r@  r   r`  r   zDRY RUNEXECUTEDu     ╔══════════════════════════════════════════════════════╗u(     ║   OpenClaw -> Hermes Migration   [z>8su   ]   ║u     ╠══════════════════════════════════════════════════════╣u     ║  Source:  r]  *   z<42su     ║u     ║  Target:  r_  u     ║  ✔ Migrated:  rC   z>3du       ◆ Archived:  rD   u           ║u     ║  ⊘ Skipped:   rE   u       ⚠ Conflicts: rF   u     ║  ✖ Errors:    z    Total:       u     ╚══════════════════════════════════════════════════════╝c                *    g | ]}|d          dk    |S )rQ   rC   r^   r)  s     r`   r   zmain.<locals>.<listcomp>  &    >>>aAhK:$=$=$=$=$=r_   z  Migrated:rM   rP   z
~/.hermes/r   r   u       ✔ z<35sz -> c                *    g | ]}|d          dk    |S )rQ   rD   r^   r)  s     r`   r   zmain.<locals>.<listcomp>  rL  r_   z"  Archived (manual review needed):rS   2   z...u       ◆ z  c                *    g | ]}|d          dk    |S )rQ   rF   r^   r)  s     r`   r   zmain.<locals>.<listcomp>  s&    ???qQx[J%>%>%>%>%>r_   z'  Conflicts (use --overwrite to force):u       ⚠ r  c                *    g | ]}|d          dk    |S )rQ   rG   r^   r)  s     r`   r   zmain.<locals>.<listcomp>  s&    999A!H+"8"8a"8"8"8r_   z	  Errors:u       ✖ u=     ℹ PM2 processes (Discord/Telegram bots) are NOT affected.z  Next steps:z#    1. Review ~/.hermes/config.yamlz    2. Run: hermes mcp listc              3  F   K   | ]}|d          dk    o|d         dk    V  dS )rM   r2   rQ   rD   Nr^   r)  s     r`   r  zmain.<locals>.<genexpr>.  s9      UU!qyK'EAhK:,EUUUUUUr_   z&    3. Recreate cron jobs: hermes cronrU  u       → Full report: z/MIGRATION_NOTES.mdz5  This was a dry run. Add --execute to apply changes.MIGRATION_JSON_OUTPUT)&rF  r   ro   rp   rq   rw   printrc  rd  rL   rn  r   rD  r   r  rO   r  targetrW   ro  rp  r   rq  rU  skill_conflictr  getattrrO  sumra   r   rv   r  r   r   r@   rF  rE  )r*  rr  rC  migratorrV  sr   
mode_labeltotalrC   
seen_kindsri  r   r   r  displayrD   rS   short_reasonrQ  errorss                        r`   r  r    sE   <<D3DL$,W[Wbccc   dj'3s88,QUKKKLLLqqqqq ++DK8899AACC++DK8899AACCT\""VZVkubg001FGGHHPPRRRqut~&&T122JN/c4**4?;;<<DDFFF_c)K%2 /  H F
 t]E** dj/77PUVVVWWWq 	yA7OE"&,>JJ

OOE	GGG	  x  y  y  y	
LZ
L
L
L
LMMM	  x  y  y  y	
HS!677<
H
H
H
HIII	
HS!677<
H
H
H
HIII	  x  y  y  y	
u155Q#7#7
u
u
uPQPUPUV`bcPdPd
u
u
u
uvvv	
t155A#6#6
t
t
tquuU_abOcOc
t
t
t
tuuu	
a155!#4#4
a
a
a5
a
a
a
abbb	  x  y  y  y ?>5>>>H 7mUU
 
	7 
	7DLE
""NN5!!!88M**0bDs6-#899:: Q#d3s6-3H/I/I+J+JQ+N+O+O&PP,00;;Dhhw..G5W555t556666 ?>5>>>H =2333UU
 		= 		=DLE
""NN5!!!XXh++F,00;;Dhhw..G25f++2B2B6#2#;..L;W;;;\;;<<<< @?E???I G7888 	G 	GDET&\EETXXh-C-CEEFFFF :9999F Gk 	G 	GDET&\EETXXh-C-CEEFFFF 
GGG	
IJJJ | Go3444+,,,UUuUUUUU 	<:;;;::l## 	US&*>SSSTTT\ GEFFF	GGG 
z~~-.. @dj>>>???gq!!Q&&11A-s   !2 
A:3A55A:__main__)ra   rb   rc   rd   )NNN)ro   rb   rp   rb   rq   rN   rc   rr   )r   r   rc   rL   )r   rL   rc   rL   )r   r   rc   r   r  )rl   r	   r   r   rc   rN   )r   r   rc   rU   )r   r   r   rU   rc   r   )r   r   rc   r   )r   r   r   r   rc   r   )r   r   r   r   rc   r   )r   rL   )r   r   rc   rd   )r   rL   rc   rd   )r  r  r  r  r   r!  rc   r"  )r   r   r0  r   rc   rL   )r   rL   rc   rL   )r   rL   rc   rW   )rl   rL   rc   rL   )rl   r	   rc   r	   )rl   r	   r  rv   rc   r	   )rU  r   rV  rU   rc   r   )rc   r9  )rc   r!  )Q__doc__
__future__r   rA  r   rc  rD  r   r   dataclassesr   r   r   r   pathlibr   typingr	   r
   r   r   r   r   r   	Exceptionr   r  r  r  r  r  rg  r*  r@   r\   rv   rB   STATUS_MIGRATEDSTATUS_ARCHIVEDr  r  r  STATUS_PLANNEDREASON_TARGET_EXISTSr  rK   rn   r   r   r   r   r   r   r   r   r   r   r   compile
IGNORECASEr   r   r   r   r   r/  r3  rK  rG  rJ  r@  rH  rL  rO  rN  rl  rn  rF  r  rY   
SystemExitr^   r_   r`   <module>rn     sn	     # " " " " "    				 				  0 0 0 0 0 0 0 0 0 0             = = = = = = = = = = = = = = = =KKKK   DDD    + 1  766     #3 M8
F M8
 )_ M8 N M8 J M8" %n #M8* &i +M82 $] 3M8: V ;M8B R CM8J #Q KM8R !T SM8Z $D [M8b "Y cM8j $f kM8r  R sM8z $X {M8B  Z CM8 M8J %a KM8R (V SM8Z ] [M8b (j cM8j )f kM8r %k sM8z 7| {M8B (m CM8J (e KM8R 2p SM8Z -} [M8b (T cM8j &j kM8r !b sM8z /t {M8B 0d CM8J +` KM8 M8R *P SM8 M8  M M M M^" " "F C)**I%* %*  % % % %^ @ #F              (,'+ % % % % %P   , , , ,- - - -3 3 3 3    .2 2 2 2   
 
 
 
R R R R
 
 
 
, RZ%r}55x@RZ//:RZ..93        "   ) ) ) )I I I IX% % % %D   $ (   BJ122BJ+,,BJ122BJ233BJ-.. 1 1 1 1G G G G   * * * *   (5V 5V 5V 5VpF# F# F# F# F# F# F# F#RF0 0 0 0fy. y. y. y.x z
*TTVV

 s   	A AA