|
453 | 453 | " 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", |
454 | 454 | " return current\n", |
455 | 455 | " \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", |
458 | 458 | " parent = current.parent.parent\n", |
459 | 459 | " 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", |
460 | 460 | " return parent\n", |
|
470 | 470 | " 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", |
471 | 471 | " return parent\n", |
472 | 472 | " \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", |
473 | 481 | " # Fallback: return current directory\n", |
474 | 482 | " return current\n", |
475 | 483 | "\n", |
|
484 | 492 | " import os\n", |
485 | 493 | " from pathlib import Path\n", |
486 | 494 | " \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", |
492 | 507 | " 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", |
496 | 510 | " 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", |
499 | 512 | " project_root = current.parent.parent\n", |
500 | | - " # Check if we're in notebooks/ (go up 1 level)\n", |
501 | 513 | " elif current.name == NOTEBOOKS_DIR:\n", |
502 | 514 | " project_root = current.parent\n", |
503 | 515 | " else:\n", |
504 | | - " # Try going up from current directory\n", |
505 | 516 | " project_root = current\n", |
506 | 517 | " 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", |
508 | 519 | " project_root = parent\n", |
509 | 520 | " 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", |
512 | 531 | " os.chdir(project_root)\n", |
513 | 532 | " builtins.__project_root__ = project_root\n", |
514 | 533 | " return project_root\n", |
515 | 534 | "\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", |
537 | 535 | "# Find and change to project root\n", |
538 | 536 | "project_root = find_project_root()\n", |
539 | 537 | "if project_root is None:\n", |
|
1340 | 1338 | " import builtins\n", |
1341 | 1339 | " import os\n", |
1342 | 1340 | " 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", |
1349 | 1354 | " 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", |
1353 | 1357 | " 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", |
1356 | 1359 | " project_root = current.parent.parent\n", |
1357 | | - " # Check if we're in notebooks/ (go up 1 level)\n", |
1358 | 1360 | " elif current.name == NOTEBOOKS_DIR:\n", |
1359 | 1361 | " project_root = current.parent\n", |
1360 | 1362 | " else:\n", |
1361 | | - " # Try going up from current directory\n", |
1362 | 1363 | " project_root = current\n", |
1363 | 1364 | " 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", |
1365 | 1366 | " project_root = parent\n", |
1366 | 1367 | " 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", |
1369 | 1378 | " os.chdir(project_root)\n", |
1370 | 1379 | " builtins.__project_root__ = project_root\n", |
1371 | 1380 | " return project_root\n", |
|
2848 | 2857 | " os.chdir(project_root)\n", |
2849 | 2858 | " builtins.__project_root__ = project_root\n", |
2850 | 2859 | " 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", |
2852 | 2867 | " 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", |
2855 | 2871 | " project_root = current.parent.parent\n", |
2856 | 2872 | " elif current.name == NOTEBOOKS_DIR:\n", |
2857 | 2873 | " project_root = current.parent\n", |
2858 | 2874 | " else:\n", |
2859 | | - " # Try going up from current directory\n", |
| 2875 | + " project_root = current\n", |
2860 | 2876 | " 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", |
2862 | 2878 | " project_root = parent\n", |
2863 | 2879 | " 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", |
2866 | 2890 | " os.chdir(project_root)\n", |
2867 | 2891 | " builtins.__project_root__ = project_root\n", |
2868 | 2892 | " \n", |
|
3385 | 3409 | " NOTEBOOK_SETUP_DIR = \"setup\"\n", |
3386 | 3410 | " NOTEBOOKS_DIR = \"notebooks\"\n", |
3387 | 3411 | "\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", |
3388 | 3418 | " def get_project_root():\n", |
3389 | 3419 | " \"\"\"Detect repo root (same rules as Step 2) if that cell was not run.\"\"\"\n", |
3390 | 3420 | " import builtins\n", |
3391 | 3421 | " import os\n", |
3392 | 3422 | "\n", |
3393 | 3423 | " 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", |
3395 | 3428 | "\n", |
3396 | 3429 | " 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", |
3401 | 3431 | " 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", |
3403 | 3433 | " project_root = current.parent.parent\n", |
3404 | 3434 | " elif current.name == NOTEBOOKS_DIR:\n", |
3405 | 3435 | " project_root = current.parent\n", |
3406 | 3436 | " else:\n", |
3407 | 3437 | " project_root = current\n", |
3408 | 3438 | " 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", |
3413 | 3440 | " project_root = parent\n", |
3414 | 3441 | " break\n", |
3415 | 3442 | "\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", |
3416 | 3452 | " os.chdir(project_root)\n", |
3417 | 3453 | " builtins.__project_root__ = project_root\n", |
3418 | 3454 | " return project_root\n", |
|
0 commit comments