
    ~iu&                    :   d Z ddlmZ ddlZddlZddlZddlmZmZ ddlm	Z	 ddl
mZ  e	ej                  j                  dd            Zed	z  d
z  dz  Z G d de      ZddZddZddZddddddd	 	 	 	 	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy)u[   사람 author PR을 bot equivalent로 재작성. 원본 commit 보존(cherry-pick + amend).    )annotationsN)datetimetimezone)Path)AnyWORKSPACE_ROOTz/home/jay/workspacememoryzorchestration-auditzhandoff-to-bot.jsonlc                      e Zd ZdZy)HandoffErroru'   handoff-to-bot 작업 실패 시 raise.N)__name__
__module____qualname____doc__     E/home/jay/workspace/.worktrees/task-2481-dev4/utils/handoff_to_bot.pyr   r      s    1r   r   c                 f    t        j                  t        j                        j	                  d      S )Nz%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftimer   r   r   _nowr      s!    <<%../CDDr   c                4    t        j                  | fddd|S )u   기본 subprocess.run 래퍼.T)capture_outputtext)
subprocessrun)cmdkwargss     r   _default_runnerr      s    >>#HdHHHr   c                F    |dddt        |       ddgd      }|j                  dk7  r,t        d	|  d
|j                  dd j	                                	 t        j                  |j                  xs d      S # t
        j                  $ r}t        d|       |d}~ww xY w)u   gh pr view로 PR 메타 조회.ghprview--jsonz+number,author,headRefName,commits,url,state   timeoutr   u   gh pr view 실패 (PR #): iNz{}u   gh pr view JSON 파싱 실패: )	str
returncoder   stderrstripjsonloadsstdoutJSONDecodeError)	pr_numberrunnerprocexcs       r   _default_pr_viewr5      s    	tVS^	@	BD
 !4YKs4;;tuCUC[C[C]B^_``Mzz$++-.. M<SEBCLMs   "A9 9B BB zjeon-jonghyuk-taskctl-botz7jeon-jonghyuk-taskctl-bot[bot]@users.noreply.github.comF)	bot_login	bot_email	bot_tokendry_runpr_view_funcr2   c               Z	  # |t         }||#dR#fd}|}n|}	  ||       }	|	j                  d      xs i j                  dd      }|	j                  dd|        }|	j                  d	      xs g }g }|D ]Z  }t	        |t
              r)|j                  d
      xs |j                  d      xs d}nt        |      }|sJ|j                  |       \ d|  d}g }d}|r(t        | |d||g d       | |d|t        t              ddS  |ddd|dgd      }|j                  dk7  rH |dd|gd      }|j                  dk7  r,t        d| d|j                  dd j                                |D ]  } |dd|gd      }|j                  dk7  r8 |g dd       t        d| d |j                  dd j                                 |dd!d"d#d$| d%| d&d'gd      }|j                  dk7  r,t        d(| d |j                  dd j                                 |g d)d*      }|j                  dk(  s|j                  |j                  j                                 i }|r||d+<    |dd,d-|d.gd/i t        j                  |0      }|j                  dk7  r)t        d1|j                  dd j                                d2|  d3| d4}d5|  d6| d7| d8d9j!                  |       d:| d;}d<d=d>d?|d@|dA|g	} ||di t        j                  |0      }|j                  dk7  r)t        dB|j                  dd j                                |j                  j                         }  |d<d=dC|dDdEgdi t        j                  |0      }!|!j                  dk(  r/	 t#        j$                  |!j                        j                  dE      } |d<d=dFt        |       dGdH| dI| gdi t        j                  |0      }"|"j                  dk7  rBt        | |||||dJdKL       t        dM|  dN| dO|"j                  dd j                                t        | |||||dJdPL       | |||t        t              || dQS # t        $ r  t        $ r}
t        d|
       |
d}
~
ww xY w# t        $ r d}Y w xY w)Su  사람 author PR을 bot equivalent로 재작성.

    1) 원본 PR 메타 조회 (number, author, head_branch, commits[])
    2) 새 branch 'task/handoff-<pr_number>-bot' 생성
    3) cherry-pick 각 commit + git commit --amend --author --reset-author로 author=bot 강제
    4) git push (bot_token), gh pr create (author=bot)
    5) 원본 PR close
    6) audit jsonl append
    7) 반환: {original_pr, original_author, new_pr, new_branch, mapping_log_path}

    원본 commit 영구 삭제 절대 금지(cherry-pick은 원본 브랜치를 건드리지 않음).
    dry_run=True면 실제 git/gh 호출 없이 mapping dict만 반환 + audit jsonl 기록.
    Nc                    t        |       S )N)r5   )pr_num
_pv_runners    r   _resolved_pr_viewz,handoff_pr_to_bot.<locals>._resolved_pr_viewH   s    #FJ77r   u   PR 메타 조회 실패: authorloginunknownheadRefNamezpr-commitsoidsha ztask/handoff-z-botT)r1   original_authornew_pr
new_branchoriginal_commitsnew_commitsr9   )original_prrH   rI   rJ   mapping_log_pathr9   gitcheckoutz-bzorigin/main<   r&   r   r%   u   새 branch 'u   ' 생성/checkout 실패: i8cherry-pick)rO   rR   z--abortu   cherry-pick 실패 (sha=r(   commitz--amendz	--no-editz	--author=z <>z--reset-authoru   git commit --amend 실패 (sha=)rO   z	rev-parseHEAD
   GH_TOKENpushoriginz--force-with-leasex   )r'   envu   git push 실패: z[handoff-bot] PR #z (original author: )zBot handoff: original PR #z by @z.

Original branch: z
Original commits: z, z
Handoff branch: 
r!   r"   createz--titlez--bodyz--headu   gh pr create 실패: r#   r$   numberclosez	--commentzClosed: bot handoff to PR #z on branch FCLOSE_FAILED)r1   rH   rI   rJ   rK   rL   r9   outcomeu   원본 PR #u    close 실패 — 새 PR #uA   와 원본이 모두 열린 상태. 수동 정리 필요. stderr=
HANDED_OFF)rM   rH   rI   rJ   rN   rL   pr_url)r=   intreturndict[str, Any])r   r   	Exceptionget
isinstancedictr)   append_append_audit_logHANDOFF_LOGr*   r+   r,   r/   osenvironjoinr-   r.   )$r1   r6   r7   r8   r9   r:   r2   r?   _pr_view_fnpr_datar4   rH   head_branchcommits_rawrK   crE   rJ   rL   new_pr_numberr3   proc2rF   cp_proc
amend_procrev_procpush_env	push_procpr_titlepr_body
create_cmdcreate_procrd   	view_proc
close_procr>   s$                                      @r   handoff_pr_to_botr   +   s   0 ~ 
	8 ("Gi( {{8,277KO++ms9+->?K++i(.BK"$ )a%%,4!%%,4"Ca&C##C() !40JK $M +!-	
 %.$ #K 0
 	
 5*dJFPRSD!z:6Cq zl*DT[[QUQVEWE]E]E_D`a 
   8%4bA"4bA*3%s7>>$%3H3N3N3P2QR  xKI;b15 
 

   A%1#c*:K:KDE:R:X:X:Z9[\  6C!#x4467186  "H(	*.BC&rzz&X&I
 q .y/?/?/F/L/L/N.OPQQ#I;.A/ARRSTH
$YKu_4E F'= )!YY'789 :%,b	*  	dH8'*	J &rzz&X&K
 "2;3E3Ede3L3R3R3T2UVWW %%'F	tVZ8<&rzz&X&I
 q 	! JJy'7'78<<XFM
 	tWc)nk&}o[	M	O&rzz&X&	J ! 	+ !-#"		
 )$>}o N,,6,=,=de,D,J,J,L+MO
 	
 ')	 !* ," I   G6se<=3FGr  	! M	!s)   Q3 .R 3RRRR*)R*OK)rb   c           
        t         j                  j                  dd       t               | |||||||d	}t         j	                  dd      5 }	|	j                  t        j                  |d      d	z          d
d
d
       y
# 1 sw Y   y
xY w)un   audit jsonl에 handoff 기록 추가.

    outcome: 'OK' | 'DRY_RUN' | 'HANDED_OFF' | 'CLOSE_FAILED' 등.
    T)parentsexist_ok)	tsrM   rH   rI   rJ   rK   rL   r9   rb   azutf-8)encodingF)ensure_asciir]   N)rn   parentmkdirr   openwriter-   dumps)
r1   rH   rI   rJ   rK   rL   r9   rb   recordfs
             r   rm   rm     s     TD9f * ,"
F 
		#		0 ?A	

66=>? ? ?s   *B  B	)rf   r)   )r   	list[str]r   r   rf   zsubprocess.CompletedProcess)r1   re   r2   r   rf   rg   )r1   re   r6   r)   r7   r)   r8   z
str | Noner9   boolrf   rg   )r1   re   rH   r)   rI   z
int | NonerJ   r)   rK   r   rL   r   r9   r   rb   r)   rf   None)r   
__future__r   r-   ro   r   r   r   pathlibr   typingr   rp   ri   	WORKSPACErn   rh   r   r   r   r5   r   rm   r   r   r   <module>r      s)   a "  	  '   02GHI	("%::=SS29 2EI
M$ 1N SS S 	S
 S S S~ ?? ? 	?
 ?  ? ? ? ? 
?r   