nao-core 0.0.16__py3-none-any.whl → 0.0.17__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.
Files changed (48) hide show
  1. nao_core/__init__.py +1 -1
  2. nao_core/bin/chats/588bbb8a-dcbc-42dc-b0d8-b6b9ed13e2fb.json +45 -0
  3. nao_core/bin/fastapi/main.py +19 -2
  4. nao_core/bin/migrations-postgres/{0000_supreme_cable.sql → 0000_user_auth_and_chat_tables.sql} +35 -22
  5. nao_core/bin/migrations-postgres/meta/0000_snapshot.json +208 -111
  6. nao_core/bin/migrations-postgres/meta/_journal.json +2 -2
  7. nao_core/bin/migrations-sqlite/{0000_cloudy_squirrel_girl.sql → 0000_user_auth_and_chat_tables.sql} +35 -22
  8. nao_core/bin/migrations-sqlite/meta/0000_snapshot.json +189 -105
  9. nao_core/bin/migrations-sqlite/meta/_journal.json +2 -2
  10. nao_core/bin/nao-chat-server +0 -0
  11. nao_core/bin/public/assets/_chat-layout-Do0mWziW.js +1 -0
  12. nao_core/bin/public/assets/_chat-layout.index-mxrV7qZY.js +1 -0
  13. nao_core/bin/public/assets/agentProvider-cEZoyU1e.js +1 -0
  14. nao_core/bin/public/assets/code-block-F6WJLWQG-oIWcWPcR.js +153 -0
  15. nao_core/bin/public/assets/createLucideIcon-BGNfPWE_.js +1 -0
  16. nao_core/bin/public/assets/index-B-_pu_22.js +59 -0
  17. nao_core/bin/public/assets/index-CWAm1NQa.css +1 -0
  18. nao_core/bin/public/assets/login-CF4uOXFH.js +1 -0
  19. nao_core/bin/public/assets/mermaid-FSSLJTFX-BzFakw7W.js +380 -0
  20. nao_core/bin/public/assets/signinForm-D98dwmLQ.js +1 -0
  21. nao_core/bin/public/assets/signup-CQSmDpcH.js +1 -0
  22. nao_core/bin/public/assets/utils-DzJYey0s.js +1 -0
  23. nao_core/bin/public/index.html +2 -2
  24. nao_core/bin/public/nao-logo-greyscale.svg +25 -0
  25. nao_core/commands/init.py +111 -0
  26. nao_core/commands/sync/__init__.py +59 -0
  27. nao_core/commands/sync/accessors.py +212 -0
  28. nao_core/commands/sync/databases.py +132 -0
  29. nao_core/commands/sync/registry.py +23 -0
  30. nao_core/commands/sync/repositories.py +103 -0
  31. nao_core/config/base.py +2 -0
  32. nao_core/config/repos/__init__.py +3 -0
  33. nao_core/config/repos/base.py +11 -0
  34. {nao_core-0.0.16.dist-info → nao_core-0.0.17.dist-info}/METADATA +1 -1
  35. nao_core-0.0.17.dist-info/RECORD +51 -0
  36. nao_core/bin/public/assets/_chatId-z5gRlor1.js +0 -1
  37. nao_core/bin/public/assets/chat-messages-DUR3D342.js +0 -1
  38. nao_core/bin/public/assets/index-BDlcD_HE.js +0 -1
  39. nao_core/bin/public/assets/index-Bc7icYyJ.css +0 -1
  40. nao_core/bin/public/assets/index-CGg3ZQH6.js +0 -49
  41. nao_core/bin/public/assets/login-D87n9R5V.js +0 -1
  42. nao_core/bin/public/assets/signinForm-9PY1Lvqj.js +0 -1
  43. nao_core/bin/public/assets/signup-B7NC1g08.js +0 -1
  44. nao_core/commands/sync.py +0 -380
  45. nao_core-0.0.16.dist-info/RECORD +0 -39
  46. {nao_core-0.0.16.dist-info → nao_core-0.0.17.dist-info}/WHEEL +0 -0
  47. {nao_core-0.0.16.dist-info → nao_core-0.0.17.dist-info}/entry_points.txt +0 -0
  48. {nao_core-0.0.16.dist-info → nao_core-0.0.17.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1 @@
1
+ import{r as b,j as e,c as h,t as g,h as v,L as y}from"./index-B-_pu_22.js";import{c as x,B as c}from"./createLucideIcon-BGNfPWE_.js";import{a as u}from"./utils-DzJYey0s.js";const j=[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],w=x("eye-off",j);const N=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],k=x("eye",N);function S({className:a,type:s,...r}){const[i,o]=b.useState(!1),n=s==="password",l=n&&i?"text":s;return n?e.jsxs("div",{className:"relative",children:[e.jsx("input",{type:l,"data-slot":"input",className:u("file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm","focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]","aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive","pr-10",a),...r}),e.jsx("button",{type:"button",onClick:()=>o(!i),className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",tabIndex:-1,children:i?e.jsx(w,{size:16}):e.jsx(k,{size:16})})]}):e.jsx("input",{type:s,"data-slot":"input",className:u("file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm","focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]","aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",a),...r})}function M({title:a,fields:s,formData:r,onSubmit:i,onChange:o,submitButtonText:n,footerText:l,footerLinkText:m,footerLinkTo:p,error:d}){const f=h(g.hasGoogleSetup.queryOptions());return e.jsxs("div",{className:"container mx-auto w-full max-w-2xl p-12 my-auto",children:[e.jsx("div",{className:"text-3xl font-bold mb-8 text-center",children:a}),e.jsxs("form",{onSubmit:i,className:"space-y-6",children:[s.map(t=>e.jsx(S,{name:t.name,type:t.type,placeholder:t.placeholder,value:r[t.name],onChange:o,required:!0,className:"h-12 text-base"},t.name)),d&&e.jsx("p",{className:"text-red-500 text-center text-base",children:d}),e.jsx(c,{type:"submit",className:"w-full h-12 text-base",disabled:Object.values(r).some(t=>!t),children:n})]}),f.data&&e.jsxs("div",{className:"mt-8",children:[e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute inset-0 flex items-center",children:e.jsx("div",{className:"w-full border-t border-gray-300"})}),e.jsx("div",{className:"relative flex justify-center text-sm",children:e.jsx("span",{className:"px-2 bg-background text-muted-foreground",children:"Or continue with"})})]}),e.jsx("div",{className:"flex justify-center items-center gap-4 p-4",children:e.jsx(c,{type:"button",variant:"outline",onClick:v,children:e.jsx("img",{src:"/google-icon.svg",alt:"Google",className:"w-5 h-5"})})})]}),e.jsxs("p",{className:"text-center text-sm text-muted-foreground mt-8",children:[l," ",e.jsx(y,{to:p,className:"text-primary hover:underline font-medium",children:m})]})]})}export{M as S};
@@ -0,0 +1 @@
1
+ import{u as l,r as o,j as c,s as g}from"./index-B-_pu_22.js";import{S as u}from"./signinForm-D98dwmLQ.js";import"./createLucideIcon-BGNfPWE_.js";import"./utils-DzJYey0s.js";function x(){const n=l(),[e,r]=o.useState({name:"",email:"",password:""}),[s,t]=o.useState(""),i=async a=>{a.preventDefault(),t(""),await g.email({name:e.name,email:e.email,password:e.password},{onSuccess:()=>{n({to:"/"})},onError:p=>{t(p.error.message)}})},m=a=>{r({...e,[a.target.name]:a.target.value})};return c.jsx(u,{title:"Sign Up",fields:[{name:"name",placeholder:"Name"},{name:"email",type:"email",placeholder:"Email"},{name:"password",type:"password",placeholder:"Password"}],formData:e,onSubmit:i,onChange:m,submitButtonText:"Sign Up",footerText:"Already have an account?",footerLinkText:"Sign in",footerLinkTo:"/login",error:s})}export{x as component};
@@ -0,0 +1 @@
1
+ function xe(e){var t,r,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(r=xe(e[t]))&&(o&&(o+=" "),o+=r)}else for(r in e)e[r]&&(o&&(o+=" "),o+=r);return o}function Ge(){for(var e,t,r=0,o="",a=arguments.length;r<a;r++)(e=arguments[r])&&(t=xe(e))&&(o&&(o+=" "),o+=t);return o}const Te=(e,t)=>{const r=new Array(e.length+t.length);for(let o=0;o<e.length;o++)r[o]=e[o];for(let o=0;o<t.length;o++)r[e.length+o]=t[o];return r},Oe=(e,t)=>({classGroupId:e,validator:t}),we=(e=new Map,t=null,r)=>({nextPart:e,validators:t,classGroupId:r}),H="-",ue=[],je="arbitrary..",Le=e=>{const t=Ne(e),{conflictingClassGroups:r,conflictingClassGroupModifiers:o}=e;return{getClassGroupId:i=>{if(i.startsWith("[")&&i.endsWith("]"))return Ee(i);const u=i.split(H),c=u[0]===""&&u.length>1?1:0;return ke(u,c,t)},getConflictingClassGroupIds:(i,u)=>{if(u){const c=o[i],f=r[i];return c?f?Te(f,c):c:f||ue}return r[i]||ue}}},ke=(e,t,r)=>{if(e.length-t===0)return r.classGroupId;const a=e[t],d=r.nextPart.get(a);if(d){const f=ke(e,t+1,d);if(f)return f}const i=r.validators;if(i===null)return;const u=t===0?e.join(H):e.slice(t).join(H),c=i.length;for(let f=0;f<c;f++){const h=i[f];if(h.validator(u))return h.classGroupId}},Ee=e=>e.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const t=e.slice(1,-1),r=t.indexOf(":"),o=t.slice(0,r);return o?je+o:void 0})(),Ne=e=>{const{theme:t,classGroups:r}=e;return Be(r,t)},Be=(e,t)=>{const r=we();for(const o in e){const a=e[o];se(a,r,o,t)}return r},se=(e,t,r,o)=>{const a=e.length;for(let d=0;d<a;d++){const i=e[d];Ve(i,t,r,o)}},Ve=(e,t,r,o)=>{if(typeof e=="string"){Fe(e,t,r);return}if(typeof e=="function"){_e(e,t,r,o);return}We(e,t,r,o)},Fe=(e,t,r)=>{const o=e===""?t:ye(t,e);o.classGroupId=r},_e=(e,t,r,o)=>{if($e(e)){se(e(o),t,r,o);return}t.validators===null&&(t.validators=[]),t.validators.push(Oe(r,e))},We=(e,t,r,o)=>{const a=Object.entries(e),d=a.length;for(let i=0;i<d;i++){const[u,c]=a[i];se(c,ye(t,u),r,o)}},ye=(e,t)=>{let r=e;const o=t.split(H),a=o.length;for(let d=0;d<a;d++){const i=o[d];let u=r.nextPart.get(i);u||(u=we(),r.nextPart.set(i,u)),r=u}return r},$e=e=>"isThemeGetter"in e&&e.isThemeGetter===!0,Ue=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,r=Object.create(null),o=Object.create(null);const a=(d,i)=>{r[d]=i,t++,t>e&&(t=0,o=r,r=Object.create(null))};return{get(d){let i=r[d];if(i!==void 0)return i;if((i=o[d])!==void 0)return a(d,i),i},set(d,i){d in r?r[d]=i:a(d,i)}}},te="!",fe=":",De=[],be=(e,t,r,o,a)=>({modifiers:e,hasImportantModifier:t,baseClassName:r,maybePostfixModifierPosition:o,isExternal:a}),Ye=e=>{const{prefix:t,experimentalParseClassName:r}=e;let o=a=>{const d=[];let i=0,u=0,c=0,f;const h=a.length;for(let v=0;v<h;v++){const w=a[v];if(i===0&&u===0){if(w===fe){d.push(a.slice(c,v)),c=v+1;continue}if(w==="/"){f=v;continue}}w==="["?i++:w==="]"?i--:w==="("?u++:w===")"&&u--}const y=d.length===0?a:a.slice(c);let z=y,R=!1;y.endsWith(te)?(z=y.slice(0,-1),R=!0):y.startsWith(te)&&(z=y.slice(1),R=!0);const I=f&&f>c?f-c:void 0;return be(d,R,z,I)};if(t){const a=t+fe,d=o;o=i=>i.startsWith(a)?d(i.slice(a.length)):be(De,!1,i,void 0,!0)}if(r){const a=o;o=d=>r({className:d,parseClassName:a})}return o},qe=e=>{const t=new Map;return e.orderSensitiveModifiers.forEach((r,o)=>{t.set(r,1e6+o)}),r=>{const o=[];let a=[];for(let d=0;d<r.length;d++){const i=r[d],u=i[0]==="[",c=t.has(i);u||c?(a.length>0&&(a.sort(),o.push(...a),a=[]),o.push(i)):a.push(i)}return a.length>0&&(a.sort(),o.push(...a)),o}},Xe=e=>({cache:Ue(e.cacheSize),parseClassName:Ye(e),sortModifiers:qe(e),...Le(e)}),Je=/\s+/,Ke=(e,t)=>{const{parseClassName:r,getClassGroupId:o,getConflictingClassGroupIds:a,sortModifiers:d}=t,i=[],u=e.trim().split(Je);let c="";for(let f=u.length-1;f>=0;f-=1){const h=u[f],{isExternal:y,modifiers:z,hasImportantModifier:R,baseClassName:I,maybePostfixModifierPosition:v}=r(h);if(y){c=h+(c.length>0?" "+c:c);continue}let w=!!v,P=o(w?I.substring(0,v):I);if(!P){if(!w){c=h+(c.length>0?" "+c:c);continue}if(P=o(I),!P){c=h+(c.length>0?" "+c:c);continue}w=!1}const $=z.length===0?"":z.length===1?z[0]:d(z).join(":"),F=R?$+te:$,j=F+P;if(i.indexOf(j)>-1)continue;i.push(j);const L=a(P,w);for(let G=0;G<L.length;++G){const _=L[G];i.push(F+_)}c=h+(c.length>0?" "+c:c)}return c},He=(...e)=>{let t=0,r,o,a="";for(;t<e.length;)(r=e[t++])&&(o=ve(r))&&(a&&(a+=" "),a+=o);return a},ve=e=>{if(typeof e=="string")return e;let t,r="";for(let o=0;o<e.length;o++)e[o]&&(t=ve(e[o]))&&(r&&(r+=" "),r+=t);return r},Qe=(e,...t)=>{let r,o,a,d;const i=c=>{const f=t.reduce((h,y)=>y(h),e());return r=Xe(f),o=r.cache.get,a=r.cache.set,d=u,u(c)},u=c=>{const f=o(c);if(f)return f;const h=Ke(c,r);return a(c,h),h};return d=i,(...c)=>d(He(...c))},Ze=[],b=e=>{const t=r=>r[e]||Ze;return t.isThemeGetter=!0,t},ze=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Ce=/^\((?:(\w[\w-]*):)?(.+)\)$/i,eo=/^\d+\/\d+$/,oo=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,ro=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,to=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,so=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,no=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,N=e=>eo.test(e),p=e=>!!e&&!Number.isNaN(Number(e)),M=e=>!!e&&Number.isInteger(Number(e)),oe=e=>e.endsWith("%")&&p(e.slice(0,-1)),S=e=>oo.test(e),ao=()=>!0,io=e=>ro.test(e)&&!to.test(e),Ae=()=>!1,lo=e=>so.test(e),co=e=>no.test(e),mo=e=>!s(e)&&!n(e),po=e=>B(e,Re,Ae),s=e=>ze.test(e),O=e=>B(e,Ie,io),re=e=>B(e,ho,p),ge=e=>B(e,Se,Ae),uo=e=>B(e,Me,co),J=e=>B(e,Pe,lo),n=e=>Ce.test(e),W=e=>V(e,Ie),fo=e=>V(e,xo),he=e=>V(e,Se),bo=e=>V(e,Re),go=e=>V(e,Me),K=e=>V(e,Pe,!0),B=(e,t,r)=>{const o=ze.exec(e);return o?o[1]?t(o[1]):r(o[2]):!1},V=(e,t,r=!1)=>{const o=Ce.exec(e);return o?o[1]?t(o[1]):r:!1},Se=e=>e==="position"||e==="percentage",Me=e=>e==="image"||e==="url",Re=e=>e==="length"||e==="size"||e==="bg-size",Ie=e=>e==="length",ho=e=>e==="number",xo=e=>e==="family-name",Pe=e=>e==="shadow",wo=()=>{const e=b("color"),t=b("font"),r=b("text"),o=b("font-weight"),a=b("tracking"),d=b("leading"),i=b("breakpoint"),u=b("container"),c=b("spacing"),f=b("radius"),h=b("shadow"),y=b("inset-shadow"),z=b("text-shadow"),R=b("drop-shadow"),I=b("blur"),v=b("perspective"),w=b("aspect"),P=b("ease"),$=b("animate"),F=()=>["auto","avoid","all","avoid-page","page","left","right","column"],j=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],L=()=>[...j(),n,s],G=()=>["auto","hidden","clip","visible","scroll"],_=()=>["auto","contain","none"],m=()=>[n,s,c],C=()=>[N,"full","auto",...m()],ne=()=>[M,"none","subgrid",n,s],ae=()=>["auto",{span:["full",M,n,s]},M,n,s],U=()=>[M,"auto",n,s],ie=()=>["auto","min","max","fr",n,s],Q=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],E=()=>["start","end","center","stretch","center-safe","end-safe"],A=()=>["auto",...m()],T=()=>[N,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...m()],l=()=>[e,n,s],le=()=>[...j(),he,ge,{position:[n,s]}],ce=()=>["no-repeat",{repeat:["","x","y","space","round"]}],de=()=>["auto","cover","contain",bo,po,{size:[n,s]}],Z=()=>[oe,W,O],x=()=>["","none","full",f,n,s],k=()=>["",p,W,O],D=()=>["solid","dashed","dotted","double"],me=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],g=()=>[p,oe,he,ge],pe=()=>["","none",I,n,s],Y=()=>["none",p,n,s],q=()=>["none",p,n,s],ee=()=>[p,n,s],X=()=>[N,"full",...m()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[S],breakpoint:[S],color:[ao],container:[S],"drop-shadow":[S],ease:["in","out","in-out"],font:[mo],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[S],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[S],shadow:[S],spacing:["px",p],text:[S],"text-shadow":[S],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",N,s,n,w]}],container:["container"],columns:[{columns:[p,s,n,u]}],"break-after":[{"break-after":F()}],"break-before":[{"break-before":F()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:L()}],overflow:[{overflow:G()}],"overflow-x":[{"overflow-x":G()}],"overflow-y":[{"overflow-y":G()}],overscroll:[{overscroll:_()}],"overscroll-x":[{"overscroll-x":_()}],"overscroll-y":[{"overscroll-y":_()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:C()}],"inset-x":[{"inset-x":C()}],"inset-y":[{"inset-y":C()}],start:[{start:C()}],end:[{end:C()}],top:[{top:C()}],right:[{right:C()}],bottom:[{bottom:C()}],left:[{left:C()}],visibility:["visible","invisible","collapse"],z:[{z:[M,"auto",n,s]}],basis:[{basis:[N,"full","auto",u,...m()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[p,N,"auto","initial","none",s]}],grow:[{grow:["",p,n,s]}],shrink:[{shrink:["",p,n,s]}],order:[{order:[M,"first","last","none",n,s]}],"grid-cols":[{"grid-cols":ne()}],"col-start-end":[{col:ae()}],"col-start":[{"col-start":U()}],"col-end":[{"col-end":U()}],"grid-rows":[{"grid-rows":ne()}],"row-start-end":[{row:ae()}],"row-start":[{"row-start":U()}],"row-end":[{"row-end":U()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":ie()}],"auto-rows":[{"auto-rows":ie()}],gap:[{gap:m()}],"gap-x":[{"gap-x":m()}],"gap-y":[{"gap-y":m()}],"justify-content":[{justify:[...Q(),"normal"]}],"justify-items":[{"justify-items":[...E(),"normal"]}],"justify-self":[{"justify-self":["auto",...E()]}],"align-content":[{content:["normal",...Q()]}],"align-items":[{items:[...E(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...E(),{baseline:["","last"]}]}],"place-content":[{"place-content":Q()}],"place-items":[{"place-items":[...E(),"baseline"]}],"place-self":[{"place-self":["auto",...E()]}],p:[{p:m()}],px:[{px:m()}],py:[{py:m()}],ps:[{ps:m()}],pe:[{pe:m()}],pt:[{pt:m()}],pr:[{pr:m()}],pb:[{pb:m()}],pl:[{pl:m()}],m:[{m:A()}],mx:[{mx:A()}],my:[{my:A()}],ms:[{ms:A()}],me:[{me:A()}],mt:[{mt:A()}],mr:[{mr:A()}],mb:[{mb:A()}],ml:[{ml:A()}],"space-x":[{"space-x":m()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":m()}],"space-y-reverse":["space-y-reverse"],size:[{size:T()}],w:[{w:[u,"screen",...T()]}],"min-w":[{"min-w":[u,"screen","none",...T()]}],"max-w":[{"max-w":[u,"screen","none","prose",{screen:[i]},...T()]}],h:[{h:["screen","lh",...T()]}],"min-h":[{"min-h":["screen","lh","none",...T()]}],"max-h":[{"max-h":["screen","lh",...T()]}],"font-size":[{text:["base",r,W,O]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[o,n,re]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",oe,s]}],"font-family":[{font:[fo,s,t]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[a,n,s]}],"line-clamp":[{"line-clamp":[p,"none",n,re]}],leading:[{leading:[d,...m()]}],"list-image":[{"list-image":["none",n,s]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",n,s]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:l()}],"text-color":[{text:l()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...D(),"wavy"]}],"text-decoration-thickness":[{decoration:[p,"from-font","auto",n,O]}],"text-decoration-color":[{decoration:l()}],"underline-offset":[{"underline-offset":[p,"auto",n,s]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:m()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",n,s]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",n,s]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:le()}],"bg-repeat":[{bg:ce()}],"bg-size":[{bg:de()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},M,n,s],radial:["",n,s],conic:[M,n,s]},go,uo]}],"bg-color":[{bg:l()}],"gradient-from-pos":[{from:Z()}],"gradient-via-pos":[{via:Z()}],"gradient-to-pos":[{to:Z()}],"gradient-from":[{from:l()}],"gradient-via":[{via:l()}],"gradient-to":[{to:l()}],rounded:[{rounded:x()}],"rounded-s":[{"rounded-s":x()}],"rounded-e":[{"rounded-e":x()}],"rounded-t":[{"rounded-t":x()}],"rounded-r":[{"rounded-r":x()}],"rounded-b":[{"rounded-b":x()}],"rounded-l":[{"rounded-l":x()}],"rounded-ss":[{"rounded-ss":x()}],"rounded-se":[{"rounded-se":x()}],"rounded-ee":[{"rounded-ee":x()}],"rounded-es":[{"rounded-es":x()}],"rounded-tl":[{"rounded-tl":x()}],"rounded-tr":[{"rounded-tr":x()}],"rounded-br":[{"rounded-br":x()}],"rounded-bl":[{"rounded-bl":x()}],"border-w":[{border:k()}],"border-w-x":[{"border-x":k()}],"border-w-y":[{"border-y":k()}],"border-w-s":[{"border-s":k()}],"border-w-e":[{"border-e":k()}],"border-w-t":[{"border-t":k()}],"border-w-r":[{"border-r":k()}],"border-w-b":[{"border-b":k()}],"border-w-l":[{"border-l":k()}],"divide-x":[{"divide-x":k()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":k()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...D(),"hidden","none"]}],"divide-style":[{divide:[...D(),"hidden","none"]}],"border-color":[{border:l()}],"border-color-x":[{"border-x":l()}],"border-color-y":[{"border-y":l()}],"border-color-s":[{"border-s":l()}],"border-color-e":[{"border-e":l()}],"border-color-t":[{"border-t":l()}],"border-color-r":[{"border-r":l()}],"border-color-b":[{"border-b":l()}],"border-color-l":[{"border-l":l()}],"divide-color":[{divide:l()}],"outline-style":[{outline:[...D(),"none","hidden"]}],"outline-offset":[{"outline-offset":[p,n,s]}],"outline-w":[{outline:["",p,W,O]}],"outline-color":[{outline:l()}],shadow:[{shadow:["","none",h,K,J]}],"shadow-color":[{shadow:l()}],"inset-shadow":[{"inset-shadow":["none",y,K,J]}],"inset-shadow-color":[{"inset-shadow":l()}],"ring-w":[{ring:k()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:l()}],"ring-offset-w":[{"ring-offset":[p,O]}],"ring-offset-color":[{"ring-offset":l()}],"inset-ring-w":[{"inset-ring":k()}],"inset-ring-color":[{"inset-ring":l()}],"text-shadow":[{"text-shadow":["none",z,K,J]}],"text-shadow-color":[{"text-shadow":l()}],opacity:[{opacity:[p,n,s]}],"mix-blend":[{"mix-blend":[...me(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":me()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[p]}],"mask-image-linear-from-pos":[{"mask-linear-from":g()}],"mask-image-linear-to-pos":[{"mask-linear-to":g()}],"mask-image-linear-from-color":[{"mask-linear-from":l()}],"mask-image-linear-to-color":[{"mask-linear-to":l()}],"mask-image-t-from-pos":[{"mask-t-from":g()}],"mask-image-t-to-pos":[{"mask-t-to":g()}],"mask-image-t-from-color":[{"mask-t-from":l()}],"mask-image-t-to-color":[{"mask-t-to":l()}],"mask-image-r-from-pos":[{"mask-r-from":g()}],"mask-image-r-to-pos":[{"mask-r-to":g()}],"mask-image-r-from-color":[{"mask-r-from":l()}],"mask-image-r-to-color":[{"mask-r-to":l()}],"mask-image-b-from-pos":[{"mask-b-from":g()}],"mask-image-b-to-pos":[{"mask-b-to":g()}],"mask-image-b-from-color":[{"mask-b-from":l()}],"mask-image-b-to-color":[{"mask-b-to":l()}],"mask-image-l-from-pos":[{"mask-l-from":g()}],"mask-image-l-to-pos":[{"mask-l-to":g()}],"mask-image-l-from-color":[{"mask-l-from":l()}],"mask-image-l-to-color":[{"mask-l-to":l()}],"mask-image-x-from-pos":[{"mask-x-from":g()}],"mask-image-x-to-pos":[{"mask-x-to":g()}],"mask-image-x-from-color":[{"mask-x-from":l()}],"mask-image-x-to-color":[{"mask-x-to":l()}],"mask-image-y-from-pos":[{"mask-y-from":g()}],"mask-image-y-to-pos":[{"mask-y-to":g()}],"mask-image-y-from-color":[{"mask-y-from":l()}],"mask-image-y-to-color":[{"mask-y-to":l()}],"mask-image-radial":[{"mask-radial":[n,s]}],"mask-image-radial-from-pos":[{"mask-radial-from":g()}],"mask-image-radial-to-pos":[{"mask-radial-to":g()}],"mask-image-radial-from-color":[{"mask-radial-from":l()}],"mask-image-radial-to-color":[{"mask-radial-to":l()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":j()}],"mask-image-conic-pos":[{"mask-conic":[p]}],"mask-image-conic-from-pos":[{"mask-conic-from":g()}],"mask-image-conic-to-pos":[{"mask-conic-to":g()}],"mask-image-conic-from-color":[{"mask-conic-from":l()}],"mask-image-conic-to-color":[{"mask-conic-to":l()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:le()}],"mask-repeat":[{mask:ce()}],"mask-size":[{mask:de()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",n,s]}],filter:[{filter:["","none",n,s]}],blur:[{blur:pe()}],brightness:[{brightness:[p,n,s]}],contrast:[{contrast:[p,n,s]}],"drop-shadow":[{"drop-shadow":["","none",R,K,J]}],"drop-shadow-color":[{"drop-shadow":l()}],grayscale:[{grayscale:["",p,n,s]}],"hue-rotate":[{"hue-rotate":[p,n,s]}],invert:[{invert:["",p,n,s]}],saturate:[{saturate:[p,n,s]}],sepia:[{sepia:["",p,n,s]}],"backdrop-filter":[{"backdrop-filter":["","none",n,s]}],"backdrop-blur":[{"backdrop-blur":pe()}],"backdrop-brightness":[{"backdrop-brightness":[p,n,s]}],"backdrop-contrast":[{"backdrop-contrast":[p,n,s]}],"backdrop-grayscale":[{"backdrop-grayscale":["",p,n,s]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[p,n,s]}],"backdrop-invert":[{"backdrop-invert":["",p,n,s]}],"backdrop-opacity":[{"backdrop-opacity":[p,n,s]}],"backdrop-saturate":[{"backdrop-saturate":[p,n,s]}],"backdrop-sepia":[{"backdrop-sepia":["",p,n,s]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":m()}],"border-spacing-x":[{"border-spacing-x":m()}],"border-spacing-y":[{"border-spacing-y":m()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",n,s]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[p,"initial",n,s]}],ease:[{ease:["linear","initial",P,n,s]}],delay:[{delay:[p,n,s]}],animate:[{animate:["none",$,n,s]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[v,n,s]}],"perspective-origin":[{"perspective-origin":L()}],rotate:[{rotate:Y()}],"rotate-x":[{"rotate-x":Y()}],"rotate-y":[{"rotate-y":Y()}],"rotate-z":[{"rotate-z":Y()}],scale:[{scale:q()}],"scale-x":[{"scale-x":q()}],"scale-y":[{"scale-y":q()}],"scale-z":[{"scale-z":q()}],"scale-3d":["scale-3d"],skew:[{skew:ee()}],"skew-x":[{"skew-x":ee()}],"skew-y":[{"skew-y":ee()}],transform:[{transform:[n,s,"","none","gpu","cpu"]}],"transform-origin":[{origin:L()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:X()}],"translate-x":[{"translate-x":X()}],"translate-y":[{"translate-y":X()}],"translate-z":[{"translate-z":X()}],"translate-none":["translate-none"],accent:[{accent:l()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:l()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",n,s]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":m()}],"scroll-mx":[{"scroll-mx":m()}],"scroll-my":[{"scroll-my":m()}],"scroll-ms":[{"scroll-ms":m()}],"scroll-me":[{"scroll-me":m()}],"scroll-mt":[{"scroll-mt":m()}],"scroll-mr":[{"scroll-mr":m()}],"scroll-mb":[{"scroll-mb":m()}],"scroll-ml":[{"scroll-ml":m()}],"scroll-p":[{"scroll-p":m()}],"scroll-px":[{"scroll-px":m()}],"scroll-py":[{"scroll-py":m()}],"scroll-ps":[{"scroll-ps":m()}],"scroll-pe":[{"scroll-pe":m()}],"scroll-pt":[{"scroll-pt":m()}],"scroll-pr":[{"scroll-pr":m()}],"scroll-pb":[{"scroll-pb":m()}],"scroll-pl":[{"scroll-pl":m()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",n,s]}],fill:[{fill:["none",...l()]}],"stroke-w":[{stroke:[p,W,O,re]}],stroke:[{stroke:["none",...l()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},ko=Qe(wo);function yo(...e){return ko(Ge(e))}function vo(e){if(e===0)return"0 B";const t=1024,r=["B","KB","MB","GB","TB"],o=Math.floor(Math.log(e)/Math.log(t)),a=e/Math.pow(t,o);return`${a%1===0?a:a.toFixed(1)} ${r[o]}`}function zo(e){return e.charAt(0).toUpperCase()+e.slice(1)}export{yo as a,Ge as b,zo as c,vo as f,ko as t};
@@ -9,8 +9,8 @@
9
9
  <link rel="apple-touch-icon" href="/logo192.png" />
10
10
  <link rel="manifest" href="/manifest.json" />
11
11
  <title>nao — Chat with your data</title>
12
- <script type="module" crossorigin src="/assets/index-CGg3ZQH6.js"></script>
13
- <link rel="stylesheet" crossorigin href="/assets/index-Bc7icYyJ.css">
12
+ <script type="module" crossorigin src="/assets/index-B-_pu_22.js"></script>
13
+ <link rel="stylesheet" crossorigin href="/assets/index-CWAm1NQa.css">
14
14
  </head>
15
15
  <body>
16
16
  <div id="app"></div>
@@ -0,0 +1,25 @@
1
+ <svg width="400" height="271" viewBox="0 0 400 271" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g filter="url(#filter0_d_logo)">
3
+ <path d="M230.221 0V60.4343L200.004 171.999L169.787 60.4343V0H230.221Z" fill="url(#paint0_linear_logo)"/>
4
+ <path d="M157.301 212.692L60.4343 232.414H0V171.999H60.4343L157.301 212.692Z" fill="url(#paint0_linear_logo)"/>
5
+ <path d="M400 171.999V232.414H339.605L242.699 212.692L339.605 171.999H400Z" fill="url(#paint0_linear_logo)"/>
6
+ <path d="M169.851 182.534L39.4834 112.542V52.1272H99.8981L169.851 182.534Z" fill="url(#paint0_linear_logo)"/>
7
+ <path d="M360.553 52.1272V112.542L230.166 182.534L300.119 52.1272H360.553Z" fill="url(#paint0_linear_logo)"/>
8
+ </g>
9
+ <defs>
10
+ <filter id="filter0_d_logo" x="-4" y="0" width="408" height="275" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
11
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
12
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
13
+ <feOffset dy="4"/>
14
+ <feGaussianBlur stdDeviation="2"/>
15
+ <feComposite in2="hardAlpha" operator="out"/>
16
+ <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
17
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_logo"/>
18
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_logo" result="shape"/>
19
+ </filter>
20
+ <linearGradient id="paint0_linear_logo" x1="400" y1="0" x2="0" y2="271" gradientUnits="userSpaceOnUse">
21
+ <stop stop-color="#C3C3C3"/>
22
+ <stop offset="1" stop-color="#595959"/>
23
+ </linearGradient>
24
+ </defs>
25
+ </svg>
nao_core/commands/init.py CHANGED
@@ -1,11 +1,14 @@
1
+ import os
1
2
  from pathlib import Path
2
3
  from typing import Annotated
3
4
 
4
5
  from cyclopts import Parameter
5
6
  from rich.console import Console
7
+ from rich.panel import Panel
6
8
  from rich.prompt import Confirm, Prompt
7
9
 
8
10
  from nao_core.config import AnyDatabaseConfig, BigQueryConfig, DatabaseType, LLMConfig, LLMProvider, NaoConfig
11
+ from nao_core.config.repos import RepoConfig
9
12
 
10
13
  console = Console()
11
14
 
@@ -40,6 +43,23 @@ class EmptyApiKeyError(InitError):
40
43
 
41
44
  def setup_project_name(force: bool = False) -> tuple[str, Path]:
42
45
  """Setup the project name."""
46
+ # Check if we're in a directory with an existing nao_config.yaml
47
+ current_dir = Path.cwd()
48
+ config_file = current_dir / "nao_config.yaml"
49
+
50
+ if config_file.exists():
51
+ # Load existing config to get project name
52
+ existing_config = NaoConfig.try_load(current_dir)
53
+ if existing_config:
54
+ console.print("\n[bold yellow]Found existing nao_config.yaml[/bold yellow]")
55
+ console.print(f"[dim]Project: {existing_config.project_name}[/dim]\n")
56
+
57
+ if force or Confirm.ask("[bold]Re-initialize this project?[/bold]", default=True):
58
+ return existing_config.project_name, current_dir
59
+ else:
60
+ raise InitError("Initialization cancelled.")
61
+
62
+ # Normal flow: prompt for project name
43
63
  project_name = Prompt.ask("[bold]Enter your project name[/bold]")
44
64
 
45
65
  if not project_name:
@@ -111,6 +131,29 @@ def setup_databases() -> list[AnyDatabaseConfig]:
111
131
  return databases
112
132
 
113
133
 
134
+ def setup_repos() -> list[RepoConfig]:
135
+ """Setup repository configurations."""
136
+ repos: list[RepoConfig] = []
137
+ should_setup = Confirm.ask("\n[bold]Set up git repositories?[/bold]", default=True)
138
+
139
+ if not should_setup:
140
+ return repos
141
+
142
+ while True:
143
+ console.print("\n[bold cyan]Git Repository Configuration[/bold cyan]\n")
144
+ name = Prompt.ask("[bold]Repository name[/bold]")
145
+ url = Prompt.ask("[bold]Repository URL[/bold]")
146
+
147
+ repos.append(RepoConfig(name=name, url=url))
148
+ console.print(f"\n[bold green]✓[/bold green] Added repository [cyan]{name}[/cyan]")
149
+
150
+ add_another = Confirm.ask("\n[bold]Add another repository?[/bold]", default=False)
151
+ if not add_another:
152
+ break
153
+
154
+ return repos
155
+
156
+
114
157
  def setup_llm() -> LLMConfig | None:
115
158
  """Setup the LLM configuration."""
116
159
  llm_config = None
@@ -142,6 +185,39 @@ def setup_llm() -> LLMConfig | None:
142
185
  return llm_config
143
186
 
144
187
 
188
+ def create_empty_structure(project_path: Path) -> tuple[list[str], list[str]]:
189
+ """Create project folder structure to guide users.
190
+
191
+ To add new folders, simply append them to the FOLDERS list below.
192
+ Each folder will be created automatically (can be empty).
193
+ """
194
+ FOLDERS = [
195
+ "databases",
196
+ "queries",
197
+ "docs",
198
+ "semantics",
199
+ "repos",
200
+ "agent/tools",
201
+ "agent/mcps",
202
+ ]
203
+
204
+ FILES = ["RULES.md"]
205
+
206
+ created_folders = []
207
+ for folder in FOLDERS:
208
+ folder_path = project_path / folder
209
+ folder_path.mkdir(parents=True, exist_ok=True)
210
+ created_folders.append(folder)
211
+
212
+ created_files = []
213
+ for file in FILES:
214
+ file_path = project_path / file
215
+ file_path.touch()
216
+ created_files.append(file)
217
+
218
+ return created_folders, created_files
219
+
220
+
145
221
  def init(
146
222
  *,
147
223
  force: Annotated[bool, Parameter(name=["-f", "--force"])] = False,
@@ -162,14 +238,49 @@ def init(
162
238
  config = NaoConfig(
163
239
  project_name=project_name,
164
240
  databases=setup_databases(),
241
+ repos=setup_repos(),
165
242
  llm=setup_llm(),
166
243
  )
167
244
  config.save(project_path)
168
245
 
246
+ # Create project folder structure
247
+ created_folders, created_files = create_empty_structure(project_path)
248
+
169
249
  console.print()
170
250
  console.print(f"[bold green]✓[/bold green] Created project [cyan]{project_name}[/cyan]")
171
251
  console.print(f"[bold green]✓[/bold green] Created [dim]{project_path / 'nao_config.yaml'}[/dim]")
172
252
  console.print()
173
253
  console.print("[bold green]Done![/bold green] Your nao project is ready. 🎉")
254
+
255
+ is_subfolder = project_path.resolve() != Path.cwd().resolve()
256
+
257
+ has_connections = config.databases or config.llm
258
+ if has_connections:
259
+ # Change directory for the debug command to run in the right context
260
+ os.chdir(project_path)
261
+ from nao_core.commands.debug import debug
262
+
263
+ debug()
264
+
265
+ console.print()
266
+
267
+ cd_instruction = ""
268
+ if is_subfolder:
269
+ cd_instruction = f"\n[bold]First, navigate to your project:[/bold]\n[cyan]cd {project_path}[/cyan]\n\n"
270
+
271
+ help_content = f"""{cd_instruction}[bold]Available Commands:[/bold]
272
+
273
+ [cyan]nao debug[/cyan] - Test connectivity to your configured databases and LLM
274
+ Verifies that all connections are working properly
275
+
276
+ [cyan]nao sync[/cyan] - Sync database schemas to local markdown files
277
+ Creates documentation for your tables and columns
278
+
279
+ [cyan]nao chat[/cyan] - Start the nao chat interface
280
+ Launch the web UI to chat with your data
281
+ """
282
+ console.print(Panel(help_content, border_style="cyan", title="🚀 Get Started", title_align="left"))
283
+ console.print()
284
+
174
285
  except InitError as e:
175
286
  console.print(f"[bold red]✗[/bold red] {e}")
@@ -0,0 +1,59 @@
1
+ """Sync command for synchronizing repositories and database schemas."""
2
+
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ from rich.console import Console
7
+
8
+ from nao_core.config import NaoConfig
9
+
10
+ from .databases import sync_databases
11
+ from .repositories import sync_repositories
12
+
13
+ console = Console()
14
+
15
+
16
+ def sync(output_dir: str = "databases", repos_dir: str = "repos"):
17
+ """Sync repositories and database schemas to local files.
18
+
19
+ Creates folder structures:
20
+ - repos/<repo_name>/ (git repositories)
21
+ - databases/bigquery/<connection>/<dataset>/<table>/*.md (database schemas)
22
+
23
+ Args:
24
+ output_dir: Output directory for database schemas (default: "databases")
25
+ repos_dir: Output directory for repositories (default: "repos")
26
+ """
27
+ console.print("\n[bold cyan]🔄 nao sync[/bold cyan]\n")
28
+
29
+ config = NaoConfig.try_load()
30
+ if not config:
31
+ console.print("[bold red]✗[/bold red] No nao_config.yaml found in current directory")
32
+ console.print("[dim]Run 'nao init' to create a configuration file[/dim]")
33
+ sys.exit(1)
34
+
35
+ console.print(f"[dim]Project:[/dim] {config.project_name}")
36
+
37
+ repos_synced = 0
38
+ if config.repos:
39
+ repos_path = Path(repos_dir)
40
+ repos_synced = sync_repositories(config.repos, repos_path)
41
+
42
+ db_path = Path(output_dir)
43
+ datasets_synced, tables_synced = sync_databases(config.databases, db_path)
44
+
45
+ console.print("\n[bold green]✓ Sync Complete[/bold green]\n")
46
+
47
+ if repos_synced > 0:
48
+ console.print(f" [dim]Repositories:[/dim] {repos_synced} synced")
49
+
50
+ if tables_synced > 0:
51
+ console.print(f" [dim]Databases:[/dim] {tables_synced} tables across {datasets_synced} datasets")
52
+
53
+ if repos_synced == 0 and tables_synced == 0:
54
+ console.print(" [dim]Nothing to sync[/dim]")
55
+
56
+ console.print()
57
+
58
+
59
+ __all__ = ["sync"]
@@ -0,0 +1,212 @@
1
+ """Data accessor classes for generating markdown documentation from database tables."""
2
+
3
+ import json
4
+ from abc import ABC, abstractmethod
5
+
6
+ from ibis import BaseBackend
7
+
8
+
9
+ class DataAccessor(ABC):
10
+ """Base class for data accessors that generate markdown files for tables."""
11
+
12
+ @property
13
+ @abstractmethod
14
+ def filename(self) -> str:
15
+ """The filename this accessor writes to (e.g., 'columns.md')."""
16
+ ...
17
+
18
+ @abstractmethod
19
+ def generate(self, conn: BaseBackend, dataset: str, table: str) -> str:
20
+ """Generate the markdown content for a table.
21
+
22
+ Args:
23
+ conn: The Ibis database connection
24
+ dataset: The dataset/schema name
25
+ table: The table name
26
+
27
+ Returns:
28
+ Markdown string content
29
+ """
30
+ ...
31
+
32
+ def get_table(self, conn: BaseBackend, dataset: str, table: str):
33
+ """Helper to get an Ibis table reference."""
34
+ full_table_name = f"{dataset}.{table}"
35
+ return conn.table(full_table_name)
36
+
37
+
38
+ def truncate_middle(text: str, max_length: int) -> str:
39
+ """Truncate text in the middle if it exceeds max_length."""
40
+ if len(text) <= max_length:
41
+ return text
42
+ half = (max_length - 3) // 2
43
+ return text[:half] + "..." + text[-half:]
44
+
45
+
46
+ class ColumnsAccessor(DataAccessor):
47
+ """Generates columns.md with column names, types, and nullable info."""
48
+
49
+ def __init__(self, max_description_length: int = 256):
50
+ self.max_description_length = max_description_length
51
+
52
+ @property
53
+ def filename(self) -> str:
54
+ return "columns.md"
55
+
56
+ def generate(self, conn: BaseBackend, dataset: str, table: str) -> str:
57
+ try:
58
+ t = self.get_table(conn, dataset, table)
59
+ schema = t.schema()
60
+
61
+ columns = list(schema.items())
62
+
63
+ lines = [
64
+ f"# {table}",
65
+ "",
66
+ f"**Dataset:** `{dataset}`",
67
+ "",
68
+ f"## Columns ({len(columns)})",
69
+ "",
70
+ ]
71
+
72
+ for name, dtype in columns:
73
+ description = None
74
+ parts = [str(dtype)]
75
+ if description:
76
+ truncated = truncate_middle(description, self.max_description_length)
77
+ parts.append(f'"{truncated}"')
78
+ lines.append(f"- {name} ({', '.join(parts)})")
79
+
80
+ return "\n".join(lines)
81
+ except Exception as e:
82
+ return f"# {table}\n\nError fetching schema: {e}"
83
+
84
+
85
+ class PreviewAccessor(DataAccessor):
86
+ """Generates preview.md with the first N rows of data as JSONL."""
87
+
88
+ def __init__(self, num_rows: int = 10):
89
+ self.num_rows = num_rows
90
+
91
+ @property
92
+ def filename(self) -> str:
93
+ return "preview.md"
94
+
95
+ def generate(self, conn: BaseBackend, dataset: str, table: str) -> str:
96
+ try:
97
+ t = self.get_table(conn, dataset, table)
98
+ preview_df = t.limit(self.num_rows).execute()
99
+
100
+ lines = [
101
+ f"# {table} - Preview",
102
+ "",
103
+ f"**Dataset:** `{dataset}`",
104
+ "",
105
+ f"## Rows ({len(preview_df)})",
106
+ "",
107
+ ]
108
+
109
+ for _, row in preview_df.iterrows():
110
+ row_dict = row.to_dict()
111
+ # Convert non-serializable types to strings
112
+ for key, val in row_dict.items():
113
+ if val is not None and not isinstance(val, (str, int, float, bool, list, dict)):
114
+ row_dict[key] = str(val)
115
+ lines.append(f"- {json.dumps(row_dict)}")
116
+
117
+ return "\n".join(lines)
118
+ except Exception as e:
119
+ return f"# {table} - Preview\n\nError fetching preview: {e}"
120
+
121
+
122
+ class DescriptionAccessor(DataAccessor):
123
+ """Generates description.md with table metadata (row count, column count, etc.)."""
124
+
125
+ @property
126
+ def filename(self) -> str:
127
+ return "description.md"
128
+
129
+ def generate(self, conn: BaseBackend, dataset: str, table: str) -> str:
130
+ try:
131
+ t = self.get_table(conn, dataset, table)
132
+ schema = t.schema()
133
+
134
+ row_count = t.count().execute()
135
+ col_count = len(schema)
136
+
137
+ lines = [
138
+ f"# {table}",
139
+ "",
140
+ f"**Dataset:** `{dataset}`",
141
+ "",
142
+ "## Table Metadata",
143
+ "",
144
+ "| Property | Value |",
145
+ "|----------|-------|",
146
+ f"| **Row Count** | {row_count:,} |",
147
+ f"| **Column Count** | {col_count} |",
148
+ "",
149
+ "## Description",
150
+ "",
151
+ "_No description available._",
152
+ "",
153
+ ]
154
+
155
+ return "\n".join(lines)
156
+ except Exception as e:
157
+ return f"# {table}\n\nError fetching description: {e}"
158
+
159
+
160
+ class ProfilingAccessor(DataAccessor):
161
+ """Generates profiling.md with column statistics and data profiling."""
162
+
163
+ @property
164
+ def filename(self) -> str:
165
+ return "profiling.md"
166
+
167
+ def generate(self, conn: BaseBackend, dataset: str, table: str) -> str:
168
+ try:
169
+ t = self.get_table(conn, dataset, table)
170
+ schema = t.schema()
171
+
172
+ lines = [
173
+ f"# {table} - Profiling",
174
+ "",
175
+ f"**Dataset:** `{dataset}`",
176
+ "",
177
+ "## Column Statistics",
178
+ "",
179
+ "| Column | Type | Nulls | Unique | Min | Max |",
180
+ "|--------|------|-------|--------|-----|-----|",
181
+ ]
182
+
183
+ for name, dtype in schema.items():
184
+ col = t[name]
185
+ dtype_str = str(dtype)
186
+
187
+ try:
188
+ null_count = t.filter(col.isnull()).count().execute()
189
+ unique_count = col.nunique().execute()
190
+
191
+ min_val = ""
192
+ max_val = ""
193
+ if dtype.is_numeric() or dtype.is_temporal():
194
+ try:
195
+ min_val = str(col.min().execute())
196
+ max_val = str(col.max().execute())
197
+ if len(min_val) > 20:
198
+ min_val = min_val[:17] + "..."
199
+ if len(max_val) > 20:
200
+ max_val = max_val[:17] + "..."
201
+ except Exception:
202
+ pass
203
+
204
+ lines.append(
205
+ f"| `{name}` | `{dtype_str}` | {null_count:,} | {unique_count:,} | {min_val} | {max_val} |"
206
+ )
207
+ except Exception as col_error:
208
+ lines.append(f"| `{name}` | `{dtype_str}` | Error: {col_error} | | | |")
209
+
210
+ return "\n".join(lines)
211
+ except Exception as e:
212
+ return f"# {table} - Profiling\n\nError fetching profiling: {e}"