
    Zi              
         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
 ddlmZ  eej                  j                  d e ee      j#                         j$                  j$                                    Zedz  dz  Zd	Zd
ZddZddZddZdddZddZddZddZddZddZd dZ e!dk(  r ejD                   e               yy)!u  gemini_feedback_loop.py — Gemini failure 시 자동 수정 루프 강제.

흐름:
  1) gemini_review_gate.py 결과 (`failure`) 후 호출
  2) 카운트 파일 `memory/events/<task-id>.gemini-loop-count` 증가
  3) 안전한 자동 수정 적용 (linter/typo 한정)
       - black/ruff/isort 등이 있으면 차례로 실행 (있는 것만)
  4) 변경 있으면 새 commit + push (force-with-lease 금지)
  5) 카운트 > MAX_LOOPS 시:
       - PR에 `human_review_required` 라벨 추가 (gh api POST issues/<num>/labels)
       - PR comment "@회장 리뷰 필요"
       - exit_code=2 (queue 등록 차단 시그널)

CLI:
    python3 scripts/gemini_feedback_loop.py         --task-id task-XXXX --pr-number 123 --repo OWNER/REPO [--max-loops 3] [--dry-run]
    )annotationsN)datetimetimezone)Path	WORKSPACEmemoryeventshuman_review_required   c                 d    t        j                  t        j                        j	                         S )N)r   nowr   utc	isoformat     O/home/jay/workspace/.worktrees/task-2471+1-dev2/scripts/gemini_feedback_loop.py_now_isor   %   s    <<%//11r   c                    t         |  dz  }|j                         sy	 t        |j                         j	                               S # t
        $ r Y yw xY w)N.gemini-loop-countr   )
EVENTS_DIRexistsint	read_textstrip
ValueError)task_idps     r   _read_countr   )   sQ    y 233A88:1;;=&&()) s   &A 	AAc                z    t         j                  dd       t         |  dz  j                  t        |             y )NT)parentsexist_okr   )r   mkdir
write_textstr)r   values     r   _write_countr&   3   s4    TD1WI/00<<SZHr   c           	         t        j                  | dd||rt        |      nd       }|j                  |j                  |j
                  fS )NT)capture_outputtexttimeoutcwd)
subprocessrunr$   
returncodestdoutstderr)cmdr+   r*   procs       r   _runr3   8   s>    >>#dw`cTWX[T\imnD??DKK44r   c           	     T   g g d}ddgdddt        |       gfddgdt        |       gfddgdt        |       gfg}|D ]i  \  }}t        j                  |d         |d
   j                  |d          6t	        || d      \  }}}|d   j                  |d   ||dd	 |dd	 d       k |S )z<Run available auto-formatters in workspace. Returns summary.ranskippedruffz	--versioncheckz--fixblackisortr   Nr7   x   )r+   r*   r6   i8)toolrcstdout_tailstderr_tail)r$   shutilwhichappendr3   )	workspacesummary
candidatesprobeactionr>   outerrs           r   apply_auto_fixesrK   =   s    2.G
+	'3y> JK
;	'3y>!:;
;	'3y>!:;J
 $ rv<<a!)I%%eAh/F	3?CuQxr#de*ehimineopqr Nr   c                P   t        ddt        |       ddg      \  }}}|j                         sddiS t        ddt        |       ddg       t        ddt        |       d	d
|g      \  }}}|dk7  rd|dS t        ddt        |       dgd      \  }}}d||j                         dd  dS )Ngitz-Cstatusz--porcelainchangedFaddz-Acommitz-mr   )rO   
commit_errpush<   )r*   Ti)rO   push_rcpush_err)r3   r$   r   )rD   message_
status_outr>   rJ   rU   rV   s           r   push_changesrZ   N   s    UD#i.(MRSAz15!!%s9~ud	34udC	NHdGLMJB3	Qw 44c)nf ErRGQX^^=Mde=TUUr   c                    t        j                  d|gi      }t        j                  ddddd|  d| dd	d
gdd|d      }|j                  |j
                  |j                  dS )Nlabelsghapi-XPOSTrepos//issues/z/labels--input-T   r(   r)   inputr*   r>   r/   r0   jsondumpsr,   r-   r.   r/   r0   )repo	pr_numberlabelbodyr2   s        r   gh_add_labelrp   Z   sk    ::x%)*D>>	udFfTF(9+W$MyZ]^$dBD //T[[DKKPPr   c                    t        j                  d|i      }t        j                  ddddd|  d| dd	d
gdd|d      }|j                  |j
                  |j                  dS )Nro   r]   r^   r_   r`   ra   rb   z	/commentsrc   rd   Tre   rf   rh   ri   )rl   rm   commentro   r2   s        r   
gh_commentrs   c   sj    ::vw'(D>>	udFfTF(9+Y$OQZ\_`$dBD //T[[DKKPPr   c                   | j                   }|s1t        t        j                  ddi      t        j
                         yt        |      dz   }||t               | j                  d}|| j                  kD  rd|d<   | j                  rX| j                  sLt        | j                  | j                  t              |d	<   t        | j                  | j                  d
      |d<   t        t        j                  |d             t        ||       y| j                  st        ||       | j                  st!        t"              ng dgd}||d<   | j                  r&d|d<   t        t        j                  |d             yt%        t"        d| d|       }||d<   |j'                  d      rdnd|d<   t        t        j                  |d             y)Nerrorz--task-id required)file      )r   
loop_countts	max_loops	exhaustedstatern   uP   @회장 자동 수정 루프 한계 초과 — 직접 리뷰 부탁드립니다.rr   F)ensure_asciizdry-runr5   fixesr   [z] gemini auto-fix loop rS   rO   pushedz
no-changes)r   printrj   rk   sysr0   r   r   r{   rm   dry_runrp   rl   HUMAN_LABELrs   r&   rK   r   rZ   get)argsr   countrI   fix_summarypush_results         r   loopr   l   s}   llGdjj'#789

K 1$E#5
Y]YgYghCt~~"G>>$,,'		4>>;OCL'		4>>  DV  WC	Ndjj512We$<<We$59\\"9-r_h^iGjKCL|| Gdjj512yAgY6MeW*UVKCK*y98|CL	$**Su
-.r   c                 z   t        j                  d      } | j                  dd       | j                  dt        d       | j                  d	t        j
                  j                  d
d             | j                  dt        t               | j                  dd       | j                         }t        |      S )Nz%Gemini failure feedback auto-fix loop)descriptionz	--task-idT)requiredz--pr-numberr   )typedefaultz--repoGH_REPOzJonghyukJeon/dev_workspace)r   z--max-loopsz	--dry-run
store_true)rH   )
argparseArgumentParseradd_argumentr   osenvironr   MAX_LOOPS_DEFAULT
parse_argsr   )apr   s     r   mainr      s    		 	 -T	UBOOK$O/OOMQO7OOHbjjnnY@\&]O^OOM5FOGOOKO5==?D:r   __main__)returnr$   )r   r$   r   r   )r   r$   r%   r   r   None)NrT   )r1   z	list[str]r+   zPath | Noner*   r   r   ztuple[int, str, str])rD   r   r   dict)rD   r   rW   r$   r   r   )rl   r$   rm   r   rn   r$   r   r   )rl   r$   rm   r   rr   r$   r   r   )r   zargparse.Namespacer   r   )r   r   )#__doc__
__future__r   r   rj   r   rA   r,   r   r   r   pathlibr   r   r   r$   __file__resolveparentr   r   r   r   r   r   r&   r3   rK   rZ   rp   rs   r   r   __name__exitr   r   r   <module>r      s   $ #   	   
 ' Sh1G1G1I1P1P1W1W-XYZ	!H,
% 2I
5
"	VQQ F zCHHTV r   