recce-nightly 1.5.0.20250527__py3-none-any.whl → 1.6.0.20250529__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.

Potentially problematic release.


This version of recce-nightly might be problematic. Click here for more details.

Files changed (24) hide show
  1. recce/VERSION +1 -1
  2. recce/adapter/dbt_adapter/__init__.py +112 -91
  3. recce/data/404.html +2 -2
  4. recce/data/_next/static/chunks/711-5ac2c87eb5073191.js +1 -0
  5. recce/data/_next/static/chunks/app/layout-c76e6ca2ce9857e9.js +1 -0
  6. recce/data/_next/static/chunks/app/page-f0b9d7985eaf7eed.js +1 -0
  7. recce/data/index.html +2 -2
  8. recce/data/index.txt +3 -3
  9. recce/models/types.py +47 -1
  10. recce/server.py +4 -9
  11. recce/util/cll.py +110 -90
  12. {recce_nightly-1.5.0.20250527.dist-info → recce_nightly-1.6.0.20250529.dist-info}/METADATA +1 -1
  13. {recce_nightly-1.5.0.20250527.dist-info → recce_nightly-1.6.0.20250529.dist-info}/RECORD +21 -21
  14. tests/adapter/dbt_adapter/dbt_test_helper.py +1 -2
  15. tests/adapter/dbt_adapter/test_dbt_cll.py +95 -18
  16. recce/data/_next/static/chunks/711-9f4b13e082dc2f43.js +0 -1
  17. recce/data/_next/static/chunks/app/layout-84447815782d7e41.js +0 -1
  18. recce/data/_next/static/chunks/app/page-183db1bcb15b328f.js +0 -1
  19. /recce/data/_next/static/{_i7vGe6giBb07tZ0Ml9uG → 1rwJEkX_z2KfSDpX3cGQ1}/_buildManifest.js +0 -0
  20. /recce/data/_next/static/{_i7vGe6giBb07tZ0Ml9uG → 1rwJEkX_z2KfSDpX3cGQ1}/_ssgManifest.js +0 -0
  21. {recce_nightly-1.5.0.20250527.dist-info → recce_nightly-1.6.0.20250529.dist-info}/WHEEL +0 -0
  22. {recce_nightly-1.5.0.20250527.dist-info → recce_nightly-1.6.0.20250529.dist-info}/entry_points.txt +0 -0
  23. {recce_nightly-1.5.0.20250527.dist-info → recce_nightly-1.6.0.20250529.dist-info}/licenses/LICENSE +0 -0
  24. {recce_nightly-1.5.0.20250527.dist-info → recce_nightly-1.6.0.20250529.dist-info}/top_level.txt +0 -0
recce/data/index.html CHANGED
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="/logo/recce-logo-white.png"/><link rel="stylesheet" href="/_next/static/css/1b121dc4d36aeb4d.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/951e2e0eea2d4a5b.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/17a96168e3a9db13.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/6d6961e0422ac782.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-8442f6926a7a34ce.js"/><script src="/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js" async=""></script><script src="/_next/static/chunks/700-3b65fc3666820d00.js" async=""></script><script src="/_next/static/chunks/main-app-0225a2255968e566.js" async=""></script><script src="/_next/static/chunks/9746af58-d74bef4d03eea6ab.js" async=""></script><script src="/_next/static/chunks/47d8844f-79a1b53c66a7d7ec.js" async=""></script><script src="/_next/static/chunks/a30376cd-ac45432855afb688.js" async=""></script><script src="/_next/static/chunks/6dc81886-c94b9b91bc2c3caf.js" async=""></script><script src="/_next/static/chunks/3a92ee20-3b5d922d4157af5e.js" async=""></script><script src="/_next/static/chunks/3998a672-eaad84bdd88cc73e.js" async=""></script><script src="/_next/static/chunks/e24bf851-0f8cbc99656833e7.js" async=""></script><script src="/_next/static/chunks/c1ceaa8b-a1e442154d23515e.js" async=""></script><script src="/_next/static/chunks/6ef81909-694dc38134099299.js" async=""></script><script src="/_next/static/chunks/ce84277d-f42c2c58049cea2d.js" async=""></script><script src="/_next/static/chunks/fee69bc6-f17d36c080742e74.js" async=""></script><script src="/_next/static/chunks/7a8a3e83-d7fa409d97b38b2b.js" async=""></script><script src="/_next/static/chunks/450c323b-1bb5db526e54435a.js" async=""></script><script src="/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js" async=""></script><script src="/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js" async=""></script><script src="/_next/static/chunks/b63b1b3f-7395c74e11a14e95.js" async=""></script><script src="/_next/static/chunks/7f27ae6c-413f6b869a04183a.js" async=""></script><script src="/_next/static/chunks/c132bf7d-8102037f9ccf372a.js" async=""></script><script src="/_next/static/chunks/cd9f8d63-e020f408095ed77c.js" async=""></script><script src="/_next/static/chunks/316-9e0164c48e40d69b.js" async=""></script><script src="/_next/static/chunks/963-7cb453d3f159e7cc.js" async=""></script><script src="/_next/static/chunks/711-9f4b13e082dc2f43.js" async=""></script><script src="/_next/static/chunks/app/page-183db1bcb15b328f.js" async=""></script><script src="/_next/static/chunks/350-30608a95db2634b6.js" async=""></script><script src="/_next/static/chunks/app/layout-84447815782d7e41.js" async=""></script><title>recce</title><meta name="description" content="Recce: Data validation toolkit for comprehensive PR review"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="32x32"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><style data-emotion="css-global dh58eu">:host,:root,[data-theme]{--chakra-ring-inset:var(--chakra-empty,/*!*/ /*!*/);--chakra-ring-offset-width:0px;--chakra-ring-offset-color:#fff;--chakra-ring-color:rgba(66, 153, 225, 0.6);--chakra-ring-offset-shadow:0 0 #0000;--chakra-ring-shadow:0 0 #0000;--chakra-space-x-reverse:0;--chakra-space-y-reverse:0;--chakra-colors-transparent:transparent;--chakra-colors-current:currentColor;--chakra-colors-black:#000000;--chakra-colors-white:#FFFFFF;--chakra-colors-whiteAlpha-50:rgba(255, 255, 255, 0.04);--chakra-colors-whiteAlpha-100:rgba(255, 255, 255, 0.06);--chakra-colors-whiteAlpha-200:rgba(255, 255, 255, 0.08);--chakra-colors-whiteAlpha-300:rgba(255, 255, 255, 0.16);--chakra-colors-whiteAlpha-400:rgba(255, 255, 255, 0.24);--chakra-colors-whiteAlpha-500:rgba(255, 255, 255, 0.36);--chakra-colors-whiteAlpha-600:rgba(255, 255, 255, 0.48);--chakra-colors-whiteAlpha-700:rgba(255, 255, 255, 0.64);--chakra-colors-whiteAlpha-800:rgba(255, 255, 255, 0.80);--chakra-colors-whiteAlpha-900:rgba(255, 255, 255, 0.92);--chakra-colors-blackAlpha-50:rgba(0, 0, 0, 0.04);--chakra-colors-blackAlpha-100:rgba(0, 0, 0, 0.06);--chakra-colors-blackAlpha-200:rgba(0, 0, 0, 0.08);--chakra-colors-blackAlpha-300:rgba(0, 0, 0, 0.16);--chakra-colors-blackAlpha-400:rgba(0, 0, 0, 0.24);--chakra-colors-blackAlpha-500:rgba(0, 0, 0, 0.36);--chakra-colors-blackAlpha-600:rgba(0, 0, 0, 0.48);--chakra-colors-blackAlpha-700:rgba(0, 0, 0, 0.64);--chakra-colors-blackAlpha-800:rgba(0, 0, 0, 0.80);--chakra-colors-blackAlpha-900:rgba(0, 0, 0, 0.92);--chakra-colors-gray-50:#F7FAFC;--chakra-colors-gray-100:#EDF2F7;--chakra-colors-gray-200:#E2E8F0;--chakra-colors-gray-300:#CBD5E0;--chakra-colors-gray-400:#A0AEC0;--chakra-colors-gray-500:#718096;--chakra-colors-gray-600:#4A5568;--chakra-colors-gray-700:#2D3748;--chakra-colors-gray-800:#1A202C;--chakra-colors-gray-900:#171923;--chakra-colors-red-50:#FFF5F5;--chakra-colors-red-100:#FED7D7;--chakra-colors-red-200:#FEB2B2;--chakra-colors-red-300:#FC8181;--chakra-colors-red-400:#F56565;--chakra-colors-red-500:#E53E3E;--chakra-colors-red-600:#C53030;--chakra-colors-red-700:#9B2C2C;--chakra-colors-red-800:#822727;--chakra-colors-red-900:#63171B;--chakra-colors-orange-50:#FFFAF0;--chakra-colors-orange-100:#FEEBC8;--chakra-colors-orange-200:#FBD38D;--chakra-colors-orange-300:#F6AD55;--chakra-colors-orange-400:#ED8936;--chakra-colors-orange-500:#DD6B20;--chakra-colors-orange-600:#C05621;--chakra-colors-orange-700:#9C4221;--chakra-colors-orange-800:#7B341E;--chakra-colors-orange-900:#652B19;--chakra-colors-yellow-50:#FFFFF0;--chakra-colors-yellow-100:#FEFCBF;--chakra-colors-yellow-200:#FAF089;--chakra-colors-yellow-300:#F6E05E;--chakra-colors-yellow-400:#ECC94B;--chakra-colors-yellow-500:#D69E2E;--chakra-colors-yellow-600:#B7791F;--chakra-colors-yellow-700:#975A16;--chakra-colors-yellow-800:#744210;--chakra-colors-yellow-900:#5F370E;--chakra-colors-green-50:#F0FFF4;--chakra-colors-green-100:#C6F6D5;--chakra-colors-green-200:#9AE6B4;--chakra-colors-green-300:#68D391;--chakra-colors-green-400:#48BB78;--chakra-colors-green-500:#38A169;--chakra-colors-green-600:#2F855A;--chakra-colors-green-700:#276749;--chakra-colors-green-800:#22543D;--chakra-colors-green-900:#1C4532;--chakra-colors-teal-50:#E6FFFA;--chakra-colors-teal-100:#B2F5EA;--chakra-colors-teal-200:#81E6D9;--chakra-colors-teal-300:#4FD1C5;--chakra-colors-teal-400:#38B2AC;--chakra-colors-teal-500:#319795;--chakra-colors-teal-600:#2C7A7B;--chakra-colors-teal-700:#285E61;--chakra-colors-teal-800:#234E52;--chakra-colors-teal-900:#1D4044;--chakra-colors-blue-50:#ebf8ff;--chakra-colors-blue-100:#bee3f8;--chakra-colors-blue-200:#90cdf4;--chakra-colors-blue-300:#63b3ed;--chakra-colors-blue-400:#4299e1;--chakra-colors-blue-500:#3182ce;--chakra-colors-blue-600:#2b6cb0;--chakra-colors-blue-700:#2c5282;--chakra-colors-blue-800:#2a4365;--chakra-colors-blue-900:#1A365D;--chakra-colors-cyan-50:#EDFDFD;--chakra-colors-cyan-100:#C4F1F9;--chakra-colors-cyan-200:#9DECF9;--chakra-colors-cyan-300:#76E4F7;--chakra-colors-cyan-400:#0BC5EA;--chakra-colors-cyan-500:#00B5D8;--chakra-colors-cyan-600:#00A3C4;--chakra-colors-cyan-700:#0987A0;--chakra-colors-cyan-800:#086F83;--chakra-colors-cyan-900:#065666;--chakra-colors-purple-50:#FAF5FF;--chakra-colors-purple-100:#E9D8FD;--chakra-colors-purple-200:#D6BCFA;--chakra-colors-purple-300:#B794F4;--chakra-colors-purple-400:#9F7AEA;--chakra-colors-purple-500:#805AD5;--chakra-colors-purple-600:#6B46C1;--chakra-colors-purple-700:#553C9A;--chakra-colors-purple-800:#44337A;--chakra-colors-purple-900:#322659;--chakra-colors-pink-50:#FFF5F7;--chakra-colors-pink-100:#FED7E2;--chakra-colors-pink-200:#FBB6CE;--chakra-colors-pink-300:#F687B3;--chakra-colors-pink-400:#ED64A6;--chakra-colors-pink-500:#D53F8C;--chakra-colors-pink-600:#B83280;--chakra-colors-pink-700:#97266D;--chakra-colors-pink-800:#702459;--chakra-colors-pink-900:#521B41;--chakra-colors-brand-100:#fd683e;--chakra-colors-brand-200:#fd683e;--chakra-colors-brand-300:#fd683e;--chakra-colors-brand-400:#fd683e;--chakra-colors-brand-500:#fd683e;--chakra-colors-brand-600:#fd683e;--chakra-colors-brand-700:#fd683e;--chakra-colors-brand-800:#fd683e;--chakra-colors-brand-900:#fd683e;--chakra-borders-none:0;--chakra-borders-1px:1px solid;--chakra-borders-2px:2px solid;--chakra-borders-4px:4px solid;--chakra-borders-8px:8px solid;--chakra-fonts-heading:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--chakra-fonts-body:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--chakra-fonts-mono:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--chakra-fontSizes-3xs:0.45rem;--chakra-fontSizes-2xs:0.625rem;--chakra-fontSizes-xs:0.75rem;--chakra-fontSizes-sm:0.875rem;--chakra-fontSizes-md:1rem;--chakra-fontSizes-lg:1.125rem;--chakra-fontSizes-xl:1.25rem;--chakra-fontSizes-2xl:1.5rem;--chakra-fontSizes-3xl:1.875rem;--chakra-fontSizes-4xl:2.25rem;--chakra-fontSizes-5xl:3rem;--chakra-fontSizes-6xl:3.75rem;--chakra-fontSizes-7xl:4.5rem;--chakra-fontSizes-8xl:6rem;--chakra-fontSizes-9xl:8rem;--chakra-fontWeights-hairline:100;--chakra-fontWeights-thin:200;--chakra-fontWeights-light:300;--chakra-fontWeights-normal:400;--chakra-fontWeights-medium:500;--chakra-fontWeights-semibold:600;--chakra-fontWeights-bold:700;--chakra-fontWeights-extrabold:800;--chakra-fontWeights-black:900;--chakra-letterSpacings-tighter:-0.05em;--chakra-letterSpacings-tight:-0.025em;--chakra-letterSpacings-normal:0;--chakra-letterSpacings-wide:0.025em;--chakra-letterSpacings-wider:0.05em;--chakra-letterSpacings-widest:0.1em;--chakra-lineHeights-3:.75rem;--chakra-lineHeights-4:1rem;--chakra-lineHeights-5:1.25rem;--chakra-lineHeights-6:1.5rem;--chakra-lineHeights-7:1.75rem;--chakra-lineHeights-8:2rem;--chakra-lineHeights-9:2.25rem;--chakra-lineHeights-10:2.5rem;--chakra-lineHeights-normal:normal;--chakra-lineHeights-none:1;--chakra-lineHeights-shorter:1.25;--chakra-lineHeights-short:1.375;--chakra-lineHeights-base:1.5;--chakra-lineHeights-tall:1.625;--chakra-lineHeights-taller:2;--chakra-radii-none:0;--chakra-radii-sm:0.125rem;--chakra-radii-base:0.25rem;--chakra-radii-md:0.375rem;--chakra-radii-lg:0.5rem;--chakra-radii-xl:0.75rem;--chakra-radii-2xl:1rem;--chakra-radii-3xl:1.5rem;--chakra-radii-full:9999px;--chakra-space-1:0.25rem;--chakra-space-2:0.5rem;--chakra-space-3:0.75rem;--chakra-space-4:1rem;--chakra-space-5:1.25rem;--chakra-space-6:1.5rem;--chakra-space-7:1.75rem;--chakra-space-8:2rem;--chakra-space-9:2.25rem;--chakra-space-10:2.5rem;--chakra-space-12:3rem;--chakra-space-14:3.5rem;--chakra-space-16:4rem;--chakra-space-20:5rem;--chakra-space-24:6rem;--chakra-space-28:7rem;--chakra-space-32:8rem;--chakra-space-36:9rem;--chakra-space-40:10rem;--chakra-space-44:11rem;--chakra-space-48:12rem;--chakra-space-52:13rem;--chakra-space-56:14rem;--chakra-space-60:15rem;--chakra-space-64:16rem;--chakra-space-72:18rem;--chakra-space-80:20rem;--chakra-space-96:24rem;--chakra-space-px:1px;--chakra-space-0-5:0.125rem;--chakra-space-1-5:0.375rem;--chakra-space-2-5:0.625rem;--chakra-space-3-5:0.875rem;--chakra-shadows-xs:0 0 0 1px rgba(0, 0, 0, 0.05);--chakra-shadows-sm:0 1px 2px 0 rgba(0, 0, 0, 0.05);--chakra-shadows-base:0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);--chakra-shadows-md:0 4px 6px -1px rgba(0, 0, 0, 0.1),0 2px 4px -1px rgba(0, 0, 0, 0.06);--chakra-shadows-lg:0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05);--chakra-shadows-xl:0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04);--chakra-shadows-2xl:0 25px 50px -12px rgba(0, 0, 0, 0.25);--chakra-shadows-outline:0 0 0 3px rgba(66, 153, 225, 0.6);--chakra-shadows-inner:inset 0 2px 4px 0 rgba(0,0,0,0.06);--chakra-shadows-none:none;--chakra-shadows-dark-lg:rgba(0, 0, 0, 0.1) 0px 0px 0px 1px,rgba(0, 0, 0, 0.2) 0px 5px 10px,rgba(0, 0, 0, 0.4) 0px 15px 40px;--chakra-sizes-1:0.25rem;--chakra-sizes-2:0.5rem;--chakra-sizes-3:0.75rem;--chakra-sizes-4:1rem;--chakra-sizes-5:1.25rem;--chakra-sizes-6:1.5rem;--chakra-sizes-7:1.75rem;--chakra-sizes-8:2rem;--chakra-sizes-9:2.25rem;--chakra-sizes-10:2.5rem;--chakra-sizes-12:3rem;--chakra-sizes-14:3.5rem;--chakra-sizes-16:4rem;--chakra-sizes-20:5rem;--chakra-sizes-24:6rem;--chakra-sizes-28:7rem;--chakra-sizes-32:8rem;--chakra-sizes-36:9rem;--chakra-sizes-40:10rem;--chakra-sizes-44:11rem;--chakra-sizes-48:12rem;--chakra-sizes-52:13rem;--chakra-sizes-56:14rem;--chakra-sizes-60:15rem;--chakra-sizes-64:16rem;--chakra-sizes-72:18rem;--chakra-sizes-80:20rem;--chakra-sizes-96:24rem;--chakra-sizes-px:1px;--chakra-sizes-0-5:0.125rem;--chakra-sizes-1-5:0.375rem;--chakra-sizes-2-5:0.625rem;--chakra-sizes-3-5:0.875rem;--chakra-sizes-max:max-content;--chakra-sizes-min:min-content;--chakra-sizes-full:100%;--chakra-sizes-3xs:14rem;--chakra-sizes-2xs:16rem;--chakra-sizes-xs:20rem;--chakra-sizes-sm:24rem;--chakra-sizes-md:28rem;--chakra-sizes-lg:32rem;--chakra-sizes-xl:36rem;--chakra-sizes-2xl:42rem;--chakra-sizes-3xl:48rem;--chakra-sizes-4xl:56rem;--chakra-sizes-5xl:64rem;--chakra-sizes-6xl:72rem;--chakra-sizes-7xl:80rem;--chakra-sizes-8xl:90rem;--chakra-sizes-prose:60ch;--chakra-sizes-container-sm:640px;--chakra-sizes-container-md:768px;--chakra-sizes-container-lg:1024px;--chakra-sizes-container-xl:1280px;--chakra-zIndices-hide:-1;--chakra-zIndices-auto:auto;--chakra-zIndices-base:0;--chakra-zIndices-docked:10;--chakra-zIndices-dropdown:1000;--chakra-zIndices-sticky:1100;--chakra-zIndices-banner:1200;--chakra-zIndices-overlay:1300;--chakra-zIndices-modal:1400;--chakra-zIndices-popover:1500;--chakra-zIndices-skipLink:1600;--chakra-zIndices-toast:1700;--chakra-zIndices-tooltip:1800;--chakra-transition-property-common:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform;--chakra-transition-property-colors:background-color,border-color,color,fill,stroke;--chakra-transition-property-dimensions:width,height;--chakra-transition-property-position:left,right,top,bottom;--chakra-transition-property-background:background-color,background-image,background-position;--chakra-transition-easing-ease-in:cubic-bezier(0.4, 0, 1, 1);--chakra-transition-easing-ease-out:cubic-bezier(0, 0, 0.2, 1);--chakra-transition-easing-ease-in-out:cubic-bezier(0.4, 0, 0.2, 1);--chakra-transition-duration-ultra-fast:50ms;--chakra-transition-duration-faster:100ms;--chakra-transition-duration-fast:150ms;--chakra-transition-duration-normal:200ms;--chakra-transition-duration-slow:300ms;--chakra-transition-duration-slower:400ms;--chakra-transition-duration-ultra-slow:500ms;--chakra-blur-none:0;--chakra-blur-sm:4px;--chakra-blur-base:8px;--chakra-blur-md:12px;--chakra-blur-lg:16px;--chakra-blur-xl:24px;--chakra-blur-2xl:40px;--chakra-blur-3xl:64px;--chakra-breakpoints-base:0em;--chakra-breakpoints-sm:30em;--chakra-breakpoints-md:48em;--chakra-breakpoints-lg:62em;--chakra-breakpoints-xl:80em;--chakra-breakpoints-2xl:96em;}.chakra-ui-light :host:not([data-theme]),.chakra-ui-light :root:not([data-theme]),.chakra-ui-light [data-theme]:not([data-theme]),[data-theme=light] :host:not([data-theme]),[data-theme=light] :root:not([data-theme]),[data-theme=light] [data-theme]:not([data-theme]),:host[data-theme=light],:root[data-theme=light],[data-theme][data-theme=light]{--chakra-colors-chakra-body-text:var(--chakra-colors-gray-800);--chakra-colors-chakra-body-bg:var(--chakra-colors-white);--chakra-colors-chakra-border-color:var(--chakra-colors-gray-200);--chakra-colors-chakra-inverse-text:var(--chakra-colors-white);--chakra-colors-chakra-subtle-bg:var(--chakra-colors-gray-100);--chakra-colors-chakra-subtle-text:var(--chakra-colors-gray-600);--chakra-colors-chakra-placeholder-color:var(--chakra-colors-gray-500);}.chakra-ui-dark :host:not([data-theme]),.chakra-ui-dark :root:not([data-theme]),.chakra-ui-dark [data-theme]:not([data-theme]),[data-theme=dark] :host:not([data-theme]),[data-theme=dark] :root:not([data-theme]),[data-theme=dark] [data-theme]:not([data-theme]),:host[data-theme=dark],:root[data-theme=dark],[data-theme][data-theme=dark]{--chakra-colors-chakra-body-text:var(--chakra-colors-whiteAlpha-900);--chakra-colors-chakra-body-bg:var(--chakra-colors-gray-800);--chakra-colors-chakra-border-color:var(--chakra-colors-whiteAlpha-300);--chakra-colors-chakra-inverse-text:var(--chakra-colors-gray-800);--chakra-colors-chakra-subtle-bg:var(--chakra-colors-gray-700);--chakra-colors-chakra-subtle-text:var(--chakra-colors-gray-400);--chakra-colors-chakra-placeholder-color:var(--chakra-colors-whiteAlpha-400);}</style><style data-emotion="css-global fubdgu">html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:system-ui,sans-serif;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;touch-action:manipulation;}body{position:relative;min-height:100%;margin:0;font-feature-settings:"kern";}:where(*, *::before, *::after){border-width:0;border-style:solid;box-sizing:border-box;word-wrap:break-word;}main{display:block;}hr{border-top-width:1px;box-sizing:content-box;height:0;overflow:visible;}:where(pre, code, kbd,samp){font-family:SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:1em;}a{background-color:transparent;color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit;}abbr[title]{border-bottom:none;-webkit-text-decoration:underline;text-decoration:underline;-webkit-text-decoration:underline dotted;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;}:where(b, strong){font-weight:bold;}small{font-size:80%;}:where(sub,sup){font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sub{bottom:-0.25em;}sup{top:-0.5em;}img{border-style:none;}:where(button, input, optgroup, select, textarea){font-family:inherit;font-size:100%;line-height:1.15;margin:0;}:where(button, input){overflow:visible;}:where(button, select){text-transform:none;}:where(
1
+ <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="/logo/recce-logo-white.png"/><link rel="stylesheet" href="/_next/static/css/1b121dc4d36aeb4d.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/951e2e0eea2d4a5b.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/17a96168e3a9db13.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/6d6961e0422ac782.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-8442f6926a7a34ce.js"/><script src="/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js" async=""></script><script src="/_next/static/chunks/700-3b65fc3666820d00.js" async=""></script><script src="/_next/static/chunks/main-app-0225a2255968e566.js" async=""></script><script src="/_next/static/chunks/9746af58-d74bef4d03eea6ab.js" async=""></script><script src="/_next/static/chunks/47d8844f-79a1b53c66a7d7ec.js" async=""></script><script src="/_next/static/chunks/a30376cd-ac45432855afb688.js" async=""></script><script src="/_next/static/chunks/6dc81886-c94b9b91bc2c3caf.js" async=""></script><script src="/_next/static/chunks/3a92ee20-3b5d922d4157af5e.js" async=""></script><script src="/_next/static/chunks/3998a672-eaad84bdd88cc73e.js" async=""></script><script src="/_next/static/chunks/e24bf851-0f8cbc99656833e7.js" async=""></script><script src="/_next/static/chunks/c1ceaa8b-a1e442154d23515e.js" async=""></script><script src="/_next/static/chunks/6ef81909-694dc38134099299.js" async=""></script><script src="/_next/static/chunks/ce84277d-f42c2c58049cea2d.js" async=""></script><script src="/_next/static/chunks/fee69bc6-f17d36c080742e74.js" async=""></script><script src="/_next/static/chunks/7a8a3e83-d7fa409d97b38b2b.js" async=""></script><script src="/_next/static/chunks/450c323b-1bb5db526e54435a.js" async=""></script><script src="/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js" async=""></script><script src="/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js" async=""></script><script src="/_next/static/chunks/b63b1b3f-7395c74e11a14e95.js" async=""></script><script src="/_next/static/chunks/7f27ae6c-413f6b869a04183a.js" async=""></script><script src="/_next/static/chunks/c132bf7d-8102037f9ccf372a.js" async=""></script><script src="/_next/static/chunks/cd9f8d63-e020f408095ed77c.js" async=""></script><script src="/_next/static/chunks/316-9e0164c48e40d69b.js" async=""></script><script src="/_next/static/chunks/963-7cb453d3f159e7cc.js" async=""></script><script src="/_next/static/chunks/711-5ac2c87eb5073191.js" async=""></script><script src="/_next/static/chunks/app/page-f0b9d7985eaf7eed.js" async=""></script><script src="/_next/static/chunks/350-30608a95db2634b6.js" async=""></script><script src="/_next/static/chunks/app/layout-c76e6ca2ce9857e9.js" async=""></script><title>recce</title><meta name="description" content="Recce: Data validation toolkit for comprehensive PR review"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="32x32"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><style data-emotion="css-global dh58eu">:host,:root,[data-theme]{--chakra-ring-inset:var(--chakra-empty,/*!*/ /*!*/);--chakra-ring-offset-width:0px;--chakra-ring-offset-color:#fff;--chakra-ring-color:rgba(66, 153, 225, 0.6);--chakra-ring-offset-shadow:0 0 #0000;--chakra-ring-shadow:0 0 #0000;--chakra-space-x-reverse:0;--chakra-space-y-reverse:0;--chakra-colors-transparent:transparent;--chakra-colors-current:currentColor;--chakra-colors-black:#000000;--chakra-colors-white:#FFFFFF;--chakra-colors-whiteAlpha-50:rgba(255, 255, 255, 0.04);--chakra-colors-whiteAlpha-100:rgba(255, 255, 255, 0.06);--chakra-colors-whiteAlpha-200:rgba(255, 255, 255, 0.08);--chakra-colors-whiteAlpha-300:rgba(255, 255, 255, 0.16);--chakra-colors-whiteAlpha-400:rgba(255, 255, 255, 0.24);--chakra-colors-whiteAlpha-500:rgba(255, 255, 255, 0.36);--chakra-colors-whiteAlpha-600:rgba(255, 255, 255, 0.48);--chakra-colors-whiteAlpha-700:rgba(255, 255, 255, 0.64);--chakra-colors-whiteAlpha-800:rgba(255, 255, 255, 0.80);--chakra-colors-whiteAlpha-900:rgba(255, 255, 255, 0.92);--chakra-colors-blackAlpha-50:rgba(0, 0, 0, 0.04);--chakra-colors-blackAlpha-100:rgba(0, 0, 0, 0.06);--chakra-colors-blackAlpha-200:rgba(0, 0, 0, 0.08);--chakra-colors-blackAlpha-300:rgba(0, 0, 0, 0.16);--chakra-colors-blackAlpha-400:rgba(0, 0, 0, 0.24);--chakra-colors-blackAlpha-500:rgba(0, 0, 0, 0.36);--chakra-colors-blackAlpha-600:rgba(0, 0, 0, 0.48);--chakra-colors-blackAlpha-700:rgba(0, 0, 0, 0.64);--chakra-colors-blackAlpha-800:rgba(0, 0, 0, 0.80);--chakra-colors-blackAlpha-900:rgba(0, 0, 0, 0.92);--chakra-colors-gray-50:#F7FAFC;--chakra-colors-gray-100:#EDF2F7;--chakra-colors-gray-200:#E2E8F0;--chakra-colors-gray-300:#CBD5E0;--chakra-colors-gray-400:#A0AEC0;--chakra-colors-gray-500:#718096;--chakra-colors-gray-600:#4A5568;--chakra-colors-gray-700:#2D3748;--chakra-colors-gray-800:#1A202C;--chakra-colors-gray-900:#171923;--chakra-colors-red-50:#FFF5F5;--chakra-colors-red-100:#FED7D7;--chakra-colors-red-200:#FEB2B2;--chakra-colors-red-300:#FC8181;--chakra-colors-red-400:#F56565;--chakra-colors-red-500:#E53E3E;--chakra-colors-red-600:#C53030;--chakra-colors-red-700:#9B2C2C;--chakra-colors-red-800:#822727;--chakra-colors-red-900:#63171B;--chakra-colors-orange-50:#FFFAF0;--chakra-colors-orange-100:#FEEBC8;--chakra-colors-orange-200:#FBD38D;--chakra-colors-orange-300:#F6AD55;--chakra-colors-orange-400:#ED8936;--chakra-colors-orange-500:#DD6B20;--chakra-colors-orange-600:#C05621;--chakra-colors-orange-700:#9C4221;--chakra-colors-orange-800:#7B341E;--chakra-colors-orange-900:#652B19;--chakra-colors-yellow-50:#FFFFF0;--chakra-colors-yellow-100:#FEFCBF;--chakra-colors-yellow-200:#FAF089;--chakra-colors-yellow-300:#F6E05E;--chakra-colors-yellow-400:#ECC94B;--chakra-colors-yellow-500:#D69E2E;--chakra-colors-yellow-600:#B7791F;--chakra-colors-yellow-700:#975A16;--chakra-colors-yellow-800:#744210;--chakra-colors-yellow-900:#5F370E;--chakra-colors-green-50:#F0FFF4;--chakra-colors-green-100:#C6F6D5;--chakra-colors-green-200:#9AE6B4;--chakra-colors-green-300:#68D391;--chakra-colors-green-400:#48BB78;--chakra-colors-green-500:#38A169;--chakra-colors-green-600:#2F855A;--chakra-colors-green-700:#276749;--chakra-colors-green-800:#22543D;--chakra-colors-green-900:#1C4532;--chakra-colors-teal-50:#E6FFFA;--chakra-colors-teal-100:#B2F5EA;--chakra-colors-teal-200:#81E6D9;--chakra-colors-teal-300:#4FD1C5;--chakra-colors-teal-400:#38B2AC;--chakra-colors-teal-500:#319795;--chakra-colors-teal-600:#2C7A7B;--chakra-colors-teal-700:#285E61;--chakra-colors-teal-800:#234E52;--chakra-colors-teal-900:#1D4044;--chakra-colors-blue-50:#ebf8ff;--chakra-colors-blue-100:#bee3f8;--chakra-colors-blue-200:#90cdf4;--chakra-colors-blue-300:#63b3ed;--chakra-colors-blue-400:#4299e1;--chakra-colors-blue-500:#3182ce;--chakra-colors-blue-600:#2b6cb0;--chakra-colors-blue-700:#2c5282;--chakra-colors-blue-800:#2a4365;--chakra-colors-blue-900:#1A365D;--chakra-colors-cyan-50:#EDFDFD;--chakra-colors-cyan-100:#C4F1F9;--chakra-colors-cyan-200:#9DECF9;--chakra-colors-cyan-300:#76E4F7;--chakra-colors-cyan-400:#0BC5EA;--chakra-colors-cyan-500:#00B5D8;--chakra-colors-cyan-600:#00A3C4;--chakra-colors-cyan-700:#0987A0;--chakra-colors-cyan-800:#086F83;--chakra-colors-cyan-900:#065666;--chakra-colors-purple-50:#FAF5FF;--chakra-colors-purple-100:#E9D8FD;--chakra-colors-purple-200:#D6BCFA;--chakra-colors-purple-300:#B794F4;--chakra-colors-purple-400:#9F7AEA;--chakra-colors-purple-500:#805AD5;--chakra-colors-purple-600:#6B46C1;--chakra-colors-purple-700:#553C9A;--chakra-colors-purple-800:#44337A;--chakra-colors-purple-900:#322659;--chakra-colors-pink-50:#FFF5F7;--chakra-colors-pink-100:#FED7E2;--chakra-colors-pink-200:#FBB6CE;--chakra-colors-pink-300:#F687B3;--chakra-colors-pink-400:#ED64A6;--chakra-colors-pink-500:#D53F8C;--chakra-colors-pink-600:#B83280;--chakra-colors-pink-700:#97266D;--chakra-colors-pink-800:#702459;--chakra-colors-pink-900:#521B41;--chakra-colors-brand-100:#fd683e;--chakra-colors-brand-200:#fd683e;--chakra-colors-brand-300:#fd683e;--chakra-colors-brand-400:#fd683e;--chakra-colors-brand-500:#fd683e;--chakra-colors-brand-600:#fd683e;--chakra-colors-brand-700:#fd683e;--chakra-colors-brand-800:#fd683e;--chakra-colors-brand-900:#fd683e;--chakra-borders-none:0;--chakra-borders-1px:1px solid;--chakra-borders-2px:2px solid;--chakra-borders-4px:4px solid;--chakra-borders-8px:8px solid;--chakra-fonts-heading:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--chakra-fonts-body:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--chakra-fonts-mono:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--chakra-fontSizes-3xs:0.45rem;--chakra-fontSizes-2xs:0.625rem;--chakra-fontSizes-xs:0.75rem;--chakra-fontSizes-sm:0.875rem;--chakra-fontSizes-md:1rem;--chakra-fontSizes-lg:1.125rem;--chakra-fontSizes-xl:1.25rem;--chakra-fontSizes-2xl:1.5rem;--chakra-fontSizes-3xl:1.875rem;--chakra-fontSizes-4xl:2.25rem;--chakra-fontSizes-5xl:3rem;--chakra-fontSizes-6xl:3.75rem;--chakra-fontSizes-7xl:4.5rem;--chakra-fontSizes-8xl:6rem;--chakra-fontSizes-9xl:8rem;--chakra-fontWeights-hairline:100;--chakra-fontWeights-thin:200;--chakra-fontWeights-light:300;--chakra-fontWeights-normal:400;--chakra-fontWeights-medium:500;--chakra-fontWeights-semibold:600;--chakra-fontWeights-bold:700;--chakra-fontWeights-extrabold:800;--chakra-fontWeights-black:900;--chakra-letterSpacings-tighter:-0.05em;--chakra-letterSpacings-tight:-0.025em;--chakra-letterSpacings-normal:0;--chakra-letterSpacings-wide:0.025em;--chakra-letterSpacings-wider:0.05em;--chakra-letterSpacings-widest:0.1em;--chakra-lineHeights-3:.75rem;--chakra-lineHeights-4:1rem;--chakra-lineHeights-5:1.25rem;--chakra-lineHeights-6:1.5rem;--chakra-lineHeights-7:1.75rem;--chakra-lineHeights-8:2rem;--chakra-lineHeights-9:2.25rem;--chakra-lineHeights-10:2.5rem;--chakra-lineHeights-normal:normal;--chakra-lineHeights-none:1;--chakra-lineHeights-shorter:1.25;--chakra-lineHeights-short:1.375;--chakra-lineHeights-base:1.5;--chakra-lineHeights-tall:1.625;--chakra-lineHeights-taller:2;--chakra-radii-none:0;--chakra-radii-sm:0.125rem;--chakra-radii-base:0.25rem;--chakra-radii-md:0.375rem;--chakra-radii-lg:0.5rem;--chakra-radii-xl:0.75rem;--chakra-radii-2xl:1rem;--chakra-radii-3xl:1.5rem;--chakra-radii-full:9999px;--chakra-space-1:0.25rem;--chakra-space-2:0.5rem;--chakra-space-3:0.75rem;--chakra-space-4:1rem;--chakra-space-5:1.25rem;--chakra-space-6:1.5rem;--chakra-space-7:1.75rem;--chakra-space-8:2rem;--chakra-space-9:2.25rem;--chakra-space-10:2.5rem;--chakra-space-12:3rem;--chakra-space-14:3.5rem;--chakra-space-16:4rem;--chakra-space-20:5rem;--chakra-space-24:6rem;--chakra-space-28:7rem;--chakra-space-32:8rem;--chakra-space-36:9rem;--chakra-space-40:10rem;--chakra-space-44:11rem;--chakra-space-48:12rem;--chakra-space-52:13rem;--chakra-space-56:14rem;--chakra-space-60:15rem;--chakra-space-64:16rem;--chakra-space-72:18rem;--chakra-space-80:20rem;--chakra-space-96:24rem;--chakra-space-px:1px;--chakra-space-0-5:0.125rem;--chakra-space-1-5:0.375rem;--chakra-space-2-5:0.625rem;--chakra-space-3-5:0.875rem;--chakra-shadows-xs:0 0 0 1px rgba(0, 0, 0, 0.05);--chakra-shadows-sm:0 1px 2px 0 rgba(0, 0, 0, 0.05);--chakra-shadows-base:0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);--chakra-shadows-md:0 4px 6px -1px rgba(0, 0, 0, 0.1),0 2px 4px -1px rgba(0, 0, 0, 0.06);--chakra-shadows-lg:0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05);--chakra-shadows-xl:0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04);--chakra-shadows-2xl:0 25px 50px -12px rgba(0, 0, 0, 0.25);--chakra-shadows-outline:0 0 0 3px rgba(66, 153, 225, 0.6);--chakra-shadows-inner:inset 0 2px 4px 0 rgba(0,0,0,0.06);--chakra-shadows-none:none;--chakra-shadows-dark-lg:rgba(0, 0, 0, 0.1) 0px 0px 0px 1px,rgba(0, 0, 0, 0.2) 0px 5px 10px,rgba(0, 0, 0, 0.4) 0px 15px 40px;--chakra-sizes-1:0.25rem;--chakra-sizes-2:0.5rem;--chakra-sizes-3:0.75rem;--chakra-sizes-4:1rem;--chakra-sizes-5:1.25rem;--chakra-sizes-6:1.5rem;--chakra-sizes-7:1.75rem;--chakra-sizes-8:2rem;--chakra-sizes-9:2.25rem;--chakra-sizes-10:2.5rem;--chakra-sizes-12:3rem;--chakra-sizes-14:3.5rem;--chakra-sizes-16:4rem;--chakra-sizes-20:5rem;--chakra-sizes-24:6rem;--chakra-sizes-28:7rem;--chakra-sizes-32:8rem;--chakra-sizes-36:9rem;--chakra-sizes-40:10rem;--chakra-sizes-44:11rem;--chakra-sizes-48:12rem;--chakra-sizes-52:13rem;--chakra-sizes-56:14rem;--chakra-sizes-60:15rem;--chakra-sizes-64:16rem;--chakra-sizes-72:18rem;--chakra-sizes-80:20rem;--chakra-sizes-96:24rem;--chakra-sizes-px:1px;--chakra-sizes-0-5:0.125rem;--chakra-sizes-1-5:0.375rem;--chakra-sizes-2-5:0.625rem;--chakra-sizes-3-5:0.875rem;--chakra-sizes-max:max-content;--chakra-sizes-min:min-content;--chakra-sizes-full:100%;--chakra-sizes-3xs:14rem;--chakra-sizes-2xs:16rem;--chakra-sizes-xs:20rem;--chakra-sizes-sm:24rem;--chakra-sizes-md:28rem;--chakra-sizes-lg:32rem;--chakra-sizes-xl:36rem;--chakra-sizes-2xl:42rem;--chakra-sizes-3xl:48rem;--chakra-sizes-4xl:56rem;--chakra-sizes-5xl:64rem;--chakra-sizes-6xl:72rem;--chakra-sizes-7xl:80rem;--chakra-sizes-8xl:90rem;--chakra-sizes-prose:60ch;--chakra-sizes-container-sm:640px;--chakra-sizes-container-md:768px;--chakra-sizes-container-lg:1024px;--chakra-sizes-container-xl:1280px;--chakra-zIndices-hide:-1;--chakra-zIndices-auto:auto;--chakra-zIndices-base:0;--chakra-zIndices-docked:10;--chakra-zIndices-dropdown:1000;--chakra-zIndices-sticky:1100;--chakra-zIndices-banner:1200;--chakra-zIndices-overlay:1300;--chakra-zIndices-modal:1400;--chakra-zIndices-popover:1500;--chakra-zIndices-skipLink:1600;--chakra-zIndices-toast:1700;--chakra-zIndices-tooltip:1800;--chakra-transition-property-common:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform;--chakra-transition-property-colors:background-color,border-color,color,fill,stroke;--chakra-transition-property-dimensions:width,height;--chakra-transition-property-position:left,right,top,bottom;--chakra-transition-property-background:background-color,background-image,background-position;--chakra-transition-easing-ease-in:cubic-bezier(0.4, 0, 1, 1);--chakra-transition-easing-ease-out:cubic-bezier(0, 0, 0.2, 1);--chakra-transition-easing-ease-in-out:cubic-bezier(0.4, 0, 0.2, 1);--chakra-transition-duration-ultra-fast:50ms;--chakra-transition-duration-faster:100ms;--chakra-transition-duration-fast:150ms;--chakra-transition-duration-normal:200ms;--chakra-transition-duration-slow:300ms;--chakra-transition-duration-slower:400ms;--chakra-transition-duration-ultra-slow:500ms;--chakra-blur-none:0;--chakra-blur-sm:4px;--chakra-blur-base:8px;--chakra-blur-md:12px;--chakra-blur-lg:16px;--chakra-blur-xl:24px;--chakra-blur-2xl:40px;--chakra-blur-3xl:64px;--chakra-breakpoints-base:0em;--chakra-breakpoints-sm:30em;--chakra-breakpoints-md:48em;--chakra-breakpoints-lg:62em;--chakra-breakpoints-xl:80em;--chakra-breakpoints-2xl:96em;}.chakra-ui-light :host:not([data-theme]),.chakra-ui-light :root:not([data-theme]),.chakra-ui-light [data-theme]:not([data-theme]),[data-theme=light] :host:not([data-theme]),[data-theme=light] :root:not([data-theme]),[data-theme=light] [data-theme]:not([data-theme]),:host[data-theme=light],:root[data-theme=light],[data-theme][data-theme=light]{--chakra-colors-chakra-body-text:var(--chakra-colors-gray-800);--chakra-colors-chakra-body-bg:var(--chakra-colors-white);--chakra-colors-chakra-border-color:var(--chakra-colors-gray-200);--chakra-colors-chakra-inverse-text:var(--chakra-colors-white);--chakra-colors-chakra-subtle-bg:var(--chakra-colors-gray-100);--chakra-colors-chakra-subtle-text:var(--chakra-colors-gray-600);--chakra-colors-chakra-placeholder-color:var(--chakra-colors-gray-500);}.chakra-ui-dark :host:not([data-theme]),.chakra-ui-dark :root:not([data-theme]),.chakra-ui-dark [data-theme]:not([data-theme]),[data-theme=dark] :host:not([data-theme]),[data-theme=dark] :root:not([data-theme]),[data-theme=dark] [data-theme]:not([data-theme]),:host[data-theme=dark],:root[data-theme=dark],[data-theme][data-theme=dark]{--chakra-colors-chakra-body-text:var(--chakra-colors-whiteAlpha-900);--chakra-colors-chakra-body-bg:var(--chakra-colors-gray-800);--chakra-colors-chakra-border-color:var(--chakra-colors-whiteAlpha-300);--chakra-colors-chakra-inverse-text:var(--chakra-colors-gray-800);--chakra-colors-chakra-subtle-bg:var(--chakra-colors-gray-700);--chakra-colors-chakra-subtle-text:var(--chakra-colors-gray-400);--chakra-colors-chakra-placeholder-color:var(--chakra-colors-whiteAlpha-400);}</style><style data-emotion="css-global fubdgu">html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:system-ui,sans-serif;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;touch-action:manipulation;}body{position:relative;min-height:100%;margin:0;font-feature-settings:"kern";}:where(*, *::before, *::after){border-width:0;border-style:solid;box-sizing:border-box;word-wrap:break-word;}main{display:block;}hr{border-top-width:1px;box-sizing:content-box;height:0;overflow:visible;}:where(pre, code, kbd,samp){font-family:SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:1em;}a{background-color:transparent;color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit;}abbr[title]{border-bottom:none;-webkit-text-decoration:underline;text-decoration:underline;-webkit-text-decoration:underline dotted;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;}:where(b, strong){font-weight:bold;}small{font-size:80%;}:where(sub,sup){font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sub{bottom:-0.25em;}sup{top:-0.5em;}img{border-style:none;}:where(button, input, optgroup, select, textarea){font-family:inherit;font-size:100%;line-height:1.15;margin:0;}:where(button, input){overflow:visible;}:where(button, select){text-transform:none;}:where(
2
2
  button::-moz-focus-inner,
3
3
  [type="button"]::-moz-focus-inner,
4
4
  [type="reset"]::-moz-focus-inner,
@@ -24,4 +24,4 @@
24
24
  transparent 0%,
25
25
  #3182ce 50%,
26
26
  transparent 100%
27
- );position:absolute;will-change:left;min-width:50%;-webkit-animation:animation-11lmxjq 1s ease infinite normal none running;animation:animation-11lmxjq 1s ease infinite normal none running;}@-webkit-keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}@keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}</style><div style="width:0%" data-indeterminate="" aria-valuemax="100" aria-valuemin="0" role="progressbar" class="css-h5ends"></div></div></div><div class="css-0"></div></div></div><span></span></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-8442f6926a7a34ce.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\"]\n3:HL[\"/_next/static/css/17a96168e3a9db13.css\",\"style\"]\n4:HL[\"/_next/static/css/6d6961e0422ac782.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"5:I[37194,[],\"\"]\n7:I[86822,[],\"ClientPageRoot\"]\n8:I[89424,[\"509\",\"static/chunks/9746af58-d74bef4d03eea6ab.js\",\"989\",\"static/chunks/47d8844f-79a1b53c66a7d7ec.js\",\"147\",\"static/chunks/a30376cd-ac45432855afb688.js\",\"495\",\"static/chunks/6dc81886-c94b9b91bc2c3caf.js\",\"376\",\"static/chunks/3a92ee20-3b5d922d4157af5e.js\",\"678\",\"static/chunks/3998a672-eaad84bdd88cc73e.js\",\"266\",\"static/chunks/e24bf851-0f8cbc99656833e7.js\",\"517\",\"static/chunks/c1ceaa8b-a1e442154d23515e.js\",\"455\",\"static/chunks/6ef81909-694dc38134099299.js\",\"648\",\"static/chunks/ce84277d-f42c2c58049cea2d.js\",\"995\",\"static/chunks/fee69bc6-f17d36c080742e74.js\",\"739\",\"static/chunks/7a8a3e83-d7fa409d97b38b2b.js\",\"283\",\"static/chunks/450c323b-1bb5db526e54435a.js\",\"303\",\"static/chunks/36e1c10d-bb0210cbd6573a8d.js\",\"22\",\"static/chunks/29e3cc0d-8c150e37dff9631b.js\",\"25\",\"static/chunks/b63b1b3f-7395c74e11a14e95.js\",\"355\",\"static/chunks/7f27ae6c-413f6b869a04183a.js\",\"599\",\"static/chunks/c132bf7d-8102037f9ccf372a.js\",\"971\",\"static/chunks/cd9f8d63-e020f408095ed77c.js\",\"316\",\"static/chunks/316-9e0164c48e40d69b.js\",\"963\",\"static/chunks/963-7cb453d3f159e7cc.js\",\"711\",\"static/chunks/711-9f4b13e082dc2f43.js\",\"931\",\"static/chunks/app/page-183db1bcb15b328f.js\"],\"default\",1]\n9:I[84046,[\"509\",\"static/chunks/9746af58-d74bef4d03eea6ab.js\",\"989\",\"static/chunks/47d8844f-79a1b53c66a7d7ec.js\",\"147\",\"static/chunks/a30376cd-ac45432855afb688.js\",\"495\",\"static/chunks/6dc81886-c94b9b91bc2c3caf.js\",\"376\",\"static/chunks/3a92ee20-3b5d922d4157af5e.js\",\"678\",\"static/chunks/3998a672-eaad84bdd88cc73e.js\",\"266\",\"static/chunks/e24bf851-0f8cbc99656833e7.js\",\"517\",\"static/chunks/c1ceaa8b-a1e442154d23515e.js\",\"455\",\"static/chunks/6ef81909-694dc38134099299.js\",\"316\",\"static/chunks/316-9e0164c48e40d69b.js\",\"350\",\"static/chunks/350-30608a95db2634b6.js\",\"711\",\"static/chunks/711-9f4b13e082dc2f43.js\",\"185\",\"static/chunks/app/layout-84447815782d7e41.js\"],\"default\"]\na:I[79137,[],\"\"]\nb:I[63846,[],\"\"]\nd:I[67160,[],\"\"]\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L5\",null,{\"buildId\":\"_i7vGe6giBb07tZ0Ml9uG\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"\"],\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[[\"$L6\",[\"$\",\"$L7\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$8\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/17a96168e3a9db13.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/6d6961e0422ac782.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],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\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$La\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lb\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"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.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$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\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"32x32\"}]]\n6:null\n"])</script></body></html>
27
+ );position:absolute;will-change:left;min-width:50%;-webkit-animation:animation-11lmxjq 1s ease infinite normal none running;animation:animation-11lmxjq 1s ease infinite normal none running;}@-webkit-keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}@keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}</style><div style="width:0%" data-indeterminate="" aria-valuemax="100" aria-valuemin="0" role="progressbar" class="css-h5ends"></div></div></div><div class="css-0"></div></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-8442f6926a7a34ce.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\"]\n3:HL[\"/_next/static/css/17a96168e3a9db13.css\",\"style\"]\n4:HL[\"/_next/static/css/6d6961e0422ac782.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"5:I[37194,[],\"\"]\n7:I[86822,[],\"ClientPageRoot\"]\n8:I[2324,[\"509\",\"static/chunks/9746af58-d74bef4d03eea6ab.js\",\"989\",\"static/chunks/47d8844f-79a1b53c66a7d7ec.js\",\"147\",\"static/chunks/a30376cd-ac45432855afb688.js\",\"495\",\"static/chunks/6dc81886-c94b9b91bc2c3caf.js\",\"376\",\"static/chunks/3a92ee20-3b5d922d4157af5e.js\",\"678\",\"static/chunks/3998a672-eaad84bdd88cc73e.js\",\"266\",\"static/chunks/e24bf851-0f8cbc99656833e7.js\",\"517\",\"static/chunks/c1ceaa8b-a1e442154d23515e.js\",\"455\",\"static/chunks/6ef81909-694dc38134099299.js\",\"648\",\"static/chunks/ce84277d-f42c2c58049cea2d.js\",\"995\",\"static/chunks/fee69bc6-f17d36c080742e74.js\",\"739\",\"static/chunks/7a8a3e83-d7fa409d97b38b2b.js\",\"283\",\"static/chunks/450c323b-1bb5db526e54435a.js\",\"303\",\"static/chunks/36e1c10d-bb0210cbd6573a8d.js\",\"22\",\"static/chunks/29e3cc0d-8c150e37dff9631b.js\",\"25\",\"static/chunks/b63b1b3f-7395c74e11a14e95.js\",\"355\",\"static/chunks/7f27ae6c-413f6b869a04183a.js\",\"599\",\"static/chunks/c132bf7d-8102037f9ccf372a.js\",\"971\",\"static/chunks/cd9f8d63-e020f408095ed77c.js\",\"316\",\"static/chunks/316-9e0164c48e40d69b.js\",\"963\",\"static/chunks/963-7cb453d3f159e7cc.js\",\"711\",\"static/chunks/711-5ac2c87eb5073191.js\",\"931\",\"static/chunks/app/page-f0b9d7985eaf7eed.js\"],\"default\",1]\n9:I[84046,[\"509\",\"static/chunks/9746af58-d74bef4d03eea6ab.js\",\"989\",\"static/chunks/47d8844f-79a1b53c66a7d7ec.js\",\"147\",\"static/chunks/a30376cd-ac45432855afb688.js\",\"495\",\"static/chunks/6dc81886-c94b9b91bc2c3caf.js\",\"376\",\"static/chunks/3a92ee20-3b5d922d4157af5e.js\",\"678\",\"static/chunks/3998a672-eaad84bdd88cc73e.js\",\"266\",\"static/chunks/e24bf851-0f8cbc99656833e7.js\",\"517\",\"static/chunks/c1ceaa8b-a1e442154d23515e.js\",\"455\",\"static/chunks/6ef81909-694dc38134099299.js\",\"316\",\"static/chunks/316-9e0164c48e40d69b.js\",\"350\",\"static/chunks/350-30608a95db2634b6.js\",\"711\",\"static/chunks/711-5ac2c87eb5073191.js\",\"185\",\"static/chunks/app/layout-c76e6ca2ce9857e9.js\"],\"default\"]\na:I[79137,[],\"\"]\nb:I[63846,[],\"\"]\nd:I[67160,[],\"\"]\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L5\",null,{\"buildId\":\"1rwJEkX_z2KfSDpX3cGQ1\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"\"],\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[[\"$L6\",[\"$\",\"$L7\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$8\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/17a96168e3a9db13.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/6d6961e0422ac782.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],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\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$La\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lb\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"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.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$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\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"32x32\"}]]\n6:null\n"])</script></body></html>
recce/data/index.txt CHANGED
@@ -1,8 +1,8 @@
1
1
  2:I[86822,[],"ClientPageRoot"]
2
- 3:I[89424,["509","static/chunks/9746af58-d74bef4d03eea6ab.js","989","static/chunks/47d8844f-79a1b53c66a7d7ec.js","147","static/chunks/a30376cd-ac45432855afb688.js","495","static/chunks/6dc81886-c94b9b91bc2c3caf.js","376","static/chunks/3a92ee20-3b5d922d4157af5e.js","678","static/chunks/3998a672-eaad84bdd88cc73e.js","266","static/chunks/e24bf851-0f8cbc99656833e7.js","517","static/chunks/c1ceaa8b-a1e442154d23515e.js","455","static/chunks/6ef81909-694dc38134099299.js","648","static/chunks/ce84277d-f42c2c58049cea2d.js","995","static/chunks/fee69bc6-f17d36c080742e74.js","739","static/chunks/7a8a3e83-d7fa409d97b38b2b.js","283","static/chunks/450c323b-1bb5db526e54435a.js","303","static/chunks/36e1c10d-bb0210cbd6573a8d.js","22","static/chunks/29e3cc0d-8c150e37dff9631b.js","25","static/chunks/b63b1b3f-7395c74e11a14e95.js","355","static/chunks/7f27ae6c-413f6b869a04183a.js","599","static/chunks/c132bf7d-8102037f9ccf372a.js","971","static/chunks/cd9f8d63-e020f408095ed77c.js","316","static/chunks/316-9e0164c48e40d69b.js","963","static/chunks/963-7cb453d3f159e7cc.js","711","static/chunks/711-9f4b13e082dc2f43.js","931","static/chunks/app/page-183db1bcb15b328f.js"],"default",1]
3
- 4:I[84046,["509","static/chunks/9746af58-d74bef4d03eea6ab.js","989","static/chunks/47d8844f-79a1b53c66a7d7ec.js","147","static/chunks/a30376cd-ac45432855afb688.js","495","static/chunks/6dc81886-c94b9b91bc2c3caf.js","376","static/chunks/3a92ee20-3b5d922d4157af5e.js","678","static/chunks/3998a672-eaad84bdd88cc73e.js","266","static/chunks/e24bf851-0f8cbc99656833e7.js","517","static/chunks/c1ceaa8b-a1e442154d23515e.js","455","static/chunks/6ef81909-694dc38134099299.js","316","static/chunks/316-9e0164c48e40d69b.js","350","static/chunks/350-30608a95db2634b6.js","711","static/chunks/711-9f4b13e082dc2f43.js","185","static/chunks/app/layout-84447815782d7e41.js"],"default"]
2
+ 3:I[2324,["509","static/chunks/9746af58-d74bef4d03eea6ab.js","989","static/chunks/47d8844f-79a1b53c66a7d7ec.js","147","static/chunks/a30376cd-ac45432855afb688.js","495","static/chunks/6dc81886-c94b9b91bc2c3caf.js","376","static/chunks/3a92ee20-3b5d922d4157af5e.js","678","static/chunks/3998a672-eaad84bdd88cc73e.js","266","static/chunks/e24bf851-0f8cbc99656833e7.js","517","static/chunks/c1ceaa8b-a1e442154d23515e.js","455","static/chunks/6ef81909-694dc38134099299.js","648","static/chunks/ce84277d-f42c2c58049cea2d.js","995","static/chunks/fee69bc6-f17d36c080742e74.js","739","static/chunks/7a8a3e83-d7fa409d97b38b2b.js","283","static/chunks/450c323b-1bb5db526e54435a.js","303","static/chunks/36e1c10d-bb0210cbd6573a8d.js","22","static/chunks/29e3cc0d-8c150e37dff9631b.js","25","static/chunks/b63b1b3f-7395c74e11a14e95.js","355","static/chunks/7f27ae6c-413f6b869a04183a.js","599","static/chunks/c132bf7d-8102037f9ccf372a.js","971","static/chunks/cd9f8d63-e020f408095ed77c.js","316","static/chunks/316-9e0164c48e40d69b.js","963","static/chunks/963-7cb453d3f159e7cc.js","711","static/chunks/711-5ac2c87eb5073191.js","931","static/chunks/app/page-f0b9d7985eaf7eed.js"],"default",1]
3
+ 4:I[84046,["509","static/chunks/9746af58-d74bef4d03eea6ab.js","989","static/chunks/47d8844f-79a1b53c66a7d7ec.js","147","static/chunks/a30376cd-ac45432855afb688.js","495","static/chunks/6dc81886-c94b9b91bc2c3caf.js","376","static/chunks/3a92ee20-3b5d922d4157af5e.js","678","static/chunks/3998a672-eaad84bdd88cc73e.js","266","static/chunks/e24bf851-0f8cbc99656833e7.js","517","static/chunks/c1ceaa8b-a1e442154d23515e.js","455","static/chunks/6ef81909-694dc38134099299.js","316","static/chunks/316-9e0164c48e40d69b.js","350","static/chunks/350-30608a95db2634b6.js","711","static/chunks/711-5ac2c87eb5073191.js","185","static/chunks/app/layout-c76e6ca2ce9857e9.js"],"default"]
4
4
  5:I[79137,[],""]
5
5
  6:I[63846,[],""]
6
- 0:["_i7vGe6giBb07tZ0Ml9uG",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/17a96168e3a9db13.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/6d6961e0422ac782.css","precedence":"next","crossOrigin":"$undefined"}]]],null],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":["$","$L4",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":{"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."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
6
+ 0:["1rwJEkX_z2KfSDpX3cGQ1",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/17a96168e3a9db13.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/6d6961e0422ac782.css","precedence":"next","crossOrigin":"$undefined"}]]],null],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":["$","$L4",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":{"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."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
7
7
  7:[["$","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"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"32x32"}]]
8
8
  1:null
recce/models/types.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import uuid
2
2
  from datetime import datetime, timezone
3
3
  from enum import Enum
4
- from typing import Literal, Optional
4
+ from typing import Dict, List, Literal, Optional
5
5
 
6
6
  from pydantic import UUID4, BaseModel, Field
7
7
 
@@ -110,3 +110,49 @@ class LineageDiff(BaseModel):
110
110
  base: dict
111
111
  current: dict
112
112
  diff: dict[str, NodeDiff]
113
+
114
+
115
+ # Column Level Linage
116
+ class CllColumnDep(BaseModel):
117
+ node: str
118
+ column: str
119
+
120
+
121
+ class CllColumn(BaseModel):
122
+ name: Optional[str]
123
+
124
+ # data type
125
+ type: Optional[str] = None
126
+
127
+ # transformation type
128
+ transformation_type: Literal["source", "passthrough", "renamed", "derived", "unknown"] = "unknown"
129
+
130
+ # column-to-column dependencies
131
+ depends_on: List[CllColumnDep] = Field(default_factory=list)
132
+
133
+
134
+ class CllNodeDependsOn(BaseModel):
135
+ # model-to-column dependencies
136
+ columns: List[CllColumnDep] = Field(default_factory=list)
137
+
138
+ # model-to-model dependencies
139
+ nodes: List[str] = Field(default_factory=list)
140
+
141
+
142
+ class CllNode(BaseModel):
143
+ id: str
144
+ name: str
145
+ package_name: str
146
+ resource_type: str
147
+ raw_code: Optional[str] = None
148
+ source_name: Optional[str] = None
149
+
150
+ # Model to column dependencies
151
+ depends_on: CllNodeDependsOn = Field(default_factory=CllNodeDependsOn)
152
+
153
+ # Column to column dependencies
154
+ columns: Dict[str, CllColumn] = Field(default_factory=dict)
155
+
156
+
157
+ class CllData(BaseModel):
158
+ nodes: Dict[str, CllNode] = Field(default_factory=dict)
recce/server.py CHANGED
@@ -36,6 +36,7 @@ from .config import RecceConfig
36
36
  from .core import RecceContext, default_context, load_context
37
37
  from .event import log_api_event, log_single_env_event
38
38
  from .exceptions import RecceException
39
+ from .models.types import CllData
39
40
  from .run import load_preset_checks
40
41
  from .state import RecceShareStateManager, RecceStateLoader
41
42
 
@@ -338,7 +339,7 @@ class CllIn(BaseModel):
338
339
 
339
340
 
340
341
  class CllOutput(BaseModel):
341
- current: Dict
342
+ current: CllData
342
343
 
343
344
 
344
345
  @app.post("/api/cll", response_model=CllOutput)
@@ -346,14 +347,8 @@ async def column_level_lineage_by_node(cll_input: CllIn):
346
347
  from recce.adapter.dbt_adapter import DbtAdapter
347
348
 
348
349
  dbt_adapter: DbtAdapter = default_context().adapter
349
-
350
- try:
351
- # TODO: Add support for by the node and column
352
- result = dbt_adapter.get_cll_by_node_id(cll_input.params.get("node_id"))
353
- except Exception as e:
354
- raise HTTPException(status_code=400, detail=str(e))
355
-
356
- return CllOutput(current=result)
350
+ cll = dbt_adapter.get_cll_by_node_id(cll_input.params.get("node_id"))
351
+ return CllOutput(current=cll)
357
352
 
358
353
 
359
354
  class SelectNodesInput(BaseModel):
recce/util/cll.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import time
2
2
  from dataclasses import dataclass
3
- from typing import Dict, List, Literal, Optional
3
+ from typing import Dict, List, Optional, Tuple
4
4
 
5
5
  import sqlglot.expressions as exp
6
6
  from sqlglot import Dialect, parse_one
@@ -9,8 +9,14 @@ from sqlglot.optimizer import Scope, traverse_scope
9
9
  from sqlglot.optimizer.qualify import qualify
10
10
 
11
11
  from recce.exceptions import RecceException
12
+ from recce.models.types import CllColumn, CllColumnDep
12
13
  from recce.util import SingletonMeta
13
14
 
15
+ CllResult = Tuple[
16
+ List[CllColumnDep], # Model to column dependencies
17
+ Dict[str, CllColumn], # Column to column dependencies
18
+ ]
19
+
14
20
 
15
21
  @dataclass
16
22
  class CLLPerformanceTracking(metaclass=SingletonMeta):
@@ -68,32 +74,11 @@ class CLLPerformanceTracking(metaclass=SingletonMeta):
68
74
  self.other_error_nodes = 0
69
75
 
70
76
 
71
- @dataclass
72
- class ColumnLevelDependsOn:
73
- node: str
74
- column: str
75
-
76
-
77
- @dataclass
78
- class ColumnLevelDependencyColumn:
79
- type: Literal["source", "passthrough", "renamed", "derived"]
80
- depends_on: List[ColumnLevelDependsOn]
81
-
82
-
83
- @dataclass()
84
- class CllResult:
85
- # Model to column dependencies
86
- depends_on: List[ColumnLevelDependsOn]
87
-
88
- # Column to column dependencies
89
- columns: Dict[str, ColumnLevelDependencyColumn]
90
-
91
-
92
- def _cll_column(proj, table_alias_map) -> ColumnLevelDependencyColumn:
77
+ def _cll_column(proj, table_alias_map) -> CllColumn:
93
78
  # given an expression, return the columns depends on
94
79
  # [{node: table, column: column}, ...]
95
80
  type = "source"
96
- depends_on: List[ColumnLevelDependsOn] = []
81
+ depends_on: List[CllColumnDep] = []
97
82
 
98
83
  # instance of Column
99
84
  if isinstance(proj, exp.Alias):
@@ -110,7 +95,7 @@ def _cll_column(proj, table_alias_map) -> ColumnLevelDependencyColumn:
110
95
  table = next(iter(table_alias_map.values()))
111
96
  else:
112
97
  table = table_alias_map.get(alias, alias)
113
- depends_on.append(ColumnLevelDependsOn(table, column.name))
98
+ depends_on.append(CllColumnDep(table, column.name))
114
99
  if type == "source":
115
100
  type = "passthrough"
116
101
  elif isinstance(expression, (exp.Paren, exp.Identifier)):
@@ -128,15 +113,10 @@ def _cll_column(proj, table_alias_map) -> ColumnLevelDependencyColumn:
128
113
  if type == "passthrough" and depends_on[0].column != alias.alias_or_name:
129
114
  type = "renamed"
130
115
 
131
- return ColumnLevelDependencyColumn(type=type, depends_on=depends_on)
132
-
133
-
134
- def cll_old(sql, schema=None, dialect=None) -> Dict[str, ColumnLevelDependencyColumn]:
135
- result = cll(sql, schema=schema, dialect=dialect)
136
- return result.columns
116
+ return CllColumn(type=type, depends_on=depends_on)
137
117
 
138
118
 
139
- def _dedeup_depends_on(depends_on: List[ColumnLevelDependsOn]) -> List[ColumnLevelDependsOn]:
119
+ def _dedeup_depends_on(depends_on: List[CllColumnDep]) -> List[CllColumnDep]:
140
120
  # deduplicate the depends_on list
141
121
  dedup_set = set()
142
122
  dedup_list = []
@@ -148,96 +128,118 @@ def _dedeup_depends_on(depends_on: List[ColumnLevelDependsOn]) -> List[ColumnLev
148
128
  return dedup_list
149
129
 
150
130
 
151
- def _dedeup_cll_result(cll_result: CllResult):
152
- cll_result.depends_on = _dedeup_depends_on(cll_result.depends_on)
153
- for column in cll_result.columns.values():
154
- column.depends_on = _dedeup_depends_on(column.depends_on)
155
-
156
-
157
131
  def _cll_set_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> CllResult:
158
- result = CllResult(depends_on=[], columns={})
159
- scope_lineage = result.columns
132
+ # model-to-column
133
+ m2c: List[CllColumnDep] = []
134
+ # column-to-column
135
+ c2c_map: Dict[str, CllColumn] = {}
160
136
 
161
137
  for union_scope in scope.union_scopes:
162
138
  sub_scope_result = scope_cll_map.get(union_scope)
139
+ if sub_scope_result is None:
140
+ raise RecceException(f"Scope {union_scope} not found in scope_cll_map")
141
+ sub_m2c, sub_c2c_map = sub_scope_result
163
142
 
164
- for k, v in sub_scope_result.columns.items():
165
- if k not in result.columns:
166
- scope_lineage[k] = v
143
+ for k, v in sub_c2c_map.items():
144
+ if k not in c2c_map:
145
+ c2c_map[k] = v
167
146
  else:
168
- scope_lineage[k].depends_on.extend(v.depends_on)
169
- scope_lineage[k].type = "derived"
147
+ c2c_map[k].depends_on.extend(v.depends_on)
148
+ c2c_map[k].transformation_type = "derived"
170
149
 
171
- result.depends_on.extend(sub_scope_result.depends_on)
172
- return result
150
+ m2c.extend(sub_m2c)
151
+ return m2c, c2c_map
173
152
 
174
153
 
175
154
  def _cll_select_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> CllResult:
176
155
  assert scope.expression.key == "select"
177
156
 
178
- column_dep_map = {}
179
- model_depends_on = []
157
+ # model-to-column
158
+ m2c: List[CllColumnDep] = []
159
+ # column-to-column
160
+ c2c_map: Dict[str, CllColumn] = {}
161
+
180
162
  table_alias_map = {t.alias_or_name: t.name for t in scope.tables}
181
163
  select = scope.expression
182
164
 
183
- def source_column_dependency(ref_column: exp.Column) -> Optional[ColumnLevelDependencyColumn]:
165
+ def source_column_dependency(ref_column: exp.Column) -> Optional[CllColumn]:
184
166
  column_name = ref_column.name
185
167
  table_name = ref_column.table if ref_column.table != "" else next(iter(table_alias_map.values()))
186
- source = scope.sources.get(table_name, None) # type: exp.Table | Scope
168
+ source = scope.sources.get(table_name, None) # transformation_type: exp.Table | Scope
187
169
  if isinstance(source, Scope):
188
- ref_cll = scope_cll_map.get(source)
189
- if ref_cll is None:
170
+ ref_cll_result = scope_cll_map.get(source)
171
+ if ref_cll_result is None:
190
172
  return None
191
- return ref_cll.columns.get(column_name)
173
+ _, sub_c2c_map = ref_cll_result
174
+ return sub_c2c_map.get(column_name)
192
175
  elif isinstance(source, exp.Table):
193
- return ColumnLevelDependencyColumn(
194
- type="passthrough", depends_on=[ColumnLevelDependsOn(source.name, column_name)]
176
+ return CllColumn(
177
+ name=column_name,
178
+ transformation_type="passthrough",
179
+ depends_on=[CllColumnDep(node=source.name, column=column_name)],
195
180
  )
196
181
  else:
197
182
  return None
198
183
 
184
+ def subquery_cll(subquery: exp.Subquery) -> Optional[CllResult]:
185
+ select = subquery.find(exp.Select)
186
+ if select is None:
187
+ return None
188
+
189
+ matched_scope = None
190
+ for sub_scope in scope.subquery_scopes:
191
+ if sub_scope.expression == select:
192
+ matched_scope = sub_scope
193
+ break
194
+ if matched_scope is None:
195
+ return None
196
+
197
+ return scope_cll_map.get(matched_scope)
198
+
199
199
  for proj in scope.expression.selects:
200
- type = "source"
201
- column_depends_on: List[ColumnLevelDependsOn] = []
200
+ transformation_type = "source"
201
+ column_depends_on: List[CllColumnDep] = []
202
202
  root = proj.this if isinstance(proj, exp.Alias) else proj
203
203
  for expression in root.walk(bfs=False):
204
204
  if isinstance(expression, exp.Column):
205
205
  ref_column_dependency = source_column_dependency(expression)
206
206
  if ref_column_dependency is not None:
207
207
  column_depends_on.extend(ref_column_dependency.depends_on)
208
- if ref_column_dependency.type == "derived":
209
- type = "derived"
210
- elif ref_column_dependency.type == "renamed":
211
- if type == "source" or type == "passthrough":
212
- type = "renamed"
213
- elif ref_column_dependency.type == "passthrough":
214
- if type == "source":
215
- type = "passthrough"
208
+ if ref_column_dependency.transformation_type == "derived":
209
+ transformation_type = "derived"
210
+ elif ref_column_dependency.transformation_type == "renamed":
211
+ if transformation_type == "source" or transformation_type == "passthrough":
212
+ transformation_type = "renamed"
213
+ elif ref_column_dependency.transformation_type == "passthrough":
214
+ if transformation_type == "source":
215
+ transformation_type = "passthrough"
216
216
  else:
217
- column_depends_on.append(ColumnLevelDependsOn(expression.table, expression.name))
218
- if type == "source":
219
- type = "passthrough"
217
+ column_depends_on.append(CllColumnDep(expression.table, expression.name))
218
+ if transformation_type == "source":
219
+ transformation_type = "passthrough"
220
220
 
221
221
  elif isinstance(expression, (exp.Paren, exp.Identifier)):
222
222
  pass
223
223
  else:
224
- type = "derived"
224
+ transformation_type = "derived"
225
225
 
226
226
  column_depends_on = _dedeup_depends_on(column_depends_on)
227
227
 
228
- if len(column_depends_on) == 0 and type != "source":
229
- type = "source"
228
+ if len(column_depends_on) == 0 and transformation_type != "source":
229
+ transformation_type = "source"
230
230
 
231
231
  if isinstance(proj, exp.Alias):
232
232
  alias = proj
233
- if type == "passthrough" and column_depends_on[0].column != alias.alias_or_name:
234
- type = "renamed"
233
+ if transformation_type == "passthrough" and column_depends_on[0].column != alias.alias_or_name:
234
+ transformation_type = "renamed"
235
235
 
236
- column_dep_map[proj.alias_or_name] = ColumnLevelDependencyColumn(type=type, depends_on=column_depends_on)
236
+ c2c_map[proj.alias_or_name] = CllColumn(
237
+ name=proj.alias_or_name, transformation_type=transformation_type, depends_on=column_depends_on
238
+ )
237
239
 
238
- def selected_column_dependency(ref_column: exp.Column) -> Optional[ColumnLevelDependencyColumn]:
240
+ def selected_column_dependency(ref_column: exp.Column) -> Optional[CllColumn]:
239
241
  column_name = ref_column.name
240
- return column_dep_map.get(column_name)
242
+ return c2c_map.get(column_name)
241
243
 
242
244
  # joins clause: Reference the source columns
243
245
  if select.args.get("joins"):
@@ -246,7 +248,7 @@ def _cll_select_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> Cl
246
248
  if isinstance(join, exp.Join):
247
249
  for ref_column in join.find_all(exp.Column):
248
250
  if source_column_dependency(ref_column) is not None:
249
- model_depends_on.extend(source_column_dependency(ref_column).depends_on)
251
+ m2c.extend(source_column_dependency(ref_column).depends_on)
250
252
 
251
253
  # where clauses: Reference the source columns
252
254
  if select.args.get("where"):
@@ -254,7 +256,14 @@ def _cll_select_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> Cl
254
256
  if isinstance(where, exp.Where):
255
257
  for ref_column in where.find_all(exp.Column):
256
258
  if source_column_dependency(ref_column) is not None:
257
- model_depends_on.extend(source_column_dependency(ref_column).depends_on)
259
+ m2c.extend(source_column_dependency(ref_column).depends_on)
260
+ for subquery in where.find_all(exp.Subquery):
261
+ sub_cll = subquery_cll(subquery)
262
+ if sub_cll is not None:
263
+ sub_m2c, sub_c2c_map = sub_cll
264
+ m2c.extend(sub_m2c)
265
+ for sub_c in sub_c2c_map.values():
266
+ m2c.extend(sub_c.depends_on)
258
267
 
259
268
  # group by clause: Reference the source columns, column index
260
269
  if select.args.get("group"):
@@ -262,7 +271,7 @@ def _cll_select_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> Cl
262
271
  if isinstance(group, exp.Group):
263
272
  for ref_column in group.find_all(exp.Column):
264
273
  if source_column_dependency(ref_column) is not None:
265
- model_depends_on.extend(source_column_dependency(ref_column).depends_on)
274
+ m2c.extend(source_column_dependency(ref_column).depends_on)
266
275
 
267
276
  # having clause: Reference the source columns, selected columns
268
277
  if select.args.get("having"):
@@ -270,9 +279,16 @@ def _cll_select_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> Cl
270
279
  if isinstance(having, exp.Having):
271
280
  for ref_column in having.find_all(exp.Column):
272
281
  if source_column_dependency(ref_column) is not None:
273
- model_depends_on.extend(source_column_dependency(ref_column).depends_on)
282
+ m2c.extend(source_column_dependency(ref_column).depends_on)
274
283
  elif selected_column_dependency(ref_column) is not None:
275
- model_depends_on.extend(selected_column_dependency(ref_column).depends_on)
284
+ m2c.extend(selected_column_dependency(ref_column).depends_on)
285
+ for subquery in having.find_all(exp.Subquery):
286
+ sub_cll = subquery_cll(subquery)
287
+ if sub_cll is not None:
288
+ sub_m2c, sub_c2c_map = sub_cll
289
+ m2c.extend(sub_m2c)
290
+ for sub_c in sub_c2c_map.values():
291
+ m2c.extend(sub_c.depends_on)
276
292
 
277
293
  # order by clause: Reference the source columns, selected columns, column index
278
294
  if select.args.get("order"):
@@ -280,18 +296,20 @@ def _cll_select_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> Cl
280
296
  if isinstance(order, exp.Order):
281
297
  for ref_column in order.find_all(exp.Column):
282
298
  if source_column_dependency(ref_column) is not None:
283
- model_depends_on.extend(source_column_dependency(ref_column).depends_on)
299
+ m2c.extend(source_column_dependency(ref_column).depends_on)
284
300
  elif selected_column_dependency(ref_column) is not None:
285
- model_depends_on.extend(selected_column_dependency(ref_column).depends_on)
301
+ m2c.extend(selected_column_dependency(ref_column).depends_on)
286
302
 
287
303
  for source in scope.sources.values():
288
- scope_result = scope_cll_map.get(source)
289
- if scope_result is not None:
290
- model_depends_on.extend(scope_result.depends_on)
304
+ scope_cll_result = scope_cll_map.get(source)
305
+ if scope_cll_result is None:
306
+ continue
307
+ sub_m2c, _ = scope_cll_result
308
+ m2c.extend(sub_m2c)
291
309
 
292
- model_depends_on = _dedeup_depends_on(model_depends_on)
310
+ m2c = _dedeup_depends_on(m2c)
293
311
 
294
- return CllResult(columns=column_dep_map, depends_on=model_depends_on)
312
+ return m2c, c2c_map
295
313
 
296
314
 
297
315
  def cll(sql, schema=None, dialect=None) -> CllResult:
@@ -320,7 +338,7 @@ def cll(sql, schema=None, dialect=None) -> CllResult:
320
338
  except SqlglotError as e:
321
339
  raise RecceException(f"Failed to qualify SQL: {str(e)}")
322
340
 
323
- result = CllResult(depends_on=[], columns={})
341
+ result = None
324
342
  scope_cll_map = {}
325
343
  for scope in traverse_scope(expression):
326
344
  scope_type = scope.expression.key
@@ -333,4 +351,6 @@ def cll(sql, schema=None, dialect=None) -> CllResult:
333
351
 
334
352
  scope_cll_map[scope] = result
335
353
 
354
+ if result is None:
355
+ raise RecceException("Failed to extract CLL from SQL")
336
356
  return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: recce-nightly
3
- Version: 1.5.0.20250527
3
+ Version: 1.6.0.20250529
4
4
  Summary: Environment diff tool for dbt
5
5
  Home-page: https://github.com/InfuseAI/recce
6
6
  Author: InfuseAI Dev Team