codebase-ai 0.3.4 → 0.3.5
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.
- package/dist/index.js +69 -76
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var si=Object.defineProperty;var
|
|
3
|
-
${q.bold}${e}${q.reset}`)}function tt(e,t){return process.stdout.isTTY&&!Z?`\x1B]8;;${t}\x1B\\${e}\x1B]8;;\x1B\\`:`${e} (${t})`}function Q(e){return`${q.dim}${e}${q.reset}`}function $(e){return`${q.cyan}${e}${q.reset}`}var Z,q,fe,ni,
|
|
4
|
-
`),i=!1,o=[];for(let a of n){let c=a.trim();if(c.startsWith("#")){if(i)break;continue}if(!c||c.startsWith("![")||c.startsWith("[![")||c.startsWith("<")){if(i)break;continue}i=!0,o.push(c)}return o.join(" ").slice(0,300)||null}var ds,ps=
|
|
5
|
-
`).map(s=>s.trim().replace(/^origin\//,"")).filter(s=>s&&s!=="HEAD").filter((s,n,i)=>i.indexOf(s)===n).slice(0,10):[]}async function
|
|
2
|
+
var si=Object.defineProperty;var P=(e,t)=>()=>(e&&(t=e(e=0)),t);var Vt=(e,t)=>{for(var s in t)si(e,s,{get:t[s],enumerable:!0})};function ee(e){fe=e}function Qt(e){ni=e}function u(e){fe||console.log(e)}function g(e){fe||console.log(` ${q.green}[\u2713]${q.reset} ${e}`)}function v(e){console.error(` ${q.red}[\u2717]${q.reset} ${e}`)}function _(e){fe||console.log(` ${q.yellow}[!]${q.reset} ${e}`)}function h(e){fe||console.log(` ${q.cyan}[i]${q.reset} ${e}`)}function te(e){fe||console.log(`${q.dim}${e}${q.reset}`)}function w(e){return`${q.bold}${e}${q.reset}`}function S(e){fe||console.log(`
|
|
3
|
+
${q.bold}${e}${q.reset}`)}function tt(e,t){return process.stdout.isTTY&&!Z?`\x1B]8;;${t}\x1B\\${e}\x1B]8;;\x1B\\`:`${e} (${t})`}function Q(e){return`${q.dim}${e}${q.reset}`}function $(e){return`${q.cyan}${e}${q.reset}`}var Z,q,fe,ni,F=P(()=>{"use strict";Z=!!process.env.NO_COLOR,q={reset:Z?"":"\x1B[0m",green:Z?"":"\x1B[32m",red:Z?"":"\x1B[31m",yellow:Z?"":"\x1B[33m",cyan:Z?"":"\x1B[36m",blue:Z?"":"\x1B[34m",magenta:Z?"":"\x1B[35m",dim:Z?"":"\x1B[2m",bold:Z?"":"\x1B[1m"},fe=!1,ni=!1});function rs(e,t){let s=bi(t);return e.filter(n=>s.test(n))}function bi(e){let t="^",s=0;for(;s<e.length;){let n=e[s];if(n==="*")e[s+1]==="*"?e[s+2]==="/"?(t+="(?:.*/)?",s+=3):(t+=".*",s+=2):(t+="[^/]*",s++);else if(n==="?")t+="[^/]",s++;else if(n==="{"){let i=e.indexOf("}",s);if(i!==-1){let o=e.slice(s+1,i).split(",");t+="(?:"+o.map(St).join("|")+")",s=i+1}else t+=St(n),s++}else t+=St(n),s++}return t+="$",new RegExp(t)}function St(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var as=P(()=>{"use strict"});import{readdir as yi,readFile as ki}from"fs/promises";import{existsSync as wi}from"fs";import{join as Ct,relative as vi}from"path";import{execFile as $i}from"child_process";async function cs(e,t={}){let s=new Set([...xi,...t.ignore??[]]),n=await ls(e,e,s,t.depth??10),i=new Set(n);return{root:e,files:n,async readFile(o){try{return await ki(Ct(e,o),"utf-8")}catch{return""}},fileExists(o){return i.has(o)?!0:wi(Ct(e,o))},glob(o){return rs(n,o)},exec(o,r){return new Promise(a=>{$i(o,r,{cwd:e,timeout:1e4},(c,l)=>{a(c?"":l.trim())})})}}}async function ls(e,t,s,n,i=0){if(i>n)return[];let o=[];try{let r=await yi(t,{withFileTypes:!0});for(let a of r){if(s.has(a.name)||a.isDirectory()&&a.name.startsWith(".")&&!new Set([".github",".husky",".circleci"]).has(a.name))continue;let c=Ct(t,a.name),l=vi(e,c);if(a.isDirectory()){o.push(l+"/");let p=await ls(e,c,s,n,i+1);o.push(...p)}else o.push(l)}}catch{}return o}var xi,us=P(()=>{"use strict";as();xi=new Set(["node_modules",".git","dist","build",".next",".nuxt",".output","__pycache__","vendor",".venv","venv","target","coverage",".cache",".turbo",".vercel",".netlify",".parcel-cache",".svelte-kit",".angular","out","bin","obj"])});async function ji(e){let t=await e.readFile("package.json");if(t)try{let r=JSON.parse(t);if(r.name)return r.name}catch{}let s=await e.readFile("Cargo.toml");if(s){let r=s.match(/^name\s*=\s*"([^"]+)"/m);if(r)return r[1]}let n=await e.readFile("pyproject.toml");if(n){let r=n.match(/^name\s*=\s*"([^"]+)"/m);if(r)return r[1]}let i=await e.readFile("go.mod");if(i){let r=i.match(/^module\s+(\S+)/m);if(r)return r[1].split("/").pop()||r[1]}let o=await e.exec("git",["remote","get-url","origin"]);return o?o.replace(/.*[:/]/,"").replace(/\.git$/,""):e.root.split("/").pop()||"unknown"}async function Si(e){let t=await e.readFile("package.json");if(t)try{let i=JSON.parse(t);if(i.description)return i.description}catch{}let s=await e.readFile("Cargo.toml");if(s){let i=s.match(/^description\s*=\s*"([^"]+)"/m);if(i)return i[1]}let n=await e.readFile("pyproject.toml");if(n){let i=n.match(/^description\s*=\s*"([^"]+)"/m);if(i)return i[1]}return null}async function Ci(e){let t=["README.md","readme.md","README","README.txt","README.rst"],s="";for(let a of t)if(s=await e.readFile(a),s)break;if(!s)return null;let n=s.split(`
|
|
4
|
+
`),i=!1,o=[];for(let a of n){let c=a.trim();if(c.startsWith("#")){if(i)break;continue}if(!c||c.startsWith("![")||c.startsWith("[![")||c.startsWith("<")){if(i)break;continue}i=!0,o.push(c)}return o.join(" ").slice(0,300)||null}var ds,ps=P(()=>{"use strict";ds={name:"project",category:"project",async detect(e){let[t,s,n]=await Promise.all([ji(e),Si(e),Ci(e)]);return{name:t,description:s||n||null}}}});async function Ei(e){return await e.exec("git",["remote","get-url","origin"])||null}async function _i(e){let t=await e.exec("git",["symbolic-ref","refs/remotes/origin/HEAD"]);if(t)return t.replace("refs/remotes/origin/","");let s=await e.exec("git",["branch","--list","main","master"]);return s.includes("main")?"main":s.includes("master")?"master":await e.exec("git",["branch","--show-current"])||null}async function Ri(e){let t=await e.exec("git",["branch","-a","--sort=-committerdate","--format=%(refname:short)"]);return t?t.split(`
|
|
5
|
+
`).map(s=>s.trim().replace(/^origin\//,"")).filter(s=>s&&s!=="HEAD").filter((s,n,i)=>i.indexOf(s)===n).slice(0,10):[]}async function Pi(e){let t=await e.readFile("package.json");if(t)try{if(JSON.parse(t).workspaces)return!0}catch{}return e.fileExists("pnpm-workspace.yaml")||e.fileExists("lerna.json")||e.fileExists("turbo.json")||e.fileExists("nx.json")||e.fileExists("rush.json")}async function Di(e){if(e.fileExists("turbo.json"))return"turborepo";if(e.fileExists("nx.json"))return"nx";if(e.fileExists("lerna.json"))return"lerna";if(e.fileExists("rush.json"))return"rush";if(e.fileExists("pnpm-workspace.yaml"))return"pnpm";let t=await e.readFile("package.json");if(t)try{if(JSON.parse(t).workspaces)return"npm/yarn"}catch{}return null}var fs,ms=P(()=>{"use strict";fs={name:"repo",category:"repo",async detect(e){let[t,s,n,i,o]=await Promise.all([Ei(e),_i(e),Ri(e),Pi(e),Di(e)]);return{url:t,default_branch:s,is_monorepo:i,workspace_manager:i?o:null,active_branches:n}}}});import{existsSync as Ai}from"fs";import{join as Oi}from"path";function Li(e,t){let s={},n=[];for(let o of e){let a=o.replace(/\/$/,"").split("/");if(a.length===1&&!o.endsWith("/")){n.push(a[0]);continue}if(a.length<2)continue;let c=a[0]+"/";a.length===2&&!o.endsWith("/")?(s[c]||(s[c]=new Set),s[c].add(a[1])):a.length>=3&&(s[c]||(s[c]=new Set),s[c].add(a[1]+"/"))}let i={};if(n.length>0){let o=n.sort();i["./"]=o.length>15?[...o.slice(0,13),`... (${o.length} files)`]:o}for(let[o,r]of Object.entries(s)){let a=[...r].sort();i[o]=a.length>20?[...a.slice(0,18),`... (${a.length} items)`]:a}return i}var Ii,Ni,gs,hs=P(()=>{"use strict";Ii=["src/index.ts","src/index.js","src/main.ts","src/main.js","src/app.ts","src/app.js","src/server.ts","src/server.js","src/app/layout.tsx","src/app/page.tsx","app/layout.tsx","pages/_app.tsx","pages/_app.js","pages/index.tsx","index.ts","index.js","main.ts","main.js","app/main.py","main.py","app.py","manage.py","main.go","cmd/main.go","src/main.rs","src/lib.rs","lib/main.dart","Program.cs"],Ni=["dist","build",".next","out","target","bin","obj",".output",".nuxt",".svelte-kit",".vercel"],gs={name:"structure",category:"structure",async detect(e){let t=Ii.filter(i=>e.fileExists(i)),s=Ni.filter(i=>Ai(Oi(e.root,i))),n=Li(e.files,4);return{entry_points:t,build_output:s,tree:n}}}});function Ui(e){let t={};for(let s of e.files){if(s.endsWith("/"))continue;let n="."+s.split(".").pop(),i=Fi[n];i&&(t[i]=(t[i]||0)+1)}return Object.entries(t).sort((s,n)=>n[1]-s[1]).map(([s])=>s)}async function Bi(e){let t=await e.readFile("package.json");if(!t)return{};try{let s=JSON.parse(t);return{...s.dependencies||{},...s.devDependencies||{}}}catch{return{}}}function Ji(e){let t=[];for(let[n,i]of Object.entries(e)){let o=Mi[n];if(o){let r=i.replace(/^[\^~>=<]+/,"").split(".").slice(0,2).join(".");t.push(`${o}@${r}`)}}let s=Wi(e);return t.push(...s),[...new Set(t)]}function Wi(e){let t=[],s=Object.keys(e).join(" ");if(s.includes("next")){let n=e.next?.replace(/^[\^~>=<]+/,"").split(".").slice(0,2).join("."),i=[];n&&(parseFloat(n)>=13&&i.push("app-router available"),i.push(n)),t.push(i.length>0?`next.js@${i.join(" ")}`:"next.js")}if(s.includes("vue")){let n=e.vue?.replace(/^[\^~>=<]+/,"");if(n){let i=parseInt(n.split(".")[0],10);t.push(i>=3?`vue@${n}`:`vue@${n}`)}else t.push("vue");if(s.includes("nuxt")){let i=e.nuxt?.replace(/^[\^~>=<]+/,"");if(i){let o=parseInt(i.split(".")[0],10);t.push(o>=3?`nuxt@${i} (Nuxt 3)`:`nuxt@${i} (Nuxt 2)`)}else t.push("nuxt")}}if(s.includes("@sveltejs/kit")){let n=e["@sveltejs/kit"]?.replace(/^[\^~>=<]+/,"");t.push(n?`sveltekit@${n}`:"sveltekit")}if(s.includes("astro")){let n=e.astro?.replace(/^[\^~>=<]+/,""),i=[];e["@astrojs/react"]&&i.push("react"),e["@astrojs/vue"]&&i.push("vue"),e["@astrojs/svelte"]&&i.push("svelte"),e["@astrojs/preact"]&&i.push("preact"),e["@astrojs/solid-js"]&&i.push("solid"),i.length>0?t.push(n?`astro@${n} (${i.join(", ")})`:`astro (${i.join(", ")})`):t.push(n?`astro@${n}`:"astro")}if(s.includes("@remix-run/react")||s.includes("@remix-run/node")){let n=e["@remix-run/react"]?.replace(/^[\^~>=<]+/,"")||e["@remix-run/node"]?.replace(/^[\^~>=<]+/,"");t.push(n?`remix@${n}`:"remix")}if(s.includes("@angular/core")){let n=e["@angular/core"]?.replace(/^[\^~>=<]+/,"").split(".").slice(0,2).join(".");t.push(n?`angular@${n}`:"angular")}if(s.includes("gatsby")){let n=e.gatsby?.replace(/^[\^~>=<]+/,"");t.push(n?`gatsby@${n}`:"gatsby")}return t}function Ki(e,t){return e.fileExists("pnpm-lock.yaml")?"pnpm":e.fileExists("yarn.lock")?"yarn":e.fileExists("bun.lockb")||e.fileExists("bun.lock")?"bun":e.fileExists("package-lock.json")?"npm":e.fileExists("Cargo.lock")?"cargo":e.fileExists("poetry.lock")?"poetry":e.fileExists("Pipfile.lock")?"pipenv":e.fileExists("go.sum")?"go modules":e.fileExists("Gemfile.lock")?"bundler":e.fileExists("composer.lock")?"composer":Object.keys(t).length>0?"npm":null}function Et(e,t){for(let s of Object.keys(e))if(t[s])return t[s];return null}function zi(e,t){let s=new Set;for(let n of Object.keys(e))t[n]&&s.add(t[n]);return[...s]}async function Vi(e){let t=await e.readFile("prisma/schema.prisma");if(!t)return null;let s=t.match(/datasource\s+\w+\s*\{([^}]+)\}/);if(!s)return null;let n=s[1].match(/provider\s*=\s*"(.*?)"/);if(!n)return null;let i=n[1].toLowerCase();return i==="postgresql"||i==="postgres"?"postgresql":i==="mysql"?"mysql":i==="sqlite"?"sqlite":i==="sqlserver"?"sqlserver":i==="mongodb"?"mongodb":i==="cockroachdb"?"cockroachdb":i}async function Qi(e){let t=[],s=["migrations/","prisma/migrations/","db/migrate/","database/migrations/","src/migrations/","server/migrations/","api/migrations/","migrate/","sql/","db/sql/"];for(let r of s)if(e.files.some(a=>a.startsWith(r))){let a=await Yi(e,r);a&&!t.includes(a)&&t.push(a)}let n=await Xi(e);for(let r of n)t.includes(r)||t.push(r);let i=await Zi(e);for(let r of i)t.includes(r)||t.push(r);let o=await eo(e);for(let r of o)t.includes(r)||t.push(r);return t}async function Yi(e,t){let s=e.files.filter(n=>n.startsWith(t));for(let n of s){let i=await e.readFile(n);if(!i)continue;let o=i.toLowerCase();if(o.includes("create table")||o.includes("alter table")){if(o.includes("postgresql")||o.includes("serial")||o.includes("bigserial"))return"postgresql";if(o.includes("mysql")||o.includes("engine=innodb"))return"mysql";if(o.includes("sqlite"))return"sqlite";if(o.includes("mongodb")||o.includes("mongoose"))return"mongodb";if(o.includes("redis"))return"redis";if(o.includes("elasticsearch"))return"elasticsearch"}}return null}async function Xi(e){let t=[],s=["docker-compose.yml","docker-compose.yaml","docker-compose.dev.yml","docker-compose.prod.yml","compose.yml","compose.yaml"];for(let n of s){if(!e.fileExists(n))continue;let i=await e.readFile(n);if(!i)continue;let o=i.toLowerCase();(o.includes("postgres")||o.includes("postgresql"))&&t.push("postgresql"),o.includes("mysql")&&t.push("mysql"),o.includes("mariadb")&&t.push("mariadb"),(o.includes("mongodb")||o.includes("mongo"))&&t.push("mongodb"),o.includes("redis")&&t.push("redis"),o.includes("elasticsearch")&&t.push("elasticsearch"),o.includes("cassandra")&&t.push("cassandra"),o.includes("couchdb")&&t.push("couchdb"),o.includes("neo4j")&&t.push("neo4j"),o.includes("rabbitmq")&&t.push("rabbitmq"),o.includes("dynamodb")&&t.push("dynamodb")}return t}async function Zi(e){let t=[],s=await e.readFile("ormconfig.json")||await e.readFile("ormconfig.js")||await e.readFile("src/data-source.ts");if(s){let r=s.toLowerCase();(r.includes("postgres")||r.includes("pg"))&&t.push("postgresql"),r.includes("mysql")&&t.push("mysql"),r.includes("sqlite")&&t.push("sqlite"),r.includes("mongodb")&&t.push("mongodb")}let n=[".sequelizerc","config/database.js","config/config.js"];for(let r of n){let a=await e.readFile(r);if(a){let c=a.toLowerCase();c.includes("postgres")&&t.push("postgresql"),c.includes("mysql")&&t.push("mysql"),c.includes("sqlite")&&t.push("sqlite"),c.includes("mariadb")&&t.push("mariadb")}}let i=await e.readFile("mikro-orm.config.ts")||await e.readFile("mikro-orm.config.js");if(i){let r=i.toLowerCase();r.includes("postgres")&&t.push("postgresql"),r.includes("mysql")&&t.push("mysql"),r.includes("sqlite")&&t.push("sqlite"),r.includes("mongodb")&&t.push("mongodb")}let o=["drizzle.config.ts","drizzle.config.js","drizzle.config.json"];for(let r of o){let a=await e.readFile(r);if(a){let c=a.toLowerCase();(c.includes("postgres")||c.includes("pg"))&&t.push("postgresql"),c.includes("mysql")&&t.push("mysql"),c.includes("sqlite")&&t.push("sqlite")}}return t}async function eo(e){let t=[],s=e.files.filter(n=>n.endsWith(".sql")||n.includes("schema")||n.includes("migrate")||n.includes("migration"));for(let n of s){let i=await e.readFile(n);if(!i)continue;let o=i.toLowerCase();(o.includes("serial")||o.includes("bigserial")||o.includes("text[]")||o.includes("jsonb")||o.includes("create extension")||o.includes("pg_"))&&(t.includes("postgresql")||t.push("postgresql")),(o.includes("engine=innodb")||o.includes("auto_increment")||o.includes("tinyint")||o.includes("mediumint")||o.includes("enum("))&&(t.includes("mysql")||t.push("mysql")),(o.includes("autoincrement")||o.includes("integer primary key"))&&(t.includes("sqlite")||t.push("sqlite"))}return t}async function to(e){let t=await e.readFile("pyproject.toml"),s=await e.readFile("requirements.txt"),n=await e.readFile("setup.py"),i=t+`
|
|
6
6
|
`+s+`
|
|
7
|
-
`+n;if(i.includes("fastapi")){let o=we(s,"fastapi")||we(t,"fastapi");return o?`fastapi@${o}`:"fastapi"}if(i.includes("django")){let o=we(s,"django")||we(t,"django"),r=[];o&&r.push(o);let a=await
|
|
7
|
+
`+n;if(i.includes("fastapi")){let o=we(s,"fastapi")||we(t,"fastapi");return o?`fastapi@${o}`:"fastapi"}if(i.includes("django")){let o=we(s,"django")||we(t,"django"),r=[];o&&r.push(o);let a=await so(e);a.length>0&&r.push(`apps: ${a.join(", ")}`);let c=await no(e);return c&&r.push(c),r.length>0?`django@${r.join(" ")}`:o?`django@${o}`:"django"}if(i.includes("flask")){let o=we(s,"flask")||we(t,"flask");return o?`flask@${o}`:"flask"}return i.includes("starlette")?"starlette":i.includes("tornado")?"tornado":i.includes("aiohttp")?"aiohttp":i.includes("sanic")?"sanic":i.includes("pyramid")?"pyramid":i.includes("bottle")?"bottle":i.includes("cherrypy")?"cherrypy":i.includes("falcon")?"falcon":i.includes("masonite")?"masonite":i.includes("torch")||i.includes("pytorch")?"pytorch":i.includes("tensorflow")?"tensorflow":i.includes("keras")?"keras":i.includes("scikit-learn")?"scikit-learn":i.includes("pandas")?"pandas":i.includes("numpy")?"numpy":i.includes("celery")?"celery":i.includes("rq")?"rq":null}async function so(e){let t=[],s=e.files.filter(n=>n.includes("settings.py")||n.includes("settings/")||n.match(/settings.*\.py$/));for(let n of s.slice(0,3))try{let i=await e.readFile(n);if(!i)continue;let o=i.match(/INSTALLED_APPS\s*=\s*\[([\s\S]*?)\]/);if(o){let r=o[1],a=r.match(/'([^']+)'/g)||r.match(/"([^"]+)"/g)||[];for(let c of a){let l=c.replace(/['"]/g,"");!l.startsWith("django.")&&l.includes(".")&&t.push(l.split(".")[0])}}}catch{}return[...new Set(t)].slice(0,5)}async function no(e){let t=e.files.some(i=>i.endsWith("settings.py")),s=e.files.some(i=>i.includes("settings/")&&i.endsWith(".py"));return e.files.some(i=>i.includes("settings_dev.py")||i.includes("settings.dev"))?"settings:dev":s?"settings:dir":t?"settings:py":null}async function io(e){let t=await e.readFile("go.mod");if(!t)return null;let s=[];if(t.includes("github.com/gin-gonic/gin")){let n=Ne(t,"github.com/gin-gonic/gin");s.push(n?`gin@${n}`:"gin")}if(t.includes("github.com/gofiber/fiber")){let n=Ne(t,"github.com/gofiber/fiber");s.push(n?`fiber@${n}`:"fiber")}if(t.includes("github.com/labstack/echo")){let n=Ne(t,"github.com/labstack/echo");s.push(n?`echo@${n}`:"echo")}if(t.includes("github.com/gorilla/mux")){let n=Ne(t,"github.com/gorilla/mux");s.push(n?`gorilla/mux@${n}`:"gorilla/mux")}if(t.includes("go-chi/chi")){let n=Ne(t,"go-chi/chi");s.push(n?`chi@${n}`:"chi")}return t.includes("grpc")&&s.push("grpc"),t.includes("net/http")&&s.push("net/http (std)"),s.length>0?s.join(", "):null}async function oo(e){let t=await e.readFile("Cargo.toml");if(!t)return null;let s=[];if(t.includes("actix-web")){let n=nt(t,"actix-web");s.push(n?`actix-web@${n}`:"actix-web")}if(t.includes("axum")){let n=nt(t,"axum");s.push(n?`axum@${n}`:"axum")}if(t.includes("rocket")){let n=nt(t,"rocket");s.push(n?`rocket@${n}`:"rocket")}if(t.includes("warp")&&s.push("warp"),t.includes("tokio")){let n=nt(t,"tokio");s.push(n?`tokio@${n}`:"tokio")}return t.includes("hyper")&&s.push("hyper"),t.includes("tonic")&&s.push("tonic (grpc)"),s.length>0?s.join(", "):null}async function ro(e){let t=await e.readFile("pom.xml"),s=await e.readFile("build.gradle"),n=await e.readFile("build.gradle.kts"),i=t+`
|
|
8
8
|
`+s+`
|
|
9
|
-
`+n;if(i.includes("spring-boot")){let o=it(t,"spring-boot-starter-parent")||ot(s,"org.springframework.boot");return o?`spring boot@${o}`:"spring boot"}if(i.includes("spring-framework")||i.includes("spring-core")){let o=it(t,"spring-framework")||ot(s,"org.springframework");return o?`spring@${o}`:"spring"}if(i.includes("micronaut")){let o=it(t,"micronaut")||ot(s,"io.micronaut");return o?`micronaut@${o}`:"micronaut"}if(i.includes("quarkus")){let o=it(t,"quarkus")||ot(s,"io.quarkus");return o?`quarkus@${o}`:"quarkus"}return i.includes("jakarta")?"jakarta ee":i.includes("javax")?"java ee":i.includes("vertx")?"vert.x":i.includes("kafka")?"kafka":null}async function
|
|
10
|
-
`+s;if(n.includes("rails")){let i=bs(n,"rails"),o=[];i&&o.push(i);let r=await
|
|
11
|
-
`)){let i=n.match(/^([a-zA-Z_-]+)\s*:/);i&&s.add(i[1])}return{dev:s.has("dev")?"make dev":s.has("run")?"make run":null,build:s.has("build")?"make build":null,test:s.has("test")?"make test":null,lint:s.has("lint")?"make lint":null,format:s.has("format")?"make format":s.has("fmt")?"make fmt":null}}async function
|
|
12
|
-
`)){let n=s.trim();if(!n||n.startsWith("#"))continue;let i=n.match(/^([a-zA-Z0-9_-]+)\s*=/);i&&t.push(i[1].toLowerCase())}return t}function
|
|
13
|
-
`)){let n=s.trim();if(!n||n.startsWith("#")||n.startsWith("-"))continue;let i=n.split(/[>=<!;\[]/)[0].trim().toLowerCase();i&&t.push(i)}return t}function
|
|
14
|
-
`)){let r=o.trim();if(!r||r.startsWith("//"))continue;let a=r.split(/\s+/);a[0]&&t.push(a[0])}let n=e.matchAll(/^require\s+(\S+)[ \t]+\S+/gm);for(let i of n)t.push(i[1]);return t}async function
|
|
15
|
-
`)){let o=i.match(/gem\s+["']([^"']+)["']/);o&&(s.push(o[1]),ve.has(o[1])&&n.push(o[1]))}return{direct_count:s.length,dev_count:0,notable:[...new Set(n)].sort()}}async function
|
|
9
|
+
`+n;if(i.includes("spring-boot")){let o=it(t,"spring-boot-starter-parent")||ot(s,"org.springframework.boot");return o?`spring boot@${o}`:"spring boot"}if(i.includes("spring-framework")||i.includes("spring-core")){let o=it(t,"spring-framework")||ot(s,"org.springframework");return o?`spring@${o}`:"spring"}if(i.includes("micronaut")){let o=it(t,"micronaut")||ot(s,"io.micronaut");return o?`micronaut@${o}`:"micronaut"}if(i.includes("quarkus")){let o=it(t,"quarkus")||ot(s,"io.quarkus");return o?`quarkus@${o}`:"quarkus"}return i.includes("jakarta")?"jakarta ee":i.includes("javax")?"java ee":i.includes("vertx")?"vert.x":i.includes("kafka")?"kafka":null}async function ao(e){let t=await e.readFile("Gemfile"),s=await e.readFile(".gemspec"),n=t+`
|
|
10
|
+
`+s;if(n.includes("rails")){let i=bs(n,"rails"),o=[];i&&o.push(i);let r=await co(e);return r.length>0&&o.push(r.join(", ")),o.length>0?`rails@${o.join(" ")}`:`rails@${i||"unknown"}`}if(n.includes("sinatra")){let i=bs(n,"sinatra");return i?`sinatra@${i}`:"sinatra"}return n.includes("grape")?"grape":n.includes("hanami")?"hanami":n.includes("roda")?"roda":n.includes("padrino")?"padrino":n.includes("sidekiq")?"sidekiq":n.includes("resque")?"resque":n.includes("puma")?"puma":n.includes("unicorn")?"unicorn":null}async function co(e){let t=[],s=await e.readFile("Gemfile");return s&&(s.includes("devise")&&t.push("devise"),s.includes("pundit")&&t.push("pundit"),s.includes("cancancan")&&t.push("cancancan"),s.includes("rspec-rails")&&t.push("rspec"),s.includes("minitest")&&t.push("minitest"),s.includes("factory_bot_rails")&&t.push("factory_bot"),s.includes("faker")&&t.push("faker"),s.includes("sidekiq")&&t.push("sidekiq"),(s.includes("redis")||s.includes("redis-rails"))&&t.push("redis"),s.includes("pg")&&t.push("postgresql"),s.includes("mysql2")&&t.push("mysql"),s.includes("sqlite3")&&t.push("sqlite"),s.includes("aws-sdk")&&t.push("aws"),s.includes("bootstrap")&&t.push("bootstrap"),s.includes("tailwindcss-rails")&&t.push("tailwind")),t.slice(0,5)}async function lo(e){let t=await e.readFile("composer.json");if(!t)return null;try{let s=JSON.parse(t),n={...s.require||{},...s["require-dev"]||{}},i=Object.keys(n).join(" ");if(i.includes("laravel")){let o=n["laravel/framework"]||n["laravel/lumen"];return o?`laravel@${o.replace(/^[\^~>=<]+/,"")}`:"laravel"}if(i.includes("symfony")){let o=n["symfony/framework-bundle"];return o?`symfony@${o.replace(/^[\^~>=<]+/,"")}`:"symfony"}if(i.includes("slim")){let o=n["slim/slim"];return o?`slim@${o.replace(/^[\^~>=<]+/,"")}`:"slim"}if(i.includes("codeigniter"))return"codeigniter";if(i.includes("cakephp"))return"cakephp";if(i.includes("yii")){let o=n["yiisoft/yii2"];return o?`yii@${o.replace(/^[\^~>=<]+/,"")}`:"yii"}if(i.includes("lumen"))return"lumen"}catch{}return null}async function uo(e){let t=e.files.filter(n=>n.endsWith(".csproj"));if(t.length===0)return null;let s=[];for(let n of t){let i=await e.readFile(n);if(i.includes("Microsoft.AspNetCore")){let o=po(i,"Microsoft.AspNetCore.App");s.push(o?`asp.net core@${o}`:"asp.net core")}i.includes("EntityFramework")&&s.push("entity framework"),i.includes("NUnit")&&s.push("nunit"),i.includes("xUnit")&&s.push("xunit"),i.includes("Moq")&&s.push("moq")}return s.length>0?s.join(", "):null}function we(e,t){if(!e)return null;let s=[new RegExp(`${t}===?\\s*([\\d.]+)`),new RegExp(`${t}>=?\\s*([\\d.]+)`),new RegExp(`${t}~=?\\s*([\\d.]+)`),new RegExp(`${t}@([\\d.]+)`),new RegExp(`"${t}":\\s*"([\\d.]+)"`),new RegExp(`'${t}':\\s*'([\\d.]+)'`)];for(let n of s){let i=e.match(n);if(i)return i[1]}return null}function Ne(e,t){let s=new RegExp(`${t}\\s+v([\\d.]+)`),n=e.match(s);return n?n[1]:null}function nt(e,t){let s=new RegExp(`${t}\\s*=\\s*"([\\d.]+)"`),n=e.match(s);return n?n[1]:null}function it(e,t){if(!e)return null;let s=new RegExp(`<artifactId>${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}</artifactId>[\\s\\S]*?<version>([\\d.]+)</version>`),n=e.match(s);return n?n[1]:null}function ot(e,t){if(!e)return null;let s=[new RegExp(`${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}:[^:]*:([\\d.]+)`),new RegExp(`${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}:([\\d.]+)`)];for(let n of s){let i=e.match(n);if(i)return i[1]}return null}function bs(e,t){let s=new RegExp(`gem\\s+['"]${t}['"][^,]*,\\s*['"]~?>?\\s*([\\d.]+)['"]`),n=e.match(s);return n?n[1]:null}function po(e,t){let s=new RegExp(`<PackageReference\\s+Include="${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"[^>]*Version="([\\d.]+)"`),n=e.match(s);return n?n[1]:null}var Fi,Mi,Ti,qi,Hi,Gi,ys,ks=P(()=>{"use strict";Fi={".ts":"typescript",".tsx":"typescript-react",".js":"javascript",".jsx":"javascript-react",".mjs":"javascript",".cjs":"javascript",".py":"python",".pyi":"python",".go":"go",".rs":"rust",".java":"java",".kt":"kotlin",".kts":"kotlin",".cs":"csharp",".rb":"ruby",".php":"php",".swift":"swift",".dart":"dart",".ex":"elixir",".exs":"elixir",".zig":"zig",".scala":"scala",".sc":"scala",".cpp":"c++",".cc":"c++",".cxx":"c++",".hpp":"c++",".h":"c++",".c":"c",".sh":"shell",".bash":"shell",".zsh":"shell",".fish":"shell",".ps1":"powershell",".lua":"lua",".r":"r",".R":"r",".m":"matlab",".mlx":"matlab",".jl":"julia",".nim":"nim",".cr":"crystal",".v":"v",".wasm":"webassembly",".wat":"webassembly",".graphql":"graphql",".gql":"graphql",".sol":"solidity",".move":"move",".mo":"motoko",".toml":"toml",".yaml":"yaml",".yml":"yaml",".json":"json",".xml":"xml",".md":"markdown"},Mi={next:"next.js",react:"react","react-dom":"react",vue:"vue",nuxt:"nuxt","@angular/core":"angular",svelte:"svelte","@sveltejs/kit":"sveltekit",express:"express",fastify:"fastify",hono:"hono",koa:"koa",nestjs:"nestjs","@nestjs/core":"nestjs",remix:"remix","@remix-run/react":"remix",astro:"astro",gatsby:"gatsby",electron:"electron",tauri:"tauri","react-native":"react-native",expo:"expo","@trpc/server":"trpc","@trpc/client":"trpc"},Ti={pg:"postgresql",postgres:"postgresql","pg-promise":"postgresql",mysql2:"mysql",mysql:"mysql","@mysql/xdevapi":"mysql","better-sqlite3":"sqlite",sqlite3:"sqlite","sql.js":"sqlite",mongodb:"mongodb",mongoose:"mongodb",mongoodb:"mongodb",redis:"redis",ioredis:"redis","@redis/client":"redis","redis-mock":"redis","cassandra-driver":"cassandra","express-cassandra":"cassandra",elasticsearch:"elasticsearch","@elastic/elasticsearch":"elasticsearch","@elastic/elasticsearch-ng":"elasticsearch","neo4j-driver":"neo4j",neo4j:"neo4j",couchbase:"couchbase",ottoman:"couchbase",rethinkdb:"rethinkdb",rethinkdbdash:"rethinkdb",level:"leveldb",levelup:"leveldb","aws-sdk":"dynamodb","@aws-sdk/client-dynamodb":"dynamodb",mssql:"mssql",tedious:"mssql",msnodesqlv8:"mssql",oracledb:"oracle","node-oracledb":"oracle","pg-copy-streams":"postgresql","pg-pool":"postgresql","pg-native":"postgresql"," knex":"knex",minio:"minio",firebird:"firebird","node-firebird":"firebird","hdb-pool":"sap-hana","snowflake-sdk":"snowflake","cassandra-client":"scylladb"},qi={prisma:"prisma","@prisma/client":"prisma","drizzle-orm":"drizzle",typeorm:"typeorm",sequelize:"sequelize","@mikro-orm/core":"mikro-orm",knex:"knex",mongoose:"mongoose"},Hi={tailwindcss:"tailwindcss","styled-components":"styled-components","@emotion/react":"emotion",sass:"sass","@chakra-ui/react":"chakra-ui","@mui/material":"material-ui","@mantine/core":"mantine"},Gi={vite:"vite",webpack:"webpack",esbuild:"esbuild",tsup:"tsup",rollup:"rollup",parcel:"parcel",turbopack:"turbopack",unbuild:"unbuild",pkgroll:"pkgroll","@swc/core":"swc",snowpack:"snowpack"},ys={name:"stack",category:"stack",async detect(e){let t=Ui(e),s=await Bi(e),n=Ji(s),i=Ki(e,s),o=zi(s,Ti),r=Et(s,qi),a=Et(s,Hi),c=Et(s,Gi);if(r==="prisma"){let C=await Vi(e);C&&!o.includes(C)&&o.unshift(C)}let l=await Qi(e);for(let C of l)o.includes(C)||o.push(C);let[p,d,m,y,b,j,x]=await Promise.all([to(e),io(e),oo(e),ro(e),ao(e),lo(e),uo(e)]);return p&&n.push(p),d&&n.push(d),m&&n.push(m),y&&n.push(y),b&&n.push(b),j&&n.push(j),x&&n.push(x),{languages:[...new Set(t)],frameworks:[...new Set(n)],package_manager:i,database:o.length>1?o.join(" + "):o[0]||null,orm:r,styling:a,build_tool:c}}}});async function fo(e){let t=await e.readFile("package.json");if(!t)return Fe();try{let n=JSON.parse(t).scripts||{},i="npm run";e.fileExists("pnpm-lock.yaml")?i="pnpm":e.fileExists("yarn.lock")?i="yarn":(e.fileExists("bun.lockb")||e.fileExists("bun.lock"))&&(i="bun run");let o={dev:Le(n,["dev","start","serve"],i),build:Le(n,["build","compile"],i),test:Le(n,["test","test:unit","test:run"],i),lint:Le(n,["lint","lint:check"],i),format:Le(n,["format","fmt","prettier"],i)},r=["typecheck","check","deploy","preview","clean","db:migrate","db:seed","generate","codegen","storybook"];for(let a of r)n[a]&&(o[a]=`${i} ${a}`);return o}catch{return Fe()}}function Le(e,t,s){for(let n of t)if(e[n])return`${s} ${n}`;return null}async function mo(e){let t=await e.readFile("Makefile");if(!t)return Fe();let s=new Set;for(let n of t.split(`
|
|
11
|
+
`)){let i=n.match(/^([a-zA-Z_-]+)\s*:/);i&&s.add(i[1])}return{dev:s.has("dev")?"make dev":s.has("run")?"make run":null,build:s.has("build")?"make build":null,test:s.has("test")?"make test":null,lint:s.has("lint")?"make lint":null,format:s.has("format")?"make format":s.has("fmt")?"make fmt":null}}async function go(e){if(e.fileExists("Cargo.toml"))return{dev:"cargo run",build:"cargo build",test:"cargo test",lint:"cargo clippy",format:"cargo fmt"};if(e.fileExists("go.mod"))return{dev:"go run .",build:"go build .",test:"go test ./...",lint:e.fileExists(".golangci.yml")||e.fileExists(".golangci.yaml")?"golangci-lint run":null,format:"go fmt ./..."};if(e.fileExists("pyproject.toml")||e.fileExists("requirements.txt")||e.fileExists("setup.py")){let s=e.fileExists("poetry.lock")?"poetry run":e.fileExists("Pipfile.lock")?"pipenv run":e.fileExists("uv.lock")?"uv run":"python -m",n=e.files.some(d=>d.includes("pytest")||d.includes("test_"))||e.fileExists("pytest.ini"),i=e.fileExists("ruff.toml")||e.fileExists(".ruff.toml")||e.fileExists("pyproject.toml"),o=e.fileExists("pyproject.toml")||e.fileExists(".black"),r=e.fileExists("mypy.ini")||e.fileExists(".mypy.ini"),a=e.fileExists("manage.py"),c=e.files.some(d=>d.includes("main.py")||d.includes("app.py")),l=null;a?l=`${s} python manage.py runserver`:c?l=`${s} uvicorn main:app --reload`:e.fileExists("vite.config.ts")&&(l=`${s} vite`);let p=null;return e.fileExists("pyproject.toml")&&(p=`${s} build`),{dev:l,build:p,test:n?`${s} pytest`:`${s} unittest`,lint:i?`${s} ruff check .`:r?`${s} mypy .`:null,format:i?`${s} ruff format .`:o?`${s} black .`:null}}if(e.fileExists("pom.xml"))return{dev:"mvn spring-boot:run",build:"mvn compile",test:"mvn test",lint:"mvn checkstyle:check",format:null};if(e.fileExists("build.gradle")||e.fileExists("build.gradle.kts"))return{dev:"./gradlew bootRun",build:"./gradlew build",test:"./gradlew test",lint:"./gradlew checkstyleMain",format:null};if(e.fileExists("build.gradle.kts"))return{dev:"./gradlew run",build:"./gradlew build",test:"./gradlew test",lint:"./gradlew ktlintCheck",format:"./gradlew ktlintFormat"};if(e.files.some(s=>s.endsWith(".csproj")||s.endsWith(".sln")))return{dev:"dotnet run",build:"dotnet build",test:"dotnet test",lint:null,format:"dotnet format"};if(e.fileExists("Gemfile")){let s="bundle exec",n=e.fileExists("bin/rails")||e.files.some(o=>o.includes("config/application.rb")),i=e.fileExists("Rakefile");return{dev:n?`${s} rails server`:null,build:null,test:n?`${s} rails test`:i?`${s} rake test`:`${s} rspec`,lint:e.fileExists(".rubocop.yml")?`${s} rubocop`:null,format:e.fileExists(".rubocop.yml")?`${s} rubocop -a`:null}}if(e.fileExists("composer.json")){let s="composer",n=e.fileExists("artisan")||e.files.some(o=>o.includes("config/app.php")),i=e.files.some(o=>o.includes("symfony"));return{dev:n?"php artisan serve":i?"symfony server:start":"php -S localhost:8000",build:`${s} install`,test:n?"php artisan test":`${s} test`,lint:e.fileExists("phpunit.xml")||e.fileExists("phpunit.xml.dist")?`${s} phpunit`:null,format:e.fileExists(".php-cs-fixer.php")?"vendor/bin/php-cs-fixer fix":null}}if(e.fileExists("Package.swift")||e.files.some(s=>s.endsWith(".xcodeproj")))return{dev:"swift run",build:"swift build",test:"swift test",lint:null,format:"swift format ."};if(e.fileExists("pubspec.yaml"))return{dev:e.fileExists("lib/main.dart")?"flutter run":"dart run",build:e.fileExists("lib/main.dart")?"flutter build":"dart compile exe",test:"flutter test",lint:"flutter analyze",format:"dart format ."};if(e.fileExists("mix.exs"))return{dev:"mix phx.server",build:"mix compile",test:"mix test",lint:"mix format --check-formatted",format:"mix format"};if(e.fileExists("build.sbt"))return{dev:"sbt run",build:"sbt compile",test:"sbt test",lint:"sbt scalafmtCheck",format:"sbt scalafmt"};if(e.fileExists("CMakeLists.txt"))return{dev:null,build:"cmake --build build",test:"ctest --test-dir build",lint:null,format:null};let t=e.fileExists("Cargo.toml")||e.fileExists("go.mod")||e.fileExists("pyproject.toml")||e.fileExists("requirements.txt")||e.fileExists("setup.py")||e.fileExists("pom.xml")||e.fileExists("build.gradle")||e.fileExists("build.gradle.kts")||e.fileExists("Gemfile")||e.fileExists("composer.json")||e.fileExists("Package.swift")||e.fileExists("pubspec.yaml")||e.fileExists("mix.exs")||e.fileExists("build.sbt")||e.fileExists("CMakeLists.txt");return e.fileExists("Makefile")&&!t?Fe():e.files.some(s=>s.endsWith(".sh"))?{dev:null,build:null,test:null,lint:"shellcheck *.sh",format:"shfmt -w *.sh"}:Fe()}function Fe(){return{dev:null,build:null,test:null,lint:null,format:null}}var ws,vs=P(()=>{"use strict";ws={name:"commands",category:"commands",async detect(e){let t=await fo(e);if(Object.values(t).some(Boolean))return t;let s=await mo(e);return Object.values(s).some(Boolean)?s:await go(e)}}});function rt(e,t){return e.filter(s=>t.has(s)).sort()}function yo(e){let t=[],s=[],n=e.match(/\[project\]\s[\s\S]*?dependencies\s*=\s*\[([\s\S]*?)\]/);n&&t.push(...xs(n[1]));let i=e.match(/\[project\.optional-dependencies\]\s*[\s\S]*?(?=\n\[|$)/);if(i){let a=i[0].matchAll(/\w+\s*=\s*\[([\s\S]*?)\]/g);for(let c of a)s.push(...xs(c[1]))}let o=e.match(/\[tool\.poetry\.dependencies\]\s*\n([\s\S]*?)(?=\n\[|$)/);if(o){let a=at(o[1]);t.push(...a.filter(c=>c!=="python"))}let r=e.match(/\[tool\.poetry\.(?:group\.dev\.|dev-)dependencies\]\s*\n([\s\S]*?)(?=\n\[|$)/);return r&&s.push(...at(r[1])),t.length===0&&s.length===0?null:{direct:t,dev:s}}function xs(e){let t=[],s=e.matchAll(/"([^"]+)"|'([^']+)'/g);for(let n of s){let o=(n[1]||n[2]).split(/[>=<!;\[]/)[0].trim().toLowerCase();o&&t.push(o)}return t}function at(e){let t=[];for(let s of e.split(`
|
|
12
|
+
`)){let n=s.trim();if(!n||n.startsWith("#"))continue;let i=n.match(/^([a-zA-Z0-9_-]+)\s*=/);i&&t.push(i[1].toLowerCase())}return t}function ko(e){let t=[];for(let s of e.split(`
|
|
13
|
+
`)){let n=s.trim();if(!n||n.startsWith("#")||n.startsWith("-"))continue;let i=n.split(/[>=<!;\[]/)[0].trim().toLowerCase();i&&t.push(i)}return t}function wo(e){let t=[],s=[],n=e.match(/\[dependencies\]\s*\n([\s\S]*?)(?=\n\[|$)/);n&&t.push(...at(n[1]));let i=e.match(/\[dev-dependencies\]\s*\n([\s\S]*?)(?=\n\[|$)/);return i&&s.push(...at(i[1])),{direct:t,dev:s}}function vo(e){let t=[],s=e.matchAll(/require\s*\(([\s\S]*?)\)/g);for(let i of s)for(let o of i[1].split(`
|
|
14
|
+
`)){let r=o.trim();if(!r||r.startsWith("//"))continue;let a=r.split(/\s+/);a[0]&&t.push(a[0])}let n=e.matchAll(/^require\s+(\S+)[ \t]+\S+/gm);for(let i of n)t.push(i[1]);return t}async function $o(e){let t=await e.readFile("Gemfile");if(!t)return{direct_count:0,dev_count:0,notable:[]};let s=[],n=[];for(let i of t.split(`
|
|
15
|
+
`)){let o=i.match(/gem\s+["']([^"']+)["']/);o&&(s.push(o[1]),ve.has(o[1])&&n.push(o[1]))}return{direct_count:s.length,dev_count:0,notable:[...new Set(n)].sort()}}async function xo(e){let t=await e.readFile("composer.json");if(!t)return{direct_count:0,dev_count:0,notable:[]};try{let s=JSON.parse(t),n=s.require||{},i=s["require-dev"]||{},o={...n,...i},r=Object.keys(o).filter(a=>ve.has(a)).sort();return{direct_count:Object.keys(n).length,dev_count:Object.keys(i).length,notable:r}}catch{return{direct_count:0,dev_count:0,notable:[]}}}async function jo(e){let t=await e.readFile("pom.xml"),s=await e.readFile("build.gradle"),n=await e.readFile("build.gradle.kts"),i=(t||"")+`
|
|
16
16
|
`+(s||"")+`
|
|
17
|
-
`+(n||"");if(!i.trim())return{direct_count:0,dev_count:0,notable:[]};let o=[],r=[],a=/<artifactId>([^<]+)<\/artifactId>/g,c;for(;(c=a.exec(i))!==null;)o.push(c[1]),ve.has(c[1])&&r.push(c[1]);let l=/(?:implementation|compile|api)\s+['"]([^:'"]+)/g;for(;(c=l.exec(i))!==null;){let p=c[1].split(":").pop();p&&(o.push(p),ve.has(p)&&r.push(p))}return{direct_count:[...new Set(o)].length,dev_count:0,notable:[...new Set(r)].sort()}}async function
|
|
18
|
-
`),i="";for(let o of n){let r=o.trim();if(!r)continue;if(r.startsWith("#")){i+=(i?" ":"")+r.slice(1).trim();continue}let a=r.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(a){let[,c,l]=a,p=l==='""'||l==="''"||l==="";t[c]={description:i||void 0,required:s||p},i=""}}}var
|
|
19
|
-
`).filter(Boolean):[]}async function
|
|
20
|
-
`).map(s=>s.replace(/^\s*\d+\s+/,"").trim()).filter(Boolean):[]}async function Lo(e){return(await e.exec("git",["status","--porcelain"])).length>0}var _s,Rs=D(()=>{"use strict";_s={name:"git",category:"git",async detect(e){let[t,s,n]=await Promise.all([Io(e),No(e),Lo(e)]);return{recent_commits:t,last_committers:s,uncommitted_changes:n}}}});async function Fo(e){if(e.glob("vitest.config.*").length>0)return"vitest";if(e.glob("jest.config.*").length>0)return"jest";if(e.fileExists(".mocharc.yml")||e.fileExists(".mocharc.json"))return"mocha";if(e.glob("playwright.config.*").length>0)return"playwright";if(e.glob("cypress.config.*").length>0)return"cypress";let t=await e.readFile("package.json");if(t)try{let s=JSON.parse(t),n={...s.dependencies||{},...s.devDependencies||{}},o=(s.scripts||{}).test||"";if(n.vitest||o.includes("vitest"))return"vitest";if(n.jest||o.includes("jest"))return"jest";if(n.mocha||o.includes("mocha"))return"mocha";if(n["@playwright/test"]||o.includes("playwright"))return"playwright";if(n.cypress)return"cypress";if(n.ava)return"ava";if(n.tap)return"tap"}catch{}if(e.fileExists("pytest.ini")||e.fileExists("pyproject.toml")||e.fileExists("setup.cfg")||e.fileExists("tox.ini")){let s=await e.readFile("pyproject.toml"),n=await e.readFile("setup.cfg"),i=await e.readFile("pytest.ini");if(s?.includes("pytest")||n?.includes("pytest")||i||e.files.some(o=>o.includes("test_")||o.includes("_test.py")))return"pytest";if(s?.includes("unittest")||n?.includes("unittest"))return"unittest";if(s?.includes("nose"))return"nose"}if(e.files.some(s=>s.endsWith("_test.go")))return"go test";if(e.files.some(s=>s.includes("/tests/")||s.startsWith("tests/")||s.endsWith("tests.rs")||s.match(/mod\s+tests/)))return"cargo test";if(e.fileExists("spec/spec_helper.rb")||e.fileExists(".rspec")||e.files.some(s=>s.includes("/spec/")&&s.endsWith("_spec.rb")))return"rspec";if(e.fileExists("test/minitest_helper.rb"))return"minitest";if(e.files.some(s=>s.endsWith("Test.java")||s.endsWith("Tests.java")))return"junit";if(e.fileExists("pom.xml")){let s=await e.readFile("pom.xml");if(s?.includes("junit")||s?.includes("testng"))return s?.includes("testng")?"testng":"junit"}if(e.fileExists("phpunit.xml")||e.fileExists("phpunit.xml.dist")||e.files.some(s=>s.includes("tests/")&&s.endsWith(".php")))return"phpunit";if(e.files.some(s=>s.endsWith("Test.cs")||s.endsWith("Tests.cs")))return"nunit";if(e.fileExists("build.sbt")){let s=await e.readFile("build.sbt");if(s?.includes("scalatest"))return"scalatest";if(s?.includes("specs2"))return"specs2"}return e.files.some(s=>s.endsWith("Tests.swift")||s.endsWith("XCTest.swift"))?"xctest":null}async function Mo(e){if(e.fileExists("eslint.config.js")||e.fileExists("eslint.config.mjs")||e.fileExists("eslint.config.ts")||e.glob(".eslintrc*").length>0)return"eslint";if(e.fileExists("biome.json")||e.fileExists("biome.jsonc"))return"biome";if(e.fileExists("ruff.toml")||e.fileExists(".ruff.toml"))return"ruff";if(e.fileExists(".pylintrc")||e.fileExists("pylintrc"))return"pylint";if(e.fileExists(".flake8")||e.fileExists("setup.cfg")||e.fileExists(".flake8rc"))return"flake8";if(e.fileExists(".golangci.yml")||e.fileExists(".golangci.yaml")||e.fileExists(".golangci-lint.yml"))return"golangci-lint";if(e.fileExists("clippy.toml"))return"clippy";if(e.fileExists(".rubocop.yml")||e.fileExists(".rubocop.yaml"))return"rubocop";if(e.fileExists(".php_cs")||e.fileExists("phpstan.neon")||e.fileExists("phpunit.xml"))return"php-cs-fixer";if(e.fileExists("psalm.xml"))return"psalm";if(e.fileExists(".swiftlint.yml")||e.fileExists(".swiftlint.yaml"))return"swiftlint";if(e.fileExists(".kotlinlint.xml"))return"ktlint";if(e.fileExists("detekt.yml")||e.fileExists("detekt.yaml"))return"detekt";if(e.fileExists("checkstyle.xml"))return"checkstyle";if(e.fileExists("pmd.xml"))return"pmd";if(e.fileExists(".scalafix.conf"))return"scalafix";let t=await e.readFile("pyproject.toml");if(t){if(t.includes("ruff"))return"ruff";if(t.includes("pylint"))return"pylint";if(t.includes("flake8"))return"flake8";if(t.includes("mypy"))return"mypy";if(t.includes("black"))return"black"}let s=await e.readFile("package.json");if(s)try{let i=JSON.parse(s),o={...i.dependencies||{},...i.devDependencies||{}},a=(i.scripts||{}).lint||"";if(o.eslint||a.includes("eslint"))return"eslint";if(o["@biomejs/biome"]||a.includes("biome"))return"biome";if(o.oxlint||a.includes("oxlint"))return"oxlint";if(o.standard)return"standard";if(o.xo)return"xo";if(o["@typescript-eslint/eslint-plugin"])return"eslint";if(o.dprint)return"dprint"}catch{}return e.fileExists("golangci-lint.yml")||e.fileExists(".golangci.yml")?"golangci-lint":(await e.readFile("Cargo.toml"))?.includes("clippy")?"clippy":e.fileExists(".rubocop.yml")?"rubocop":e.fileExists("phpstan.neon")?"phpstan":e.fileExists("ecs.php")||e.fileExists("easy-coding-standard.yml")?"ecs":null}async function To(e){if(e.glob(".prettierrc*").length>0||e.fileExists("prettier.config.js")||e.fileExists("prettier.config.mjs")||e.fileExists("prettier.config.cjs")||e.fileExists("prettier.config.ts"))return"prettier";if(e.fileExists("biome.json")||e.fileExists("biome.jsonc"))return"biome";if(e.fileExists("ruff.toml")||e.fileExists(".ruff.toml"))return"ruff";if(e.fileExists("rustfmt.toml")||e.fileExists(".rustfmt.toml"))return"rustfmt";if(e.fileExists("dprint.json")||e.fileExists("dprint.jsonc"))return"dprint";if(e.fileExists(".editorconfig"))return"editorconfig";if(e.fileExists(".gofmt")||e.fileExists("gofmt.toml"))return"gofmt";if(e.fileExists(".scalafmt.conf"))return"scalafmt";if(e.fileExists(".black")||e.fileExists("pyproject.toml"))return"black";if(e.fileExists(".isort.cfg")||e.fileExists("pyproject.toml"))return"isort";if(e.fileExists(".swiftformat"))return"swiftformat";if(e.fileExists(".php-cs-fixer.php")||e.fileExists(".php-cs-fixer.dist.php"))return"php-cs-fixer";if(e.fileExists(".rubocop.yml"))return"rubocop";if(e.fileExists("prettier.config.ts")||e.fileExists(".prettierignore"))return"prettier";let t=await e.readFile("pyproject.toml");if(t){if(t.includes("black"))return"black";if(t.includes("isort"))return"isort";if(t.includes("autopep8"))return"autopep8";if(t.includes("yapf"))return"yapf"}let s=await e.readFile("package.json");if(s)try{let n=JSON.parse(s),i={...n.dependencies||{},...n.devDependencies||{}},o=n.scripts||{},r=(o.format||"")+(o.fmt||"");if(i.prettier||r.includes("prettier"))return"prettier";if(i["@biomejs/biome"]||r.includes("biome"))return"biome";if(i.dprint)return"dprint"}catch{}return e.fileExists(".gofmtrc")||e.fileExists("gofmt.toml")?"gofmt":e.fileExists("rustfmt.toml")?"rustfmt":e.fileExists(".rubocop.yml")?"rubocop":e.fileExists(".swiftformat")?"swiftformat":e.fileExists(".scalafmt.conf")?"scalafmt":null}function qo(e){return e.files.some(t=>t.startsWith(".github/workflows/"))?"github-actions":e.fileExists(".gitlab-ci.yml")||e.fileExists(".gitlab-ci.yaml")?"gitlab-ci":e.fileExists("Jenkinsfile")||e.fileExists("Jenkinsfile")?"jenkins":e.files.some(t=>t.startsWith(".circleci/"))?"circleci":e.fileExists("bitbucket-pipelines.yml")?"bitbucket-pipelines":e.fileExists(".travis.yml")?"travis-ci":e.fileExists("azure-pipelines.yml")||e.fileExists("azure-pipelines.yaml")?"azure-pipelines":e.fileExists("buildspec.yml")?"aws-codebuild":e.fileExists("cloudbuild.yaml")||e.fileExists("cloudbuild.yml")?"google-cloud-build":e.fileExists(".drone.yml")?"drone-ci":e.fileExists("workflow.yml")?"gsuite-actions":e.fileExists("now.json")||e.fileExists(".vercelignore")?"vercel":e.fileExists("netlify.toml")?"netlify":e.fileExists(".github/workflows/ci.yml")||e.fileExists(".github/workflows/cd.yml")?"github-actions":e.fileExists("procfile")||e.fileExists("Procfile")?"heroku":e.fileExists("appveyor.yml")?"appveyor":e.fileExists("codeship-services.yml")||e.fileExists("codeship-steps.yml")?"codeship":e.fileExists("semantic.yml")?"semantic-release":e.fileExists(".rerun.yaml")||e.fileExists(".rerun.yml")?"rerun":e.fileExists("woodpecker.yml")?"woodpecker-ci":e.fileExists(".forgejo")?"forgejo":null}function Ho(e){return!!(e.files.some(t=>t.startsWith(".husky/"))||e.fileExists(".pre-commit-config.yaml")||e.fileExists(".pre-commit-config.yml")||e.fileExists(".lintstagedrc")||e.fileExists("lint-staged.config.js")||e.fileExists("lint-staged.config.mjs")||e.fileExists("lint-staged.config.ts")||e.fileExists("lefthook.yml")||e.fileExists("lefthook.yaml")||e.fileExists("lefthook-local.yml")||e.fileExists(".git/hooks/pre-commit")||e.fileExists(".simple-git-hooks.cjs")||e.fileExists(".simple-git-hooks.js")||e.fileExists(".yorkielerc")||e.fileExists(".yorkie")||e.fileExists(".huskyrc")||e.fileExists(".huskyrc.json")||e.fileExists(".huskyrc.js")||e.fileExists(".pre-commit-hook.json"))}var Ps,Ds=D(()=>{"use strict";Ps={name:"quality",category:"quality",async detect(e){let[t,s,n]=await Promise.all([Fo(e),Mo(e),To(e)]);return{test_framework:t,linter:s,formatter:n,ci:qo(e),pre_commit_hooks:Ho(e)}}}});function Go(e){return e.files.some(t=>t.match(/^(src\/)?app\/layout\.(tsx?|jsx?)$/))?"app-router":e.files.some(t=>t.match(/^(src\/)?pages\/_app\./))?"pages-router":e.files.some(t=>t.includes("/controllers/"))&&e.files.some(t=>t.includes("/models/"))?"mvc":e.files.some(t=>t.startsWith("src/features/"))?"feature-sliced":e.files.some(t=>t.startsWith("src/modules/"))?"modular":e.files.some(t=>t.includes("/services/"))&&e.files.some(t=>t.includes("/repositories/"))?"layered":e.files.some(t=>t.startsWith("src/routes/"))?"file-based-routing":e.files.some(t=>t.startsWith("src/commands/")||t.startsWith("cmd/"))?"command-based":e.files.some(t=>t.startsWith("src/detectors/")||t.startsWith("src/plugins/"))?"plugin-based":e.files.some(t=>t.includes("/domain/"))&&e.files.some(t=>t.includes("/infra/")||t.includes("/infrastructure/"))?"hexagonal":e.files.some(t=>t.includes("/services/"))&&e.files.some(t=>t.includes("/handlers/")||t.includes("/controllers/"))?"layered":e.files.some(t=>t.match(/^internal\/.+\/.+/))?"package-per-feature":null}async function Uo(e){let t=await e.readFile("package.json");if(!t)return null;try{let s=JSON.parse(t),n={...s.dependencies||{},...s.devDependencies||{}},i=[];return n.zustand&&i.push("zustand"),(n["@reduxjs/toolkit"]||n.redux)&&i.push("redux"),n.mobx&&i.push("mobx"),n.jotai&&i.push("jotai"),n.recoil&&i.push("recoil"),n.pinia&&i.push("pinia"),n.vuex&&i.push("vuex"),n["@tanstack/react-query"]&&i.push("react-query"),n["@tanstack/vue-query"]&&i.push("vue-query"),n.swr&&i.push("swr"),i.length>0?i.join(" + "):null}catch{return null}}async function Bo(e){let t=await e.readFile("package.json"),s=[];if(t)try{let n=JSON.parse(t),i={...n.dependencies||{},...n.devDependencies||{}};(i["@trpc/server"]||i["@trpc/client"])&&s.push("trpc"),(i.graphql||i["@apollo/server"])&&s.push("graphql")}catch{}return e.glob("**/*.proto").length>0&&s.push("grpc"),e.files.some(n=>n.match(/\/api\/.*route\.(ts|js)$/))&&s.push("route-handlers"),e.files.some(n=>n.includes("/routes/")||n.includes("/controllers/"))&&s.push("rest"),e.files.some(n=>n.match(/\/actions?\.(ts|js)$/))&&s.push("server-actions"),s.length>0?s.join(" + "):null}function Jo(e){let t={},s=new Set;for(let i of e.files){let o=i.match(/^src\/([^/]+)\//);o&&s.add(o[1])}for(let i of s){let o=As[i];o&&(t[`src/${i}/`]=o)}let n=new Set;for(let i of e.files){let o=i.match(/^([^/]+)\//);o&&!o[1].startsWith(".")&&o[1]!=="src"&&o[1]!=="node_modules"&&n.add(o[1])}for(let i of n){let o=As[i];o&&!t[`src/${i}/`]&&(t[`${i}/`]=o)}return t}var As,Os,Is=D(()=>{"use strict";As={app:"routes and pages",api:"API routes",pages:"page components",components:"reusable UI components",lib:"shared utilities",utils:"utility functions",helpers:"helper functions",hooks:"React hooks",services:"business logic / services",models:"data models",controllers:"request handlers",middleware:"middleware",routes:"routing",store:"state management",stores:"state stores",types:"type definitions",interfaces:"interface definitions",schemas:"validation schemas",config:"configuration",constants:"constants",assets:"static assets",styles:"stylesheets",tests:"test files",__tests__:"test files",test:"test files",spec:"test specifications",features:"feature modules",modules:"application modules",plugins:"plugin system",providers:"context providers",contexts:"React contexts",commands:"CLI commands",cmd:"CLI commands",cli:"CLI interface",detectors:"detection / analysis modules",scanners:"scanning modules",scanner:"scanning engine",integrations:"third-party integrations",adapters:"adapters / connectors",handlers:"event / request handlers",resolvers:"GraphQL resolvers",guards:"auth / route guards",pipes:"data transform pipes",decorators:"decorators",validators:"validation logic",migrations:"database migrations",seeds:"database seed data",fixtures:"test fixtures",mocks:"test mocks",stubs:"test stubs",github:"GitHub integration",git:"git integration",mcp:"MCP server / protocol",server:"HTTP / API server",client:"client-side code",core:"core business logic",domain:"domain logic",infra:"infrastructure",db:"database layer",database:"database layer",auth:"authentication / authorization",email:"email handling",notifications:"notification system",jobs:"background jobs / workers",workers:"background workers",queues:"job / message queues",events:"event system",shared:"shared / cross-cutting code",common:"common utilities",internal:"internal modules",pkg:"packages / library code",proto:"protobuf definitions",generated:"auto-generated code",scripts:"build / utility scripts",tools:"development tools",docs:"documentation"},Os={name:"patterns",category:"patterns",async detect(e){return{architecture:Go(e),state_management:await Uo(e),api_style:await Bo(e),key_modules:Jo(e)}}}});async function Wo(e){let t=["openapi.json","openapi.yaml","openapi.yml","swagger.json","swagger.yaml","swagger.yml","api-specs/openapi.json","api-specs/openapi.yaml","docs/openapi.json","docs/openapi.yaml","spec/openapi.json","spec/openapi.yaml","api/openapi.json","api/openapi.yaml"];for(let s of t)if(e.fileExists(s)){let n=await e.readFile(s);if(n)try{let i=JSON.parse(n);if(i.openapi||i.swagger)return{version:i.openapi||i.swagger,title:i.info?.title||null,file:s,type:i.openapi?"openapi":"swagger"}}catch{if(n.includes("openapi:")||n.includes("swagger:"))return{version:_t(n,"openapi")||_t(n,"swagger"),title:_t(n,"title"),file:s,type:n.includes("openapi:")?"openapi":"swagger"}}}return null}async function Ko(e){let t=e.files.filter(i=>i.endsWith(".graphql")||i.endsWith(".gql")||i.includes("/graphql/")||i.includes("/schema/"));if(t.length===0)return null;let s=[],n=[];for(let i of t){let o=await e.readFile(i);o&&((o.includes("type Query")||o.includes("type Mutation")||o.includes("type Subscription"))&&s.push(i),(o.includes("Query:")||o.includes("Mutation:")||o.includes("resolver"))&&n.push(i))}return s.length===0&&n.length===0?null:{schema_files:s,resolver_files:n,total_files:t.length}}async function zo(e){let t=e.files.filter(n=>n.endsWith(".proto"));if(t.length===0)return null;let s=[];for(let n of t){let i=await e.readFile(n);i&&i.includes("service ")&&s.push(n)}return{proto_files:t,service_definitions:s}}async function Vo(e){let t=e.files.filter(n=>n.includes("postman")&&(n.endsWith(".json")||n.endsWith(".json.backup")));if(t.length===0)return null;let s=[];for(let n of t){let i=await e.readFile(n);if(i)try{let o=JSON.parse(i);o.info?.schema?.includes("postman")&&s.push({file:n,name:o.info?.name||null})}catch{}}return s.length===0?null:{collections:s}}function _t(e,t){let s=new RegExp(`^${t}:\\s*(.+)$`,"m"),n=e.match(s);return n?n[1].trim():null}var Ns,Ls=D(()=>{"use strict";Ns={name:"api-docs",category:"config",async detect(e){let[t,s,n,i]=await Promise.all([Wo(e),Ko(e),zo(e),Vo(e)]);return{openapi:t,graphql:s,grpc:n,postman:i}}}});var Rt,Fs=D(()=>{"use strict";ps();ms();hs();ks();vs();Ss();Es();Rs();Ds();Is();Ls();Rt=[ds,fs,gs,ys,ws,js,Cs,_s,Ps,Os,Ns]});function L(e,t){return e?String(e).slice(0,t):""}var Pt=D(()=>{"use strict"});import{execFile as Ms}from"child_process";async function Me(e,t,s={}){return new Promise(n=>{let i=["api","graphql","-f",`query=${t}`,"-H","Accept: application/vnd.github.v3+json"];for(let[o,r]of Object.entries(s))i.push("-f",`${o}=${JSON.stringify(r)}`);Ms("gh",i,{cwd:e,timeout:3e4},(o,r,a)=>{if(o){n(null);return}try{let c=JSON.parse(r.trim());if(c.errors&&c.errors.length>0){n(null);return}n(c.data||null)}catch{n(null)}})})}function tr(e){let t=[/github\.com[:/]([^/]+)\/(.+?)(\.git)?$/,/github\.com[:/]([^/]+)\/(.+)$/];for(let s of t){let n=e.match(s);if(n)return{owner:n[1],repo:n[2].replace(/\.git$/,"")}}return null}function sr(e){let t=e.labels?.nodes||[],s=e.assignees?.nodes||[],n=e.milestone,i=e.reactions||{},o=e.comments,r=e.timelineItems;return{number:e.number,title:L(e.title,200),state:e.state?.toLowerCase()==="open"?"open":"closed",url:e.url||void 0,labels:t.map(a=>L(a.name,50)).filter(Boolean),assignee:L(s[0]?.login,100)||null,milestone:n?.title||null,created_at:e.createdAt,updated_at:e.updatedAt,comments_count:o?.totalCount||0,reactions:{thumbs_up:i.thumbsUp||0,thumbs_down:i.thumbsDown||0,laugh:i.laugh||0,hooray:i.hooray||0,confused:i.confused||0,heart:i.heart||0,rocket:i.rocket||0,eyes:i.eyes||0},timeline_events:r?.totalCount||0,body:L(e.body||"",2e3)}}function nr(e){let t=e.labels?.nodes||[],s=e.reviewRequests?.nodes||[],n=e.author,i=e.statusCheckRollup,o=e.comments,r;if(i?.state){let l=i.state.toLowerCase();l==="success"||l==="completed"?r="passing":l==="failure"||l==="error"?r="failing":r="pending"}let a=e.mergeable==="MERGEABLE",c=e.mergeable==="CONFLICTING";return{number:e.number,title:L(e.title,200),state:(e.state||"open").toLowerCase(),url:e.url||void 0,author:L(n?.login,100)||"unknown",branch:L(e.headRefName,200),labels:t.map(l=>L(l.name,50)).filter(Boolean),reviewers:s.map(l=>L(l.requestedReviewer?.login,100)).filter(Boolean),created_at:e.createdAt,updated_at:e.updatedAt,checks_status:r,mergeable:a,merge_conflicts:c,additions:e.additions||0,deletions:e.deletions||0,comments_count:o?.totalCount||0,review_decision:e.reviewDecision?.toLowerCase()==="approved"?"approved":e.reviewDecision?.toLowerCase()==="changes_requested"?"changes_requested":e.reviewDecision?.toLowerCase()==="review_required"?"review_required":null}}async function Ts(e,t,s={}){let{includeIssues:n=!0,includePRs:i=!0,includeMilestones:o=!0,includeReleases:r=!0,includeProjects:a=!0,limit:c=50}=s,l=tr(t);if(!l)return{};let{owner:p,repo:d}=l,m={},[y,b,x,j,E]=await Promise.all([n?Me(e,Qo,{owner:p,repo:d,limit:c}).catch(f=>(R(`GitHub issues query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),i?Me(e,Yo,{owner:p,repo:d,limit:Math.min(c,30)}).catch(f=>(R(`GitHub pull requests query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),o?Me(e,Xo,{owner:p,repo:d}).catch(f=>(R(`GitHub milestones query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),r?Me(e,Zo,{owner:p,repo:d,limit:10}).catch(f=>(R(`GitHub releases query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),a?Me(e,er,{owner:p,repo:d}).catch(f=>(R(`GitHub projects query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null)]);return y?.repository?.issues?.nodes&&(m.issues=y.repository.issues.nodes.map(sr)),b?.repository?.pullRequests?.nodes&&(m.pull_requests=b.repository.pullRequests.nodes.map(nr)),x?.repository?.milestones?.nodes&&(m.milestones=x.repository.milestones.nodes.map(f=>{let P=f.issues?.nodes||[],A=f.closedIssues?.totalCount||0,G=f.issues?.totalCount||P.length,_=G-A;return{title:f.title,description:f.description||"",due_date:f.dueOn||null,progress:{open:_,closed:A,percent:G>0?Math.round(A/G*100):0},issues:P.map(U=>U.number)}})),j?.repository?.releases?.nodes&&(m.releases=j.repository.releases.nodes.map(f=>({tag_name:f.tagName,name:f.name||f.tagName,created_at:f.createdAt,url:f.url,author:f.author?.login||"unknown",prerelease:!!f.isPrerelease}))),E?.repository?.projectsV2?.nodes&&(m.project_boards=E.repository.projectsV2.nodes.filter(f=>f!==null).map(f=>{let P=f.columns?.nodes||[],A=f.items?.totalCount||0;return{number:f.number,title:f.title,state:(f.state||"open").toLowerCase(),url:f.url,columns:P.map(G=>({name:G.name,cards_count:A}))}})),m}async function qs(e){return new Promise(t=>{Ms("gh",["--version"],{cwd:e,timeout:5e3},(s,n)=>{if(s){t(!1);return}let i=n.match(/gh version (\d+)\.(\d+)/);if(i){let o=parseInt(i[1],10),r=parseInt(i[2],10);t(o>2||o===2&&r>=0)}else t(!1)})})}var Qo,Yo,Xo,Zo,er,Hs=D(()=>{"use strict";M();Pt();Qo=`
|
|
17
|
+
`+(n||"");if(!i.trim())return{direct_count:0,dev_count:0,notable:[]};let o=[],r=[],a=/<artifactId>([^<]+)<\/artifactId>/g,c;for(;(c=a.exec(i))!==null;)o.push(c[1]),ve.has(c[1])&&r.push(c[1]);let l=/(?:implementation|compile|api)\s+['"]([^:'"]+)/g;for(;(c=l.exec(i))!==null;){let p=c[1].split(":").pop();p&&(o.push(p),ve.has(p)&&r.push(p))}return{direct_count:[...new Set(o)].length,dev_count:0,notable:[...new Set(r)].sort()}}async function So(e){let t=e.files.filter(i=>i.endsWith(".csproj"));if(t.length===0)return{direct_count:0,dev_count:0,notable:[]};let s=[],n=[];for(let i of t){let o=await e.readFile(i),r=/<PackageReference\s+Include="([^"]+)"/g,a;for(;(a=r.exec(o))!==null;){s.push(a[1]);let c=a[1].split(".")[0].toLowerCase();ve.has(c)&&n.push(a[1])}}return{direct_count:[...new Set(s)].length,dev_count:0,notable:[...new Set(n)].sort()}}function Co(e){return e.fileExists("pnpm-lock.yaml")?"pnpm-lock.yaml":e.fileExists("yarn.lock")?"yarn.lock":e.fileExists("package-lock.json")?"package-lock.json":e.fileExists("bun.lockb")||e.fileExists("bun.lock")?"bun.lock":e.fileExists("Cargo.lock")?"Cargo.lock":e.fileExists("poetry.lock")?"poetry.lock":e.fileExists("Pipfile.lock")?"Pipfile.lock":e.fileExists("uv.lock")?"uv.lock":e.fileExists("go.sum")?"go.sum":e.fileExists("Gemfile.lock")?"Gemfile.lock":e.fileExists("composer.lock")?"composer.lock":e.fileExists(".mvn/jvm.config")?"maven":e.fileExists(".gradle")?"gradle":e.fileExists("Package.resolved")?"swift":e.fileExists("pubspec.lock")?"pubspec.lock":e.fileExists("mix.lock")?"mix.lock":e.fileExists("project/target/resolution-cache")?"sbt":e.fileExists("packages.lock.json")?"nuget":null}var ve,$s,ho,bo,js,Ss=P(()=>{"use strict";ve=new Set(["next","react","vue","angular","svelte","nuxt","remix","astro","gatsby","express","fastify","hono","nestjs","koa","solid","solid-js","qwik","prisma","@prisma/client","drizzle-orm","typeorm","sequelize","mongoose","knex","zustand","redux","@reduxjs/toolkit","mobx","jotai","recoil","pinia","vuex","@tanstack/react-query","@swr/core","react-query","zod","joi","yup","ajv","class-validator","@trpc/server","graphql","apollo-server","@apollo/client","graphql-yoga","jest","vitest","mocha","playwright","@playwright/test","cypress","msw","webpack","vite","esbuild","rollup","turbo","nx","tsup","unbuild","pkgroll","tailwindcss","styled-components","@emotion/react","@chakra-ui/react","@mui/material","@mantine/core","next-auth","@auth/core","passport","jsonwebtoken","lucia-auth","@vercel/node","@netlify/functions","serverless","sst","fastapi","django","flask","starlette","tornado","aiohttp","sqlalchemy","alembic","pydantic","typer","click","pytest","black","ruff","mypy","pylint","celery","redis","pymongo","psycopg2","numpy","pandas","torch","tensorflow","scikit-learn","gin-gonic","gorilla/mux","go-chi/chi","labstack/echo","gofiber/fiber","gorm","sqlx","lib/pq","go-redis","testify","stretchr","grpc","protobuf","cobra","actix-web","axum","rocket","warp","tokio","serde","diesel","sqlx","sea-orm","clap","anyhow","thiserror","tracing","rails","sinatra","grape","hanami","roda","activerecord","pg","mysql2","redis","sidekiq","rspec","rubocop","pry","byebug","laravel","symfony","slim","guzzlehttp","illuminate","doctrine/orm","ramsey/uuid","phpunit","mockery","spring-boot","spring-framework","micronaut","quarkus","hibernate","jakarta.persistence","junit","mockito","testng","Microsoft.AspNetCore","EntityFramework","Newtonsoft","NUnit","xUnit","Moq","docker","typescript","kubernetes"]),$s=new Set(["django","flask","fastapi","starlette","tornado","aiohttp","sqlalchemy","alembic","pydantic","celery","redis","pytest","numpy","pandas","scipy","scikit-learn","tensorflow","torch","transformers","langchain","requests","httpx","boto3"]),ho=new Set(["serde","tokio","axum","actix-web","rocket","warp","hyper","sqlx","diesel","sea-orm","clap","tracing","anyhow","thiserror","reqwest","tonic","prost"]),bo=new Set(["gin","echo","fiber","chi","mux","gorm","sqlx","cobra","viper","zap","testify","grpc","protobuf","wire"]),js={name:"dependencies",category:"dependencies",async detect(e){let t=Co(e),s=await e.readFile("package.json");if(s)try{let d=JSON.parse(s),m=d.dependencies||{},y=d.devDependencies||{},b={...m,...y},j=Object.keys(b).filter(x=>ve.has(x)).sort();return{direct_count:Object.keys(m).length,dev_count:Object.keys(y).length,lock_file:t,notable:j}}catch{}let n=await e.readFile("pyproject.toml");if(n){let d=yo(n);if(d){let m=rt([...d.direct,...d.dev],$s);return{direct_count:d.direct.length,dev_count:d.dev.length,lock_file:t,notable:m}}}let i=await e.readFile("requirements.txt");if(i){let d=ko(i),m=rt(d,$s);return{direct_count:d.length,dev_count:0,lock_file:t,notable:m}}let o=await e.readFile("Cargo.toml");if(o){let d=wo(o),m=rt([...d.direct,...d.dev],ho);return{direct_count:d.direct.length,dev_count:d.dev.length,lock_file:t,notable:m}}let r=await e.readFile("go.mod");if(r){let d=vo(r),m=d.map(b=>b.split("/").pop()),y=rt(m,bo);return{direct_count:d.length,dev_count:0,lock_file:t,notable:y}}let a=await $o(e);if(a.direct_count>0)return{...a,lock_file:t};let c=await xo(e);if(c.direct_count>0)return{...c,lock_file:t};let l=await jo(e);if(l.direct_count>0)return{...l,lock_file:t};let p=await So(e);return p.direct_count>0?{...p,lock_file:t}:{direct_count:0,dev_count:0,lock_file:t,notable:[]}}}});async function Ro(e){let t=await e.readFile("package.json");if(!t)return null;try{let s=JSON.parse(t),n={...s.dependencies||{},...s.devDependencies||{}};for(let[i,o]of Object.entries(_o))if(n[i])return o}catch{}return null}async function Po(e){let t={},s=await e.readFile(".env.example");s&&ct(s,t,!1);let n=await e.readFile(".env");n&&ct(n,t,!0);let i=await e.readFile(".env.sample");i&&ct(i,t,!1);let o=await e.readFile(".env.template");return o&&ct(o,t,!1),t}function ct(e,t,s){let n=e.split(`
|
|
18
|
+
`),i="";for(let o of n){let r=o.trim();if(!r)continue;if(r.startsWith("#")){i+=(i?" ":"")+r.slice(1).trim();continue}let a=r.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(a){let[,c,l]=a,p=l==='""'||l==="''"||l==="";t[c]={description:i||void 0,required:s||p},i=""}}}var Eo,_o,Cs,Es=P(()=>{"use strict";Eo=["tsconfig.json","jsconfig.json","tsup.config.ts","tsup.config.js","next.config.js","next.config.mjs","next.config.ts","vite.config.ts","vite.config.js","vite.config.mjs","webpack.config.js","webpack.config.ts","rollup.config.js","rollup.config.mjs","esbuild.config.js","esbuild.config.mjs","turbo.json","nx.json","tailwind.config.js","tailwind.config.ts","tailwind.config.mjs","postcss.config.js","postcss.config.mjs","postcss.config.ts","babel.config.js","babel.config.json",".babelrc","swc.config.json",".swcrc","jest.config.js","jest.config.ts","vitest.config.ts","vitest.config.js","vitest.config.mts","playwright.config.ts","playwright.config.js","cypress.config.ts","cypress.config.js",".prettierrc",".prettierrc.js",".prettierrc.json","prettier.config.js","prettier.config.mjs",".eslintrc.js",".eslintrc.json",".eslintrc.yml","eslint.config.js","eslint.config.mjs","eslint.config.ts","biome.json","biome.jsonc","dprint.json",".editorconfig","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml","Dockerfile","fly.toml","render.yaml","vercel.json","netlify.toml","pyproject.toml","setup.cfg","setup.py","tox.ini","ruff.toml",".ruff.toml","go.mod","Cargo.toml","Gemfile","composer.json","Makefile","Taskfile.yml",".nvmrc",".node-version",".python-version",".ruby-version",".tool-versions"],_o={"launchdarkly-node-server-sdk":"launchdarkly","@unleash/proxy-client-react":"unleash",flagsmith:"flagsmith","@growthbook/growthbook-react":"growthbook"},Cs={name:"config",category:"config",async detect(e){let t=e.files.filter(o=>o.match(/^\.env(\..+)?$/)||o.match(/^\.env\./)),s=Eo.filter(o=>e.fileExists(o)),n=await Ro(e),i=await Po(e);return{env_files:t,config_files:s,feature_flags:n,env_vars:i}}}});async function Do(e){let t=await e.exec("git",["log","--oneline","-5","--format=%s"]);return t?t.split(`
|
|
19
|
+
`).filter(Boolean):[]}async function Ao(e){let t=await e.exec("git",["shortlog","-sn","--no-merges","-5"]);return t?t.split(`
|
|
20
|
+
`).map(s=>s.replace(/^\s*\d+\s+/,"").trim()).filter(Boolean):[]}async function Oo(e){return(await e.exec("git",["status","--porcelain"])).length>0}var _s,Rs=P(()=>{"use strict";_s={name:"git",category:"git",async detect(e){let[t,s,n]=await Promise.all([Do(e),Ao(e),Oo(e)]);return{recent_commits:t,last_committers:s,uncommitted_changes:n}}}});async function Io(e){if(e.glob("vitest.config.*").length>0)return"vitest";if(e.glob("jest.config.*").length>0)return"jest";if(e.fileExists(".mocharc.yml")||e.fileExists(".mocharc.json"))return"mocha";if(e.glob("playwright.config.*").length>0)return"playwright";if(e.glob("cypress.config.*").length>0)return"cypress";let t=await e.readFile("package.json");if(t)try{let s=JSON.parse(t),n={...s.dependencies||{},...s.devDependencies||{}},o=(s.scripts||{}).test||"";if(n.vitest||o.includes("vitest"))return"vitest";if(n.jest||o.includes("jest"))return"jest";if(n.mocha||o.includes("mocha"))return"mocha";if(n["@playwright/test"]||o.includes("playwright"))return"playwright";if(n.cypress)return"cypress";if(n.ava)return"ava";if(n.tap)return"tap"}catch{}if(e.fileExists("pytest.ini")||e.fileExists("pyproject.toml")||e.fileExists("setup.cfg")||e.fileExists("tox.ini")){let s=await e.readFile("pyproject.toml"),n=await e.readFile("setup.cfg"),i=await e.readFile("pytest.ini");if(s?.includes("pytest")||n?.includes("pytest")||i||e.files.some(o=>o.includes("test_")||o.includes("_test.py")))return"pytest";if(s?.includes("unittest")||n?.includes("unittest"))return"unittest";if(s?.includes("nose"))return"nose"}if(e.files.some(s=>s.endsWith("_test.go")))return"go test";if(e.files.some(s=>s.includes("/tests/")||s.startsWith("tests/")||s.endsWith("tests.rs")||s.match(/mod\s+tests/)))return"cargo test";if(e.fileExists("spec/spec_helper.rb")||e.fileExists(".rspec")||e.files.some(s=>s.includes("/spec/")&&s.endsWith("_spec.rb")))return"rspec";if(e.fileExists("test/minitest_helper.rb"))return"minitest";if(e.files.some(s=>s.endsWith("Test.java")||s.endsWith("Tests.java")))return"junit";if(e.fileExists("pom.xml")){let s=await e.readFile("pom.xml");if(s?.includes("junit")||s?.includes("testng"))return s?.includes("testng")?"testng":"junit"}if(e.fileExists("phpunit.xml")||e.fileExists("phpunit.xml.dist")||e.files.some(s=>s.includes("tests/")&&s.endsWith(".php")))return"phpunit";if(e.files.some(s=>s.endsWith("Test.cs")||s.endsWith("Tests.cs")))return"nunit";if(e.fileExists("build.sbt")){let s=await e.readFile("build.sbt");if(s?.includes("scalatest"))return"scalatest";if(s?.includes("specs2"))return"specs2"}return e.files.some(s=>s.endsWith("Tests.swift")||s.endsWith("XCTest.swift"))?"xctest":null}async function No(e){if(e.fileExists("eslint.config.js")||e.fileExists("eslint.config.mjs")||e.fileExists("eslint.config.ts")||e.glob(".eslintrc*").length>0)return"eslint";if(e.fileExists("biome.json")||e.fileExists("biome.jsonc"))return"biome";if(e.fileExists("ruff.toml")||e.fileExists(".ruff.toml"))return"ruff";if(e.fileExists(".pylintrc")||e.fileExists("pylintrc"))return"pylint";if(e.fileExists(".flake8")||e.fileExists("setup.cfg")||e.fileExists(".flake8rc"))return"flake8";if(e.fileExists(".golangci.yml")||e.fileExists(".golangci.yaml")||e.fileExists(".golangci-lint.yml"))return"golangci-lint";if(e.fileExists("clippy.toml"))return"clippy";if(e.fileExists(".rubocop.yml")||e.fileExists(".rubocop.yaml"))return"rubocop";if(e.fileExists(".php_cs")||e.fileExists("phpstan.neon")||e.fileExists("phpunit.xml"))return"php-cs-fixer";if(e.fileExists("psalm.xml"))return"psalm";if(e.fileExists(".swiftlint.yml")||e.fileExists(".swiftlint.yaml"))return"swiftlint";if(e.fileExists(".kotlinlint.xml"))return"ktlint";if(e.fileExists("detekt.yml")||e.fileExists("detekt.yaml"))return"detekt";if(e.fileExists("checkstyle.xml"))return"checkstyle";if(e.fileExists("pmd.xml"))return"pmd";if(e.fileExists(".scalafix.conf"))return"scalafix";let t=await e.readFile("pyproject.toml");if(t){if(t.includes("ruff"))return"ruff";if(t.includes("pylint"))return"pylint";if(t.includes("flake8"))return"flake8";if(t.includes("mypy"))return"mypy";if(t.includes("black"))return"black"}let s=await e.readFile("package.json");if(s)try{let i=JSON.parse(s),o={...i.dependencies||{},...i.devDependencies||{}},a=(i.scripts||{}).lint||"";if(o.eslint||a.includes("eslint"))return"eslint";if(o["@biomejs/biome"]||a.includes("biome"))return"biome";if(o.oxlint||a.includes("oxlint"))return"oxlint";if(o.standard)return"standard";if(o.xo)return"xo";if(o["@typescript-eslint/eslint-plugin"])return"eslint";if(o.dprint)return"dprint"}catch{}return e.fileExists("golangci-lint.yml")||e.fileExists(".golangci.yml")?"golangci-lint":(await e.readFile("Cargo.toml"))?.includes("clippy")?"clippy":e.fileExists(".rubocop.yml")?"rubocop":e.fileExists("phpstan.neon")?"phpstan":e.fileExists("ecs.php")||e.fileExists("easy-coding-standard.yml")?"ecs":null}async function Lo(e){if(e.glob(".prettierrc*").length>0||e.fileExists("prettier.config.js")||e.fileExists("prettier.config.mjs")||e.fileExists("prettier.config.cjs")||e.fileExists("prettier.config.ts"))return"prettier";if(e.fileExists("biome.json")||e.fileExists("biome.jsonc"))return"biome";if(e.fileExists("ruff.toml")||e.fileExists(".ruff.toml"))return"ruff";if(e.fileExists("rustfmt.toml")||e.fileExists(".rustfmt.toml"))return"rustfmt";if(e.fileExists("dprint.json")||e.fileExists("dprint.jsonc"))return"dprint";if(e.fileExists(".editorconfig"))return"editorconfig";if(e.fileExists(".gofmt")||e.fileExists("gofmt.toml"))return"gofmt";if(e.fileExists(".scalafmt.conf"))return"scalafmt";if(e.fileExists(".black")||e.fileExists("pyproject.toml"))return"black";if(e.fileExists(".isort.cfg")||e.fileExists("pyproject.toml"))return"isort";if(e.fileExists(".swiftformat"))return"swiftformat";if(e.fileExists(".php-cs-fixer.php")||e.fileExists(".php-cs-fixer.dist.php"))return"php-cs-fixer";if(e.fileExists(".rubocop.yml"))return"rubocop";if(e.fileExists("prettier.config.ts")||e.fileExists(".prettierignore"))return"prettier";let t=await e.readFile("pyproject.toml");if(t){if(t.includes("black"))return"black";if(t.includes("isort"))return"isort";if(t.includes("autopep8"))return"autopep8";if(t.includes("yapf"))return"yapf"}let s=await e.readFile("package.json");if(s)try{let n=JSON.parse(s),i={...n.dependencies||{},...n.devDependencies||{}},o=n.scripts||{},r=(o.format||"")+(o.fmt||"");if(i.prettier||r.includes("prettier"))return"prettier";if(i["@biomejs/biome"]||r.includes("biome"))return"biome";if(i.dprint)return"dprint"}catch{}return e.fileExists(".gofmtrc")||e.fileExists("gofmt.toml")?"gofmt":e.fileExists("rustfmt.toml")?"rustfmt":e.fileExists(".rubocop.yml")?"rubocop":e.fileExists(".swiftformat")?"swiftformat":e.fileExists(".scalafmt.conf")?"scalafmt":null}function Fo(e){return e.files.some(t=>t.startsWith(".github/workflows/"))?"github-actions":e.fileExists(".gitlab-ci.yml")||e.fileExists(".gitlab-ci.yaml")?"gitlab-ci":e.fileExists("Jenkinsfile")||e.fileExists("Jenkinsfile")?"jenkins":e.files.some(t=>t.startsWith(".circleci/"))?"circleci":e.fileExists("bitbucket-pipelines.yml")?"bitbucket-pipelines":e.fileExists(".travis.yml")?"travis-ci":e.fileExists("azure-pipelines.yml")||e.fileExists("azure-pipelines.yaml")?"azure-pipelines":e.fileExists("buildspec.yml")?"aws-codebuild":e.fileExists("cloudbuild.yaml")||e.fileExists("cloudbuild.yml")?"google-cloud-build":e.fileExists(".drone.yml")?"drone-ci":e.fileExists("workflow.yml")?"gsuite-actions":e.fileExists("now.json")||e.fileExists(".vercelignore")?"vercel":e.fileExists("netlify.toml")?"netlify":e.fileExists(".github/workflows/ci.yml")||e.fileExists(".github/workflows/cd.yml")?"github-actions":e.fileExists("procfile")||e.fileExists("Procfile")?"heroku":e.fileExists("appveyor.yml")?"appveyor":e.fileExists("codeship-services.yml")||e.fileExists("codeship-steps.yml")?"codeship":e.fileExists("semantic.yml")?"semantic-release":e.fileExists(".rerun.yaml")||e.fileExists(".rerun.yml")?"rerun":e.fileExists("woodpecker.yml")?"woodpecker-ci":e.fileExists(".forgejo")?"forgejo":null}function Mo(e){return!!(e.files.some(t=>t.startsWith(".husky/"))||e.fileExists(".pre-commit-config.yaml")||e.fileExists(".pre-commit-config.yml")||e.fileExists(".lintstagedrc")||e.fileExists("lint-staged.config.js")||e.fileExists("lint-staged.config.mjs")||e.fileExists("lint-staged.config.ts")||e.fileExists("lefthook.yml")||e.fileExists("lefthook.yaml")||e.fileExists("lefthook-local.yml")||e.fileExists(".git/hooks/pre-commit")||e.fileExists(".simple-git-hooks.cjs")||e.fileExists(".simple-git-hooks.js")||e.fileExists(".yorkielerc")||e.fileExists(".yorkie")||e.fileExists(".huskyrc")||e.fileExists(".huskyrc.json")||e.fileExists(".huskyrc.js")||e.fileExists(".pre-commit-hook.json"))}var Ps,Ds=P(()=>{"use strict";Ps={name:"quality",category:"quality",async detect(e){let[t,s,n]=await Promise.all([Io(e),No(e),Lo(e)]);return{test_framework:t,linter:s,formatter:n,ci:Fo(e),pre_commit_hooks:Mo(e)}}}});function To(e){return e.files.some(t=>t.match(/^(src\/)?app\/layout\.(tsx?|jsx?)$/))?"app-router":e.files.some(t=>t.match(/^(src\/)?pages\/_app\./))?"pages-router":e.files.some(t=>t.includes("/controllers/"))&&e.files.some(t=>t.includes("/models/"))?"mvc":e.files.some(t=>t.startsWith("src/features/"))?"feature-sliced":e.files.some(t=>t.startsWith("src/modules/"))?"modular":e.files.some(t=>t.includes("/services/"))&&e.files.some(t=>t.includes("/repositories/"))?"layered":e.files.some(t=>t.startsWith("src/routes/"))?"file-based-routing":e.files.some(t=>t.startsWith("src/commands/")||t.startsWith("cmd/"))?"command-based":e.files.some(t=>t.startsWith("src/detectors/")||t.startsWith("src/plugins/"))?"plugin-based":e.files.some(t=>t.includes("/domain/"))&&e.files.some(t=>t.includes("/infra/")||t.includes("/infrastructure/"))?"hexagonal":e.files.some(t=>t.includes("/services/"))&&e.files.some(t=>t.includes("/handlers/")||t.includes("/controllers/"))?"layered":e.files.some(t=>t.match(/^internal\/.+\/.+/))?"package-per-feature":null}async function qo(e){let t=await e.readFile("package.json");if(!t)return null;try{let s=JSON.parse(t),n={...s.dependencies||{},...s.devDependencies||{}},i=[];return n.zustand&&i.push("zustand"),(n["@reduxjs/toolkit"]||n.redux)&&i.push("redux"),n.mobx&&i.push("mobx"),n.jotai&&i.push("jotai"),n.recoil&&i.push("recoil"),n.pinia&&i.push("pinia"),n.vuex&&i.push("vuex"),n["@tanstack/react-query"]&&i.push("react-query"),n["@tanstack/vue-query"]&&i.push("vue-query"),n.swr&&i.push("swr"),i.length>0?i.join(" + "):null}catch{return null}}async function Ho(e){let t=await e.readFile("package.json"),s=[];if(t)try{let n=JSON.parse(t),i={...n.dependencies||{},...n.devDependencies||{}};(i["@trpc/server"]||i["@trpc/client"])&&s.push("trpc"),(i.graphql||i["@apollo/server"])&&s.push("graphql")}catch{}return e.glob("**/*.proto").length>0&&s.push("grpc"),e.files.some(n=>n.match(/\/api\/.*route\.(ts|js)$/))&&s.push("route-handlers"),e.files.some(n=>n.includes("/routes/")||n.includes("/controllers/"))&&s.push("rest"),e.files.some(n=>n.match(/\/actions?\.(ts|js)$/))&&s.push("server-actions"),s.length>0?s.join(" + "):null}function Go(e){let t={},s=new Set;for(let i of e.files){let o=i.match(/^src\/([^/]+)\//);o&&s.add(o[1])}for(let i of s){let o=As[i];o&&(t[`src/${i}/`]=o)}let n=new Set;for(let i of e.files){let o=i.match(/^([^/]+)\//);o&&!o[1].startsWith(".")&&o[1]!=="src"&&o[1]!=="node_modules"&&n.add(o[1])}for(let i of n){let o=As[i];o&&!t[`src/${i}/`]&&(t[`${i}/`]=o)}return t}var As,Os,Is=P(()=>{"use strict";As={app:"routes and pages",api:"API routes",pages:"page components",components:"reusable UI components",lib:"shared utilities",utils:"utility functions",helpers:"helper functions",hooks:"React hooks",services:"business logic / services",models:"data models",controllers:"request handlers",middleware:"middleware",routes:"routing",store:"state management",stores:"state stores",types:"type definitions",interfaces:"interface definitions",schemas:"validation schemas",config:"configuration",constants:"constants",assets:"static assets",styles:"stylesheets",tests:"test files",__tests__:"test files",test:"test files",spec:"test specifications",features:"feature modules",modules:"application modules",plugins:"plugin system",providers:"context providers",contexts:"React contexts",commands:"CLI commands",cmd:"CLI commands",cli:"CLI interface",detectors:"detection / analysis modules",scanners:"scanning modules",scanner:"scanning engine",integrations:"third-party integrations",adapters:"adapters / connectors",handlers:"event / request handlers",resolvers:"GraphQL resolvers",guards:"auth / route guards",pipes:"data transform pipes",decorators:"decorators",validators:"validation logic",migrations:"database migrations",seeds:"database seed data",fixtures:"test fixtures",mocks:"test mocks",stubs:"test stubs",github:"GitHub integration",git:"git integration",mcp:"MCP server / protocol",server:"HTTP / API server",client:"client-side code",core:"core business logic",domain:"domain logic",infra:"infrastructure",db:"database layer",database:"database layer",auth:"authentication / authorization",email:"email handling",notifications:"notification system",jobs:"background jobs / workers",workers:"background workers",queues:"job / message queues",events:"event system",shared:"shared / cross-cutting code",common:"common utilities",internal:"internal modules",pkg:"packages / library code",proto:"protobuf definitions",generated:"auto-generated code",scripts:"build / utility scripts",tools:"development tools",docs:"documentation"},Os={name:"patterns",category:"patterns",async detect(e){return{architecture:To(e),state_management:await qo(e),api_style:await Ho(e),key_modules:Go(e)}}}});async function Uo(e){let t=["openapi.json","openapi.yaml","openapi.yml","swagger.json","swagger.yaml","swagger.yml","api-specs/openapi.json","api-specs/openapi.yaml","docs/openapi.json","docs/openapi.yaml","spec/openapi.json","spec/openapi.yaml","api/openapi.json","api/openapi.yaml"];for(let s of t)if(e.fileExists(s)){let n=await e.readFile(s);if(n)try{let i=JSON.parse(n);if(i.openapi||i.swagger)return{version:i.openapi||i.swagger,title:i.info?.title||null,file:s,type:i.openapi?"openapi":"swagger"}}catch{if(n.includes("openapi:")||n.includes("swagger:"))return{version:_t(n,"openapi")||_t(n,"swagger"),title:_t(n,"title"),file:s,type:n.includes("openapi:")?"openapi":"swagger"}}}return null}async function Bo(e){let t=e.files.filter(i=>i.endsWith(".graphql")||i.endsWith(".gql")||i.includes("/graphql/")||i.includes("/schema/"));if(t.length===0)return null;let s=[],n=[];for(let i of t){let o=await e.readFile(i);o&&((o.includes("type Query")||o.includes("type Mutation")||o.includes("type Subscription"))&&s.push(i),(o.includes("Query:")||o.includes("Mutation:")||o.includes("resolver"))&&n.push(i))}return s.length===0&&n.length===0?null:{schema_files:s,resolver_files:n,total_files:t.length}}async function Jo(e){let t=e.files.filter(n=>n.endsWith(".proto"));if(t.length===0)return null;let s=[];for(let n of t){let i=await e.readFile(n);i&&i.includes("service ")&&s.push(n)}return{proto_files:t,service_definitions:s}}async function Wo(e){let t=e.files.filter(n=>n.includes("postman")&&(n.endsWith(".json")||n.endsWith(".json.backup")));if(t.length===0)return null;let s=[];for(let n of t){let i=await e.readFile(n);if(i)try{let o=JSON.parse(i);o.info?.schema?.includes("postman")&&s.push({file:n,name:o.info?.name||null})}catch{}}return s.length===0?null:{collections:s}}function _t(e,t){let s=new RegExp(`^${t}:\\s*(.+)$`,"m"),n=e.match(s);return n?n[1].trim():null}var Ns,Ls=P(()=>{"use strict";Ns={name:"api-docs",category:"config",async detect(e){let[t,s,n,i]=await Promise.all([Uo(e),Bo(e),Jo(e),Wo(e)]);return{openapi:t,graphql:s,grpc:n,postman:i}}}});var Rt,Fs=P(()=>{"use strict";ps();ms();hs();ks();vs();Ss();Es();Rs();Ds();Is();Ls();Rt=[ds,fs,gs,ys,ws,js,Cs,_s,Ps,Os,Ns]});function N(e,t){return e?String(e).slice(0,t):""}var Pt=P(()=>{"use strict"});import{execFile as Ms}from"child_process";async function Me(e,t,s={}){return new Promise(n=>{let i=["api","graphql","-f",`query=${t}`,"-H","Accept: application/vnd.github.v3+json"];for(let[o,r]of Object.entries(s))i.push("-f",`${o}=${JSON.stringify(r)}`);Ms("gh",i,{cwd:e,timeout:3e4},(o,r,a)=>{if(o){n(null);return}try{let c=JSON.parse(r.trim());if(c.errors&&c.errors.length>0){n(null);return}n(c.data||null)}catch{n(null)}})})}function Xo(e){let t=[/github\.com[:/]([^/]+)\/(.+?)(\.git)?$/,/github\.com[:/]([^/]+)\/(.+)$/];for(let s of t){let n=e.match(s);if(n)return{owner:n[1],repo:n[2].replace(/\.git$/,"")}}return null}function Zo(e){let t=e.labels?.nodes||[],s=e.assignees?.nodes||[],n=e.milestone,i=e.reactions||{},o=e.comments,r=e.timelineItems;return{number:e.number,title:N(e.title,200),state:e.state?.toLowerCase()==="open"?"open":"closed",url:e.url||void 0,labels:t.map(a=>N(a.name,50)).filter(Boolean),assignee:N(s[0]?.login,100)||null,milestone:n?.title||null,created_at:e.createdAt,updated_at:e.updatedAt,comments_count:o?.totalCount||0,reactions:{thumbs_up:i.thumbsUp||0,thumbs_down:i.thumbsDown||0,laugh:i.laugh||0,hooray:i.hooray||0,confused:i.confused||0,heart:i.heart||0,rocket:i.rocket||0,eyes:i.eyes||0},timeline_events:r?.totalCount||0,body:N(e.body||"",2e3)}}function er(e){let t=e.labels?.nodes||[],s=e.reviewRequests?.nodes||[],n=e.author,i=e.statusCheckRollup,o=e.comments,r;if(i?.state){let l=i.state.toLowerCase();l==="success"||l==="completed"?r="passing":l==="failure"||l==="error"?r="failing":r="pending"}let a=e.mergeable==="MERGEABLE",c=e.mergeable==="CONFLICTING";return{number:e.number,title:N(e.title,200),state:(e.state||"open").toLowerCase(),url:e.url||void 0,author:N(n?.login,100)||"unknown",branch:N(e.headRefName,200),labels:t.map(l=>N(l.name,50)).filter(Boolean),reviewers:s.map(l=>N(l.requestedReviewer?.login,100)).filter(Boolean),created_at:e.createdAt,updated_at:e.updatedAt,checks_status:r,mergeable:a,merge_conflicts:c,additions:e.additions||0,deletions:e.deletions||0,comments_count:o?.totalCount||0,review_decision:e.reviewDecision?.toLowerCase()==="approved"?"approved":e.reviewDecision?.toLowerCase()==="changes_requested"?"changes_requested":e.reviewDecision?.toLowerCase()==="review_required"?"review_required":null}}async function Ts(e,t,s={}){let{includeIssues:n=!0,includePRs:i=!0,includeMilestones:o=!0,includeReleases:r=!0,includeProjects:a=!0,limit:c=50}=s,l=Xo(t);if(!l)return{};let{owner:p,repo:d}=l,m={},[y,b,j,x,C]=await Promise.all([n?Me(e,Ko,{owner:p,repo:d,limit:c}).catch(f=>(_(`GitHub issues query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),i?Me(e,zo,{owner:p,repo:d,limit:Math.min(c,30)}).catch(f=>(_(`GitHub pull requests query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),o?Me(e,Vo,{owner:p,repo:d}).catch(f=>(_(`GitHub milestones query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),r?Me(e,Qo,{owner:p,repo:d,limit:10}).catch(f=>(_(`GitHub releases query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null),a?Me(e,Yo,{owner:p,repo:d}).catch(f=>(_(`GitHub projects query failed: ${f instanceof Error?f.message:String(f)}`),null)):Promise.resolve(null)]);return y?.repository?.issues?.nodes&&(m.issues=y.repository.issues.nodes.map(Zo)),b?.repository?.pullRequests?.nodes&&(m.pull_requests=b.repository.pullRequests.nodes.map(er)),j?.repository?.milestones?.nodes&&(m.milestones=j.repository.milestones.nodes.map(f=>{let E=f.issues?.nodes||[],A=f.closedIssues?.totalCount||0,G=f.issues?.totalCount||E.length,R=G-A;return{title:f.title,description:f.description||"",due_date:f.dueOn||null,progress:{open:R,closed:A,percent:G>0?Math.round(A/G*100):0},issues:E.map(U=>U.number)}})),x?.repository?.releases?.nodes&&(m.releases=x.repository.releases.nodes.map(f=>({tag_name:f.tagName,name:f.name||f.tagName,created_at:f.createdAt,url:f.url,author:f.author?.login||"unknown",prerelease:!!f.isPrerelease}))),C?.repository?.projectsV2?.nodes&&(m.project_boards=C.repository.projectsV2.nodes.filter(f=>f!==null).map(f=>{let E=f.columns?.nodes||[],A=f.items?.totalCount||0;return{number:f.number,title:f.title,state:(f.state||"open").toLowerCase(),url:f.url,columns:E.map(G=>({name:G.name,cards_count:A}))}})),m}async function qs(e){return new Promise(t=>{Ms("gh",["--version"],{cwd:e,timeout:5e3},(s,n)=>{if(s){t(!1);return}let i=n.match(/gh version (\d+)\.(\d+)/);if(i){let o=parseInt(i[1],10),r=parseInt(i[2],10);t(o>2||o===2&&r>=0)}else t(!1)})})}var Ko,zo,Vo,Qo,Yo,Hs=P(()=>{"use strict";F();Pt();Ko=`
|
|
21
21
|
query($owner: String!, $repo: String!, $limit: Int) {
|
|
22
22
|
repository(owner: $owner, name: $repo) {
|
|
23
23
|
issues(first: $limit, orderBy: {field: UPDATED_AT, direction: DESC}) {
|
|
@@ -48,7 +48,7 @@ query($owner: String!, $repo: String!, $limit: Int) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
`,
|
|
51
|
+
`,zo=`
|
|
52
52
|
query($owner: String!, $repo: String!, $limit: Int) {
|
|
53
53
|
repository(owner: $owner, name: $repo) {
|
|
54
54
|
pullRequests(first: $limit, orderBy: {field: UPDATED_AT, direction: DESC}) {
|
|
@@ -75,7 +75,7 @@ query($owner: String!, $repo: String!, $limit: Int) {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
`,
|
|
78
|
+
`,Vo=`
|
|
79
79
|
query($owner: String!, $repo: String!) {
|
|
80
80
|
repository(owner: $owner, name: $repo) {
|
|
81
81
|
milestones(first: 20, orderBy: {field: DUE_DATE, direction: ASC}) {
|
|
@@ -92,7 +92,7 @@ query($owner: String!, $repo: String!) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
`,
|
|
95
|
+
`,Qo=`
|
|
96
96
|
query($owner: String!, $repo: String!, $limit: Int) {
|
|
97
97
|
repository(owner: $owner, name: $repo) {
|
|
98
98
|
releases(first: $limit, orderBy: {field: CREATED_AT, direction: DESC}) {
|
|
@@ -107,7 +107,7 @@ query($owner: String!, $repo: String!, $limit: Int) {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
`,
|
|
110
|
+
`,Yo=`
|
|
111
111
|
query($owner: String!, $repo: String!) {
|
|
112
112
|
repository(owner: $owner, name: $repo) {
|
|
113
113
|
projectsV2(first: 10) {
|
|
@@ -135,11 +135,11 @@ query($owner: String!, $repo: String!) {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
`});import{execFile as Gs}from"child_process";import{readdirSync as
|
|
139
|
-
`).filter(Boolean).map(n=>{let i=JSON.parse(n),o=i.open_issues||0,r=i.closed_issues||0,a=o+r;return{title:i.title,description:i.description||"",due_date:i.due_on||null,progress:{open:o,closed:r,percent:a>0?Math.round(r/a*100):0},issues:[]}})}catch{return[]}}async function
|
|
140
|
-
`).filter(s=>s.trim());for(let s=0;s<t.length;s++)if(t[s].match(/^#+\s*(decision|why|rationale)/i))return t.slice(s+1,s+4).join(" ").trim().slice(0,200);return t[0]?.slice(0,200)||""}function
|
|
141
|
-
`).slice(0,5).find(c=>c.startsWith("#"))?.replace(/^#+\s*/,"")||i;n.push({title:a,summary:"",date:"",source:i})}catch{}return n}function
|
|
142
|
-
Written: .codebase.json (${o} KB)`)}function
|
|
138
|
+
`});import{execFile as Gs}from"child_process";import{readdirSync as tr,readFileSync as sr,existsSync as nr}from"fs";import{join as Dt}from"path";async function $e(e){if(!await xe(e,["--version"]))return null;let s=await ir(e,"git",["remote","get-url","origin"]);if(!(!!s&&(s.includes("github.com")||s.includes("github."))))return{status:{synced_at:new Date().toISOString(),github_available:!1,issues:[],pull_requests:[],kanban:{backlog:[],in_progress:[],needs_verify:[],done:[]},priorities:[]},roadmap:{milestones:[]},decisions:{from_prs:[],from_adrs:[],manual:[]}};if(!await or(e))return null;let o=await qs(e),r=[],a=[],c=[],l=[],p=[],d=!1;if(o)try{let x=await Ts(e,s,{includeIssues:!0,includePRs:!0,includeMilestones:!0,includeReleases:!0,includeProjects:!0,limit:50});r=x.issues||[],a=x.pull_requests||[],c=x.milestones||[],l=x.releases||[],p=x.project_boards||[],d=!0}catch{}d||(r=await rr(e),a=await lr(e),c=await pr(e));let[m]=await Promise.all([fr(e)]),y=hr(r),b=br(r),j=gr(e);return{status:{synced_at:new Date().toISOString(),github_available:!0,issues:r,pull_requests:a,kanban:y,priorities:b,releases:l,project_boards:p},roadmap:{milestones:c},decisions:{from_prs:m,from_adrs:j,manual:[]}}}function xe(e,t){return new Promise(s=>{Gs("gh",t,{cwd:e,timeout:3e4},(n,i)=>{s(n?"":i.trim())})})}function ir(e,t,s){return new Promise(n=>{Gs(t,s,{cwd:e,timeout:1e4},(i,o)=>{n(i?"":o.trim())})})}async function or(e){try{let t=await xe(e,["api","rate_limit"]);return t?(JSON.parse(t).resources?.core?.remaining??100)>10:!0}catch{return!0}}async function rr(e){let t=await xe(e,["issue","list","--limit","50","--state","all","--json","number,title,state,labels,assignees,milestone,createdAt,updatedAt"]);if(!t)return[];try{return JSON.parse(t).map(ar)}catch{return[]}}function ar(e){let t=e.labels||[],s=e.assignees||[],n=e.milestone,i=e.body||"";return{number:e.number,title:N(e.title,200),state:e.state?.toLowerCase()==="open"?"open":"closed",labels:t.map(o=>N(o.name,50)).filter(Boolean),assignee:N(s[0]?.login,100)||null,milestone:N(n?.title,200)||null,created_at:e.createdAt,updated_at:e.updatedAt,effort:cr(i),body:N(e.body||"",2e3)}}function cr(e){let t=e.match(/\*\*Effort:\*\*\s*([SML])\b/i);if(!t)return;let s=t[1].toUpperCase();if(s==="S"||s==="M"||s==="L")return s}async function lr(e){let t=await xe(e,["pr","list","--limit","30","--state","all","--json","number,title,state,author,headRefName,labels,reviewRequests,createdAt,updatedAt"]);if(!t)return[];try{return JSON.parse(t).map(dr)}catch{return[]}}function dr(e){let t=e.labels||[],s=e.reviewRequests||[],n=e.author;return{number:e.number,title:N(e.title,200),state:(e.state||"open").toLowerCase(),author:N(n?.login,100)||"unknown",branch:N(e.headRefName,ur),labels:t.map(i=>N(i.name,50)).filter(Boolean),reviewers:s.map(i=>N(i.login||i.name,100)).filter(Boolean),created_at:e.createdAt,updated_at:e.updatedAt}}async function pr(e){let t=await xe(e,["api","repos/{owner}/{repo}/milestones","--jq",".[] | {title,description,due_on,open_issues,closed_issues}"]);if(!t)return[];try{return t.split(`
|
|
139
|
+
`).filter(Boolean).map(n=>{let i=JSON.parse(n),o=i.open_issues||0,r=i.closed_issues||0,a=o+r;return{title:i.title,description:i.description||"",due_date:i.due_on||null,progress:{open:o,closed:r,percent:a>0?Math.round(r/a*100):0},issues:[]}})}catch{return[]}}async function fr(e){let t=await xe(e,["pr","list","--limit","20","--state","merged","--json","number,title,body,mergedAt,url"]);if(!t)return[];try{return JSON.parse(t).filter(n=>{let i=n.body||"";return i.toLowerCase().includes("decision")||i.toLowerCase().includes("why:")||i.toLowerCase().includes("rationale")||i.toLowerCase().includes("chose")||i.toLowerCase().includes("trade-off")}).map(n=>({title:N(n.title,200),summary:mr(n.body||""),date:n.mergedAt,source:`PR #${n.number}`,url:n.url}))}catch{return[]}}function mr(e){let t=e.split(`
|
|
140
|
+
`).filter(s=>s.trim());for(let s=0;s<t.length;s++)if(t[s].match(/^#+\s*(decision|why|rationale)/i))return t.slice(s+1,s+4).join(" ").trim().slice(0,200);return t[0]?.slice(0,200)||""}function gr(e){let t=["docs/adr","docs/decisions","adr","decisions","docs/architecture/decisions"],s=[];for(let i of t){let o=Dt(e,i);if(nr(o))try{let r=tr(o).filter(a=>a.endsWith(".md")).map(a=>Dt(i,a));s.push(...r)}catch{}}let n=[];for(let i of s.slice(0,20))try{let a=sr(Dt(e,i),"utf-8").split(`
|
|
141
|
+
`).slice(0,5).find(c=>c.startsWith("#"))?.replace(/^#+\s*/,"")||i;n.push({title:a,summary:"",date:"",source:i})}catch{}return n}function hr(e){let t=e.filter(c=>c.state==="open"),s=e.filter(c=>c.state==="closed"),n=["in-progress","in progress","doing","wip"],i=t.filter(c=>c.labels.some(l=>n.includes(l.toLowerCase()))),o=["status:needs-verify","needs-verify","needs-verification"],r=t.filter(c=>!i.includes(c)&&c.labels.some(l=>o.includes(l.toLowerCase())));return{backlog:t.filter(c=>!i.includes(c)&&!r.includes(c)),in_progress:i,needs_verify:r,done:s.slice(0,20)}}function qe(e){let t=n=>{let i=5;for(let o of n.labels){let r=o.toLowerCase();r.startsWith("status:")||(r.includes("p0")||r.includes("critical")||r.includes("urgent")?i=Math.min(i,0):r==="vibekit"||r.includes("p1")||r.includes("high")||r.includes("bug")?i=Math.min(i,1):r.includes("p2")||r.includes("medium")||r==="arch"?i=Math.min(i,2):r.includes("p3")||r.includes("low")?i=Math.min(i,3):r.includes("feature")&&(i=Math.min(i,4)))}return i},s=n=>{switch(n.effort){case"S":return 0;case"M":return 1;case"L":return 2;default:return 1}};return[...e].sort((n,i)=>{let o=t(n),r=t(i);return o!==r?o-r:s(n)-s(i)})}function br(e){return qe(e.filter(t=>t.state==="open"))}var ur,He=P(()=>{"use strict";Hs();Pt();ur=200});import{readFileSync as yr,statSync as kr}from"fs";import{writeFile as wr,rename as vr}from"fs/promises";import{execFile as $r}from"child_process";import{join as lt}from"path";async function Bs(e){return new Promise(t=>{$r("git",["rev-parse","HEAD"],{cwd:e,timeout:5e3},(s,n)=>{if(s){t(null);return}t(n.trim())})})}function Js(e){try{let t=yr(lt(e,At),"utf-8"),s=JSON.parse(t);return s.cache_version!==Us?null:s}catch{return null}}async function Ws(e,t,s){let n={cache_version:Us,timestamp:new Date().toISOString(),git_sha:await Bs(e),file_count:t,file_mtimes:zs(e),manifest:s};try{let i=lt(e,At+".tmp");await wr(i,JSON.stringify(n),"utf-8"),await vr(i,lt(e,At))}catch{}}async function Ks(e,t,s){let n=await Bs(e);if(n&&t.git_sha)return n===t.git_sha;if(t.file_count!==s)return!1;let i=zs(e);for(let o of Object.keys({...t.file_mtimes,...i}))if((t.file_mtimes[o]??0)!==(i[o]??0))return!1;return!0}function zs(e){let t={};for(let s of xr)try{let n=kr(lt(e,s));t[s]=n.mtimeMs}catch{}return t}var At,Us,xr,Vs=P(()=>{"use strict";At=".codebase.cache.json",Us=2,xr=["package.json","package-lock.json","pnpm-lock.yaml","yarn.lock","tsconfig.json","tsconfig.build.json","Cargo.toml","Cargo.lock","pyproject.toml","requirements.txt","poetry.lock","go.mod","go.sum","Makefile","Dockerfile","docker-compose.yml"]});async function K(e,t={}){let s=await cs(e,{depth:t.depth});if(t.incremental){let a=Js(e);if(a&&await Ks(e,a,s.files.length))return a.manifest}let n=Rt;t.categories?.length&&(n=Rt.filter(a=>t.categories.includes(a.category)));let i=await Promise.allSettled(n.map(async a=>({category:a.category,data:await a.detect(s)}))),o={version:"1.0",generated_at:new Date().toISOString()},r=[];for(let a of i)if(a.status==="fulfilled")o[a.value.category]=a.value.data;else{let c=`Detector failed: ${a.reason instanceof Error?a.reason.message:String(a.reason)}`;r.push(c),t.quiet||_(c)}if(r.length>0&&(o._warnings=r),t.sync)try{let a=await $e(e);a&&(o.status=a.status,o.roadmap=a.roadmap,o.decisions=a.decisions)}catch{t.quiet||_("GitHub sync failed (is `gh` CLI installed and authenticated?)")}return t.incremental&&await Ws(e,s.files.length,o),o}function ut(e,t){switch(e){case"project":{let s=t.name,n=t.description;return n?`${s} \u2014 ${n.slice(0,60)}`:s||"unknown"}case"repo":{let s=t.url,n=t.default_branch;return`${s?s.replace(/.*[:/]/,"").replace(/\.git$/,""):"local"}, ${n||"unknown branch"}`}case"structure":{let s=t.entry_points,n=t.tree,i=t.build_output,o=Object.keys(n||{}).filter(a=>a!=="./"),r=[];return s?.length&&r.push(`${s.length} entry points`),o.length&&r.push(`${o.length} top-level dirs`),i?.length&&r.push(`build: ${i.join(", ")}`),r.join(", ")||"empty"}case"stack":{let s=t.languages,n=t.frameworks,i=t.build_tool,o=[...s||[],...n||[]];return i&&o.push(i),o.join(", ")||"unknown"}case"commands":return Object.entries(t).filter(([,n])=>n).map(([n])=>n).join(", ")||"none detected";case"dependencies":{let s=t.direct_count,n=t.dev_count,i=t.lock_file,o=[];return s&&o.push(`${s} direct`),n&&o.push(`${n} dev`),!s&&!n&&o.push("0 deps"),i&&o.push(i),o.join(", ")}case"config":return`${t.env_files?.length||0} env files`;case"git":{let s=t.recent_commits,n=t.uncommitted_changes;return`${s?.length||0} recent commits${n?", uncommitted changes":""}`}case"quality":{let s=[];return t.test_framework&&s.push(t.test_framework),t.linter&&s.push(t.linter),t.ci&&s.push(t.ci),s.join(", ")||"none detected"}case"patterns":{let s=t.architecture,n=t.state_management;return[s,n].filter(Boolean).join(", ")||"unknown"}case"status":{let s=t.issues||[],n=t.pull_requests||[];return`${s.length} issues, ${n.length} PRs`}default:return JSON.stringify(t).slice(0,60)}}var je=P(()=>{"use strict";us();Fs();He();F();Vs()});import{resolve as jr,join as Sr}from"path";import{writeFile as Cr}from"fs/promises";async function Ge(e){ee(e.quiet);let t=jr(e.path);u(`Scanning ${t}...`);let s=await K(t,{depth:e.depth,categories:e.categories.length?e.categories:void 0,incremental:e.incremental,quiet:e.quiet,sync:e.sync});for(let[r,a]of Object.entries(s))r==="version"||r==="generated_at"||typeof a!="object"||a===null||g(`${Er(r)} (${ut(r,a)})`);let n=Sr(t,".codebase.json"),i=JSON.stringify(s,null,2);await Cr(n,i,"utf-8");let o=(Buffer.byteLength(i)/1024).toFixed(1);u(`
|
|
142
|
+
Written: .codebase.json (${o} KB)`)}function Er(e){return e.charAt(0).toUpperCase()+e.slice(1)}var Ot=P(()=>{"use strict";je();F()});import{readFileSync as It,writeFileSync as Qs,existsSync as Nt}from"fs";import{join as dt}from"path";function Dr(e){try{let t=It(dt(e,".codebase.json"),"utf-8"),s=JSON.parse(t);return{name:s.project?.name||"Unknown",description:s.project?.description||null,languages:s.stack?.languages||[],frameworks:s.stack?.frameworks||[],commands:s.commands||{}}}catch{return null}}function Ar(e){let t=Dr(e);if(!t)return Pr;let s=[...t.languages,...t.frameworks].filter(Boolean),n=s.length?s.join(", "):"unknown",o=Object.entries(t.commands).filter(([,a])=>a).map(([a,c])=>`| \`${a}\` | \`${c}\` |`).join(`
|
|
143
143
|
`),r=o?`
|
|
144
144
|
### Project Commands
|
|
145
145
|
| Task | Command |
|
|
@@ -200,11 +200,11 @@ Commands: \`open <url>\`, \`snapshot -i\` (\u2192 \`@e1\`/\`@e2\` refs), \`click
|
|
|
200
200
|
${Se}`}function Ys(e,t){return Nt(dt(e,t))}function Xs(e,t){let s=dt(e,t),n=Nt(s)?It(s,"utf-8"):"";if(n.includes(Ue)){let i=n.indexOf(Ue),o=n.indexOf(Se);i!==-1&&o!==-1&&(n=n.slice(0,i)+n.slice(o+Se.length),n=n.replace(/\n{3,}/g,`
|
|
201
201
|
|
|
202
202
|
`).trimEnd())}Qs(s,n.trimEnd()+`
|
|
203
|
-
`+
|
|
203
|
+
`+Ar(e)+`
|
|
204
204
|
`,"utf-8")}function Zs(e,t){let s=dt(e,t);if(!Nt(s))return;let n=It(s,"utf-8"),i=n.indexOf(Ue),o=n.indexOf(Se);i!==-1&&o!==-1&&(n=n.slice(0,i)+n.slice(o+Se.length),n=n.replace(/\n{3,}/g,`
|
|
205
205
|
|
|
206
206
|
`).trim()+`
|
|
207
|
-
`,Qs(s,n,"utf-8"))}var Ue,Se,
|
|
207
|
+
`,Qs(s,n,"utf-8"))}var Ue,Se,_r,Rr,Pr,Xl,en=P(()=>{"use strict";Ue="<!-- codebase:start -->",Se="<!-- codebase:end -->",_r="# codebase:start",Rr="# codebase:end",Pr=`
|
|
208
208
|
${Ue}
|
|
209
209
|
## Project Context (auto-generated by codebase)
|
|
210
210
|
|
|
@@ -254,7 +254,7 @@ If using MCP instead of CLI: call \`project_brief\` (not \`npx codebase brief\`)
|
|
|
254
254
|
### Browser Automation (agent-browser)
|
|
255
255
|
Commands: \`open <url>\`, \`snapshot -i\` (\u2192 \`@e1\`/\`@e2\` refs), \`click @e1\`, \`fill @e2 "text"\`, \`screenshot\`, \`auth save/login <profile>\`, \`state save/load <name>\`.
|
|
256
256
|
${Se}`,Xl=`
|
|
257
|
-
${
|
|
257
|
+
${_r}
|
|
258
258
|
# Project Context (auto-generated by codebase)
|
|
259
259
|
#
|
|
260
260
|
# This project uses \`codebase\` for AI context. Run commands instead of exploring files.
|
|
@@ -284,11 +284,11 @@ ${Dr}
|
|
|
284
284
|
#
|
|
285
285
|
# MCP TOOLS (for IDE/agent integrations):
|
|
286
286
|
# If using MCP: call project_brief, get_next_task, refresh_status, list_skills
|
|
287
|
-
${
|
|
287
|
+
${Rr}`});var tn={};Vt(tn,{claudeIntegration:()=>ae});var ae,Be=P(()=>{"use strict";en();ae={name:"claude",detect:e=>Ys(e,"CLAUDE.md"),async inject(e){try{return Xs(e,"CLAUDE.md"),{ok:!0}}catch(t){return{ok:!1,message:t.message}}},remove:e=>Zs(e,"CLAUDE.md")}});import{readFileSync as Or,writeFileSync as Ir,existsSync as Nr}from"fs";import{join as Lr}from"path";function Ce(e){let t=Lr(e,".gitignore"),s=Nr(t)?Or(t,"utf-8"):"",n=!s.includes(sn),i=!s.includes(nn);if(!n&&!i)return;let o="";(n||i)&&(o+=`
|
|
288
288
|
# AI context manifest
|
|
289
289
|
`,n&&(o+=`${sn}
|
|
290
290
|
`),i&&(o+=`${nn}
|
|
291
|
-
`)),
|
|
291
|
+
`)),Ir(t,s.trimEnd()+o,"utf-8")}var sn,nn,pt=P(()=>{"use strict";sn=".codebase.json",nn=".codebase.cache.json"});import{readFileSync as Lt,writeFileSync as We,existsSync as Ee,mkdirSync as an,chmodSync as cn,unlinkSync as ou}from"fs";import{join as _e}from"path";function Re(e,t=!1){if(!Ee(_e(e,".git")))return!1;let n=`npx --yes codebase scan-only --incremental --quiet${t?" --sync":""}`;return rn(e,"post-commit",n),rn(e,"post-checkout",n),Fr(e),!0}function Fr(e){let t=_e(e,".git","hooks"),s=_e(t,"pre-commit");Ee(t)||an(t,{recursive:!0});let n=_e(e,"package.json");if(!Ee(n))return;let i=!1,o=!1,r=!1;try{let l=JSON.parse(Lt(n,"utf-8"));i=!!l.scripts?.check,o=!!l.scripts?.typecheck,r=!!l.scripts?.lint}catch{return}if(!i&&!o&&!r)return;let a;if(i)a="npm run check --silent";else{let l=[];o&&l.push("npm run typecheck --silent"),r&&l.push("npm run lint --silent"),a=l.join(" && ")}let c=`#!/bin/sh
|
|
292
292
|
${on}
|
|
293
293
|
# Run typecheck + lint before every commit. Fix errors before committing.
|
|
294
294
|
if [ -f package.json ]; then
|
|
@@ -311,10 +311,10 @@ ${s}
|
|
|
311
311
|
|
|
312
312
|
${Je}
|
|
313
313
|
${s}
|
|
314
|
-
`,"utf-8");cn(i,493)}var Je,on,ft=
|
|
315
|
-
`,"utf-8"),ae.inject(t),g("CLAUDE.md - added .codebase.json reference"),S("Git Hooks"),Re(t,!1)?(g("post-commit hook (auto-updates .codebase.json)"),g("pre-commit hook (runs typecheck + lint before every commit)"),Jr(t),g("commit-msg hook (blocks direct commits to main/master)")):h("Not a git repository - skipping hooks"),S("Claude Code Hooks"),fn(t),S("Browser Automation"),await Kr(),S("Claude Commands"),dn(t),S("Claude Skills"),pn(t),Ce(t),Wr(t,[".vibekit/daemon.lock",".vibekit/daemon.log",".vibekit/build.lock",".vibekit/milestone.env",".mcp.json"]),g(".gitignore updated"),S("Vibekit Bootstrap");let n=
|
|
314
|
+
`,"utf-8");cn(i,493)}var Je,on,ft=P(()=>{"use strict";Je="# codebase-auto-update";on="# codebase-pre-commit"});var ht={};Vt(ht,{installClaudeCommandsForFix:()=>Hr,installClaudeHooksForFix:()=>Br,installClaudeSkillsForFix:()=>Gr,runSetup:()=>Tt});import{resolve as Mr,dirname as ln,join as D}from"path";import{writeFileSync as ce,existsSync as B,mkdirSync as Ke,readFileSync as le,chmodSync as Mt,readdirSync as un,copyFileSync as mt,rmSync as Tr}from"fs";import{execFile as Pe,execFileSync as qr}from"child_process";async function Tt(e){let t=Mr(e.path);await Ge({...e,sync:!0}),S("Claude Code Integration"),B(D(t,"CLAUDE.md"))||ce(D(t,"CLAUDE.md"),`# Project Rules
|
|
315
|
+
`,"utf-8"),ae.inject(t),g("CLAUDE.md - added .codebase.json reference"),S("Git Hooks"),Re(t,!1)?(g("post-commit hook (auto-updates .codebase.json)"),g("pre-commit hook (runs typecheck + lint before every commit)"),Jr(t),g("commit-msg hook (blocks direct commits to main/master)")):h("Not a git repository - skipping hooks"),S("Claude Code Hooks"),fn(t),S("Browser Automation"),await Kr(),S("Claude Commands"),dn(t),S("Claude Skills"),pn(t),Ce(t),Wr(t,[".vibekit/daemon.lock",".vibekit/daemon.log",".vibekit/build.lock",".vibekit/milestone.env",".mcp.json"]),g(".gitignore updated"),S("Vibekit Bootstrap");let n=D(t,".vibekit");B(n)?h(".vibekit/ already exists"):(Ke(n,{recursive:!0}),g(".vibekit/ directory created")),S("GitHub Labels"),await zr()?(await Vr(t),await Qr(t)):(_("gh CLI not authenticated \u2014 skipping label/issue setup"),_("Run: gh auth login then codebase setup")),S("Product Brief");let o=D(t,"docs");B(o)||Ke(o,{recursive:!0});let r=D(o,"PRODUCT.md");B(r)?h("docs/PRODUCT.md already exists \u2014 skipping (delete to regenerate)"):(Yr(t,r),g("docs/PRODUCT.md generated \u2014 review and fill in [INFERRED] sections")),u(`
|
|
316
316
|
Done! Your project is wired for AI + autonomous loop.`),u(`
|
|
317
|
-
0. codebase brief \u2014 load project context (AI agents: call this first)`),u(" 1. Review docs/PRODUCT.md and fill in any [INFERRED] sections"),u(" 2. /simulate \u2014 AI customer journeys find & fix bugs"),u(" 3. /build \u2014 implement architectural issues autonomously"),u(" 4. /launch \u2014 gate check, release, merge to main")}function
|
|
317
|
+
0. codebase brief \u2014 load project context (AI agents: call this first)`),u(" 1. Review docs/PRODUCT.md and fill in any [INFERRED] sections"),u(" 2. /simulate \u2014 AI customer journeys find & fix bugs"),u(" 3. /build \u2014 implement architectural issues autonomously"),u(" 4. /launch \u2014 gate check, release, merge to main")}function Hr(e){dn(e)}function dn(e){let t=D(ln(new URL(import.meta.url).pathname),"..","commands");if(!B(t)){_("Claude commands not found in package \u2014 skipping");return}let s=un(t).filter(r=>r.endsWith(".md")),n=[{dir:D(e,".claude","commands"),label:".claude/commands/"},{dir:D(process.env.HOME??"~",".claude","commands"),label:"~/.claude/commands/"}],i=0,o=0;for(let{dir:r,label:a}of n){Ke(r,{recursive:!0});let c=0,l=0,p=0;for(let m of s){let y=D(t,m),b=D(r,m);if(B(b)){let j=le(y,"utf-8"),x=le(b,"utf-8");j!==x?(mt(y,b),l++):p++}else mt(y,b),c++}let d=[];c>0&&d.push(`${c} new`),l>0&&d.push(`${l} updated`),p>0&&d.push(`${p} unchanged`),c>0||l>0?g(`Claude commands \u2192 ${a} (${d.join(", ")})`):h(`Claude commands up to date \u2192 ${a}`),i+=c,o+=l}(i>0||o>0)&&(h("Available: /setup /simulate /build /launch /review /vibeloop"),h("Tip: commit .claude/commands/ to share these with your team"))}function Gr(e){pn(e)}function Ur(e,t){let s=e.split("/").pop().replace(/\.skill$/,""),n=D(t,s);try{return B(n)&&Tr(n,{recursive:!0,force:!0}),qr("unzip",["-o","-q",e,"-d",t],{timeout:3e4}),B(n)}catch{return!1}}function pn(e){let t=D(ln(new URL(import.meta.url).pathname),"../..","skills");if(!B(t)){_("Skills not found in package \u2014 skipping");return}let s=un(t).filter(a=>a.endsWith(".skill"));if(s.length===0){h("No skill files found in package");return}let n=[{dir:D(e,".claude","skills"),label:".claude/skills/"},{dir:D(process.env.HOME??"~",".claude","skills"),label:"~/.claude/skills/"}],i=0,o=0;for(let{dir:a,label:c}of n){Ke(a,{recursive:!0});let l=0,p=0,d=0;for(let y of s){let b=D(t,y),j=D(a,y),x=!1;if(B(j)){let C=le(b),f=le(j);if(!C.equals(f))mt(b,j),x=!0,p++;else{let E=y.replace(/\.skill$/,"");B(D(a,E,"SKILL.md"))?d++:x=!0}}else mt(b,j),x=!0,l++;x&&(Ur(j,a)||_(`Failed to unzip ${y} \u2014 skill may not work until manually extracted`))}let m=[];l>0&&m.push(`${l} new`),p>0&&m.push(`${p} updated`),d>0&&m.push(`${d} unchanged`),l>0||p>0?g(`Skills \u2192 ${c} (${m.join(", ")})`):h(`Skills up to date \u2192 ${c}`),i+=l,o+=p}let r=s.map(a=>a.replace(/\.skill$/,"")).join(", ");i>0||o>0?(h(`Available: ${r}`),h("Tip: commit .claude/skills/ to share these with your team")):h(`Available: ${r}`)}function Br(e){fn(e)}function fn(e){let t=D(e,".claude","hooks");Ke(t,{recursive:!0});let s=D(t,"git-guard.sh");ce(s,`#!/bin/bash
|
|
318
318
|
# codebase git-guard \u2014 PreToolUse hook
|
|
319
319
|
# Reads Claude tool input JSON from stdin, enforces git safety rules.
|
|
320
320
|
|
|
@@ -381,7 +381,7 @@ if echo "$CMD" | grep -qE "^git commit|&& git commit| git commit"; then
|
|
|
381
381
|
fi
|
|
382
382
|
|
|
383
383
|
exit 0
|
|
384
|
-
`,"utf-8"),Mt(s,493),g(".claude/hooks/git-guard.sh (PreToolUse \u2014 blocks unsafe git ops)");let i=
|
|
384
|
+
`,"utf-8"),Mt(s,493),g(".claude/hooks/git-guard.sh (PreToolUse \u2014 blocks unsafe git ops)");let i=D(t,"git-post.sh");ce(i,`#!/bin/bash
|
|
385
385
|
# codebase git-post \u2014 PostToolUse hook
|
|
386
386
|
# Reads Claude tool input JSON from stdin. Reminds to raise PR after branch push.
|
|
387
387
|
|
|
@@ -403,8 +403,8 @@ if echo "$CMD" | grep -qE "git push origin [a-zA-Z0-9/_-]+"; then
|
|
|
403
403
|
fi
|
|
404
404
|
|
|
405
405
|
exit 0
|
|
406
|
-
`,"utf-8"),Mt(i,493),g(".claude/hooks/git-post.sh (PostToolUse \u2014 PR reminder after branch push)");let r=
|
|
407
|
-
`,"utf-8"),g(".claude/settings.json (PreToolUse + PostToolUse hooks registered)")}function Jr(e){let t=
|
|
406
|
+
`,"utf-8"),Mt(i,493),g(".claude/hooks/git-post.sh (PostToolUse \u2014 PR reminder after branch push)");let r=D(e,".claude","settings.json"),a={};if(B(r))try{a=JSON.parse(le(r,"utf-8"))}catch{}let c=a.hooks??{},l="bash .claude/hooks/git-guard.sh",p="bash .claude/hooks/git-post.sh",d=c.PreToolUse??[];JSON.stringify(d).includes("git-guard")||d.push({matcher:"Bash",hooks:[{type:"command",command:l}]}),c.PreToolUse=d;let y=c.PostToolUse??[];JSON.stringify(y).includes("git-post")||y.push({matcher:"Bash",hooks:[{type:"command",command:p}]}),c.PostToolUse=y,a.hooks=c,ce(r,JSON.stringify(a,null,2)+`
|
|
407
|
+
`,"utf-8"),g(".claude/settings.json (PreToolUse + PostToolUse hooks registered)")}function Jr(e){let t=D(e,".git","hooks"),s=D(t,"commit-msg"),n="# codebase-branch-check",i=`#!/bin/sh
|
|
408
408
|
${n}
|
|
409
409
|
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
|
410
410
|
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
|
|
@@ -415,18 +415,18 @@ if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
|
|
|
415
415
|
echo ""
|
|
416
416
|
exit 1
|
|
417
417
|
fi
|
|
418
|
-
`;if(
|
|
418
|
+
`;if(B(s)){let o=le(s,"utf-8");o.includes(n)||ce(s,o.trimEnd()+`
|
|
419
419
|
|
|
420
|
-
`+i,"utf-8")}else ce(s,i,"utf-8");Mt(s,493)}function Wr(e,t){let s=
|
|
420
|
+
`+i,"utf-8")}else ce(s,i,"utf-8");Mt(s,493)}function Wr(e,t){let s=D(e,".gitignore"),n=B(s)?le(s,"utf-8"):"",i=t.filter(o=>!n.includes(o)).join(`
|
|
421
421
|
`);i&&ce(s,n.trimEnd()+`
|
|
422
422
|
`+i+`
|
|
423
|
-
`,"utf-8")}function gt(e,t){return new Promise(s=>{Pe("gh",t,{cwd:e,timeout:15e3},(n,i)=>{s({ok:!n,stdout:(i||"").trim()})})})}async function Kr(){if(await new Promise(i=>{Pe("agent-browser",["--version"],{timeout:5e3},o=>i(!o))})){h("agent-browser already installed");return}if(u("Installing agent-browser..."),!await new Promise(i=>{Pe("npm",["install","-g","agent-browser"],{timeout:12e4},o=>i(!o))})){
|
|
423
|
+
`,"utf-8")}function gt(e,t){return new Promise(s=>{Pe("gh",t,{cwd:e,timeout:15e3},(n,i)=>{s({ok:!n,stdout:(i||"").trim()})})})}async function Kr(){if(await new Promise(i=>{Pe("agent-browser",["--version"],{timeout:5e3},o=>i(!o))})){h("agent-browser already installed");return}if(u("Installing agent-browser..."),!await new Promise(i=>{Pe("npm",["install","-g","agent-browser"],{timeout:12e4},o=>i(!o))})){_("agent-browser install failed \u2014 run: npm install -g agent-browser");return}await new Promise(i=>{Pe("agent-browser",["install"],{timeout:3e5},o=>i(!o))})?g("agent-browser installed (Chrome for Testing downloaded)"):_("agent-browser installed but Chrome download failed \u2014 run: agent-browser install"),await new Promise(i=>{Pe("agent-browser",["--version"],{timeout:5e3},o=>i(!o))})||_("agent-browser validation failed \u2014 it may not be on PATH. Try: npm install -g agent-browser")}async function zr(){return new Promise(e=>{Pe("gh",["auth","status"],{timeout:5e3},t=>e(!t))})}async function Vr(e){let{stdout:t}=await gt(e,["label","list","--limit","100","--json","name","--jq",".[].name"]),s=new Set(t.split(`
|
|
424
424
|
`).filter(Boolean)),n=0;for(let o of Ft){if(s.has(o.name))continue;let{ok:r}=await gt(e,["label","create",o.name,"--color",o.color,"--description",o.description]);r&&n++}let i=Ft.length-n;n>0?g(`${n} GitHub labels created (${i} already existed)`):h(`All ${Ft.length} labels already exist`)}async function Qr(e){let{stdout:t}=await gt(e,["issue","list","--search","Highlights Index","--state","all","--limit","1","--json","number","--jq",".[0].number // empty"]);if(t){h("Highlights Index issue already exists");return}let s=`# Product Highlights Index
|
|
425
425
|
|
|
426
426
|
Tracks positive signals from /simulate cycles. Updated automatically \u2014 do not edit manually.
|
|
427
427
|
|
|
428
428
|
## Index
|
|
429
|
-
<!-- /simulate appends here -->`,{ok:n}=await gt(e,["issue","create","--title","Highlights Index","--label","highlight","--body",s]);n?g("Highlights Index issue created on GitHub"):
|
|
429
|
+
<!-- /simulate appends here -->`,{ok:n}=await gt(e,["issue","create","--title","Highlights Index","--label","highlight","--body",s]);n?g("Highlights Index issue created on GitHub"):_("Could not create Highlights Index issue")}function Yr(e,t){let s=D(e,".codebase.json"),n=null;if(B(s))try{n=JSON.parse(le(s,"utf-8"))}catch{}let i=n?.project?.name??"[INFERRED: project name]",o=n?.project?.description??"[INFERRED: one-line description]",r=(n?.stack?.languages??[]).join(", ")||"[INFERRED]",a=(n?.stack?.frameworks??[]).join(", ")||"[INFERRED]",c=n?.commands?.dev??"[INFERRED]",l=n?.commands?.build??"[INFERRED]",p=n?.commands?.test??"[INFERRED]";ce(t,`# PRODUCT.md \u2014 ${i}
|
|
430
430
|
|
|
431
431
|
> Auto-generated by \`codebase setup\`. Fill in any [INFERRED] sections.
|
|
432
432
|
|
|
@@ -475,7 +475,7 @@ ${o}
|
|
|
475
475
|
## Known Constraints
|
|
476
476
|
|
|
477
477
|
- [INFERRED: e.g. multi-tenant, RBAC, GDPR]
|
|
478
|
-
`,"utf-8")}var Ft,ze=
|
|
478
|
+
`,"utf-8")}var Ft,ze=P(()=>{"use strict";Ot();Be();pt();ft();F();Ft=[{name:"bug",color:"d73a4a",description:"Something isn't working"},{name:"arch",color:"0075ca",description:"Architectural change needed"},{name:"sim",color:"e4e669",description:"Found by simulation"},{name:"carry",color:"ff6b35",description:"Bug surviving 2+ cycles"},{name:"cycle",color:"c5def5",description:"Simulation cycle summary"},{name:"critical",color:"b60205",description:"Critical severity"},{name:"high",color:"d93f0b",description:"High severity"},{name:"medium",color:"e99695",description:"Medium severity"},{name:"low",color:"fef2c0",description:"Low severity"},{name:"highlight",color:"0e8a16",description:"Positive product signal"},{name:"vibekit",color:"7057ff",description:"Queued for autonomous build"},{name:"performance",color:"ff8c00",description:"Performance issue"},{name:"review",color:"1d76db",description:"Found by code review"}]});F();var ii={scan:{description:"Scan project and update .codebase.json manifest (lightweight \u2014 no AI tool injection)",usage:"codebase scan [path] [options]",examples:[{command:"codebase scan",description:"Scan current directory"},{command:"codebase scan ./my-project",description:"Scan specific directory"},{command:"codebase scan --depth 6",description:"Include deeper directory structure"},{command:"codebase scan --categories stack,commands",description:"Scan only specific categories"}],options:[{flag:"--path <dir>",description:"Target project directory (default: current)"},{flag:"--depth <n>",description:"Directory tree depth (default: 4)"},{flag:"--categories <list>",description:"Comma-separated categories to scan"},{flag:"--incremental",description:"Only re-scan changed areas"},{flag:"--quiet",description:"Suppress stdout output"},{flag:"--sync",description:"Sync GitHub data (requires gh CLI)"}]},init:{description:"Initialize codebase with full setup (scan + AI tools + hooks)",usage:"codebase init [options]",examples:[{command:"codebase init",description:"One-time setup for current project"},{command:"codebase init --dry-run",description:"Preview changes without modifying files"},{command:"codebase init --sync",description:"Include GitHub data sync"}],options:[{flag:"--dry-run",description:"Preview changes without applying"},{flag:"--sync",description:"Sync GitHub data (requires gh CLI)"},{flag:"--quiet",description:"Suppress output"}],seeAlso:["scan","setup"]},setup:{description:"Wire .codebase.json into Claude Code and install slash commands",usage:"codebase setup [options]",examples:[{command:"codebase setup",description:"Configure Claude Code, git hooks, and slash commands"}],options:[{flag:"--dry-run",description:"Preview changes"}]},brief:{description:"Get comprehensive project briefing (AI-facing). (GitHub STATUS section requires gh CLI auth)",usage:"codebase brief [options]",examples:[{command:"codebase brief",description:"Full project overview in one call"},{command:"codebase brief --format json | jq '.stack'",description:"Extract specific section as JSON"},{command:"codebase brief --categories stack,commands",description:"Only include selected sections"}],options:[{flag:"--format <fmt>",description:"Output format: text (default), json, markdown"},{flag:"--categories <list>",description:"Comma-separated sections to include: stack,commands,status,git,roadmap,decisions"}],seeAlso:["next","status"]},next:{description:"Show highest-priority task, what's in progress, and what needs verification",usage:"codebase next",examples:[{command:"codebase next",description:"Show next task to work on"},{command:"# Output blocks: IN PROGRESS | NEXT TASK | NEEDS VERIFY | BLOCKERS",description:"Four sections covering current state at a glance"},{command:"# Priority order: P0/critical/urgent \u2192 vibekit/P1/high/bug \u2192 P2/medium/arch \u2192 P3/low \u2192 feature \u2192 unlabeled",description:"How issues are ranked"}],seeAlso:["brief","status"]},status:{description:"Show kanban board, priorities, milestones, and decisions",usage:"codebase status [view]",examples:[{command:"codebase status",description:"Kanban board + priorities (default)"},{command:"codebase status milestones",description:"Milestone progress bars"},{command:"codebase status priorities",description:"Priority queue only"},{command:"codebase status decisions",description:"Architecture decisions log"},{command:"codebase status --mine",description:"Show only my assigned tasks"}],options:[{flag:"[view]",description:"One of: (none), milestones, priorities, decisions"},{flag:"--mine",description:"Show only your assigned items"}],seeAlso:["brief","next"]},query:{description:"Query specific field from manifest using dot-path",usage:"codebase query <path> [options]",examples:[{command:"codebase query stack.languages",description:'Get: ["typescript"]'},{command:"codebase query commands.test --force | sh",description:"Run test command"},{command:"codebase query dependencies.notable",description:"List notable packages"}],options:[{flag:"--force",description:"Plain text output (no JSON)"}]},issue:{description:"Manage GitHub issues",usage:"codebase issue <subcommand> [args]",examples:[{command:'codebase issue create "Fix auth bug"',description:"Create new issue"},{command:'codebase issue close 42 --reason "Fixed in PR #123"',description:"Close with reason"},{command:'codebase issue comment 42 --message "Fixed by refactoring auth flow"',description:"Add comment"},{command:"codebase issue list",description:"List all issues"},{command:"codebase issue list --mine",description:"List your issues"}],options:[{flag:"--message <text>",description:"Issue body (for create) or comment text"},{flag:"-m <text>",description:"Shorthand for --message"},{flag:"--reason <text>",description:"Close reason"}]},mcp:{description:"Start MCP server for AI tool integration (Transport: stdio, Protocol: 2024-11-05). .mcp.json is written automatically by `codebase init`",usage:"codebase mcp",examples:[{command:"codebase mcp",description:"Start stdio MCP server"},{command:"# Tools: project_brief, get_codebase, query_codebase, get_next_task, get_blockers,",description:""},{command:"# create_issue, close_issue, update_issue, get_issue, get_pr,",description:""},{command:"# list_commands, list_skills, get_plan, update_plan, rescan_project, refresh_status",description:"16 tools total"}],seeAlso:["serve"]},serve:{description:"Start HTTP server (REST alternative to MCP, default port 3000)",usage:"codebase serve [--port N]",examples:[{command:"codebase serve",description:"Start HTTP server on port 3000"},{command:"codebase serve --port 8080",description:"Start on custom port"}],options:[{flag:"--port <n>",description:"Port to listen on (default: 3000)"}],seeAlso:["mcp"]},skills:{description:"List installed Claude skills",usage:"codebase skills",examples:[{command:"codebase skills",description:"List all installed skills with descriptions"}],seeAlso:["setup"]},doctor:{description:"Diagnose setup and configuration issues",usage:"codebase doctor",examples:[{command:"codebase doctor",description:"Run health check"}],seeAlso:["fix"]},fix:{description:"Auto-repair issues found by doctor",usage:"codebase fix",examples:[{command:"codebase fix",description:"Auto-fix all issues"}],seeAlso:["doctor"]},release:{description:"Gate check \u2192 tag \u2192 merge develop\u2192main \u2192 GitHub release",usage:"codebase release [version] [options]",examples:[{command:"codebase release",description:"Auto-increment version and release"},{command:"codebase release v1.2.0",description:"Release with explicit version"},{command:"codebase release --dry-run",description:"Preview release without tagging"}],options:[{flag:"--dry-run",description:"Preview release notes without creating tag or merge"}],seeAlso:["doctor"]}};function Yt(){console.log(`
|
|
479
479
|
${w("codebase")} \u2014 One command. Every AI tool understands your project instantly.
|
|
480
480
|
|
|
481
481
|
${w("QUICK START")}
|
|
@@ -552,27 +552,20 @@ ${w("SEE ALSO")}
|
|
|
552
552
|
`:""}${w("MORE HELP")}
|
|
553
553
|
${$("codebase --help")} Show all commands
|
|
554
554
|
${tt("https://github.com/ZySec-AI/codebase/docs","Full documentation")}
|
|
555
|
-
`)}var Nc={E_NO_GIT:{message:"Not a git repository",suggestion:"Initialize git first: "+$("git init")},E_NO_PACKAGE_JSON:{message:"No package.json found",suggestion:"Initialize project: "+$("npm init")+" or "+$("pnpm init")},E_GH_NOT_AUTHENTICATED:{message:"GitHub CLI not authenticated",suggestion:"Run: "+$("gh auth login")},E_MANIFEST_NOT_FOUND:{message:".codebase.json not found",suggestion:"Run: "+$("codebase init")+" to generate it"},E_INVALID_PATH:{message:"Invalid directory path",suggestion:"Use absolute path or path relative to current directory"},E_PERMISSION_DENIED:{message:"Permission denied",suggestion:"Check file permissions or run with appropriate access"}};var oi={command:"init",subcommand:"",positionals:[],path:process.cwd(),format:"text",depth:4,categories:[],incremental:!1,quiet:!1,force:!1,verbose:!1,port:7432,tools:[],dryRun:!1,since:"",sync:!1,message:"",reason:"",examples:!1,helpCommand:!1},Zt=new Set(["scan","setup","query","mcp","issue","status","init","scan-only","brief","next","doctor","fix","release","plan","skills","serve"]);function es(e){let t={...oi},s=[];for(let n=0;n<e.length;n++){let i=e[n];if(!i.startsWith("-")&&Zt.has(i)){if(t.command=i,e[n+1]==="--help"||e[n+1]==="-h")return t.helpCommand=!0,t;break}}for(let n=0;n<e.length;n++){let i=e[n];if((i==="--help"||i==="-h")&&!t.command&&(Yt(),process.exit(0)),(i==="--version"||i==="-v")&&(console.log("codebase 0.3.
|
|
556
|
-
${
|
|
557
|
-
|
|
558
|
-
`)
|
|
559
|
-
|
|
560
|
-
`);let r=
|
|
561
|
-
${C.green}\u2713${C.reset} ${C.bold}Updated to ${s}!${C.reset} Restart codebase to use the new version.
|
|
562
|
-
`:`
|
|
563
|
-
${C.yellow}!${C.reset} Update failed. Run manually: ${C.bold}${n}${C.reset}
|
|
564
|
-
`),process.exit(0)}Ot();ze();je();import{resolve as Zr,join as he}from"path";import{existsSync as bt,writeFileSync as ea,readFileSync as hn}from"fs";import{execFile as gn}from"child_process";import{writeFile as qt,rename as ta}from"fs/promises";import{homedir as sa}from"os";Be();var Xr=[ae];function mn(e){return Xr.filter(t=>t.detect(e))}Be();pt();ft();M();function na(e){if(!bt(he(e,".codebase.json")))return!1;let t=he(e,"CLAUDE.md");if(bt(t))try{let s=hn(t,"utf-8"),n=s.includes("<!-- codebase:start -->")&&s.includes("<!-- codebase:end -->"),i=s.includes("# codebase:start")&&s.includes("# codebase:end");if(n||i)return!0}catch{}return!1}async function bn(e){let t=Date.now();ee(e.quiet);let s=Zr(e.path);if(na(s)&&!e.force){S(`codebase \u2014 refreshing project manifest
|
|
565
|
-
`);let P=await De()==="authenticated";u(`Scanning ${s}...`);let A=await W(s,{depth:e.depth,categories:e.categories.length?e.categories:void 0,quiet:e.quiet,sync:P}),G=he(s,".codebase.json"),_=JSON.stringify(A,null,2);await qt(G,_,"utf-8");let U=(Buffer.byteLength(_)/1024).toFixed(1);g(`Manifest refreshed \u2014 .codebase.json (${U} KB)`),h("Already initialized. Run with --force to force full re-setup.");return}S(`codebase \u2014 activating project intelligence
|
|
566
|
-
`);let n=await De();n==="authenticated"?g("GitHub CLI \u2014 authenticated"):n==="not-authenticated"?(R("GitHub CLI installed but not logged in"),h("Run: gh auth login"),h("After login, re-run `npx codebase` for full GitHub integration\n")):(h("GitHub CLI not found \u2014 GitHub features disabled"),h(`To enable: brew install gh && gh auth login
|
|
567
|
-
`));let i=n==="authenticated";u(`Scanning ${s}...`);let o=await W(s,{depth:e.depth,categories:e.categories.length?e.categories:void 0,quiet:e.quiet,sync:i});for(let[f,P]of Object.entries(o))f==="version"||f==="generated_at"||typeof P!="object"||P===null||g(`${ia(f)} (${ut(f,P)})`);let r=he(s,".codebase.json"),a=JSON.stringify(o,null,2);await qt(r,a,"utf-8");let c=(Buffer.byteLength(a)/1024).toFixed(1);u(`
|
|
555
|
+
`)}var Nc={E_NO_GIT:{message:"Not a git repository",suggestion:"Initialize git first: "+$("git init")},E_NO_PACKAGE_JSON:{message:"No package.json found",suggestion:"Initialize project: "+$("npm init")+" or "+$("pnpm init")},E_GH_NOT_AUTHENTICATED:{message:"GitHub CLI not authenticated",suggestion:"Run: "+$("gh auth login")},E_MANIFEST_NOT_FOUND:{message:".codebase.json not found",suggestion:"Run: "+$("codebase init")+" to generate it"},E_INVALID_PATH:{message:"Invalid directory path",suggestion:"Use absolute path or path relative to current directory"},E_PERMISSION_DENIED:{message:"Permission denied",suggestion:"Check file permissions or run with appropriate access"}};var oi={command:"init",subcommand:"",positionals:[],path:process.cwd(),format:"text",depth:4,categories:[],incremental:!1,quiet:!1,force:!1,verbose:!1,port:7432,tools:[],dryRun:!1,since:"",sync:!1,message:"",reason:"",examples:!1,helpCommand:!1},Zt=new Set(["scan","setup","query","mcp","issue","status","init","scan-only","brief","next","doctor","fix","release","plan","skills","serve"]);function es(e){let t={...oi},s=[];for(let n=0;n<e.length;n++){let i=e[n];if(!i.startsWith("-")&&Zt.has(i)){if(t.command=i,e[n+1]==="--help"||e[n+1]==="-h")return t.helpCommand=!0,t;break}}for(let n=0;n<e.length;n++){let i=e[n];if((i==="--help"||i==="-h")&&!t.command&&(Yt(),process.exit(0)),(i==="--version"||i==="-v")&&(console.log("codebase 0.3.5"),process.exit(0)),i.startsWith("--")){let o=i.slice(2);if(o==="quiet"||o==="q"){t.quiet=!0;continue}if(o==="force"){t.force=!0;continue}if(o==="raw"){console.error("Warning: --raw is deprecated, use --force instead"),t.force=!0;continue}if(o==="verbose"||o==="V"){t.verbose=!0;continue}if(o==="incremental"){t.incremental=!0;continue}if(o==="dry-run"){t.dryRun=!0;continue}if(o==="sync"){t.sync=!0;continue}if(o==="examples"){t.examples=!0;continue}if(o==="mine"){s.push("mine");continue}let r=e[n+1];if(!r||r.startsWith("--"))continue;n++,o==="path"?t.path=r:o==="format"?t.format=r:o==="depth"?t.depth=parseInt(r,10)||4:o==="categories"?t.categories=r.split(",").map(a=>a.trim()):o==="port"?t.port=parseInt(r,10)||7432:o==="tools"?t.tools=r.split(",").map(a=>a.trim()):o==="since"?t.since=r:o==="message"||o==="m"?t.message=r:o==="reason"&&(t.reason=r);continue}s.push(i)}if(s.length>0&&Zt.has(s[0])&&(t.command=s.shift()),s.length>0){let n=s[0];["install","uninstall","create","close","comment","list","map"].includes(n)&&(t.subcommand=s.shift())}return t.positionals=s,s.length>0&&/^[\/\.~]/.test(s[0])&&(t.path=s[0]),process.env.CODEBASE_OUTPUT&&(t.path=process.env.CODEBASE_OUTPUT),process.env.CODEBASE_PORT&&(t.port=parseInt(process.env.CODEBASE_PORT,10)||7432),process.env.CODEBASE_DEPTH&&(t.depth=parseInt(process.env.CODEBASE_DEPTH,10)||4),process.env.CODEBASE_QUIET==="true"&&(t.quiet=!0),t}function ts(e){Xt(e),process.exit(0)}F();import{get as ri}from"https";import{readFileSync as jt,writeFileSync as ai,mkdirSync as ci}from"fs";import{homedir as li}from"os";import{join as ss}from"path";import{execSync as st}from"child_process";var ns=ss(li(),".codebase"),is=ss(ns,"update-check.json"),ui=1440*60*1e3,me="codebase-ai",ke=!!process.env.NO_COLOR,M={yellow:ke?"":"\x1B[33m",cyan:ke?"":"\x1B[36m",green:ke?"":"\x1B[32m",bold:ke?"":"\x1B[1m",dim:ke?"":"\x1B[2m",reset:ke?"":"\x1B[0m"};function di(){return"0.3.5"}function pi(e,t){let s=l=>l.replace(/^v/,"").split(".").map(Number),[n,i,o]=s(e),[r,a,c]=s(t);return n!==r?n>r:i!==a?i>a:o>c}function fi(){try{return JSON.parse(jt(is,"utf8"))}catch{return null}}function mi(e){try{ci(ns,{recursive:!0}),ai(is,JSON.stringify({version:e,checkedAt:Date.now()}))}catch{}}function gi(){return new Promise((e,t)=>{let s=ri(`https://registry.npmjs.org/${me}/latest`,{headers:{accept:"application/json"}},n=>{let i="";n.on("data",o=>i+=o.toString()),n.on("end",()=>{try{e(JSON.parse(i).version)}catch{t(new Error("parse error"))}})});s.on("error",t),s.setTimeout(3e3,()=>{s.destroy(),t(new Error("timeout"))})})}function hi(){try{let e=st("npm root -g 2>/dev/null",{encoding:"utf8"}).trim();if(e&&jt(`${e}/${me}/package.json`,"utf8"))return`npm install -g ${me}@latest`}catch{}try{st("pnpm --version 2>/dev/null",{encoding:"utf8"});let e=st("pnpm root -g 2>/dev/null",{encoding:"utf8"}).trim();if(e&&jt(`${e}/${me}/package.json`,"utf8"))return`pnpm add -g ${me}@latest`}catch{}try{return st("yarn --version 2>/dev/null",{encoding:"utf8"}),`yarn global add ${me}@latest`}catch{}return`npm install -g ${me}@latest`}async function os(){if(process.env.CI||process.env.NO_UPDATE_CHECK||process.env.CODEBASE_NO_UPDATE_CHECK||!process.stdout.isTTY)return;let e=di(),t=fi(),s;if(t&&Date.now()-t.checkedAt<ui)s=t.version;else try{s=await gi(),mi(s)}catch{return}if(!pi(s,e))return;let n=hi();console.error(`
|
|
556
|
+
${M.yellow}\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510${M.reset}`),console.error(` ${M.yellow}\u2502${M.reset} ${M.bold}Update available${M.reset} ${M.dim}${e}${M.reset} ${M.yellow}\u2192${M.reset} ${M.bold}${M.cyan}${s}${M.reset}`),console.error(` ${M.yellow}\u2502${M.reset} Run: ${M.bold}${n}${M.reset}`),console.error(` ${M.yellow}\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518${M.reset}
|
|
557
|
+
`)}Ot();ze();je();import{resolve as Zr,join as he}from"path";import{existsSync as bt,writeFileSync as ea,readFileSync as hn}from"fs";import{execFile as gn}from"child_process";import{writeFile as qt,rename as ta}from"fs/promises";import{homedir as sa}from"os";Be();var Xr=[ae];function mn(e){return Xr.filter(t=>t.detect(e))}Be();pt();ft();F();function na(e){if(!bt(he(e,".codebase.json")))return!1;let t=he(e,"CLAUDE.md");if(bt(t))try{let s=hn(t,"utf-8"),n=s.includes("<!-- codebase:start -->")&&s.includes("<!-- codebase:end -->"),i=s.includes("# codebase:start")&&s.includes("# codebase:end");if(n||i)return!0}catch{}return!1}async function bn(e){let t=Date.now();ee(e.quiet);let s=Zr(e.path);if(na(s)&&!e.force){S(`codebase \u2014 refreshing project manifest
|
|
558
|
+
`);let E=await De()==="authenticated";u(`Scanning ${s}...`);let A=await K(s,{depth:e.depth,categories:e.categories.length?e.categories:void 0,quiet:e.quiet,sync:E}),G=he(s,".codebase.json"),R=JSON.stringify(A,null,2);await qt(G,R,"utf-8");let U=(Buffer.byteLength(R)/1024).toFixed(1);g(`Manifest refreshed \u2014 .codebase.json (${U} KB)`),h("Already initialized. Run with --force to force full re-setup.");return}S(`codebase \u2014 activating project intelligence
|
|
559
|
+
`);let n=await De();n==="authenticated"?g("GitHub CLI \u2014 authenticated"):n==="not-authenticated"?(_("GitHub CLI installed but not logged in"),h("Run: gh auth login"),h("After login, re-run `npx codebase` for full GitHub integration\n")):(h("GitHub CLI not found \u2014 GitHub features disabled"),h(`To enable: brew install gh && gh auth login
|
|
560
|
+
`));let i=n==="authenticated";u(`Scanning ${s}...`);let o=await K(s,{depth:e.depth,categories:e.categories.length?e.categories:void 0,quiet:e.quiet,sync:i});for(let[f,E]of Object.entries(o))f==="version"||f==="generated_at"||typeof E!="object"||E===null||g(`${ia(f)} (${ut(f,E)})`);let r=he(s,".codebase.json"),a=JSON.stringify(o,null,2);await qt(r,a,"utf-8");let c=(Buffer.byteLength(a)/1024).toFixed(1);u(`
|
|
568
561
|
Written: .codebase.json (${c} KB)`),S("AI Tool Integration");let l=mn(s),p=oa(),d=new Set(l.map(f=>f.name));for(let f of p)d.has(f.name)||(l.push(f),d.add(f.name));l.length===0?(h("No AI tool detected in project or system configs"),h("Creating CLAUDE.md as default (works with Claude Code, and readable by all tools)"),ea(he(s,"CLAUDE.md"),`# Project Rules
|
|
569
562
|
|
|
570
|
-
`,"utf-8"),l=[ae]):u(` Detected: ${l.map(f=>f.name).join(", ")}`);for(let f of l){let
|
|
563
|
+
`,"utf-8"),l=[ae]):u(` Detected: ${l.map(f=>f.name).join(", ")}`);for(let f of l){let E=await f.inject(s);E.ok?g(`${f.name} \u2014 instructions injected`):_(`${f.name} \u2014 injection failed: ${E.message||"unknown error"}`)}S("MCP Server (native AI tool access)");let m=await Ht(s,d);if(m.length){for(let f of m)g(`${f} \u2014 MCP server auto-configured`);h("AI tools can now call project_brief, get_next_task, create_issue, etc. natively")}else h("AI tools will read .codebase.json directly."),h("To enable MCP later, add to your tool's MCP config:"),u(' { "command": "npx", "args": ["codebase", "mcp"] }');if(S("Auto-Update Hooks"),Re(s,i)?(g("post-commit hook \u2014 manifest updates on every commit"),g("post-checkout hook \u2014 manifest updates on branch switch"),i&&g("hooks include GitHub sync \u2014 issues/PRs stay current")):h("Not a git repository \u2014 skipping hooks"),Ce(s),g(".gitignore updated"),S(`Ready!
|
|
571
564
|
`),u(`Your project is now fully activated. Here's what happens automatically:
|
|
572
565
|
`),u(" On every commit \u2192 .codebase.json updates (code + GitHub data)"),u(" On branch switch \u2192 .codebase.json updates"),u(" When AI starts \u2192 reads .codebase.json or calls project_brief via MCP"),u(" AI knows \u2192 stack, commands, open issues, priorities, blockers, decisions"),u(` AI can \u2192 create issues, close issues, get next task, check blockers
|
|
573
|
-
`),i){let f=o.status?.issues?.filter(A=>A.state==="open").length||0,
|
|
566
|
+
`),i){let f=o.status?.issues?.filter(A=>A.state==="open").length||0,E=o.status?.pull_requests?.filter(A=>A.state==="open").length||0;(f||E)&&u(` GitHub synced: ${f} open issues, ${E} open PRs`)}let b=o.stack?.languages??[];!(Object.keys(o.commands??{}).length>0)&&b.every(f=>f==="json"||f==="yaml"||f==="markdown")&&(u(" Next steps for a new project:"),u(" 1. Add your source files (e.g. src/index.ts, src/index.js)"),u(" 2. Add scripts to package.json (build, test, dev, etc.)"),u(" 3. Re-run `codebase` \u2014 the manifest will update automatically\n")),u(`
|
|
574
567
|
You don't need to run this again. Everything stays alive.
|
|
575
|
-
`);let
|
|
568
|
+
`);let C=((Date.now()-t)/1e3).toFixed(1);g(`Done (${C}s)`)}function ia(e){return e.charAt(0).toUpperCase()+e.slice(1)}function De(){return new Promise(e=>{gn("sh",["-c","which gh 2>/dev/null"],{timeout:5e3},t=>{if(t){e("not-installed");return}gn("sh",["-c","gh auth status 2>&1"],{timeout:1e4},(s,n,i)=>{let o=(n||"")+(i||"");!s&&o.includes("Logged in")?e("authenticated"):e("not-authenticated")})})})}function oa(){let e=sa(),t=[];return bt(he(e,".claude"))&&t.push(ae),t}async function Ht(e,t){let s=[],n={command:"npx",args:["codebase","mcp"],cwd:e};if(t.has("claude")||t.size===0){let i=he(e,".mcp.json");await ra(i,"codebase",n)&&s.push("Claude Code (project .mcp.json)")}return s}async function ra(e,t,s){let n={};if(bt(e)){try{n=JSON.parse(hn(e,"utf-8"))}catch{n={}}let o=n.mcpServers;if(o&&o[t])return!1}n.mcpServers||(n.mcpServers={}),n.mcpServers[t]=s;let i=`${e}.tmp`;return await qt(i,JSON.stringify(n,null,2)+`
|
|
576
569
|
`,"utf-8"),await ta(i,e),!0}import{resolve as aa,join as ca}from"path";import{readFile as la}from"fs/promises";import{existsSync as ua}from"fs";function yt(e){let t=[],s=e.project?.name||"Unknown Project";t.push(`# PROJECT BRIEF: ${s}`),e.project?.description&&t.push(e.project.description),t.push(`
|
|
577
570
|
Generated: ${e.generated_at}
|
|
578
571
|
`),t.push("## Technical Overview");let n=[];if(e.repo?.url&&(n.push(`Repository: ${e.repo.url}`),n.push(`Default branch: ${e.repo.default_branch||"unknown"}`),e.repo.is_monorepo&&n.push(`Monorepo: yes (${e.repo.workspace_manager||"workspaces"})`)),e.stack){let o=[];e.stack.languages?.length&&o.push(`Languages: ${e.stack.languages.join(", ")}`),e.stack.frameworks?.length&&o.push(`Frameworks: ${e.stack.frameworks.join(", ")}`),e.stack.package_manager&&o.push(`Package manager: ${e.stack.package_manager}`),e.stack.database&&o.push(`Database: ${e.stack.database}`),e.stack.orm&&o.push(`ORM: ${e.stack.orm}`),e.stack.styling&&o.push(`Styling: ${e.stack.styling}`),e.stack.build_tool&&o.push(`Build tool: ${e.stack.build_tool}`),n.push(o.join(`
|
|
@@ -590,16 +583,16 @@ Generated: ${e.generated_at}
|
|
|
590
583
|
## Recent Decisions`);for(let o of i.slice(0,5))t.push(`- ${o.title} (${o.source})`),o.summary&&t.push(` ${o.summary.slice(0,150)}`)}if(e.git&&(e.git.uncommitted_changes&&(t.push(`
|
|
591
584
|
## WARNING`),t.push("There are uncommitted changes in the working directory.")),e.git.recent_commits?.length)){t.push(`
|
|
592
585
|
## Recent Commits`);for(let o of e.git.recent_commits.slice(0,3))t.push(`- ${o}`)}return t.join(`
|
|
593
|
-
`)}
|
|
594
|
-
`)}function da(e,t){let s={version:e.version,generated_at:e.generated_at,project:e.project},n={project:"project",repo:"repo",structure:"structure",stack:"stack",commands:"commands",dependencies:"dependencies",config:"config",git:"git",quality:"quality",patterns:"patterns",status:"status",roadmap:"roadmap",decisions:"decisions"};for(let i of t){let o=n[i.toLowerCase()];o&&e[o]&&(s[o]=e[o])}return s}function pa(e,t){return t==="json"?JSON.stringify(e,null,2):yt(e)}
|
|
586
|
+
`)}F();async function yn(e){let t=aa(e.path),s=ca(t,".codebase.json");ua(s)||(console.error("No manifest found. Run 'codebase init' to set up this project first."),process.exit(1));let n;try{let r=await la(s,"utf-8");n=JSON.parse(r)}catch{v("No .codebase.json found (or it's corrupted). Run `npx codebase` first."),process.exit(1)}!e.quiet&&!n.status&&!n.roadmap&&_("GitHub data unavailable (gh not authenticated or --sync not used). Issues, PRs and milestones not included.");let i=n;e.categories.length>0&&(i=da(n,e.categories));let o=pa(i,e.format);process.stdout.write(o+`
|
|
587
|
+
`)}function da(e,t){let s={version:e.version,generated_at:e.generated_at,project:e.project},n={project:"project",repo:"repo",structure:"structure",stack:"stack",commands:"commands",dependencies:"dependencies",config:"config",git:"git",quality:"quality",patterns:"patterns",status:"status",roadmap:"roadmap",decisions:"decisions"};for(let i of t){let o=n[i.toLowerCase()];o&&e[o]&&(s[o]=e[o])}return s}function pa(e,t){return t==="json"?JSON.stringify(e,null,2):yt(e)}F();He();import{resolve as fa,join as kn}from"path";import{readFile as ma}from"fs/promises";import{existsSync as ga}from"fs";function ha(e){for(let t of e){let s=t.toLowerCase();if(!s.startsWith("status:")&&(s.includes("p0")||s.includes("critical")||s.includes("urgent")))return"critical (P0)"}for(let t of e){let s=t.toLowerCase();if(!s.startsWith("status:")&&(s==="vibekit"||s.includes("p1")||s.includes("high")||s.includes("bug")))return"high (P1)"}for(let t of e){let s=t.toLowerCase();if(!s.startsWith("status:")&&(s.includes("p2")||s.includes("medium")||s==="arch"))return"medium (P2)"}for(let t of e){let s=t.toLowerCase();if(!s.startsWith("status:")&&(s.includes("p3")||s.includes("low")))return"low (P3)"}for(let t of e)if(t.toLowerCase().includes("feature"))return"feature";return"unlabeled (lowest)"}async function wn(e){let t=fa(e.path);ga(kn(t,".codebase.json"))||(console.error("No manifest found. Run 'codebase init' to set up this project first."),process.exit(1));let s;try{let l=await ma(kn(t,".codebase.json"),"utf-8");s=JSON.parse(l)}catch{v("No .codebase.json found (or it's corrupted). Run `npx codebase` first."),process.exit(1)}let n=s.status;if(!n||!n.github_available){h("No GitHub data. Run `npx codebase` with `gh` CLI authenticated.");return}let i=n.kanban?.in_progress||[];if(i.length){u(w("IN PROGRESS (don't duplicate):"));for(let l of i){let p=l.assignee?` \u2192 @${l.assignee}`:"";u(` #${l.number}: ${l.title}${p}`)}u("")}let o=n.priorities??[];if(!o.length){let l=(s.status?.issues??[]).filter(p=>p.state==="open");o=qe(l)}let r=o[0];if(!r){u("No open tasks in the backlog. Create one:"),u(' codebase issue create "task title"');return}if(u(w("NEXT TASK:")),u(` #${r.number}: ${r.title}`),r.labels.length&&u(` Labels: ${r.labels.join(", ")}`),u(` Priority: ${ha(r.labels)}`),r.effort){let l={S:"Small (hours)",M:"Medium (days)",L:"Large (weeks)"}[r.effort];u(` Effort: ${l}`)}r.assignee&&u(` Assignee: @${r.assignee}`),r.milestone&&u(` Milestone: ${r.milestone}`),r.mapped_files?.length&&u(` Start in: ${r.mapped_files.join(", ")}`);let a=n.kanban?.needs_verify??[];if(a.length>0){u(`
|
|
595
588
|
${w("NEEDS VERIFY (simulate to close):")}`);for(let l of a.slice(0,5))u(` #${l.number}: ${l.title}`)}let c=n.issues?.filter(l=>l.state==="open"&&l.labels.some(p=>p.toLowerCase().includes("blocked")||p.toLowerCase().includes("blocker")))||[];if(c.length){u(`
|
|
596
|
-
${w("BLOCKERS:")}`);for(let l of c)u(` #${l.number}: ${l.title} [${l.labels.join(", ")}]`)}}import{resolve as ba,join as ya}from"path";import{readFile as ka}from"fs/promises";import{existsSync as wa}from"fs";function Ae(e,t){let s=t.split("."),n=e;for(let i of s){if(n==null||typeof n!="object")return;n=n[i]}return n}
|
|
589
|
+
${w("BLOCKERS:")}`);for(let l of c)u(` #${l.number}: ${l.title} [${l.labels.join(", ")}]`)}}import{resolve as ba,join as ya}from"path";import{readFile as ka}from"fs/promises";import{existsSync as wa}from"fs";function Ae(e,t){let s=t.split("."),n=e;for(let i of s){if(n==null||typeof n!="object")return;n=n[i]}return n}F();async function vn(e){let t=ba(e.path),s=ya(t,".codebase.json");wa(s)||(console.error("No manifest found. Run 'codebase init' to set up this project first."),process.exit(1));let n;try{let r=await ka(s,"utf-8");n=JSON.parse(r)}catch{v("No .codebase.json found (or it's corrupted). Run `npx codebase` first."),process.exit(1)}let i=e.positionals[0];if(!i){process.stdout.write(JSON.stringify(n,null,2)+`
|
|
597
590
|
`);return}let o=Ae(n,i);o===void 0&&(v(`Path "${i}" not found in manifest.`),process.exit(1)),e.force?typeof o=="string"?process.stdout.write(o+`
|
|
598
591
|
`):Array.isArray(o)?process.stdout.write(o.join(`
|
|
599
592
|
`)+`
|
|
600
593
|
`):process.stdout.write(JSON.stringify(o)+`
|
|
601
594
|
`):process.stdout.write(JSON.stringify(o,null,2)+`
|
|
602
|
-
`)}import{resolve as $a}from"path";
|
|
595
|
+
`)}import{resolve as $a}from"path";F();import{execFile as va}from"child_process";function Oe(e,t){return new Promise((s,n)=>{va("gh",t,{cwd:e,timeout:3e4},(i,o,r)=>{i?n(new Error(r||i.message)):s(o.trim())})})}async function $n(e,t,s,n){let i=s||`## Summary
|
|
603
596
|
|
|
604
597
|
${t}
|
|
605
598
|
|
|
@@ -615,15 +608,15 @@ ${t}
|
|
|
615
608
|
|
|
616
609
|
`,o=["issue","create","--title",t,"--body",i];n?.length&&o.push("--label",n.join(","));try{let r=await Oe(e,o),a=r.split("/").pop()??"";g(`Created #${a} \u2014 ${r}`)}catch(r){v(`Failed to create issue: ${r.message}`)}}async function xn(e,t,s){try{let n=["issue","close",t];s&&n.push("--comment",s),await Oe(e,n);try{let i=await Oe(e,["issue","view",t,"--json","title,url"]),{title:o,url:r}=JSON.parse(i);g(`Closed #${t}: ${o}`),u(` ${r}`)}catch{g(`Closed issue #${t}`)}}catch(n){v(`Failed to close issue: ${n.message}`)}}async function jn(e,t){try{let s=["issue","list","--limit","30"];t==="mine"&&s.push("--assignee","@me");let n=await Oe(e,s);n?u(n):u("No issues found.")}catch(s){v(`Failed to list issues: ${s.message}`)}}async function Sn(e,t,s){try{let n=await Oe(e,["issue","comment",t,"--body",s]);n?g(`Comment added to #${t} \u2014 ${n}`):g(`Comment added to #${t}`)}catch(n){v(`Failed to comment on issue: ${n.message}`)}}async function Cn(e,t,s){try{let n=`**Mapped files:**
|
|
617
610
|
${s.map(i=>`- \`${i}\``).join(`
|
|
618
|
-
`)}`;await Oe(e,["issue","comment",t,"--body",n]),g(`Mapped issue #${t} to ${s.length} files`)}catch(n){v(`Failed to map issue: ${n.message}`)}}
|
|
611
|
+
`)}`;await Oe(e,["issue","comment",t,"--body",n]),g(`Mapped issue #${t} to ${s.length} files`)}catch(n){v(`Failed to map issue: ${n.message}`)}}F();async function En(e){let t=$a(e.path);switch(e.subcommand){case"create":{let s=e.positionals[0];s||(v('Usage: codebase issue create "Issue title" [--message "body"]'),process.exit(1)),await $n(t,s,e.message||void 0);break}case"close":{let s=e.positionals[0];s||(v('Usage: codebase issue close <number> [--reason "reason"]'),process.exit(1)),await xn(t,s,e.reason||void 0);break}case"comment":{let s=e.positionals[0],n=e.message;(!s||!n)&&(v('Usage: codebase issue comment <number> --message "text"'),process.exit(1)),await Sn(t,s,n);break}case"list":{let s=e.positionals[0];await jn(t,s);break}case"map":{let s=e.positionals[0],n=e.positionals.slice(1);(!s||n.length===0)&&(v("Usage: codebase issue map <number> <file1> <file2> ..."),process.exit(1)),await Cn(t,s,n);break}default:v("Usage: codebase issue create|close|comment|list|map"),process.exit(1)}}He();F();import{resolve as xa,join as Gt}from"path";import{readFile as _n,writeFile as ja,rename as Sa}from"fs/promises";import{existsSync as Ca}from"fs";async function Rn(e){let t=xa(e.path);Ca(Gt(t,".codebase.json"))||(console.error("No manifest found. Run 'codebase init' to set up this project first."),process.exit(1));let s=null;try{s=JSON.parse(await _n(Gt(t,".codebase.json"),"utf-8"))}catch{}if(!s?.status){h("Syncing from GitHub...");let o=await $e(t);if(o||(v("Could not sync. Is `gh` CLI installed and authenticated?"),process.exit(1)),o&&s){s.status=o.status,s.roadmap=o.roadmap,s.decisions=o.decisions;try{let r=Gt(t,".codebase.json"),c={...JSON.parse(await _n(r,"utf-8")),status:o.status,roadmap:o.roadmap,decisions:o.decisions},l=r+".tmp";await ja(l,JSON.stringify(c,null,2),"utf-8"),await Sa(l,r)}catch{}}}let n=s?.status;if(!n){v("No status data available.");return}let i=e.positionals[0];(i==="kanban"||!i)&&Ea(n),(i==="priorities"||!i)&&_a(n),i==="milestones"&&s?.roadmap&&Ra(s.roadmap),i==="decisions"&&s?.decisions&&Pa(s.decisions),i||te(`
|
|
619
612
|
Also try: codebase status milestones | codebase status priorities | codebase status decisions`)}function Ea(e){S("Kanban Board");let{kanban:t}=e;u(`
|
|
620
613
|
${w("BACKLOG")} (${t.backlog.length})`);for(let n of t.backlog.slice(0,10))u(` #${n.number} ${n.title}`);t.backlog.length>10&&te(` \u2026 and ${t.backlog.length-10} more`),u(`
|
|
621
614
|
${w("IN PROGRESS")} (${t.in_progress.length})`);for(let n of t.in_progress.slice(0,10)){let i=n.assignee?` @${n.assignee}`:"";u(` #${n.number} ${n.title}${i}`)}t.in_progress.length>10&&te(` \u2026 and ${t.in_progress.length-10} more`);let s=t.needs_verify??[];if(s.length>0){u(`
|
|
622
615
|
${w("NEEDS VERIFY")} (${s.length})`);for(let n of s.slice(0,10))u(` #${n.number} ${n.title}`);s.length>10&&te(` \u2026 and ${s.length-10} more`)}u(`
|
|
623
616
|
${w("DONE")} (${t.done.length} recent)`);for(let n of t.done.slice(0,5))u(` #${n.number} ${n.title}`);t.done.length>5&&te(` \u2026 and ${t.done.length-5} more`)}function _a(e){S("Priority Queue");for(let t of e.priorities.slice(0,15)){let s=t.labels.length?` [${t.labels.join(", ")}]`:"",n=t.assignee?` \u2192 @${t.assignee}`:"";u(` #${t.number} ${t.title}${s}${n}`)}}function Ra(e){S("Milestones");for(let t of e.milestones){let s=Da(t.progress.percent),n=t.due_date?` (due: ${t.due_date.split("T")[0]})`:"";u(`
|
|
624
|
-
${w(t.title)} ${s} ${t.progress.percent}%${n}`),u(` ${t.progress.closed}/${t.progress.open+t.progress.closed} issues closed`)}}function Pa(e){S("Decisions");let t=[...e.from_prs.map(s=>({...s,type:"PR"})),...e.from_adrs.map(s=>({...s,type:"ADR"})),...e.manual.map(s=>({...s,type:"Manual"}))].sort((s,n)=>(n.date||"").localeCompare(s.date||""));for(let s of t.slice(0,15))u(` [${s.type}] ${s.title}`),s.summary&&u(` ${s.summary.slice(0,100)}`)}function Da(e){let t=Math.round(e/5),s=20-t;return`[${"\u2588".repeat(t)}${"\u2591".repeat(s)}]`}import{resolve as Ga}from"path";import{createInterface as Aa}from"readline";import{readFile as Qe,writeFile as wt,rename as vt}from"fs/promises";import{existsSync as kt,readdirSync as Pn}from"fs";import{join as Y,resolve as Dn}from"path";import{homedir as An}from"os";import{execFile as In}from"child_process";je();He();var Oa=[{name:"project_brief",description:"CALL THIS FIRST at the start of every session. Returns a complete project briefing: what the project is, tech stack, current priorities, open issues, blockers, what to work on next, and recent decisions. This is your single source of truth \u2014 call it before doing anything else.",inputSchema:{type:"object",properties:{}}},{name:"get_codebase",description:"Get codebase data by category with optional sparse field selection. Use the 'fields' array to request only specific fields (e.g. fields: ['languages', 'frameworks'] from category: 'stack'). For single dot-path lookups use query_codebase instead.",inputSchema:{type:"object",properties:{category:{type:"string",description:"Section to retrieve: repo, structure, stack, commands, dependencies, config, git, quality, patterns, status, roadmap, decisions"},fields:{type:"array",items:{type:"string"},description:"Optional. When category is specified, return only these keys from that section. E.g. ['languages', 'frameworks'] for stack."}}}},{name:"query_codebase",description:"Query a specific field using dot-path notation. Handles both targeted dot-path queries (e.g. 'stack.languages') and full category reads (e.g. 'stack'). Examples: 'stack.languages', 'commands.test', 'status.kanban.in_progress', 'roadmap.milestones'.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Dot-path query, e.g. 'stack.languages', 'commands.test', 'status.priorities'"},fields:{type:"array",items:{type:"string"},description:"Optional: return only these fields from the result object"}},required:["path"]}},{name:"get_next_task",description:"Get the highest-priority task you should work on next. Returns the top open issue ranked by priority labels (P0 > P1 > bugs > features), including mapped files so you know where to start coding.",inputSchema:{type:"object",properties:{}}},{name:"get_blockers",description:"Get all current blockers \u2014 issues labeled as blocked, PRs waiting for review, PRs with failing CI checks, PRs with merge conflicts, and uncommitted changes. Shows what's preventing progress.",inputSchema:{type:"object",properties:{}}},{name:"create_issue",description:"Create a new GitHub issue. Use this when you discover a bug, identify needed work, or the user asks to track something. Returns the issue URL.",inputSchema:{type:"object",properties:{title:{type:"string",description:"Issue title"},body:{type:"string",description:"Issue body/description (markdown)"},labels:{type:"array",items:{type:"string"},description:"Labels to apply: bug, feature, enhancement, P0, P1, P2, etc."}},required:["title"]}},{name:"close_issue",description:"Close a GitHub issue after fixing it. Add a comment explaining what was done.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Issue number to close"},comment:{type:"string",description:"Comment explaining resolution"}},required:["number"]}},{name:"update_issue",description:"Update a GitHub issue \u2014 add/remove labels, set assignee. Use this to advance issues through the pipeline (e.g., add 'status:in-progress', remove 'status:backlog').",inputSchema:{type:"object",properties:{number:{type:"number",description:"Issue number"},add_labels:{type:"array",items:{type:"string"},description:"Labels to add"},remove_labels:{type:"array",items:{type:"string"},description:"Labels to remove"},assignee:{type:"string",description:"GitHub username to assign (or empty string to unassign)"}},required:["number"]}},{name:"list_commands",description:"List installed Claude Code slash commands in this project. Returns names of available commands (e.g. /vibeloop, /setup, /simulate, /build, /launch, /review).",inputSchema:{type:"object",properties:{}}},{name:"list_skills",description:"List installed Claude Code skills with their names and descriptions. Skills extend /review and other commands with stack-specific analysis.",inputSchema:{type:"object",properties:{}}},{name:"get_plan",description:"Read the project's PLAN.md \u2014 Claude's persistent working memory across sessions. Contains current sprint goals, in-flight work, decisions log, and blockers. Call this after project_brief to restore loop context.",inputSchema:{type:"object",properties:{}}},{name:"update_plan",description:"Append a status update to PLAN.md. Use this at the end of each build or simulate cycle to record what was done, decisions made, and what's next. Creates PLAN.md if it doesn't exist.",inputSchema:{type:"object",properties:{message:{type:"string",description:"Status update text to append to PLAN.md Update Log section"}},required:["message"]}},{name:"get_issue",description:"Get full details of a specific GitHub issue by number, including body, comments, and linked PRs. Use this when working on an issue and need its complete specification.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Issue number"}},required:["number"]}},{name:"get_pr",description:"Get full details of a specific pull request by number, including body, review status, checks, and diff stats.",inputSchema:{type:"object",properties:{number:{type:"number",description:"PR number"}},required:["number"]}},{name:"rescan_project",description:"Rescan the project to refresh the manifest after making changes. Call this after major refactors, dependency updates, or when your cached data feels stale.",inputSchema:{type:"object",properties:{sync:{type:"boolean",description:"Also refresh GitHub data (issues, PRs, milestones). Default: true."},incremental:{type:"boolean",description:"Only re-scan changed areas (faster). Default: false."}}}},{name:"refresh_status",description:"Refresh only GitHub data (issues, PRs, milestones) without re-scanning the filesystem. Much faster than rescan_project. Call this after creating/closing issues to get fresh priority data.",inputSchema:{type:"object",properties:{}}}];async function Nn(e){let t=Aa({input:process.stdin,terminal:!1});for await(let s of t){if(!s.trim())continue;let n;try{n=JSON.parse(s)}catch{On({jsonrpc:"2.0",id:0,error:{code:-32700,message:"Parse error"}});continue}let i=await Ia(n,e);i&&On(i)}}async function Ia(e,t){switch(e.method){case"initialize":return O(e.id,{protocolVersion:"2024-11-05",serverInfo:{name:"codebase",version:"0.3.
|
|
617
|
+
${w(t.title)} ${s} ${t.progress.percent}%${n}`),u(` ${t.progress.closed}/${t.progress.open+t.progress.closed} issues closed`)}}function Pa(e){S("Decisions");let t=[...e.from_prs.map(s=>({...s,type:"PR"})),...e.from_adrs.map(s=>({...s,type:"ADR"})),...e.manual.map(s=>({...s,type:"Manual"}))].sort((s,n)=>(n.date||"").localeCompare(s.date||""));for(let s of t.slice(0,15))u(` [${s.type}] ${s.title}`),s.summary&&u(` ${s.summary.slice(0,100)}`)}function Da(e){let t=Math.round(e/5),s=20-t;return`[${"\u2588".repeat(t)}${"\u2591".repeat(s)}]`}import{resolve as Ga}from"path";import{createInterface as Aa}from"readline";import{readFile as Qe,writeFile as wt,rename as vt}from"fs/promises";import{existsSync as kt,readdirSync as Pn}from"fs";import{join as Y,resolve as Dn}from"path";import{homedir as An}from"os";import{execFile as In}from"child_process";je();He();var Oa=[{name:"project_brief",description:"CALL THIS FIRST at the start of every session. Returns a complete project briefing: what the project is, tech stack, current priorities, open issues, blockers, what to work on next, and recent decisions. This is your single source of truth \u2014 call it before doing anything else.",inputSchema:{type:"object",properties:{}}},{name:"get_codebase",description:"Get codebase data by category with optional sparse field selection. Use the 'fields' array to request only specific fields (e.g. fields: ['languages', 'frameworks'] from category: 'stack'). For single dot-path lookups use query_codebase instead.",inputSchema:{type:"object",properties:{category:{type:"string",description:"Section to retrieve: repo, structure, stack, commands, dependencies, config, git, quality, patterns, status, roadmap, decisions"},fields:{type:"array",items:{type:"string"},description:"Optional. When category is specified, return only these keys from that section. E.g. ['languages', 'frameworks'] for stack."}}}},{name:"query_codebase",description:"Query a specific field using dot-path notation. Handles both targeted dot-path queries (e.g. 'stack.languages') and full category reads (e.g. 'stack'). Examples: 'stack.languages', 'commands.test', 'status.kanban.in_progress', 'roadmap.milestones'.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Dot-path query, e.g. 'stack.languages', 'commands.test', 'status.priorities'"},fields:{type:"array",items:{type:"string"},description:"Optional: return only these fields from the result object"}},required:["path"]}},{name:"get_next_task",description:"Get the highest-priority task you should work on next. Returns the top open issue ranked by priority labels (P0 > P1 > bugs > features), including mapped files so you know where to start coding.",inputSchema:{type:"object",properties:{}}},{name:"get_blockers",description:"Get all current blockers \u2014 issues labeled as blocked, PRs waiting for review, PRs with failing CI checks, PRs with merge conflicts, and uncommitted changes. Shows what's preventing progress.",inputSchema:{type:"object",properties:{}}},{name:"create_issue",description:"Create a new GitHub issue. Use this when you discover a bug, identify needed work, or the user asks to track something. Returns the issue URL.",inputSchema:{type:"object",properties:{title:{type:"string",description:"Issue title"},body:{type:"string",description:"Issue body/description (markdown)"},labels:{type:"array",items:{type:"string"},description:"Labels to apply: bug, feature, enhancement, P0, P1, P2, etc."}},required:["title"]}},{name:"close_issue",description:"Close a GitHub issue after fixing it. Add a comment explaining what was done.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Issue number to close"},comment:{type:"string",description:"Comment explaining resolution"}},required:["number"]}},{name:"update_issue",description:"Update a GitHub issue \u2014 add/remove labels, set assignee. Use this to advance issues through the pipeline (e.g., add 'status:in-progress', remove 'status:backlog').",inputSchema:{type:"object",properties:{number:{type:"number",description:"Issue number"},add_labels:{type:"array",items:{type:"string"},description:"Labels to add"},remove_labels:{type:"array",items:{type:"string"},description:"Labels to remove"},assignee:{type:"string",description:"GitHub username to assign (or empty string to unassign)"}},required:["number"]}},{name:"list_commands",description:"List installed Claude Code slash commands in this project. Returns names of available commands (e.g. /vibeloop, /setup, /simulate, /build, /launch, /review).",inputSchema:{type:"object",properties:{}}},{name:"list_skills",description:"List installed Claude Code skills with their names and descriptions. Skills extend /review and other commands with stack-specific analysis.",inputSchema:{type:"object",properties:{}}},{name:"get_plan",description:"Read the project's PLAN.md \u2014 Claude's persistent working memory across sessions. Contains current sprint goals, in-flight work, decisions log, and blockers. Call this after project_brief to restore loop context.",inputSchema:{type:"object",properties:{}}},{name:"update_plan",description:"Append a status update to PLAN.md. Use this at the end of each build or simulate cycle to record what was done, decisions made, and what's next. Creates PLAN.md if it doesn't exist.",inputSchema:{type:"object",properties:{message:{type:"string",description:"Status update text to append to PLAN.md Update Log section"}},required:["message"]}},{name:"get_issue",description:"Get full details of a specific GitHub issue by number, including body, comments, and linked PRs. Use this when working on an issue and need its complete specification.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Issue number"}},required:["number"]}},{name:"get_pr",description:"Get full details of a specific pull request by number, including body, review status, checks, and diff stats.",inputSchema:{type:"object",properties:{number:{type:"number",description:"PR number"}},required:["number"]}},{name:"rescan_project",description:"Rescan the project to refresh the manifest after making changes. Call this after major refactors, dependency updates, or when your cached data feels stale.",inputSchema:{type:"object",properties:{sync:{type:"boolean",description:"Also refresh GitHub data (issues, PRs, milestones). Default: true."},incremental:{type:"boolean",description:"Only re-scan changed areas (faster). Default: false."}}}},{name:"refresh_status",description:"Refresh only GitHub data (issues, PRs, milestones) without re-scanning the filesystem. Much faster than rescan_project. Call this after creating/closing issues to get fresh priority data.",inputSchema:{type:"object",properties:{}}}];async function Nn(e){let t=Aa({input:process.stdin,terminal:!1});for await(let s of t){if(!s.trim())continue;let n;try{n=JSON.parse(s)}catch{On({jsonrpc:"2.0",id:0,error:{code:-32700,message:"Parse error"}});continue}let i=await Ia(n,e);i&&On(i)}}async function Ia(e,t){switch(e.method){case"initialize":return O(e.id,{protocolVersion:"2024-11-05",serverInfo:{name:"codebase",version:"0.3.5"},capabilities:{tools:{}}});case"notifications/initialized":return null;case"tools/list":return O(e.id,{tools:Oa});case"tools/call":return Na(e,t);default:return{jsonrpc:"2.0",id:e.id,error:{code:-32601,message:`Method not found: ${e.method}`}}}}async function Na(e,t){let s=e.params||{},n=s.name,i=s.arguments||{};try{switch(n){case"project_brief":{let o=await Ve(t,!0),r=yt(o);return O(e.id,{content:[{type:"text",text:r}]})}case"get_codebase":{let o=await Ve(t),r=i.category,a=i.fields;if(r){let c=o[r];if(a?.length&&c&&typeof c=="object"&&c!==null){let l={};for(let p of a)l[p]=c[p];return O(e.id,{content:[{type:"text",text:JSON.stringify(l,null,2)}]})}return O(e.id,{content:[{type:"text",text:JSON.stringify(c??null,null,2)}]})}return O(e.id,{content:[{type:"text",text:JSON.stringify(o,null,2)}]})}case"query_codebase":{let o=await Ve(t),r=i.path,a=i.fields,c=Ae(o,r);if(a?.length&&c!==null&&c!==void 0&&typeof c=="object"&&!Array.isArray(c)){let l={};for(let p of a)l[p]=c[p];c=l}return O(e.id,{content:[{type:"text",text:JSON.stringify(c??null,null,2)}]})}case"get_next_task":{let o=await Ve(t,!0),r=Fa(o);return O(e.id,{content:[{type:"text",text:JSON.stringify(r,null,2)}]})}case"get_blockers":{let o=await Ve(t,!0),r=Ma(o);return O(e.id,{content:[{type:"text",text:JSON.stringify(r,null,2)}]})}case"create_issue":{let o=await Ta(t,i);return await Bt(t),O(e.id,{content:[{type:"text",text:o}]})}case"close_issue":{let o=await qa(t,i);return await Bt(t),O(e.id,{content:[{type:"text",text:o}]})}case"update_issue":{let o=await Ha(t,i);return await Bt(t),O(e.id,{content:[{type:"text",text:o}]})}case"list_commands":{let o=Y(t,".claude","commands"),r=Y(An(),".claude","commands"),a=new Set,c=[];for(let p of[o,r])if(kt(p))for(let d of Pn(p))d.endsWith(".md")&&!a.has(d)&&(a.add(d),c.push(d));if(c.length===0)return O(e.id,{content:[{type:"text",text:"No slash commands installed. Run: codebase setup"}]});let l=c.map(p=>"/"+p.replace(/\.md$/,"")).join(", ");return O(e.id,{content:[{type:"text",text:`Installed commands (${c.length}): ${l}
|
|
625
618
|
|
|
626
|
-
Loop: /simulate \u2192 /build \u2192 /launch`}]})}case"list_skills":{let o=Y(An(),".claude","skills"),r=Y(t,".claude","skills"),a=new Set,c=[];for(let p of[r,o])if(kt(p))for(let d of Pn(p))d.endsWith(".skill")&&!a.has(d)&&(a.add(d),c.push({file:d,dir:p}));if(c.length===0)return O(e.id,{content:[{type:"text",text:"No skills installed in ~/.claude/skills/ or <project>/.claude/skills/. Run: codebase setup"}]});let l=[];return await Promise.all(c.map(({file:p,dir:d})=>new Promise(m=>{let y=Y(d,p);In("unzip",["-p",y,"*/SKILL.md"],{timeout:1e4},(b,
|
|
619
|
+
Loop: /simulate \u2192 /build \u2192 /launch`}]})}case"list_skills":{let o=Y(An(),".claude","skills"),r=Y(t,".claude","skills"),a=new Set,c=[];for(let p of[r,o])if(kt(p))for(let d of Pn(p))d.endsWith(".skill")&&!a.has(d)&&(a.add(d),c.push({file:d,dir:p}));if(c.length===0)return O(e.id,{content:[{type:"text",text:"No skills installed in ~/.claude/skills/ or <project>/.claude/skills/. Run: codebase setup"}]});let l=[];return await Promise.all(c.map(({file:p,dir:d})=>new Promise(m=>{let y=Y(d,p);In("unzip",["-p",y,"*/SKILL.md"],{timeout:1e4},(b,j)=>{if(b||!j.trim()){m();return}let x=j.match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!x){m();return}let C=x[1],f=C.match(/^name:\s*(.+)$/m),E=C.match(/^description:\s*(.+)$/m),A=f?f[1].trim():p.replace(/\.skill$/,""),G=E?E[1].trim():"";l.push({name:A,description:G,file:p}),m()})}))),O(e.id,{content:[{type:"text",text:JSON.stringify(l,null,2)}]})}case"get_plan":{let o=Y(Dn(t),"PLAN.md");if(!kt(o))return O(e.id,{content:[{type:"text",text:"No PLAN.md found. Use update_plan to create one."}]});let r=await Qe(o,"utf-8");return O(e.id,{content:[{type:"text",text:r}]})}case"update_plan":{let o=Y(Dn(t),"PLAN.md"),r=i.message,c=`
|
|
627
620
|
<!-- updated: ${new Date().toISOString().split("T")[0]} -->
|
|
628
621
|
${r.trim()}
|
|
629
622
|
`,l;if(!kt(o))l=`# PLAN.md \u2014 Autonomous Loop State
|
|
@@ -645,21 +638,21 @@ ${r.trim()}
|
|
|
645
638
|
## Update Log
|
|
646
639
|
${c}`;else{let d=await Qe(o,"utf-8");d.includes("## Update Log")?l=d.replace(/(## Update Log\n)/,`$1${c}`):l=d+`
|
|
647
640
|
## Update Log
|
|
648
|
-
${c}`}let p=o+".tmp";return await wt(p,l,"utf-8"),await vt(p,o),O(e.id,{content:[{type:"text",text:"PLAN.md updated."}]})}case"get_issue":{let o=i.number,r=await se(t,["issue","view",String(o),"--json","number,title,state,body,labels,assignees,milestone,comments,url"]),a=JSON.parse(r);return O(e.id,{content:[{type:"text",text:JSON.stringify(a,null,2)}]})}case"get_pr":{let o=i.number,r=await se(t,["pr","view",String(o),"--json","number,title,state,body,author,labels,reviewRequests,reviewDecision,statusCheckRollup,additions,deletions,comments,url"]),a=JSON.parse(r);return O(e.id,{content:[{type:"text",text:JSON.stringify(a,null,2)}]})}case"rescan_project":{let o=i.sync!==!1,r=await
|
|
649
|
-
`)}async function Ln(e){let t=Ga(e.path);await Nn(t)}import{resolve as Ua,join as T}from"path";import{homedir as Ba}from"os";import{existsSync as H,readFileSync as ne,statSync as Fn,readdirSync as Mn}from"fs";
|
|
650
|
-
`);let i=T(s,".codebase.json"),o=null;if(H(i))try{let k=ne(i,"utf-8");o=JSON.parse(k);let I=Fn(i),
|
|
641
|
+
${c}`}let p=o+".tmp";return await wt(p,l,"utf-8"),await vt(p,o),O(e.id,{content:[{type:"text",text:"PLAN.md updated."}]})}case"get_issue":{let o=i.number,r=await se(t,["issue","view",String(o),"--json","number,title,state,body,labels,assignees,milestone,comments,url"]),a=JSON.parse(r);return O(e.id,{content:[{type:"text",text:JSON.stringify(a,null,2)}]})}case"get_pr":{let o=i.number,r=await se(t,["pr","view",String(o),"--json","number,title,state,body,author,labels,reviewRequests,reviewDecision,statusCheckRollup,additions,deletions,comments,url"]),a=JSON.parse(r);return O(e.id,{content:[{type:"text",text:JSON.stringify(a,null,2)}]})}case"rescan_project":{let o=i.sync!==!1,r=await K(t,{quiet:!0,sync:o,incremental:i.incremental===!0}),a=Y(t,".codebase.json"),c=a+".tmp";return await wt(c,JSON.stringify(r,null,2),"utf-8"),await vt(c,a),O(e.id,{content:[{type:"text",text:`Project rescanned. Manifest updated at ${r.generated_at}`}]})}case"refresh_status":{let o=Y(t,".codebase.json"),r=await $e(t);if(r){let a=await Qe(o,"utf-8"),c=JSON.parse(a);c.status=r.status,c.roadmap=r.roadmap,c.decisions=r.decisions;let l=c;l.generated_at=new Date().toISOString();let p=o+".tmp";await wt(p,JSON.stringify(l,null,2),"utf-8"),await vt(p,o)}return O(e.id,{content:[{type:"text",text:`GitHub data refreshed at ${new Date().toISOString()}`}]})}default:return{jsonrpc:"2.0",id:e.id,error:{code:-32602,message:`Unknown tool: ${n}`}}}}catch(o){return O(e.id,{content:[{type:"text",text:`Error: ${o.message}`}],isError:!0})}}var Ut=Number(process.env.CODEBASE_MANIFEST_TTL_HOURS),La=(Number.isFinite(Ut)&&Ut>0?Ut:24)*60*60*1e3;async function Ve(e,t=!1){try{let s=await Qe(Y(e,".codebase.json"),"utf-8"),n=JSON.parse(s);return n.generated_at&&Date.now()-new Date(n.generated_at).getTime()<=La?n:await K(e,{quiet:!0,sync:t})}catch{return await K(e,{quiet:!0,sync:t})}}function Fa(e){let t=(e.status?.issues||[]).filter(c=>c.state==="open"),s=e.status?.priorities?.length?e.status.priorities:qe(t);if(!s.length)return{summary:"No open issues found. The project has no tracked tasks. You can create issues with the create_issue tool when you identify work to do.",task:null,queue:[]};let n=s[0],i=s.slice(1,4).map(c=>({number:c.number,title:c.title,labels:c.labels})),o=[`NEXT TASK: #${n.number} \u2014 ${n.title}`];n.labels.length&&o.push(`[${n.labels.join(", ")}]`),n.assignee&&o.push(`(assigned to @${n.assignee})`),n.mapped_files?.length&&o.push(`Start in: ${n.mapped_files.join(", ")}`);let r=n.effort?{S:"Small (hours)",M:"Medium (days)",L:"Large (weeks)"}[n.effort]:void 0;r&&o.push(`Effort: ${r}`);let a=(e.status?.kanban?.needs_verify??[]).map(c=>({number:c.number,title:c.title}));return{summary:o.join(" "),task:{number:n.number,title:n.title,labels:n.labels,effort:n.effort,assignee:n.assignee,mapped_files:n.mapped_files||[],url:n.url,body:n.body||""},queue:i,needs_verify:a}}function Ma(e){let t=(e.status?.issues||[]).filter(c=>c.state==="open"&&c.labels.some(l=>l.toLowerCase().includes("blocked")||l.toLowerCase().includes("blocker"))),s=(e.status?.pull_requests||[]).filter(c=>c.state==="open"&&c.reviewers.length>0&&c.review_decision!=="approved"),n=(e.status?.pull_requests||[]).filter(c=>c.state==="open"&&c.checks_status==="failing"),i=(e.status?.pull_requests||[]).filter(c=>c.state==="open"&&c.merge_conflicts===!0),o=e.git?.uncommitted_changes??!1,r=t.length>0||s.length>0||n.length>0||i.length>0||o,a=[];return r?(t.length&&a.push(`${t.length} blocked issue(s)`),s.length&&a.push(`${s.length} PR(s) awaiting review`),n.length&&a.push(`${n.length} PR(s) with failing checks`),i.length&&a.push(`${i.length} PR(s) with merge conflicts`),o&&a.push("uncommitted changes in working directory")):a.push("No blockers found. All clear to proceed with the next task."),{summary:a.join(", "),has_blockers:r,blocked_issues:t.map(c=>({number:c.number,title:c.title,labels:c.labels,url:c.url})),prs_waiting_review:s.map(c=>({number:c.number,title:c.title,reviewers:c.reviewers,url:c.url})),prs_failing_checks:n.map(c=>({number:c.number,title:c.title,url:c.url})),prs_with_conflicts:i.map(c=>({number:c.number,title:c.title,url:c.url})),uncommitted_changes:o}}function se(e,t){return new Promise((s,n)=>{In("gh",t,{cwd:e,timeout:3e4},(i,o,r)=>{i?n(new Error(r||i.message)):s(o.trim())})})}async function Ta(e,t){let s=t.title,n=t.body||s,i=t.labels,o=["issue","create","--title",s,"--body",n];if(i?.length){let a=i.filter(c=>!c.includes(","));a.length&&o.push("--label",a.join(","))}return`Issue created: ${await se(e,o)}`}async function qa(e,t){let s=t.number,n=t.comment;return n&&await se(e,["issue","comment",String(s),"--body",n]),await se(e,["issue","close",String(s)]),`Issue #${s} closed.`}async function Ha(e,t){let s=t.number,n=t.add_labels,i=t.remove_labels,o=t.assignee,r=[];if(n?.length&&(await se(e,["issue","edit",String(s),"--add-label",n.join(",")]),r.push(`added labels: ${n.join(", ")}`)),i?.length&&(await se(e,["issue","edit",String(s),"--remove-label",i.join(",")]),r.push(`removed labels: ${i.join(", ")}`)),o!==void 0)if(o===""){let a=await se(e,["issue","view",String(s),"--json","assignees"]),{assignees:c}=JSON.parse(a);for(let l of c)await se(e,["issue","edit",String(s),"--remove-assignee",l.login]);r.push("unassigned all assignees")}else await se(e,["issue","edit",String(s),"--add-assignee",o]),r.push(`assigned to @${o}`);return r.length===0?`Issue #${s}: no changes requested.`:`Issue #${s} updated: ${r.join("; ")}.`}async function Bt(e){try{let t=Y(e,".codebase.json"),s=await Qe(t,"utf-8"),n=JSON.parse(s);n.generated_at="1970-01-01T00:00:00.000Z";let i=t+".tmp";await wt(i,JSON.stringify(n,null,2),"utf-8"),await vt(i,t)}catch{}}function O(e,t){return{jsonrpc:"2.0",id:e,result:t}}function On(e){process.stdout.write(JSON.stringify(e)+`
|
|
642
|
+
`)}async function Ln(e){let t=Ga(e.path);await Nn(t)}import{resolve as Ua,join as T}from"path";import{homedir as Ba}from"os";import{existsSync as H,readFileSync as ne,statSync as Fn,readdirSync as Mn}from"fs";F();var Ja="# codebase-auto-update";async function qn(e){let t=Date.now();ee(e.quiet);let s=Ua(e.path),n=[];S(`codebase doctor
|
|
643
|
+
`);let i=T(s,".codebase.json"),o=null;if(H(i))try{let k=ne(i,"utf-8");o=JSON.parse(k);let I=Fn(i),L=(I.size/1024).toFixed(1),V=Date.now()-I.mtimeMs,et=Ya(V);n.push({label:"Manifest",ok:!0,detail:`.codebase.json (${L} KB, ${et})`})}catch{n.push({label:"Manifest",ok:!1,detail:"Corrupted \u2014 run `codebase fix`"})}else n.push({label:"Manifest",ok:!1,detail:"Missing \u2014 run `codebase fix`"});if(o){let k=o.generated_at?new Date(o.generated_at).getTime():0,I=(Date.now()-k)/(1e3*60*60),L=!1;if(H(T(s,"src")))try{Fn(T(s,"src")).mtimeMs>k&&(L=!0)}catch{}L?n.push({label:"Freshness",ok:!1,detail:`Stale (${Math.round(I)} hours old)`}):n.push({label:"Freshness",ok:!0,detail:"Up to date"});let V=["project","repo","structure","stack","commands","dependencies","config","git","quality","patterns","api_docs"],et=V.filter(ye=>ye in o);if(et.length===V.length)n.push({label:"Detectors",ok:!0,detail:"11/11 categories present"});else{let ye=V.filter(ti=>!et.includes(ti));n.push({label:"Detectors",ok:!1,detail:`Missing: ${ye.join(", ")}`})}let xt=o._warnings;if(Array.isArray(xt)&&xt.length>0)for(let ye of xt)n.push({label:"Detector Warning",ok:!1,detail:`(non-fatal) ${ye}`})}let r=await De(),a=r==="authenticated";if(r==="authenticated"?n.push({label:"GitHub CLI",ok:!0,detail:"Authenticated"}):r==="not-authenticated"?n.push({label:"GitHub CLI",ok:!1,detail:"Not authenticated \u2014 run `gh auth login`"}):n.push({label:"GitHub CLI",ok:!1,detail:"Not installed \u2014 brew install gh"}),o){let k=o.repo?.url,I=o.status?.github_available,L=k?.includes("github.com");L&&I===!1?n.push({label:"GitHub Sync",ok:!1,detail:"Repo has GitHub remote but github_available is false"}):!L&&I===!0?n.push({label:"GitHub Sync",ok:!1,detail:"No GitHub remote but github_available is true"}):n.push({label:"GitHub Sync",ok:!0,detail:"Consistent"})}let c=Wa(s);n.push({label:"Claude Code",ok:c,detail:c?"CLAUDE.md injected":"CLAUDE.md injection missing \u2014 run `codebase fix`"});let l=Ka(s);if(n.push({label:"MCP",ok:l,detail:l?".mcp.json configured":".mcp.json missing \u2014 run `codebase fix`"}),H(T(s,".git"))){let k=Tn(s,"post-commit"),I=Tn(s,"post-checkout"),L=Qa(s);if(k&&I){let V=a&&L?" (with --sync)":"";n.push({label:"Git Hooks",ok:!0,detail:`post-commit + post-checkout${V}`})}else{let V=[];k||V.push("post-commit"),I||V.push("post-checkout"),n.push({label:"Git Hooks",ok:!1,detail:`${V.join(" + ")} missing`})}a&&k&&!L&&n.push({label:"Hook Sync",ok:!1,detail:"Missing --sync flag"})}else n.push({label:"Git Hooks",ok:!0,detail:"Not a git repo \u2014 skipped"});if(H(T(s,".git"))&&(za(s)?n.push({label:"Branch Hook",ok:!0,detail:"commit-msg blocks direct commits to main/master"}):n.push({label:"Branch Hook",ok:!1,detail:"commit-msg hook missing \u2014 run `codebase fix`"})),H(T(s,".git"))){let k=Va(s);(()=>{try{let L=JSON.parse(ne(T(s,"package.json"),"utf-8"));return!!(L.scripts?.check||L.scripts?.typecheck||L.scripts?.lint)}catch{return!1}})()?k?n.push({label:"Pre-commit",ok:!0,detail:"Runs lint + typecheck before every commit"}):n.push({label:"Pre-commit",ok:!1,detail:"pre-commit hook missing \u2014 run `codebase fix`"}):n.push({label:"Pre-commit",ok:!0,detail:"No lint/typecheck scripts \u2014 skipped"})}let p=T(s,".claude","commands");if(H(p)){let k=Mn(p).filter(I=>I.endsWith(".md"));n.push({label:"Claude Commands",ok:k.length>0,detail:`${k.length} commands in .claude/commands/`})}else n.push({label:"Claude Commands",ok:!1,detail:".claude/commands/ missing \u2014 run `codebase setup`"});let d=T(Ba(),".claude","skills");if(H(d)){let k=Mn(d).filter(I=>I.endsWith(".skill"));if(k.length>0){let I=k.map(L=>L.replace(/\.skill$/,"")).join(", ");n.push({label:"Claude Skills",ok:!0,detail:`${k.length} skill${k.length>1?"s":""} installed: ${I}`})}else n.push({label:"Claude Skills",ok:!1,detail:"No skills installed \u2014 run: codebase setup"})}else n.push({label:"Claude Skills",ok:!1,detail:"No skills installed \u2014 run: codebase setup"});let m=T(s,".claude","hooks","git-guard.sh"),y=T(s,".claude","hooks","git-post.sh"),b=T(s,".claude","settings.json"),j=H(m)&&H(y),x=(()=>{if(!H(b))return!1;try{let k=JSON.parse(ne(b,"utf-8")),I=JSON.stringify(k.hooks?.PreToolUse??""),L=JSON.stringify(k.hooks?.PostToolUse??"");return I.includes("git-guard")&&L.includes("git-post")}catch{return!1}})();if(j&&x)n.push({label:"Claude Hooks",ok:!0,detail:"git-guard + git-post wired in settings.json"});else{let k=[];j||k.push("hook scripts"),x||k.push("settings.json wiring"),n.push({label:"Claude Hooks",ok:!1,detail:`Missing: ${k.join(", ")} \u2014 run \`codebase setup\``})}let C=T(s,".gitignore");H(C)?ne(C,"utf-8").includes(".codebase.json")?n.push({label:"Gitignore",ok:!0,detail:".codebase.json in .gitignore"}):n.push({label:"Gitignore",ok:!1,detail:".codebase.json not in .gitignore"}):n.push({label:"Gitignore",ok:!1,detail:".gitignore missing"});let f=!!process.env.NO_COLOR,E=f?"":"\x1B[32m",A=f?"":"\x1B[31m",G=f?"":"\x1B[0m",R=20;function U(k){return["Manifest","Freshness","Detectors","Detector Warning"].includes(k)?"MANIFEST":["GitHub CLI","GitHub Sync"].includes(k)?"GITHUB":["Claude Code","MCP","Claude Commands","Claude Skills","Claude Hooks"].includes(k)?"AI TOOLS":"GIT"}let z=null;for(let k of n){let I=U(k.label.trimStart());I!==z&&(u(""),te(` ${I}`),z=I);let L=k.ok?`${E}\u2713${G}`:`${A}\u2717${G}`;u(` ${k.label.trimStart().padEnd(R)} ${L} ${k.detail}`)}let X=n.filter(k=>!k.ok),Ie=n.length,oe=Ie-X.length;u(""),X.length===0?u(` ${w(`Health: ${oe}/${Ie}`)} \u2014 All checks passed.`):u(` ${w(`Health: ${oe}/${Ie}`)} \u2014 ${X.length} issue${X.length>1?"s":""} found. Run \`codebase fix\` to repair.`),u("");let ei=((Date.now()-t)/1e3).toFixed(1);g(`Done (${ei}s)`),X.length>0&&process.exit(1)}function Wa(e){let t=T(e,"CLAUDE.md");return H(t)?ne(t,"utf-8").includes("<!-- codebase:start -->"):!1}function Ka(e){let t=T(e,".mcp.json");if(!H(t))return!1;try{return!!JSON.parse(ne(t,"utf-8")).mcpServers?.codebase}catch{return!1}}function Tn(e,t){let s=T(e,".git","hooks",t);return H(s)?ne(s,"utf-8").includes(Ja):!1}function za(e){let t=T(e,".git","hooks","commit-msg");return H(t)?ne(t,"utf-8").includes("codebase-branch-check"):!1}function Va(e){let t=T(e,".git","hooks","pre-commit");return H(t)?ne(t,"utf-8").includes("codebase-pre-commit"):!1}function Qa(e){let t=T(e,".git","hooks","post-commit");return H(t)?ne(t,"utf-8").includes("--sync"):!1}function Ya(e){let t=Math.floor(e/1e3);if(t<60)return`${t} sec ago`;let s=Math.floor(t/60);if(s<60)return`${s} min ago`;let n=Math.floor(s/60);if(n<24)return`${n} hr ago`;let i=Math.floor(n/24);return`${i} day${i>1?"s":""} ago`}je();import{resolve as Xa,join as J}from"path";import{homedir as Za}from"os";import{existsSync as W,readFileSync as de,readdirSync as ec}from"fs";import{writeFile as tc}from"fs/promises";ft();pt();F();var sc="# codebase-auto-update",Gn=!!process.env.NO_COLOR,nc=Gn?"":"\x1B[32m",ic=Gn?"":"\x1B[0m";function ue(e){console.log(` ${nc}\u2713${ic} ${e}`)}async function Un(e){let t=Date.now();ee(e.quiet);let s=Xa(e.path),n=0;S(`codebase fix
|
|
651
644
|
`);let i=await De(),o=i==="authenticated";i==="not-installed"?(h("GitHub CLI not installed \u2014 install with: brew install gh"),h(`(Cannot auto-fix \u2014 requires manual installation)
|
|
652
645
|
`)):i==="not-authenticated"&&(h("GitHub CLI not authenticated \u2014 run: gh auth login"),h(`(Cannot auto-fix \u2014 requires manual login)
|
|
653
|
-
`));let r=
|
|
654
|
-
Checking launch gates...`);let r=Xe(t,".codebase.json");if(Wt(r)&&!e.dryRun)try{let
|
|
646
|
+
`));let r=J(s,".codebase.json"),a=!1;if(!W(r))a=!0;else try{let R=de(r,"utf-8");JSON.parse(R)}catch{a=!0}if(!a&&W(r))try{let R=de(r,"utf-8"),U=JSON.parse(R),z=U.generated_at?new Date(U.generated_at).getTime():0;if(W(J(s,"src"))){let{statSync:X}=await import("fs");X(J(s,"src")).mtimeMs>z&&(a=!0)}}catch{a=!0}if(a){let R=await K(s,{depth:e.depth,quiet:!0,sync:o}),U=JSON.stringify(R,null,2);await tc(r,U,"utf-8");let z=(Buffer.byteLength(U)/1024).toFixed(1);ue(`Re-scanned project \u2192 .codebase.json (${z} KB)`),n++}let{claudeIntegration:c}=await Promise.resolve().then(()=>(Be(),tn));oc(s)||(c.inject(s),ue("Re-injected Claude Code instructions into CLAUDE.md"),n++);let p=await Ht(s,new Set(["claude"]));for(let R of p)ue(`Added MCP entry to ${R}`),n++;if(W(J(s,".git"))){let R=Hn(s,"post-commit"),U=Hn(s,"post-checkout"),z=rc(s),X=ac(s);if(!R||!U||o&&!z||!X){Re(s,o);let oe=[];R||oe.push("post-commit"),U||oe.push("post-checkout"),o&&!z&&oe.push("--sync flag"),X||oe.push("pre-commit"),ue(`Installed ${oe.join(" + ")} hook${oe.length>1?"s":""}`),n++}}let d=J(s,".gitignore");(W(d)?de(d,"utf-8"):"").includes(".codebase.json")||(Ce(s),ue("Added .codebase.json to .gitignore"),n++);let y=J(s,".claude","commands");if(!W(y)){let{installClaudeCommandsForFix:R}=await Promise.resolve().then(()=>(ze(),ht));R(s),ue("Installed Claude commands \u2192 .claude/commands/"),n++}let b=J(Za(),".claude","skills");if(!(W(b)&&ec(b).some(R=>R.endsWith(".skill")))){let{installClaudeSkillsForFix:R}=await Promise.resolve().then(()=>(ze(),ht));R(s),ue("Installed Claude skills \u2192 ~/.claude/skills/"),n++}let x=J(s,".claude","hooks","git-guard.sh"),C=J(s,".claude","hooks","git-post.sh"),f=J(s,".claude","settings.json"),E=W(x)&&W(C),A=(()=>{if(!W(f))return!1;try{let R=JSON.parse(de(f,"utf-8")),U=JSON.stringify(R.hooks?.PreToolUse??""),z=JSON.stringify(R.hooks?.PostToolUse??"");return U.includes("git-guard")&&z.includes("git-post")}catch{return!1}})();if(!E||!A){let{installClaudeHooksForFix:R}=await Promise.resolve().then(()=>(ze(),ht));R(s),ue("Installed Claude Code hooks \u2192 .claude/hooks/ + settings.json"),n++}u(""),n===0?u(" Nothing to fix. Your project is healthy."):u(` Fixed ${n} issue${n>1?"s":""}. Run \`codebase doctor\` to verify.`),u("");let G=((Date.now()-t)/1e3).toFixed(1);g(`Done (${G}s)`)}function oc(e){let t=J(e,"CLAUDE.md");return W(t)?de(t,"utf-8").includes("<!-- codebase:start -->"):!1}function Hn(e,t){let s=J(e,".git","hooks",t);return W(s)?de(s,"utf-8").includes(sc):!1}function rc(e){let t=J(e,".git","hooks","post-commit");return W(t)?de(t,"utf-8").includes("--sync"):!1}function ac(e){let t=J(e,".git","hooks","pre-commit");return W(t)?de(t,"utf-8").includes("codebase-pre-commit"):!1}F();import{resolve as cc,join as Xe}from"path";import{execFile as Ze}from"child_process";import{existsSync as Wt,readFileSync as $t,writeFileSync as lc}from"fs";async function Bn(e){let t=cc(e.path),s=e.dryRun,n=e.positionals[0]??null;S(`codebase release${s?" (dry run)":""}`),await uc()||(v("gh CLI not authenticated. Run: gh auth login"),process.exit(1)),await Ye(t,"remote","get-url","origin")||(v("No git remote. Run: git remote add origin <url>"),process.exit(1)),u(`
|
|
647
|
+
Checking launch gates...`);let r=Xe(t,".codebase.json");if(Wt(r)&&!e.dryRun)try{let E=(JSON.parse($t(r,"utf-8")).status?.issues||[]).filter(A=>A.state==="open"&&A.labels.some(G=>G.toLowerCase().includes("bug")));if(E.length>0&&!e.force){v(`Gate 1a FAILED \u2014 ${E.length} open bug issue(s) in manifest`);for(let A of E.slice(0,5))u(` #${A.number}: ${A.title} [${A.labels.join(", ")}]`);u(`
|
|
655
648
|
Fix: resolve open bugs or run /simulate. Use --force to skip this gate.`),process.exit(1)}}catch{}let[a,c]=await Promise.all([Jt(t,["bug","critical"]),Jt(t,["bug","high"])]);(a>0||c>0)&&(v("Gate 1a FAILED \u2014 open blocking bugs:"),a>0&&u(` Critical: ${a}`),c>0&&u(` High: ${c}`),u(`
|
|
656
649
|
Fix: run /simulate, or close with wontfix label`),process.exit(1)),g("Gate 1a \u2014 no open bugs");let l=dc(t);if(l){let f=await pc(t,l);f.ok||(v("Gate 1b FAILED \u2014 test suite has failures"),u(f.output.split(`
|
|
657
650
|
`).slice(-10).join(`
|
|
658
651
|
`)),u(`
|
|
659
|
-
Fix: run /review to repair failing tests`),process.exit(1)),g(`Gate 1b \u2014 tests pass (${l})`)}else
|
|
652
|
+
Fix: run /review to repair failing tests`),process.exit(1)),g(`Gate 1b \u2014 tests pass (${l})`)}else _("Gate 1b \u2014 no test runner detected (skipping)");let p=await fc(t);p!==null&&p<7&&(v(`Gate 1c FAILED \u2014 world-class score ${p}/10 (minimum 7.0)`),u(" Fix: run /simulate to improve UX score"),process.exit(1)),p!==null?g(`Gate 1c \u2014 world-class score ${p}/10`):_("Gate 1c \u2014 no simulation data yet (run /simulate first)");let d=await Jt(t,["carry"]);d>0?_(`Gate 2 \u2014 ${d} carry bug(s) will appear in release notes`):g("Gate 2 \u2014 no carry bugs");let m=await Ye(t,"status","--short");m&&(v("Gate 3 FAILED \u2014 uncommitted changes"),u(m),process.exit(1)),await Ye(t,"fetch","origin","develop"),await Ye(t,"log","HEAD..origin/develop","--oneline")&&(v("Gate 3 FAILED \u2014 branch is behind origin/develop"),u(" Fix: git pull origin develop"),process.exit(1)),g("Gate 3 \u2014 branch clean and current"),u(`
|
|
660
653
|
All gates passed.`);let b=n??await mc(t);u(`
|
|
661
|
-
Release version: ${b}`);let
|
|
662
|
-
--- DRY RUN \u2014 release notes preview ---`),u(
|
|
654
|
+
Release version: ${b}`);let j=await gc(t,b,d);if(s){u(`
|
|
655
|
+
--- DRY RUN \u2014 release notes preview ---`),u(j),u("--- DRY RUN \u2014 no tag, no merge, no GitHub release created ---");return}await be(t,["tag","-a",b,"-m",`Release ${b}`]),await be(t,["push","origin",b]),g(`Tagged ${b}`),await be(t,["checkout","main"]),await be(t,["pull","origin","main"]),await be(t,["merge","develop","--no-ff","-m",`Release ${b}`]),await be(t,["push","origin","main"]),await be(t,["checkout","develop"]),g("Merged develop \u2192 main");let{ok:x,stdout:C}=await ie(t,["release","create",b,"--title",b,"--notes",j,"--target","develop"]);x?g(`GitHub release: ${C}`):_("Could not create GitHub release \u2014 tag and merge succeeded"),await hc(t),u(`
|
|
663
656
|
codebase release ${b} complete.`),u("develop \u2192 main merged. Tag pushed. Ready.")}function Ye(e,...t){return new Promise(s=>{Ze("git",t,{cwd:e,timeout:3e4},(n,i)=>{s(n?"":i.trim())})})}function be(e,t){return new Promise((s,n)=>{Ze("git",t,{cwd:e,timeout:3e4},(i,o,r)=>{i?n(new Error(r||i.message)):s()})})}function ie(e,t){return new Promise(s=>{Ze("gh",t,{cwd:e,timeout:3e4},(n,i)=>{s({ok:!n,stdout:(i||"").trim()})})})}async function uc(){return new Promise(e=>{Ze("gh",["auth","status"],{timeout:5e3},t=>e(!t))})}async function Jt(e,t){let{stdout:s}=await ie(e,["issue","list","--label",t.join(","),"--state","open","--limit","100","--json","number","--jq","length"]);return parseInt(s,10)||0}function dc(e){try{let t=JSON.parse($t(Xe(e,"package.json"),"utf-8"));if(t.devDependencies?.vitest||t.dependencies?.vitest)return"npx vitest run";if(t.devDependencies?.jest||t.dependencies?.jest)return"npx jest";if(t.scripts?.test)return"npm test"}catch{}if(Wt(Xe(e,"pyproject.toml")))try{if($t(Xe(e,"pyproject.toml"),"utf-8").includes("pytest"))return"uv run pytest"}catch{}return null}function pc(e,t){let[s,...n]=t.split(" ");return new Promise(i=>{Ze(s,n,{cwd:e,timeout:12e4},(o,r,a)=>{i({ok:!o,output:r+a})})})}async function fc(e){let{stdout:t}=await ie(e,["issue","list","--label","cycle","--state","all","--limit","1","--json","body","--jq",".[0].body // empty"]);if(!t)return null;let s=t.match(/[Ww]orld[- ]class[^0-9]*([0-9]+(?:\.[0-9]+)?)\/10/);return s?parseFloat(s[1]):null}async function mc(e){let t=await Ye(e,"describe","--tags","--abbrev=0");if(!t)return"v0.1.0";let s=t.match(/^v?(\d+)\.(\d+)\.(\d+)$/);return s?`v${s[1]}.${s[2]}.${parseInt(s[3],10)+1}`:"v0.1.0"}async function gc(e,t,s){let n=new Date().toISOString().split("T")[0],[i,o,r,a]=await Promise.all([ie(e,["issue","list","--label","arch","--state","closed","--limit","50","--json","number,title","--jq",'.[] | "- #(.number) (.title)"']),ie(e,["issue","list","--label","bug,sim","--state","closed","--limit","50","--json","number,title","--jq",'.[] | "- #(.number) (.title)"']),ie(e,["issue","list","--label","carry","--state","open","--limit","20","--json","number,title","--jq",'.[] | "- #(.number) (.title)"']),ie(e,["issue","list","--label","arch","--state","open","--limit","20","--json","number,title","--jq",'.[] | "- #(.number) (.title)"'])]),c=`# Release ${t} \u2014 ${n}
|
|
664
657
|
|
|
665
658
|
`;return i.stdout&&(c+=`## What's New
|
|
@@ -680,7 +673,7 @@ ${a.stdout}
|
|
|
680
673
|
|
|
681
674
|
`)),c}async function hc(e){let t=Xe(e,".vibekit","milestone.env");if(!Wt(t))return;let s=$t(t,"utf-8"),n=s.match(/MILESTONE_NUMBER=(\d+)/),i=s.match(/MILESTONE_TITLE=(v[\d.]+)/);if(!n||!i)return;let{stdout:o}=await ie(e,["repo","view","--json","nameWithOwner","--jq",".nameWithOwner"]);if(!o)return;await ie(e,["api",`repos/${o}/milestones/${n[1]}`,"-X","PATCH","-f","state=closed"]),h(`Milestone ${i[1]} closed`);let r=i[1].match(/^v(\d+)\.(\d+)$/);if(!r)return;let a=`v${r[1]}.${parseInt(r[2],10)+1}`,{stdout:c}=await ie(e,["api",`repos/${o}/milestones`,"-X","POST","-f",`title=${a}`,"-f","state=open","-f","description=Next release cycle \u2014 managed by vibekit","--jq",".number"]);c&&(lc(t,`MILESTONE_NUMBER=${c}
|
|
682
675
|
MILESTONE_TITLE=${a}
|
|
683
|
-
`,"utf-8"),g(`Next milestone created: ${a}`))}
|
|
676
|
+
`,"utf-8"),g(`Next milestone created: ${a}`))}F();import{resolve as bc,join as yc}from"path";import{readFile as Wn,writeFile as Jn}from"fs/promises";import{existsSync as Kn}from"fs";var kc="PLAN.md";async function zn(e){let t=bc(e.path),s=yc(t,kc);if(e.message){await wc(s,e.message);return}if(!Kn(s)){h("No PLAN.md found. Create one by running:"),u(""),u(' codebase plan --message "Started sprint. Working on auth refactor."'),u(""),u("Or create PLAN.md manually with the vibeloop schema:"),u(" ## Current Sprint"),u(" ## In Flight"),u(" ## Decisions Log"),u(" ## Blocked");return}let n=await Wn(s,"utf-8");S("PLAN.md"),u(n)}async function wc(e,t){let n=`
|
|
684
677
|
<!-- updated: ${new Date().toISOString().split("T")[0]} -->
|
|
685
678
|
${t.trim()}
|
|
686
679
|
`;if(!Kn(e)){let o=`# PLAN.md \u2014 Autonomous Loop State
|
|
@@ -702,8 +695,8 @@ ${t.trim()}
|
|
|
702
695
|
## Update Log
|
|
703
696
|
${n}`;await Jn(e,o,"utf-8"),u(`${w("Created")} PLAN.md`);return}let i=await Wn(e,"utf-8");i.includes("## Update Log")?i=i.replace(/(## Update Log\n)/,`$1${n}`):i+=`
|
|
704
697
|
## Update Log
|
|
705
|
-
${n}`,await Jn(e,i,"utf-8"),u(`${w("Updated")} PLAN.md`)}
|
|
706
|
-
`)){let i=n.indexOf(":");if(i===-1)continue;let o=n.slice(0,i).trim(),r=n.slice(i+1).trim().replace(/^['"]|['"]$/g,"");o&&(s[o]=r)}return s}async function Vn(e){let t=Kt(process.env.HOME??"~",".claude","skills"),s=Kt(vc(e.path??"."),".claude","skills"),n=new Set,i=[];for(let d of[s,t])if($c(d))for(let m of xc(d))m.endsWith(".skill")&&!n.has(m)&&(n.add(m),i.push({file:m,dir:d}));if(i.length===0){u("No skills installed. Run: codebase setup");return}let o=[];for(let{file:d,dir:m}of i){let y=Kt(m,d),b=d.replace(/\.skill$/,""),
|
|
707
|
-
${l("Name",r)} ${l("Description",a)} File`),u(p);for(let d of o)u(` ${l(d.name,r)} ${l(d.description,a)} ${d.file}`);u("")}import{createServer as Rc}from"http";je();import{readFile as Ec,writeFile as _c}from"fs/promises";import{join as Qn}from"path";async function Yn(e,t,s){let n=new URL(e,"http://localhost"),i=n.pathname;if(i==="/health")return{status:200,body:{status:"ok",version:"0.3.
|
|
698
|
+
${n}`,await Jn(e,i,"utf-8"),u(`${w("Updated")} PLAN.md`)}F();import{join as Kt,resolve as vc}from"path";import{existsSync as $c,readdirSync as xc}from"fs";import{execFile as jc}from"child_process";function Sc(e){return new Promise((t,s)=>{jc("unzip",["-p",e,"*/SKILL.md"],(n,i)=>{n&&!i?s(n):t(i??"")})})}function Cc(e){let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!t)return{};let s={};for(let n of t[1].split(`
|
|
699
|
+
`)){let i=n.indexOf(":");if(i===-1)continue;let o=n.slice(0,i).trim(),r=n.slice(i+1).trim().replace(/^['"]|['"]$/g,"");o&&(s[o]=r)}return s}async function Vn(e){let t=Kt(process.env.HOME??"~",".claude","skills"),s=Kt(vc(e.path??"."),".claude","skills"),n=new Set,i=[];for(let d of[s,t])if($c(d))for(let m of xc(d))m.endsWith(".skill")&&!n.has(m)&&(n.add(m),i.push({file:m,dir:d}));if(i.length===0){u("No skills installed. Run: codebase setup");return}let o=[];for(let{file:d,dir:m}of i){let y=Kt(m,d),b=d.replace(/\.skill$/,""),j="";try{let x=await Sc(y),C=Cc(x);C.name&&(b=C.name),C.description&&(j=C.description)}catch{}o.push({name:b,description:j,file:d})}if(o.length===0){u("No skills installed. Run: codebase setup");return}let r=Math.max(4,...o.map(d=>d.name.length)),a=Math.max(11,...o.map(d=>d.description.length)),c=Math.max(4,...o.map(d=>d.file.length)),l=(d,m)=>d.padEnd(m),p=` ${"\u2500".repeat(r)} ${"\u2500".repeat(a)} ${"\u2500".repeat(c)}`;h(`
|
|
700
|
+
${l("Name",r)} ${l("Description",a)} File`),u(p);for(let d of o)u(` ${l(d.name,r)} ${l(d.description,a)} ${d.file}`);u("")}import{createServer as Rc}from"http";je();import{readFile as Ec,writeFile as _c}from"fs/promises";import{join as Qn}from"path";async function Yn(e,t,s){let n=new URL(e,"http://localhost"),i=n.pathname;if(i==="/health")return{status:200,body:{status:"ok",version:"0.3.5"}};if(i==="/codebase/query"&&t==="GET"){let o=n.searchParams.get("path");if(!o)return{status:400,body:{error:"Missing 'path' query parameter"}};let r=await zt(s);return r?{status:200,body:Ae(r,o)??null}:{status:404,body:{error:"No manifest. POST /codebase/scan first."}}}if(i==="/codebase/scan"&&t==="POST"){let o=await K(s,{quiet:!0});return await _c(Qn(s,".codebase.json"),JSON.stringify(o,null,2),"utf-8"),{status:200,body:o}}if(i==="/codebase"&&t==="GET"){let o=await zt(s);return o?{status:200,body:o}:{status:404,body:{error:"No manifest. POST /codebase/scan first."}}}if(i.startsWith("/codebase/")&&t==="GET"){let o=i.split("/")[2],r=await zt(s);if(!r)return{status:404,body:{error:"No manifest."}};let a=r[o];return a===void 0?{status:404,body:{error:`Category '${o}' not found.`}}:{status:200,body:a}}return{status:404,body:{error:"Not found"}}}async function zt(e){try{let t=await Ec(Qn(e,".codebase.json"),"utf-8");return JSON.parse(t)}catch{return null}}function Xn(e,t){let s=Rc(async(n,i)=>{if(i.setHeader("Access-Control-Allow-Origin","*"),i.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),i.setHeader("Access-Control-Allow-Headers","Content-Type"),i.setHeader("Content-Type","application/json"),n.method==="OPTIONS"){i.writeHead(200),i.end();return}try{let o=await Yn(n.url||"/",n.method||"GET",e);i.writeHead(o.status),i.end(JSON.stringify(o.body,null,2))}catch{i.writeHead(500),i.end(JSON.stringify({error:"Internal server error"}))}});s.listen(t,()=>{console.log(`codebase server running on http://localhost:${t}`),console.log(`
|
|
708
701
|
Endpoints:`),console.log(" GET /health Health check"),console.log(" GET /codebase Full manifest"),console.log(" GET /codebase/:category Single category"),console.log(" GET /codebase/query?path=stack.languages"),console.log(" POST /codebase/scan Trigger re-scan")}),process.on("SIGINT",()=>{s.close(),process.exit(0)}),process.on("SIGTERM",()=>{s.close(),process.exit(0)})}var pe=es(process.argv.slice(2));ee(pe.quiet);Qt(pe.verbose);pe.helpCommand&&pe.command&&ts(pe.command);var Pc={scan:Ge,init:bn,brief:yn,next:wn,setup:Tt,query:vn,issue:En,status:Rn,mcp:Ln,doctor:qn,fix:Un,release:Bn,plan:zn,skills:Vn,serve:e=>(Xn(e.path,e.port??3e3),Promise.resolve()),"scan-only":Ge};os().catch(()=>{});var[Dc]=process.versions.node.split(".").map(Number);Dc<20&&(console.error(`Error: Node.js 20 or higher is required. You are running v${process.versions.node}.`),console.error("Upgrade: https://nodejs.org"),process.exit(1));var Zn=Pc[pe.command];Zn||(v(`Unknown command: ${pe.command}`),h(`Run ${w("codebase --help")} to see all commands.`),process.exit(1));Zn(pe).catch(e=>{v(`Error: ${e.message}`);let t=e.message.toLowerCase();t.includes("not a git repository")?h(`Initialize git first: ${w("git init")}`):t.includes("permission denied")?h("Check file permissions or run with appropriate access"):t.includes("enoent")&&t.includes("gh")?h(`GitHub CLI (gh) is not installed. Install it: ${w("brew install gh && gh auth login")}`):t.includes("no such file")?h("Check that the path is correct"):t.includes("github")&&(h(`Ensure GitHub CLI is installed: ${w("gh --version")}`),h(`Authenticate: ${w("gh auth login")}`)),process.exit(1)});
|
|
709
702
|
//# sourceMappingURL=index.js.map
|