recce-nightly 1.9.0.20250619__py3-none-any.whl → 1.9.0.20250623__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
recce/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.0.20250619
1
+ 1.9.0.20250623
@@ -915,65 +915,128 @@ class DbtAdapter(BaseAdapter):
915
915
  diff=diff,
916
916
  )
917
917
 
918
- def get_cll(self, node_id: str, column: Optional[str]) -> CllData:
919
- cll = self.get_cll_by_node_id(node_id)
920
- if not column:
921
- return cll
922
-
923
- target_column = f"{node_id}_{column}"
924
- upstream, downstream = find_column_dependencies(target_column, cll.parent_map, cll.child_map)
925
- relevant_columns = {target_column}
926
- relevant_columns.update(upstream, downstream)
927
- nodes, columns = filter_lineage_vertices(cll.nodes, cll.columns, relevant_columns)
928
- p_map, c_map = filter_dependency_maps(cll.parent_map, cll.child_map, relevant_columns)
929
- return CllData(
930
- nodes=nodes,
931
- columns=columns,
932
- parent_map=p_map,
933
- child_map=c_map,
934
- )
935
-
936
- def get_cll_by_node_id(self, node_id: str, base: Optional[bool] = False) -> CllData:
918
+ def get_cll(
919
+ self,
920
+ node_id: Optional[str] = None,
921
+ column: Optional[str] = None,
922
+ change_analysis: Optional[bool] = False,
923
+ cll: Optional[bool] = True,
924
+ upstream: Optional[bool] = True,
925
+ downstream: Optional[bool] = True,
926
+ no_filter: Optional[bool] = False,
927
+ ) -> CllData:
937
928
  cll_tracker = CLLPerformanceTracking()
938
929
  cll_tracker.start_column_lineage()
939
930
 
940
- manifest = self.curr_manifest if base is False else self.base_manifest
931
+ manifest = self.curr_manifest
941
932
  manifest_dict = manifest.to_dict()
942
933
 
943
- parent_ids = find_upstream(node_id, manifest_dict.get("parent_map"))
944
- child_ids = find_downstream(node_id, manifest_dict.get("child_map"))
945
- cll_node_ids = parent_ids.union(child_ids)
946
- cll_node_ids.add(node_id)
934
+ # Find related model nodes
935
+ if node_id is not None:
936
+ cll_node_ids = {node_id}
937
+ else:
938
+ lineage_diff = self.get_lineage_diff()
939
+ cll_node_ids = lineage_diff.diff.keys()
947
940
 
948
941
  nodes = {}
949
- cll_data = CllData()
950
- for node_id in cll_node_ids:
951
- if node_id not in manifest.sources and node_id not in manifest.nodes and node_id not in manifest.exposures:
952
- continue
953
- cll_data_one = self.get_cll_cached(node_id, base=base)
954
- if cll_data_one is None:
955
- continue
956
- for n_id, n in cll_data_one.nodes.items():
957
- cll_data.nodes[n_id] = n
958
- for c_id, c in cll_data_one.columns.items():
959
- cll_data.columns[c_id] = c
960
- for p_id, parents in cll_data_one.parent_map.items():
961
- cll_data.parent_map[p_id] = parents
942
+ columns = {}
943
+ parent_map = {}
944
+ child_map = {}
945
+
946
+ if upstream:
947
+ cll_node_ids = cll_node_ids.union(find_upstream(cll_node_ids, manifest_dict.get("parent_map")))
948
+ if downstream:
949
+ cll_node_ids = cll_node_ids.union(find_downstream(cll_node_ids, manifest_dict.get("child_map")))
950
+
951
+ if cll:
952
+ for cll_node_id in cll_node_ids:
953
+ if (
954
+ cll_node_id not in manifest.sources
955
+ and cll_node_id not in manifest.nodes
956
+ and cll_node_id not in manifest.exposures
957
+ ):
958
+ continue
959
+ cll_data_one = self.get_cll_cached(cll_node_id, base=False)
960
+ if cll_data_one is None:
961
+ continue
962
+
963
+ node_diff = self.get_lineage_diff().diff.get(cll_node_id) if change_analysis else None
964
+ for n_id, n in cll_data_one.nodes.items():
965
+ nodes[n_id] = n
966
+
967
+ if node_diff is not None:
968
+ n.change_status = node_diff.change_status
969
+ if node_diff.change is not None:
970
+ n.change_category = node_diff.change.category
971
+ for c_id, c in cll_data_one.columns.items():
972
+ columns[c_id] = c
973
+ if node_diff is not None and node_diff.change is not None:
974
+ column_diff = node_diff.change.columns.get(c.name)
975
+ if column_diff:
976
+ c.change_status = column_diff
977
+
978
+ for p_id, parents in cll_data_one.parent_map.items():
979
+ parent_map[p_id] = parents
962
980
 
963
981
  # build the child map
964
- cll_data.child_map = {}
965
- for node_id, parents in cll_data.parent_map.items():
982
+ for parent_id, parents in parent_map.items():
966
983
  for parent in parents:
967
- if parent not in cll_data.child_map:
968
- cll_data.child_map[parent] = set()
969
- cll_data.child_map[parent].add(node_id)
984
+ if parent not in child_map:
985
+ child_map[parent] = set()
986
+ child_map[parent].add(parent_id)
987
+
988
+ # Find the anchor nodes
989
+ anchor_node_ids = set()
990
+ if node_id is None and column is None:
991
+ if change_analysis:
992
+ # If change analysis is requested, we need to find the nodes that have changes
993
+ for node_id, node_diff in self.get_lineage_diff().diff.items():
994
+ if node_diff.change.category == "breaking":
995
+ anchor_node_ids.add(node_id)
996
+ for column_name in node_diff.change.columns:
997
+ anchor_node_ids.add(f"{node_id}_{column_name}")
998
+ else:
999
+ lineage_diff = self.get_lineage_diff()
1000
+ anchor_node_ids = lineage_diff.diff.keys()
1001
+ elif node_id is not None and column is None:
1002
+ if change_analysis:
1003
+ # If change analysis is requested, we need to find the nodes that have changes
1004
+ node_diff = self.get_lineage_diff().diff.get(node_id)
1005
+ if node_diff:
1006
+ if node_diff.change.category == "breaking":
1007
+ anchor_node_ids.add(node_id)
1008
+ for column_name in node_diff.change.columns:
1009
+ anchor_node_ids.add(f"{node_id}_{column_name}")
1010
+ else:
1011
+ anchor_node_ids.add(node_id)
1012
+ else:
1013
+ anchor_node_ids.add(node_id)
1014
+ else:
1015
+ anchor_node_ids.add(f"{node_id}_{column}")
1016
+
1017
+ result_node_ids = set(anchor_node_ids)
1018
+ if upstream:
1019
+ result_node_ids = result_node_ids.union(find_upstream(anchor_node_ids, parent_map))
1020
+ if downstream:
1021
+ result_node_ids = result_node_ids.union(find_downstream(anchor_node_ids, child_map))
1022
+
1023
+ # Filter the nodes and columns based on the anchor nodes
1024
+ if not no_filter:
1025
+ nodes = {k: v for k, v in nodes.items() if k in result_node_ids}
1026
+ columns = {k: v for k, v in columns.items() if k in result_node_ids}
1027
+ parent_map, child_map = filter_dependency_maps(parent_map, child_map, result_node_ids)
970
1028
 
971
1029
  cll_tracker.end_column_lineage()
972
1030
  cll_tracker.set_total_nodes(len(nodes))
973
1031
  log_performance("column level lineage", cll_tracker.to_dict())
974
1032
  cll_tracker.reset()
975
1033
 
976
- return cll_data
1034
+ return CllData(
1035
+ nodes=nodes,
1036
+ columns=columns,
1037
+ parent_map=parent_map,
1038
+ child_map=child_map,
1039
+ )
977
1040
 
978
1041
  @lru_cache(maxsize=128)
979
1042
  def get_cll_cached(self, node_id: str, base: Optional[bool] = False) -> Optional[CllData]:
@@ -1202,7 +1265,7 @@ class DbtAdapter(BaseAdapter):
1202
1265
  change_category = diff_info.change.category
1203
1266
 
1204
1267
  if change_category == "breaking":
1205
- cll = self.get_cll_by_node_id(node_id)
1268
+ cll = self.get_cll(node_id, no_filter=True)
1206
1269
  _, downstream = find_column_dependencies(node_id, cll.parent_map, cll.child_map)
1207
1270
  relevant_columns = {node_id}
1208
1271
  relevant_columns.update(downstream)
@@ -1220,7 +1283,7 @@ class DbtAdapter(BaseAdapter):
1220
1283
  return CllData()
1221
1284
  change_columns = diff_info.change.columns
1222
1285
 
1223
- cll = self.get_cll_by_node_id(node_id)
1286
+ cll = self.get_cll(node_id, no_filter=True)
1224
1287
  relevant_columns = set()
1225
1288
  for col, change_status in change_columns.items():
1226
1289
  if change_status == "removed":
recce/cli.py CHANGED
@@ -17,9 +17,9 @@ from recce.state import RecceCloudStateManager, RecceShareStateManager, RecceSta
17
17
  from recce.summary import generate_markdown_summary
18
18
  from recce.util.api_token import prepare_api_token, show_invalid_api_token_message
19
19
  from recce.util.logger import CustomFormatter
20
+ from recce.util.onboarding_state import update_onboarding_state
20
21
  from recce.util.recce_cloud import (
21
22
  RecceCloudException,
22
- get_recce_cloud_onboarding_state,
23
23
  )
24
24
 
25
25
  from .core import RecceContext, set_default_context
@@ -397,15 +397,21 @@ def server(host, port, lifetime, state_file=None, **kwargs):
397
397
  is_cloud = kwargs.get("cloud", False)
398
398
  console = Console()
399
399
  cloud_options = None
400
- flag = {"show_onboarding_guide": True, "single_env_onboarding": False, "show_relaunch_hint": False}
400
+ flag = {"single_env_onboarding": False, "show_relaunch_hint": False}
401
401
  if is_cloud:
402
402
  cloud_options = {
403
403
  "host": kwargs.get("state_file_host"),
404
404
  "token": kwargs.get("cloud_token"),
405
405
  "password": kwargs.get("password"),
406
406
  }
407
- cloud_onboarding_state = get_recce_cloud_onboarding_state(kwargs.get("cloud_token"))
408
- flag["show_onboarding_guide"] = False if cloud_onboarding_state == "completed" else True
407
+
408
+ # Check Single Environment Onboarding Mode if the review mode is False
409
+ if not Path(kwargs.get("target_base_path", "target-base")).is_dir() and not is_review:
410
+ # Mark as single env onboarding mode if user provides the target-path only
411
+ flag["single_env_onboarding"] = True
412
+ flag["show_relaunch_hint"] = True
413
+ # Use the target path as the base path
414
+ kwargs["target_base_path"] = kwargs.get("target_path")
409
415
 
410
416
  auth_options = {}
411
417
  try:
@@ -415,13 +421,8 @@ def server(host, port, lifetime, state_file=None, **kwargs):
415
421
  exit(1)
416
422
  auth_options["api_token"] = api_token
417
423
 
418
- # Check Single Environment Onboarding Mode if the review mode is False
419
- if not Path(kwargs.get("target_base_path", "target-base")).is_dir() and not is_review:
420
- # Mark as single env onboarding mode if user provides the target-path only
421
- flag["single_env_onboarding"] = True
422
- flag["show_relaunch_hint"] = True
423
- # Use the target path as the base path
424
- kwargs["target_base_path"] = kwargs.get("target_path")
424
+ # Onboarding State logic update here
425
+ update_onboarding_state(api_token, flag["single_env_onboarding"])
425
426
 
426
427
  state_loader = create_state_loader(is_review, is_cloud, state_file, cloud_options)
427
428
 
recce/data/404.html CHANGED
@@ -19,4 +19,4 @@
19
19
  pre
20
20
  ){margin:0;}button{background:transparent;padding:0;}fieldset{margin:0;padding:0;}:where(ol, ul){margin:0;padding:0;}textarea{resize:vertical;}:where(button, [role="button"]){cursor:pointer;}button::-moz-focus-inner{border:0!important;}table{border-collapse:collapse;}:where(h1, h2, h3, h4, h5, h6){font-size:inherit;font-weight:inherit;}:where(button, input, optgroup, select, textarea){padding:0;line-height:inherit;color:inherit;}:where(img, svg, video, canvas, audio, iframe, embed, object){display:block;}:where(img, video){max-width:100%;height:auto;}[data-js-focus-visible] :focus:not([data-focus-visible-added]):not(
21
21
  [data-focus-visible-disabled]
22
- ){outline:none;box-shadow:none;}select::-ms-expand{display:none;}:root,:host{--chakra-vh:100vh;}@supports (height: -webkit-fill-available){:root,:host{--chakra-vh:-webkit-fill-available;}}@supports (height: -moz-fill-available){:root,:host{--chakra-vh:-moz-fill-available;}}@supports (height: 100dvh){:root,:host{--chakra-vh:100dvh;}}</style><style data-emotion="css-global 1cgn62j">body{font-family:var(--chakra-fonts-body);color:var(--chakra-colors-chakra-body-text);background:var(--chakra-colors-chakra-body-bg);transition-property:background-color;transition-duration:var(--chakra-transition-duration-normal);line-height:var(--chakra-lineHeights-base);}*::-webkit-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::-moz-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*:-ms-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*,*::before,::after{border-color:var(--chakra-colors-chakra-border-color);}</style><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-7b49d5ba7e3a434d.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/1b121dc4d36aeb4d.css\",\"style\"]\n2:HL[\"/_next/static/css/951e2e0eea2d4a5b.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"3:I[35639,[],\"\"]\n5:I[51454,[],\"\"]\n6:I[48464,[],\"\"]\n7:I[76413,[\"509\",\"static/chunks/9746af58-a42b7d169cacadf0.js\",\"989\",\"static/chunks/47d8844f-929aed9b1c73a905.js\",\"147\",\"static/chunks/a30376cd-de84559016d7e133.js\",\"495\",\"static/chunks/6dc81886-adbfa45836061d79.js\",\"376\",\"static/chunks/3a92ee20-1081c360214f9602.js\",\"678\",\"static/chunks/3998a672-03adacad07b346ac.js\",\"20\",\"static/chunks/1bff33f1-1ef85cf5e658a751.js\",\"413\",\"static/chunks/bbda5537-9ec25eb1dd62348a.js\",\"42\",\"static/chunks/42-cd3c06533f5fd47c.js\",\"608\",\"static/chunks/608-3b079b544e5d5f5e.js\",\"92\",\"static/chunks/92-7ab55ae02606193c.js\",\"185\",\"static/chunks/app/layout-177a410a97e0d018.js\"],\"default\"]\nd:I[26480,[],\"\"]\n8:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n9:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\na:{\"display\":\"inline-block\"}\nb:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L3\",null,{\"buildId\":\"T2ShdYDyPGcOWrwJnitax\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L4\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1b121dc4d36aeb4d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/951e2e0eea2d4a5b.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$9\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$a\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$b\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Lc\"],\"globalErrorComponent\":\"$d\",\"missingSlots\":\"$We\"}]\n"])</script><script>self.__next_f.push([1,"c:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}]]\n4:null\n"])</script></body></html>
22
+ ){outline:none;box-shadow:none;}select::-ms-expand{display:none;}:root,:host{--chakra-vh:100vh;}@supports (height: -webkit-fill-available){:root,:host{--chakra-vh:-webkit-fill-available;}}@supports (height: -moz-fill-available){:root,:host{--chakra-vh:-moz-fill-available;}}@supports (height: 100dvh){:root,:host{--chakra-vh:100dvh;}}</style><style data-emotion="css-global 1cgn62j">body{font-family:var(--chakra-fonts-body);color:var(--chakra-colors-chakra-body-text);background:var(--chakra-colors-chakra-body-bg);transition-property:background-color;transition-duration:var(--chakra-transition-duration-normal);line-height:var(--chakra-lineHeights-base);}*::-webkit-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::-moz-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*:-ms-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*,*::before,::after{border-color:var(--chakra-colors-chakra-border-color);}</style><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-7b49d5ba7e3a434d.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/1b121dc4d36aeb4d.css\",\"style\"]\n2:HL[\"/_next/static/css/951e2e0eea2d4a5b.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"3:I[35639,[],\"\"]\n5:I[51454,[],\"\"]\n6:I[48464,[],\"\"]\n7:I[76413,[\"509\",\"static/chunks/9746af58-a42b7d169cacadf0.js\",\"989\",\"static/chunks/47d8844f-929aed9b1c73a905.js\",\"147\",\"static/chunks/a30376cd-de84559016d7e133.js\",\"495\",\"static/chunks/6dc81886-adbfa45836061d79.js\",\"376\",\"static/chunks/3a92ee20-1081c360214f9602.js\",\"678\",\"static/chunks/3998a672-03adacad07b346ac.js\",\"20\",\"static/chunks/1bff33f1-1ef85cf5e658a751.js\",\"413\",\"static/chunks/bbda5537-9ec25eb1dd62348a.js\",\"42\",\"static/chunks/42-cd3c06533f5fd47c.js\",\"608\",\"static/chunks/608-3b079b544e5d5f5e.js\",\"92\",\"static/chunks/92-7ab55ae02606193c.js\",\"185\",\"static/chunks/app/layout-177a410a97e0d018.js\"],\"default\"]\nd:I[26480,[],\"\"]\n8:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n9:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\na:{\"display\":\"inline-block\"}\nb:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L3\",null,{\"buildId\":\"WrRUb3nV8BhAZG_R8kVma\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L4\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1b121dc4d36aeb4d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/951e2e0eea2d4a5b.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$9\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$a\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$b\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Lc\"],\"globalErrorComponent\":\"$d\",\"missingSlots\":\"$We\"}]\n"])</script><script>self.__next_f.push([1,"c:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}]]\n4:null\n"])</script></body></html>