
    ᣟi              	           d 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ZddlmZm	Z	 dZ
dddddd	d
ddZdZd Zdedee   fdZdee   ddfdZdedee   ddfdZdeddfdZd Zedk(  r e        yy)u  
sunaiva_session_capture.py — Grov-style Stop hook for Genesis
Captures session wisdom and writes to Sunaiva vault for next session injection.

Reads the hook event from stdin (Claude Code Stop event JSON),
extracts key entities/decisions/insights from the session summary,
and persists them to the Sunaiva PostgreSQL vault.

Architecture inspired by Grov (Apache 2.0): https://github.com/TonyStef/Grov
    N)datetimetimezonez$41f4785c-e9e0-43ac-b6e8-eedb571fba57z(postgresql-genesis-u50607.vm.elestio.appiXc  postgreszCiBjh6LM7Yuqkq-jo2r7eQDw      
   )hostportuserpassworddatabaseconnect_timeout
keepaliveskeepalives_idlez/mnt/e/genesis-systemc                      	 t         j                  j                         s6t         j                  j                  d      } | rt	        j
                  |       S i S # t        $ r Y i S w xY w)z1Read the Stop hook event from stdin if available.i   )sysstdinisattyreadjsonloads	Exception)raws    >/mnt/e/genesis-system/.claude/hooks/sunaiva_session_capture.pyread_hook_eventr   %   sZ    yy!))..&Czz#& I  Is   AA 	A%$A%eventreturnc                    g }t        j                  t        j                        j	                         }| j                  dd      }| j                  dd      }t         d}	 t        |      5 }|j                         }ddd       |j                  d|dd  d	d
dd |d       |j                  d|dd  dd| d| |d       |S # 1 sw Y   MxY w# t        $ r Y ;w xY w)z>Extract key entities from the session event for vault storage.
session_idunknowntranscript_path z/memory/MEMORY.mdNsession_r   _statesession_snapshot  )nametypecontextsourcezGenesis Session sessionzSession completed at z. ID: )r   nowr   utc	isoformatgetGENESIS_ROOTopenr   appendr   )r   entitiesr,   r   
transcriptmemory_pathfmemory_contents           r   extract_session_entitiesr8   1   s   H
,,x||
$
.
.
0C <3J,b1J "N"34K+ 	&!VVXN	& 	s3Bxj/&%ds+ 	
 	 OO"3s8*-*3%vj\B	  O)	& 	&  s*   "C -C
>(C 
CC 	C"!C"r3   c                    | sy	 t        j                  di t        }|j                         }t	        j
                  t        j                        }| D ]  }ddl}|j                  |j                  dd      dd g      }|j                  dt        t        j                               t        |d   dd |j                  d	d
      ||j                  dd      |j!                         |j!                         f        |j#                          |j%                          t'        dt)        |        dt*        j,                         y# t.        $ r(}t'        d| t*        j,                         Y d}~yd}~ww xY w)z*Write extracted entities to Sunaiva vault.Nr   r)   r"     a
  
                INSERT INTO sunaiva.vault_entities
                    (id, vault_id, name, type, context, source_conversation, first_seen, last_seen)
                VALUES (%s, %s, %s, %s, %s::jsonb, %s, %s, %s)
                ON CONFLICT DO NOTHING
            r'      r(   factr*   session_capturez[sunaiva_capture] Stored z entities to vaultfilez#[sunaiva_capture] DB write failed:  )psycopg2connectDBcursorr   r,   r   r-   r   dumpsr/   executestruuiduuid4VAULT_IDr.   commitcloseprintlenr   stderrr   )r3   conncurr,   entity_jsonctx_jsones           r   write_to_vaultrV   T   s;   J%"%kkmll8<<( 	F {{FJJy"$=et$D#EFHKK  DJJL!vt$

66*

8%67			( 	

)#h-8JKRUR\R\] J3A37cjjIIJs   D?E 	E6E11E6c                    	 ddl }|j                  j                  dt        dz          ddl}| j                  dd      }t        j                  t        j                        j                         }d| dt        |       d}|j                  ||t        |      dd	| j                  d
d      d       |D ]r  }|j                  d|d   dd |j                  dd      dd d|dd|j                  dd      gdd      }|j                  d|||d   |j                  d      d       t t        d| t         j                          y# t"        $ r(}	t        d |	 t         j                          Y d}	~	yd}	~	ww xY w)!z4Write session to genesis_rlm schema via rlm_adapter.r   Nz/corer   r    zStop-hook capture at z. Entities captured: .g        r!   r"   T)r   summaryentities_toucheddecisions_madecost_usdhandoff_fileendedSESSIONr'   r&   r)   r:   sunaiva_session_capture)source_hookr   r+   r(   r<   g      ?sunaiva_stop_hook)entity_typer'   description
propertiestagssurprise_scorer*   session_entity_captured)entity_namerc   )
event_type	entity_idr   payloadz([sunaiva_capture] RLM session recorded: r>   z0[sunaiva_capture] RLM write failed (non-fatal): )r   pathinsertr0   rlm_adapterr/   r   r,   r   r-   r.   rN   record_sessionupsert_entity	add_eventrM   rO   r   )
r   r3   _sysro   r   now_strsession_summaryrR   eidrU   s
             r   write_to_rlmrw   z   s   'W		L723YY|Y7
,,x||,6681':OPST\P]^_`""!# ]#4b9 	# 	
  	F++%F^DS)"JJy"5et<+DT^_FF!;<"* , C !!4%(.vvzzRXGYZ	 " 	" 	8ECJJW W@D3::VVWs   EE	 		E:E55E:c                    	 d}t        j                  |d       t        j                  t        j
                        j                  d      }t         j                  j                  |d| d      }t        |d      5 }t        j                  | |       ddd       t         j                  j                  |d	      }d
t         dt         dt        |       d}t        j                  t         j"                  d|gt        j$                  t        |d      d       y# 1 sw Y   xY w# t&        $ r(}t)        d| t         j*                         Y d}~yd}~ww xY w)zRun the actual DB writes in a detached background subprocess.
    Writes event to a temp file then spawns a worker process.
    The hook itself returns in <100ms.
    z%/mnt/e/genesis-system/data/hook_queueT)exist_okz%Y%m%d_%H%M%S_%fsession_capture_z.jsonwNzsunaiva_capture.logz*
import sys, json, os
sys.path.insert(0, 'z%/.claude/hooks')
sys.path.insert(0, 'z/core')
queue_file = a  
try:
    with open(queue_file) as fh:
        event = json.load(fh)
    from sunaiva_session_capture import extract_session_entities, write_to_vault, write_to_rlm
    entities = extract_session_entities(event)
    write_to_vault(entities)
    write_to_rlm(event, entities)
except Exception as e:
    print(f'[bg_capture] error: {e}', file=sys.stderr)
finally:
    try:
        os.unlink(queue_file)
    except Exception:
        pass
z-ca)stdoutrO   start_new_sessionz#[sunaiva_capture] bg spawn failed: r>   )osmakedirsr   r,   r   r-   strftimerm   joinr1   r   dumpr0   repr
subprocessPopenr   
executableDEVNULLr   rM   rO   )r   	queue_dirts
queue_filer6   log_fileworker_scriptrU   s           r   run_background_capturer      s-   
$J;	
I-\\(,,'001CDWW\\)/?t5-IJ
*c" 	 aIIeQ	  77<<	+@A!N #!N #:  	( 	^^T=1%%#&"		
1	  	 <  J3A37cjjIIJs1   A;D( =DBD( D%!D( (	E1EEc                      dt         j                  v r-t               } t        |       }t	        |       t        | |       yt               } t        |        t        t        j                  i              y)uN   Hook entry point — returns immediately, spawns background worker for DB I/O.z--backgroundN)
r   argvr   r8   rV   rw   r   rM   r   rE   )r   r3   s     r   mainr      sU    !!+E2x UH%E5!	$**R.    __main__)__doc__r   r   r   r   tempfilerA   rH   r   r   rJ   rC   r0   r   dictlistr8   rV   rw   r   r   __name__r@   r   r   <module>r      s   	   	     '16*	 '	 D  T$Z  F#JT$Z #JD #JL)W )WT
 )Wt )WX)J$ )J4 )JX  zF r   