@@ -81,7 +81,10 @@ def demo(project_name, force, build_db):
8181 click .echo (f"Then: archaeology audit { project_name } --fail-on HIGH" )
8282 if build_db :
8383 cmd = [sys .executable , "-m" , "archaeology.db.builder" , "--project-root" , str (project_root )]
84- result = subprocess .run (cmd , check = True , timeout = 300 )
84+ _env = os .environ .copy ()
85+ _pkg_root = str (Path (__file__ ).parent .parent )
86+ _env ["PYTHONPATH" ] = _pkg_root + ((":" + _env ["PYTHONPATH" ]) if _env .get ("PYTHONPATH" ) else "" )
87+ result = subprocess .run (cmd , check = True , timeout = 300 , env = _env )
8588 if result .returncode != 0 :
8689 raise click .exceptions .Exit (result .returncode )
8790
@@ -138,7 +141,10 @@ def build_db(project_name, verbose):
138141 if verbose :
139142 cmd .append ("--verbose" )
140143
141- result = subprocess .run (cmd , check = True , timeout = 300 )
144+ _env = os .environ .copy ()
145+ _pkg_root = str (Path (__file__ ).parent .parent )
146+ _env ["PYTHONPATH" ] = _pkg_root + ((":" + _env ["PYTHONPATH" ]) if _env .get ("PYTHONPATH" ) else "" )
147+ result = subprocess .run (cmd , check = True , timeout = 300 , env = _env )
142148 if result .returncode == 0 and os .path .exists (db_path ):
143149 click .echo (f"Database built at { db_path } " )
144150 else :
@@ -235,12 +241,17 @@ def signals(project_name, config_path, min_gap_days, verbose):
235241 if min_gap_days is not None :
236242 config ["min_gap_days" ] = min_gap_days
237243
244+ db_path = os .path .join (_project_dir (project_name ), "data" , "archaeology.db" )
245+ if not os .path .exists (db_path ):
246+ click .echo (f"No database found. Run 'archaeology build-db { project_name } ' first." , err = True )
247+ sys .exit (1 )
248+
238249 result = detect_signals (project_name , config = config or None )
239250 if result .get ("signals" ):
240251 click .echo (f"Detected { len (result ['signals' ])} signals "
241252 f"across { len (result ['cluster_summary' ])} clusters." )
242253 else :
243- click .echo ("No signals detected. Build the database first ." )
254+ click .echo ("No significant patterns detected in the commit history ." )
244255
245256
246257@main .command ()
@@ -438,6 +449,7 @@ def visualize(project_name):
438449 first_date = ""
439450 last_date = ""
440451 agent_count = 0
452+ eras_data = None
441453 eras_json = os .path .join (project_dir , "data" , "commit-eras.json" )
442454 if os .path .exists (eras_json ):
443455 try :
@@ -518,7 +530,17 @@ def visualize(project_name):
518530 # Inline data.json so the HTML works from file:// (no CORS issues)
519531 if os .path .exists (data_json ):
520532 with open (data_json , encoding = "utf-8" ) as f :
521- data_content = f .read ()
533+ data_payload = json .load (f )
534+
535+ # Merge commit_eras and top-level fields from commit-eras.json into PROJECT_DATA
536+ # so the era timeline visualization has real data to render.
537+ if eras_data is not None :
538+ data_payload .setdefault ("commit_eras" , eras_data .get ("eras" , []))
539+ data_payload .setdefault ("total_commits" , eras_data .get ("total_commits" , 0 ))
540+ data_payload .setdefault ("first_commit_date" , eras_data .get ("first_commit_date" , "" ))
541+ data_payload .setdefault ("last_commit_date" , eras_data .get ("last_commit_date" , "" ))
542+
543+ data_content = json .dumps (data_payload )
522544 safe_data_content = data_content .replace ("<" , "\\ u003c" ).replace (">" , "\\ u003e" ).replace ("&" , "\\ u0026" )
523545 inline_script = f'<script>window.PROJECT_DATA = { safe_data_content } ; window.dispatchEvent(new Event("data-loaded"));</script>'
524546 html = html .replace (
@@ -634,7 +656,10 @@ def cascade(project_name, dry_run, skip_mine):
634656 db_path = data_dir / "archaeology.db"
635657 cmd = [sys .executable , "-m" , "archaeology.db.builder" ,
636658 "--project-root" , str (project_dir )]
637- result = subprocess .run (cmd , capture_output = True , text = True , timeout = 300 )
659+ _env = os .environ .copy ()
660+ _pkg_root = str (Path (__file__ ).parent .parent )
661+ _env ["PYTHONPATH" ] = _pkg_root + ((":" + _env ["PYTHONPATH" ]) if _env .get ("PYTHONPATH" ) else "" )
662+ result = subprocess .run (cmd , capture_output = True , text = True , timeout = 300 , env = _env )
638663 if result .returncode == 0 :
639664 click .echo (f" Database built ({ db_path } )" )
640665 else :
@@ -966,7 +991,10 @@ def sync(projects, skip_mine, skip_signals, verbose):
966991 if verbose :
967992 cmd .append ("--verbose" )
968993
969- result = subprocess .run (cmd , capture_output = not verbose , check = True , timeout = 300 )
994+ _env = os .environ .copy ()
995+ _pkg_root = str (Path (__file__ ).parent .parent )
996+ _env ["PYTHONPATH" ] = _pkg_root + ((":" + _env ["PYTHONPATH" ]) if _env .get ("PYTHONPATH" ) else "" )
997+ result = subprocess .run (cmd , capture_output = not verbose , check = True , timeout = 300 , env = _env )
970998 if result .returncode == 0 and os .path .exists (db_path ):
971999 click .echo (f" DB built" )
9721000 else :
@@ -1162,7 +1190,7 @@ def benchmark(project_name):
11621190 sys .exit (1 )
11631191
11641192
1165- @main .command ()
1193+ @main .command ("dashboard" )
11661194@click .option ("--port" , default = 8080 , help = "Port to serve on" )
11671195@click .option ("--no-open" , is_flag = True , help = "Don't open browser automatically" )
11681196def serve (port , no_open ):
0 commit comments