Skip to content

Commit 1685e47

Browse files
author
shadeform
committed
fix(setup): correct project root when notebook lives outside repo
The condition (cwd / complete_setup_guide.ipynb).exists() incorrectly assumed notebooks/setup layout, so ~/complete_setup_guide.ipynb made project_root cwd.parent.parent (filesystem root). - Use notebooks/setup only when cwd is .../notebooks/setup - Scan cwd subdirectories for src/api + scripts/setup (sibling clone) - Invalidate cached __project_root__ if markers missing - Remove unreachable duplicate code after get_project_root in Step 2 - Align Step 8 fallback, API key cell, and check_env_file fallback Made-with: Cursor
1 parent 65a5782 commit 1685e47

1 file changed

Lines changed: 107 additions & 71 deletions

File tree

notebooks/setup/complete_setup_guide.ipynb

Lines changed: 107 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@
453453
" if (current / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (current / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
454454
" return current\n",
455455
" \n",
456-
" # Check if we're in notebooks/setup/ (go up 2 levels)\n",
457-
" if (current / NOTEBOOK_FILENAME).exists() or current.name == NOTEBOOK_SETUP_DIR:\n",
456+
" # notebooks/setup/ only (NOT \"notebook file in cwd\" — that breaks ~/complete_setup_guide.ipynb)\n",
457+
" if current.name == NOTEBOOK_SETUP_DIR and current.parent.name == NOTEBOOKS_DIR:\n",
458458
" parent = current.parent.parent\n",
459459
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
460460
" return parent\n",
@@ -470,6 +470,14 @@
470470
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
471471
" return parent\n",
472472
" \n",
473+
" # Repo cloned as a subdirectory of cwd (e.g. notebook in ~, repo in ~/Multi-Agent-...)\n",
474+
" try:\n",
475+
" for child in sorted(current.iterdir(), key=lambda p: p.name.lower()):\n",
476+
" if child.is_dir() and (child / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (child / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
477+
" return child\n",
478+
" except (OSError, PermissionError):\n",
479+
" pass\n",
480+
" \n",
473481
" # Fallback: return current directory\n",
474482
" return current\n",
475483
"\n",
@@ -484,56 +492,46 @@
484492
" import os\n",
485493
" from pathlib import Path\n",
486494
" \n",
487-
" # Check if already stored\n",
488-
" if hasattr(builtins, '__project_root__'):\n",
489-
" return builtins.__project_root__\n",
490-
" \n",
491-
" # Try to find project root\n",
495+
" def _has_markers(path: Path) -> bool:\n",
496+
" return (\n",
497+
" (path / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists()\n",
498+
" and (path / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists()\n",
499+
" )\n",
500+
"\n",
501+
" if hasattr(builtins, \"__project_root__\"):\n",
502+
" cached = Path(builtins.__project_root__)\n",
503+
" if _has_markers(cached):\n",
504+
" return cached\n",
505+
" del builtins.__project_root__\n",
506+
"\n",
492507
" current = Path.cwd()\n",
493-
" \n",
494-
" # Check if we're already in project root\n",
495-
" if (current / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (current / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
508+
"\n",
509+
" if _has_markers(current):\n",
496510
" project_root = current\n",
497-
" # Check if we're in notebooks/setup/ (go up 2 levels)\n",
498-
" elif (current / NOTEBOOK_FILENAME).exists() or current.name == NOTEBOOK_SETUP_DIR:\n",
511+
" elif current.name == NOTEBOOK_SETUP_DIR and current.parent.name == NOTEBOOKS_DIR:\n",
499512
" project_root = current.parent.parent\n",
500-
" # Check if we're in notebooks/ (go up 1 level)\n",
501513
" elif current.name == NOTEBOOKS_DIR:\n",
502514
" project_root = current.parent\n",
503515
" else:\n",
504-
" # Try going up from current directory\n",
505516
" project_root = current\n",
506517
" for parent in current.parents:\n",
507-
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
518+
" if _has_markers(parent):\n",
508519
" project_root = parent\n",
509520
" break\n",
510-
" \n",
511-
" # Change to project root and store it\n",
521+
"\n",
522+
" if not _has_markers(project_root):\n",
523+
" try:\n",
524+
" for child in sorted(current.iterdir(), key=lambda p: p.name.lower()):\n",
525+
" if child.is_dir() and _has_markers(child):\n",
526+
" project_root = child\n",
527+
" break\n",
528+
" except (OSError, PermissionError):\n",
529+
" pass\n",
530+
"\n",
512531
" os.chdir(project_root)\n",
513532
" builtins.__project_root__ = project_root\n",
514533
" return project_root\n",
515534
"\n",
516-
" \n",
517-
" # Check if we're in notebooks/setup/ (go up 2 levels)\n",
518-
" if (current / NOTEBOOK_FILENAME).exists() or current.name == NOTEBOOK_SETUP_DIR:\n",
519-
" parent = current.parent.parent\n",
520-
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
521-
" return parent\n",
522-
" \n",
523-
" # Check if we're in notebooks/ (go up 1 level)\n",
524-
" if current.name == NOTEBOOKS_DIR:\n",
525-
" parent = current.parent\n",
526-
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
527-
" return parent\n",
528-
" \n",
529-
" # Try going up from current directory\n",
530-
" for parent in current.parents:\n",
531-
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
532-
" return parent\n",
533-
" \n",
534-
" # Fallback: return current directory\n",
535-
" return current\n",
536-
"\n",
537535
"# Find and change to project root\n",
538536
"project_root = find_project_root()\n",
539537
"if project_root is None:\n",
@@ -1340,32 +1338,43 @@
13401338
" import builtins\n",
13411339
" import os\n",
13421340
" from pathlib import Path\n",
1343-
" \n",
1344-
" # Check if already stored\n",
1345-
" if hasattr(builtins, '__project_root__'):\n",
1346-
" return Path(builtins.__project_root__)\n",
1347-
" \n",
1348-
" # Try to find project root\n",
1341+
"\n",
1342+
" def _has_markers(path: Path) -> bool:\n",
1343+
" return (\n",
1344+
" (path / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists()\n",
1345+
" and (path / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists()\n",
1346+
" )\n",
1347+
"\n",
1348+
" if hasattr(builtins, \"__project_root__\"):\n",
1349+
" cached = Path(builtins.__project_root__)\n",
1350+
" if _has_markers(cached):\n",
1351+
" return cached\n",
1352+
" del builtins.__project_root__\n",
1353+
"\n",
13491354
" current = Path.cwd()\n",
1350-
" \n",
1351-
" # Check if we're already in project root\n",
1352-
" if (current / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (current / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
1355+
"\n",
1356+
" if _has_markers(current):\n",
13531357
" project_root = current\n",
1354-
" # Check if we're in notebooks/setup/ (go up 2 levels)\n",
1355-
" elif (current / NOTEBOOK_FILENAME).exists() or current.name == NOTEBOOK_SETUP_DIR:\n",
1358+
" elif current.name == NOTEBOOK_SETUP_DIR and current.parent.name == NOTEBOOKS_DIR:\n",
13561359
" project_root = current.parent.parent\n",
1357-
" # Check if we're in notebooks/ (go up 1 level)\n",
13581360
" elif current.name == NOTEBOOKS_DIR:\n",
13591361
" project_root = current.parent\n",
13601362
" else:\n",
1361-
" # Try going up from current directory\n",
13621363
" project_root = current\n",
13631364
" for parent in current.parents:\n",
1364-
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
1365+
" if _has_markers(parent):\n",
13651366
" project_root = parent\n",
13661367
" break\n",
1367-
" \n",
1368-
" # Change to project root and store it\n",
1368+
"\n",
1369+
" if not _has_markers(project_root):\n",
1370+
" try:\n",
1371+
" for child in sorted(current.iterdir(), key=lambda p: p.name.lower()):\n",
1372+
" if child.is_dir() and _has_markers(child):\n",
1373+
" project_root = child\n",
1374+
" break\n",
1375+
" except (OSError, PermissionError):\n",
1376+
" pass\n",
1377+
"\n",
13691378
" os.chdir(project_root)\n",
13701379
" builtins.__project_root__ = project_root\n",
13711380
" return project_root\n",
@@ -2848,21 +2857,36 @@
28482857
" os.chdir(project_root)\n",
28492858
" builtins.__project_root__ = project_root\n",
28502859
" else:\n",
2851-
" # Fallback: try to find project root\n",
2860+
" # Fallback: try to find project root (same rules as get_project_root)\n",
2861+
" def _has_markers(path: Path) -> bool:\n",
2862+
" return (\n",
2863+
" (path / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists()\n",
2864+
" and (path / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists()\n",
2865+
" )\n",
2866+
"\n",
28522867
" current = Path.cwd()\n",
2853-
" # Check if we're in notebooks/setup/ (go up 2 levels)\n",
2854-
" if (current / NOTEBOOK_FILENAME).exists() or current.name == NOTEBOOK_SETUP_DIR:\n",
2868+
" if _has_markers(current):\n",
2869+
" project_root = current\n",
2870+
" elif current.name == NOTEBOOK_SETUP_DIR and current.parent.name == NOTEBOOKS_DIR:\n",
28552871
" project_root = current.parent.parent\n",
28562872
" elif current.name == NOTEBOOKS_DIR:\n",
28572873
" project_root = current.parent\n",
28582874
" else:\n",
2859-
" # Try going up from current directory\n",
2875+
" project_root = current\n",
28602876
" for parent in current.parents:\n",
2861-
" if (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists() and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists():\n",
2877+
" if _has_markers(parent):\n",
28622878
" project_root = parent\n",
28632879
" break\n",
2864-
" else:\n",
2865-
" project_root = current\n",
2880+
"\n",
2881+
" if not _has_markers(project_root):\n",
2882+
" try:\n",
2883+
" for child in sorted(current.iterdir(), key=lambda p: p.name.lower()):\n",
2884+
" if child.is_dir() and _has_markers(child):\n",
2885+
" project_root = child\n",
2886+
" break\n",
2887+
" except (OSError, PermissionError):\n",
2888+
" pass\n",
2889+
"\n",
28662890
" os.chdir(project_root)\n",
28672891
" builtins.__project_root__ = project_root\n",
28682892
" \n",
@@ -3385,34 +3409,46 @@
33853409
" NOTEBOOK_SETUP_DIR = \"setup\"\n",
33863410
" NOTEBOOKS_DIR = \"notebooks\"\n",
33873411
"\n",
3412+
" def _has_markers(path: Path) -> bool:\n",
3413+
" return (\n",
3414+
" (path / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists()\n",
3415+
" and (path / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists()\n",
3416+
" )\n",
3417+
"\n",
33883418
" def get_project_root():\n",
33893419
" \"\"\"Detect repo root (same rules as Step 2) if that cell was not run.\"\"\"\n",
33903420
" import builtins\n",
33913421
" import os\n",
33923422
"\n",
33933423
" if hasattr(builtins, \"__project_root__\"):\n",
3394-
" return Path(builtins.__project_root__)\n",
3424+
" cached = Path(builtins.__project_root__)\n",
3425+
" if _has_markers(cached):\n",
3426+
" return cached\n",
3427+
" del builtins.__project_root__\n",
33953428
"\n",
33963429
" current = Path.cwd()\n",
3397-
" if (\n",
3398-
" (current / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists()\n",
3399-
" and (current / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists()\n",
3400-
" ):\n",
3430+
" if _has_markers(current):\n",
34013431
" project_root = current\n",
3402-
" elif (current / NOTEBOOK_FILENAME).exists() or current.name == NOTEBOOK_SETUP_DIR:\n",
3432+
" elif current.name == NOTEBOOK_SETUP_DIR and current.parent.name == NOTEBOOKS_DIR:\n",
34033433
" project_root = current.parent.parent\n",
34043434
" elif current.name == NOTEBOOKS_DIR:\n",
34053435
" project_root = current.parent\n",
34063436
" else:\n",
34073437
" project_root = current\n",
34083438
" for parent in current.parents:\n",
3409-
" if (\n",
3410-
" (parent / PROJECT_ROOT_MARKERS[0][0] / PROJECT_ROOT_MARKERS[0][1]).exists()\n",
3411-
" and (parent / PROJECT_ROOT_MARKERS[1][0] / PROJECT_ROOT_MARKERS[1][1]).exists()\n",
3412-
" ):\n",
3439+
" if _has_markers(parent):\n",
34133440
" project_root = parent\n",
34143441
" break\n",
34153442
"\n",
3443+
" if not _has_markers(project_root):\n",
3444+
" try:\n",
3445+
" for child in sorted(current.iterdir(), key=lambda p: p.name.lower()):\n",
3446+
" if child.is_dir() and _has_markers(child):\n",
3447+
" project_root = child\n",
3448+
" break\n",
3449+
" except (OSError, PermissionError):\n",
3450+
" pass\n",
3451+
"\n",
34163452
" os.chdir(project_root)\n",
34173453
" builtins.__project_root__ = project_root\n",
34183454
" return project_root\n",

0 commit comments

Comments
 (0)