codebase-ai 0.3.4 → 0.3.7

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 CHANGED
@@ -1,23 +1,23 @@
1
1
  #!/usr/bin/env node
2
- var si=Object.defineProperty;var D=(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 R(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,M=D(()=>{"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=wi(t);return e.filter(n=>s.test(n))}function wi(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=D(()=>{"use strict"});import{readdir as vi,readFile as $i}from"fs/promises";import{existsSync as xi}from"fs";import{join as Ct,relative as ji}from"path";import{execFile as Si}from"child_process";async function cs(e,t={}){let s=new Set([...Ci,...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 $i(Ct(e,o),"utf-8")}catch{return""}},fileExists(o){return i.has(o)?!0:xi(Ct(e,o))},glob(o){return rs(n,o)},exec(o,r){return new Promise(a=>{Si(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 vi(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=ji(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 Ci,us=D(()=>{"use strict";as();Ci=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 Ei(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 _i(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 Ri(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=D(()=>{"use strict";ds={name:"project",category:"project",async detect(e){let[t,s,n]=await Promise.all([Ei(e),_i(e),Ri(e)]);return{name:t,description:s||n||null}}}});async function Pi(e){return await e.exec("git",["remote","get-url","origin"])||null}async function Di(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 Ai(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 Oi(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 Ii(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=D(()=>{"use strict";fs={name:"repo",category:"repo",async detect(e){let[t,s,n,i,o]=await Promise.all([Pi(e),Di(e),Ai(e),Oi(e),Ii(e)]);return{url:t,default_branch:s,is_monorepo:i,workspace_manager:i?o:null,active_branches:n}}}});import{existsSync as Ni}from"fs";import{join as Li}from"path";function Ti(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 Fi,Mi,gs,hs=D(()=>{"use strict";Fi=["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"],Mi=["dist","build",".next","out","target","bin","obj",".output",".nuxt",".svelte-kit",".vercel"],gs={name:"structure",category:"structure",async detect(e){let t=Fi.filter(i=>e.fileExists(i)),s=Mi.filter(i=>Ni(Li(e.root,i))),n=Ti(e.files,4);return{entry_points:t,build_output:s,tree:n}}}});function Wi(e){let t={};for(let s of e.files){if(s.endsWith("/"))continue;let n="."+s.split(".").pop(),i=qi[n];i&&(t[i]=(t[i]||0)+1)}return Object.entries(t).sort((s,n)=>n[1]-s[1]).map(([s])=>s)}async function Ki(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 zi(e){let t=[];for(let[n,i]of Object.entries(e)){let o=Hi[n];if(o){let r=i.replace(/^[\^~>=<]+/,"").split(".").slice(0,2).join(".");t.push(`${o}@${r}`)}}let s=Vi(e);return t.push(...s),[...new Set(t)]}function Vi(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 Qi(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 Yi(e,t){let s=new Set;for(let n of Object.keys(e))t[n]&&s.add(t[n]);return[...s]}async function Xi(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 Zi(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 eo(e,r);a&&!t.includes(a)&&t.push(a)}let n=await to(e);for(let r of n)t.includes(r)||t.push(r);let i=await so(e);for(let r of i)t.includes(r)||t.push(r);let o=await no(e);for(let r of o)t.includes(r)||t.push(r);return t}async function eo(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 to(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 so(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 no(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 io(e){let t=await e.readFile("pyproject.toml"),s=await e.readFile("requirements.txt"),n=await e.readFile("setup.py"),i=t+`
2
+ var Si=Object.defineProperty;var I=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ft=(e,t)=>{for(var s in t)Si(e,s,{get:t[s],enumerable:!0})};function K(e){ye=e}function fs(e){xi=e}function u(e){ye||console.log(e)}function w(e){ye||console.log(` ${G.green}[\u2713]${G.reset} ${e}`)}function E(e){console.error(` ${G.red}[\u2717]${G.reset} ${e}`)}function D(e){ye||console.log(` ${G.yellow}[!]${G.reset} ${e}`)}function v(e){ye||console.log(` ${G.cyan}[i]${G.reset} ${e}`)}function z(e){ye||console.log(`${G.dim}${e}${G.reset}`)}function j(e){return`${G.bold}${e}${G.reset}`}function R(e){ye||console.log(`
3
+ ${G.bold}${e}${G.reset}`)}function pt(e,t){return process.stdout.isTTY&&!se?`\x1B]8;;${t}\x1B\\${e}\x1B]8;;\x1B\\`:`${e} (${t})`}function ee(e){return`${G.dim}${e}${G.reset}`}function C(e){return`${G.cyan}${e}${G.reset}`}var se,G,ye,xi,M=I(()=>{"use strict";se=!!process.env.NO_COLOR,G={reset:se?"":"\x1B[0m",green:se?"":"\x1B[32m",red:se?"":"\x1B[31m",yellow:se?"":"\x1B[33m",cyan:se?"":"\x1B[36m",blue:se?"":"\x1B[34m",magenta:se?"":"\x1B[35m",dim:se?"":"\x1B[2m",bold:se?"":"\x1B[1m"},ye=!1,xi=!1});function Ss(e,t){let s=Mi(t);return e.filter(n=>s.test(n))}function Mi(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(Tt).join("|")+")",s=i+1}else t+=Tt(n),s++}else t+=Tt(n),s++}return t+="$",new RegExp(t)}function Tt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var xs=I(()=>{"use strict"});import{readdir as Ti,readFile as qi}from"fs/promises";import{existsSync as Hi}from"fs";import{join as qt,relative as Gi}from"path";import{execFile as Ui}from"child_process";async function js(e,t={}){let s=new Set([...Bi,...t.ignore??[]]),n=await Cs(e,e,s,t.depth??10),i=new Set(n);return{root:e,files:n,async readFile(o){try{return await qi(qt(e,o),"utf-8")}catch{return""}},fileExists(o){return i.has(o)?!0:Hi(qt(e,o))},glob(o){return Ss(n,o)},exec(o,r){return new Promise(a=>{Ui(o,r,{cwd:e,timeout:1e4},(c,l)=>{a(c?"":l.trim())})})}}}async function Cs(e,t,s,n,i=0){if(i>n)return[];let o=[];try{let r=await Ti(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=qt(t,a.name),l=Gi(e,c);if(a.isDirectory()){o.push(l+"/");let p=await Cs(e,c,s,n,i+1);o.push(...p)}else o.push(l)}}catch{}return o}var Bi,Es=I(()=>{"use strict";xs();Bi=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 Wi(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 Ki(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 _s,Rs=I(()=>{"use strict";_s={name:"project",category:"project",async detect(e){let[t,s,n]=await Promise.all([Ji(e),Wi(e),Ki(e)]);return{name:t,description:s||n||null}}}});async function zi(e){return await e.exec("git",["remote","get-url","origin"])||null}async function Vi(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 Qi(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 Yi(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 Xi(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 Ps,Ds=I(()=>{"use strict";Ps={name:"repo",category:"repo",async detect(e){let[t,s,n,i,o]=await Promise.all([zi(e),Vi(e),Qi(e),Yi(e),Xi(e)]);return{url:t,default_branch:s,is_monorepo:i,workspace_manager:i?o:null,active_branches:n}}}});import{existsSync as Zi}from"fs";import{join as eo}from"path";function no(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 to,so,Os,As=I(()=>{"use strict";to=["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"],so=["dist","build",".next","out","target","bin","obj",".output",".nuxt",".svelte-kit",".vercel"],Os={name:"structure",category:"structure",async detect(e){let t=to.filter(i=>e.fileExists(i)),s=so.filter(i=>Zi(eo(e.root,i))),n=no(e.files,4);return{entry_points:t,build_output:s,tree:n}}}});function uo(e){let t={};for(let s of e.files){if(s.endsWith("/"))continue;let n="."+s.split(".").pop(),i=io[n];i&&(t[i]=(t[i]||0)+1)}return Object.entries(t).sort((s,n)=>n[1]-s[1]).map(([s])=>s)}async function po(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 fo(e){let t=[];for(let[n,i]of Object.entries(e)){let o=oo[n];if(o){let r=i.replace(/^[\^~>=<]+/,"").split(".").slice(0,2).join(".");t.push(`${o}@${r}`)}}let s=mo(e);return t.push(...s),[...new Set(t)]}function mo(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 go(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 Ht(e,t){for(let s of Object.keys(e))if(t[s])return t[s];return null}function ho(e,t){let s=new Set;for(let n of Object.keys(e))t[n]&&s.add(t[n]);return[...s]}async function bo(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 yo(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 ko(e,r);a&&!t.includes(a)&&t.push(a)}let n=await wo(e);for(let r of n)t.includes(r)||t.push(r);let i=await vo(e);for(let r of i)t.includes(r)||t.push(r);let o=await $o(e);for(let r of o)t.includes(r)||t.push(r);return t}async function ko(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 wo(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 vo(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 $o(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 So(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 oo(e);a.length>0&&r.push(`apps: ${a.join(", ")}`);let c=await ro(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 oo(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 ro(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 ao(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 co(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 lo(e){let t=await e.readFile("pom.xml"),s=await e.readFile("build.gradle"),n=await e.readFile("build.gradle.kts"),i=t+`
7
+ `+n;if(i.includes("fastapi")){let o=je(s,"fastapi")||je(t,"fastapi");return o?`fastapi@${o}`:"fastapi"}if(i.includes("django")){let o=je(s,"django")||je(t,"django"),r=[];o&&r.push(o);let a=await xo(e);a.length>0&&r.push(`apps: ${a.join(", ")}`);let c=await jo(e);return c&&r.push(c),r.length>0?`django@${r.join(" ")}`:o?`django@${o}`:"django"}if(i.includes("flask")){let o=je(s,"flask")||je(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 xo(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 jo(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 Co(e){let t=await e.readFile("go.mod");if(!t)return null;let s=[];if(t.includes("github.com/gin-gonic/gin")){let n=Be(t,"github.com/gin-gonic/gin");s.push(n?`gin@${n}`:"gin")}if(t.includes("github.com/gofiber/fiber")){let n=Be(t,"github.com/gofiber/fiber");s.push(n?`fiber@${n}`:"fiber")}if(t.includes("github.com/labstack/echo")){let n=Be(t,"github.com/labstack/echo");s.push(n?`echo@${n}`:"echo")}if(t.includes("github.com/gorilla/mux")){let n=Be(t,"github.com/gorilla/mux");s.push(n?`gorilla/mux@${n}`:"gorilla/mux")}if(t.includes("go-chi/chi")){let n=Be(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 Eo(e){let t=await e.readFile("Cargo.toml");if(!t)return null;let s=[];if(t.includes("actix-web")){let n=mt(t,"actix-web");s.push(n?`actix-web@${n}`:"actix-web")}if(t.includes("axum")){let n=mt(t,"axum");s.push(n?`axum@${n}`:"axum")}if(t.includes("rocket")){let n=mt(t,"rocket");s.push(n?`rocket@${n}`:"rocket")}if(t.includes("warp")&&s.push("warp"),t.includes("tokio")){let n=mt(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 _o(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 uo(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 po(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 po(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 fo(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 mo(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=go(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 go(e,t){let s=new RegExp(`<PackageReference\\s+Include="${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"[^>]*Version="([\\d.]+)"`),n=e.match(s);return n?n[1]:null}var qi,Hi,Gi,Ui,Bi,Ji,ys,ks=D(()=>{"use strict";qi={".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"},Hi={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"},Gi={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"},Ui={prisma:"prisma","@prisma/client":"prisma","drizzle-orm":"drizzle",typeorm:"typeorm",sequelize:"sequelize","@mikro-orm/core":"mikro-orm",knex:"knex",mongoose:"mongoose"},Bi={tailwindcss:"tailwindcss","styled-components":"styled-components","@emotion/react":"emotion",sass:"sass","@chakra-ui/react":"chakra-ui","@mui/material":"material-ui","@mantine/core":"mantine"},Ji={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=Wi(e),s=await Ki(e),n=zi(s),i=Qi(e,s),o=Yi(s,Gi),r=Et(s,Ui),a=Et(s,Bi),c=Et(s,Ji);if(r==="prisma"){let E=await Xi(e);E&&!o.includes(E)&&o.unshift(E)}let l=await Zi(e);for(let E of l)o.includes(E)||o.push(E);let[p,d,m,y,b,x,j]=await Promise.all([io(e),ao(e),co(e),lo(e),uo(e),fo(e),mo(e)]);return p&&n.push(p),d&&n.push(d),m&&n.push(m),y&&n.push(y),b&&n.push(b),x&&n.push(x),j&&n.push(j),{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 ho(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 bo(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 yo(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=D(()=>{"use strict";ws={name:"commands",category:"commands",async detect(e){let t=await ho(e);if(Object.values(t).some(Boolean))return t;let s=await bo(e);return Object.values(s).some(Boolean)?s:await yo(e)}}});function rt(e,t){return e.filter(s=>t.has(s)).sort()}function vo(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 $o(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 xo(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 jo(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 So(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 Co(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 Eo(e){let t=await e.readFile("pom.xml"),s=await e.readFile("build.gradle"),n=await e.readFile("build.gradle.kts"),i=(t||"")+`
9
+ `+n;if(i.includes("spring-boot")){let o=gt(t,"spring-boot-starter-parent")||ht(s,"org.springframework.boot");return o?`spring boot@${o}`:"spring boot"}if(i.includes("spring-framework")||i.includes("spring-core")){let o=gt(t,"spring-framework")||ht(s,"org.springframework");return o?`spring@${o}`:"spring"}if(i.includes("micronaut")){let o=gt(t,"micronaut")||ht(s,"io.micronaut");return o?`micronaut@${o}`:"micronaut"}if(i.includes("quarkus")){let o=gt(t,"quarkus")||ht(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 Ro(e){let t=await e.readFile("Gemfile"),s=await e.readFile(".gemspec"),n=t+`
10
+ `+s;if(n.includes("rails")){let i=Ns(n,"rails"),o=[];i&&o.push(i);let r=await Po(e);return r.length>0&&o.push(r.join(", ")),o.length>0?`rails@${o.join(" ")}`:`rails@${i||"unknown"}`}if(n.includes("sinatra")){let i=Ns(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 Po(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 Do(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 Oo(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=Ao(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 je(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 Be(e,t){let s=new RegExp(`${t}\\s+v([\\d.]+)`),n=e.match(s);return n?n[1]:null}function mt(e,t){let s=new RegExp(`${t}\\s*=\\s*"([\\d.]+)"`),n=e.match(s);return n?n[1]:null}function gt(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 ht(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 Ns(e,t){let s=new RegExp(`gem\\s+['"]${t}['"][^,]*,\\s*['"]~?>?\\s*([\\d.]+)['"]`),n=e.match(s);return n?n[1]:null}function Ao(e,t){let s=new RegExp(`<PackageReference\\s+Include="${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"[^>]*Version="([\\d.]+)"`),n=e.match(s);return n?n[1]:null}var io,oo,ro,ao,co,lo,Is,Ls=I(()=>{"use strict";io={".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"},oo={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"},ro={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"},ao={prisma:"prisma","@prisma/client":"prisma","drizzle-orm":"drizzle",typeorm:"typeorm",sequelize:"sequelize","@mikro-orm/core":"mikro-orm",knex:"knex",mongoose:"mongoose"},co={tailwindcss:"tailwindcss","styled-components":"styled-components","@emotion/react":"emotion",sass:"sass","@chakra-ui/react":"chakra-ui","@mui/material":"material-ui","@mantine/core":"mantine"},lo={vite:"vite",webpack:"webpack",esbuild:"esbuild",tsup:"tsup",rollup:"rollup",parcel:"parcel",turbopack:"turbopack",unbuild:"unbuild",pkgroll:"pkgroll","@swc/core":"swc",snowpack:"snowpack"},Is={name:"stack",category:"stack",async detect(e){let t=uo(e),s=await po(e),n=fo(s),i=go(e,s),o=ho(s,ro),r=Ht(s,ao),a=Ht(s,co),c=Ht(s,lo);if(r==="prisma"){let x=await bo(e);x&&!o.includes(x)&&o.unshift(x)}let l=await yo(e);for(let x of l)o.includes(x)||o.push(x);let[p,d,f,$,h,b,k]=await Promise.all([So(e),Co(e),Eo(e),_o(e),Ro(e),Do(e),Oo(e)]);return p&&n.push(p),d&&n.push(d),f&&n.push(f),$&&n.push($),h&&n.push(h),b&&n.push(b),k&&n.push(k),{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 No(e){let t=await e.readFile("package.json");if(!t)return We();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:Je(n,["dev","start","serve"],i),build:Je(n,["build","compile"],i),test:Je(n,["test","test:unit","test:run"],i),lint:Je(n,["lint","lint:check"],i),format:Je(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 We()}}function Je(e,t,s){for(let n of t)if(e[n])return`${s} ${n}`;return null}async function Io(e){let t=await e.readFile("Makefile");if(!t)return We();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 Lo(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?We():e.files.some(s=>s.endsWith(".sh"))?{dev:null,build:null,test:null,lint:"shellcheck *.sh",format:"shfmt -w *.sh"}:We()}function We(){return{dev:null,build:null,test:null,lint:null,format:null}}var Fs,Ms=I(()=>{"use strict";Fs={name:"commands",category:"commands",async detect(e){let t=await No(e);if(Object.values(t).some(Boolean))return t;let s=await Io(e);return Object.values(s).some(Boolean)?s:await Lo(e)}}});function bt(e,t){return e.filter(s=>t.has(s)).sort()}function To(e){let t=[],s=[],n=e.match(/\[project\]\s[\s\S]*?dependencies\s*=\s*\[([\s\S]*?)\]/);n&&t.push(...qs(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(...qs(c[1]))}let o=e.match(/\[tool\.poetry\.dependencies\]\s*\n([\s\S]*?)(?=\n\[|$)/);if(o){let a=yt(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(...yt(r[1])),t.length===0&&s.length===0?null:{direct:t,dev:s}}function qs(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 yt(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 qo(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 Ho(e){let t=[],s=[],n=e.match(/\[dependencies\]\s*\n([\s\S]*?)(?=\n\[|$)/);n&&t.push(...yt(n[1]));let i=e.match(/\[dev-dependencies\]\s*\n([\s\S]*?)(?=\n\[|$)/);return i&&s.push(...yt(i[1])),{direct:t,dev:s}}function Go(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 Uo(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]),Ce.has(o[1])&&n.push(o[1]))}return{direct_count:s.length,dev_count:0,notable:[...new Set(n)].sort()}}async function Bo(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=>Ce.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 _o(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 Ro(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,ko,wo,js,Ss=D(()=>{"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"]),ko=new Set(["serde","tokio","axum","actix-web","rocket","warp","hyper","sqlx","diesel","sea-orm","clap","tracing","anyhow","thiserror","reqwest","tonic","prost"]),wo=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=Ro(e),s=await e.readFile("package.json");if(s)try{let d=JSON.parse(s),m=d.dependencies||{},y=d.devDependencies||{},b={...m,...y},x=Object.keys(b).filter(j=>ve.has(j)).sort();return{direct_count:Object.keys(m).length,dev_count:Object.keys(y).length,lock_file:t,notable:x}}catch{}let n=await e.readFile("pyproject.toml");if(n){let d=vo(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=$o(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=xo(o),m=rt([...d.direct,...d.dev],ko);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=jo(r),m=d.map(b=>b.split("/").pop()),y=rt(m,wo);return{direct_count:d.length,dev_count:0,lock_file:t,notable:y}}let a=await So(e);if(a.direct_count>0)return{...a,lock_file:t};let c=await Co(e);if(c.direct_count>0)return{...c,lock_file:t};let l=await Eo(e);if(l.direct_count>0)return{...l,lock_file:t};let p=await _o(e);return p.direct_count>0?{...p,lock_file:t}:{direct_count:0,dev_count:0,lock_file:t,notable:[]}}}});async function Ao(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(Do))if(n[i])return o}catch{}return null}async function Oo(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 Po,Do,Cs,Es=D(()=>{"use strict";Po=["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"],Do={"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=Po.filter(o=>e.fileExists(o)),n=await Ao(e),i=await Oo(e);return{env_files:t,config_files:s,feature_flags:n,env_vars:i}}}});async function Io(e){let t=await e.exec("git",["log","--oneline","-5","--format=%s"]);return t?t.split(`
19
- `).filter(Boolean):[]}async function No(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 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]),Ce.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),Ce.has(p)&&r.push(p))}return{direct_count:[...new Set(o)].length,dev_count:0,notable:[...new Set(r)].sort()}}async function Wo(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();Ce.has(c)&&n.push(a[1])}}return{direct_count:[...new Set(s)].length,dev_count:0,notable:[...new Set(n)].sort()}}function Ko(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 Ce,Ts,Fo,Mo,Hs,Gs=I(()=>{"use strict";Ce=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"]),Ts=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"]),Fo=new Set(["serde","tokio","axum","actix-web","rocket","warp","hyper","sqlx","diesel","sea-orm","clap","tracing","anyhow","thiserror","reqwest","tonic","prost"]),Mo=new Set(["gin","echo","fiber","chi","mux","gorm","sqlx","cobra","viper","zap","testify","grpc","protobuf","wire"]),Hs={name:"dependencies",category:"dependencies",async detect(e){let t=Ko(e),s=await e.readFile("package.json");if(s)try{let d=JSON.parse(s),f=d.dependencies||{},$=d.devDependencies||{},h={...f,...$},b=Object.keys(h).filter(k=>Ce.has(k)).sort();return{direct_count:Object.keys(f).length,dev_count:Object.keys($).length,lock_file:t,notable:b}}catch{}let n=await e.readFile("pyproject.toml");if(n){let d=To(n);if(d){let f=bt([...d.direct,...d.dev],Ts);return{direct_count:d.direct.length,dev_count:d.dev.length,lock_file:t,notable:f}}}let i=await e.readFile("requirements.txt");if(i){let d=qo(i),f=bt(d,Ts);return{direct_count:d.length,dev_count:0,lock_file:t,notable:f}}let o=await e.readFile("Cargo.toml");if(o){let d=Ho(o),f=bt([...d.direct,...d.dev],Fo);return{direct_count:d.direct.length,dev_count:d.dev.length,lock_file:t,notable:f}}let r=await e.readFile("go.mod");if(r){let d=Go(r),f=d.map(h=>h.split("/").pop()),$=bt(f,Mo);return{direct_count:d.length,dev_count:0,lock_file:t,notable:$}}let a=await Uo(e);if(a.direct_count>0)return{...a,lock_file:t};let c=await Bo(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 Wo(e);return p.direct_count>0?{...p,lock_file:t}:{direct_count:0,dev_count:0,lock_file:t,notable:[]}}}});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||{}};for(let[i,o]of Object.entries(Vo))if(n[i])return o}catch{}return null}async function Yo(e){let t={},s=await e.readFile(".env.example");s&&kt(s,t,!1);let n=await e.readFile(".env");n&&kt(n,t,!0);let i=await e.readFile(".env.sample");i&&kt(i,t,!1);let o=await e.readFile(".env.template");return o&&kt(o,t,!1),t}function kt(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 zo,Vo,Us,Bs=I(()=>{"use strict";zo=["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"],Vo={"launchdarkly-node-server-sdk":"launchdarkly","@unleash/proxy-client-react":"unleash",flagsmith:"flagsmith","@growthbook/growthbook-react":"growthbook"},Us={name:"config",category:"config",async detect(e){let t=e.files.filter(o=>o.match(/^\.env(\..+)?$/)||o.match(/^\.env\./)),s=zo.filter(o=>e.fileExists(o)),n=await Qo(e),i=await Yo(e);return{env_files:t,config_files:s,feature_flags:n,env_vars:i}}}});async function Xo(e){let t=await e.exec("git",["log","--oneline","-5","--format=%s"]);return t?t.split(`
19
+ `).filter(Boolean):[]}async function Zo(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 er(e){return(await e.exec("git",["status","--porcelain"])).length>0}var Js,Ws=I(()=>{"use strict";Js={name:"git",category:"git",async detect(e){let[t,s,n]=await Promise.all([Xo(e),Zo(e),er(e)]);return{recent_commits:t,last_committers:s,uncommitted_changes:n}}}});async function tr(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 sr(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 nr(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 ir(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 or(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 Ks,zs=I(()=>{"use strict";Ks={name:"quality",category:"quality",async detect(e){let[t,s,n]=await Promise.all([tr(e),sr(e),nr(e)]);return{test_framework:t,linter:s,formatter:n,ci:ir(e),pre_commit_hooks:or(e)}}}});function rr(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 ar(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 cr(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 lr(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=Vs[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=Vs[i];o&&!t[`src/${i}/`]&&(t[`${i}/`]=o)}return t}var Vs,Qs,Ys=I(()=>{"use strict";Vs={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"},Qs={name:"patterns",category:"patterns",async detect(e){return{architecture:rr(e),state_management:await ar(e),api_style:await cr(e),key_modules:lr(e)}}}});async function ur(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:Gt(n,"openapi")||Gt(n,"swagger"),title:Gt(n,"title"),file:s,type:n.includes("openapi:")?"openapi":"swagger"}}}return null}async function dr(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 pr(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 fr(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 Gt(e,t){let s=new RegExp(`^${t}:\\s*(.+)$`,"m"),n=e.match(s);return n?n[1].trim():null}var Xs,Zs=I(()=>{"use strict";Xs={name:"api-docs",category:"config",async detect(e){let[t,s,n,i]=await Promise.all([ur(e),dr(e),pr(e),fr(e)]);return{openapi:t,graphql:s,grpc:n,postman:i}}}});var Ut,en=I(()=>{"use strict";Rs();Ds();As();Ls();Ms();Gs();Bs();Ws();zs();Ys();Zs();Ut=[_s,Ps,Os,Is,Fs,Hs,Us,Js,Ks,Qs,Xs]});function F(e,t){return e?String(e).slice(0,t):""}var Bt=I(()=>{"use strict"});import{execFile as tn}from"child_process";async function Ke(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)}`);tn("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 kr(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 wr(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:F(e.title,200),state:e.state?.toLowerCase()==="open"?"open":"closed",url:e.url||void 0,labels:t.map(a=>F(a.name,50)).filter(Boolean),assignee:F(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:F(e.body||"",2e3)}}function vr(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:F(e.title,200),state:(e.state||"open").toLowerCase(),url:e.url||void 0,author:F(n?.login,100)||"unknown",branch:F(e.headRefName,200),labels:t.map(l=>F(l.name,50)).filter(Boolean),reviewers:s.map(l=>F(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 sn(e,t,s={}){let{includeIssues:n=!0,includePRs:i=!0,includeMilestones:o=!0,includeReleases:r=!0,includeProjects:a=!0,limit:c=50}=s,l=kr(t);if(!l)return{};let{owner:p,repo:d}=l,f={},[$,h,b,k,x]=await Promise.all([n?Ke(e,mr,{owner:p,repo:d,limit:c}).catch(m=>(D(`GitHub issues query failed: ${m instanceof Error?m.message:String(m)}`),null)):Promise.resolve(null),i?Ke(e,gr,{owner:p,repo:d,limit:Math.min(c,30)}).catch(m=>(D(`GitHub pull requests query failed: ${m instanceof Error?m.message:String(m)}`),null)):Promise.resolve(null),o?Ke(e,hr,{owner:p,repo:d}).catch(m=>(D(`GitHub milestones query failed: ${m instanceof Error?m.message:String(m)}`),null)):Promise.resolve(null),r?Ke(e,br,{owner:p,repo:d,limit:10}).catch(m=>(D(`GitHub releases query failed: ${m instanceof Error?m.message:String(m)}`),null)):Promise.resolve(null),a?Ke(e,yr,{owner:p,repo:d}).catch(m=>(D(`GitHub projects query failed: ${m instanceof Error?m.message:String(m)}`),null)):Promise.resolve(null)]);return $?.repository?.issues?.nodes&&(f.issues=$.repository.issues.nodes.map(wr)),h?.repository?.pullRequests?.nodes&&(f.pull_requests=h.repository.pullRequests.nodes.map(vr)),b?.repository?.milestones?.nodes&&(f.milestones=b.repository.milestones.nodes.map(m=>{let g=m.issues?.nodes||[],A=m.closedIssues?.totalCount||0,S=m.issues?.totalCount||g.length,X=S-A;return{title:m.title,description:m.description||"",due_date:m.dueOn||null,progress:{open:X,closed:A,percent:S>0?Math.round(A/S*100):0},issues:g.map(re=>re.number)}})),k?.repository?.releases?.nodes&&(f.releases=k.repository.releases.nodes.map(m=>({tag_name:m.tagName,name:m.name||m.tagName,created_at:m.createdAt,url:m.url,author:m.author?.login||"unknown",prerelease:!!m.isPrerelease}))),x?.repository?.projectsV2?.nodes&&(f.project_boards=x.repository.projectsV2.nodes.filter(m=>m!==null).map(m=>{let g=m.columns?.nodes||[],A=m.items?.totalCount||0;return{number:m.number,title:m.title,state:(m.state||"open").toLowerCase(),url:m.url,columns:g.map(S=>({name:S.name,cards_count:A}))}})),f}async function nn(e){return new Promise(t=>{tn("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 mr,gr,hr,br,yr,on=I(()=>{"use strict";M();Bt();mr=`
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
- `,Yo=`
51
+ `,gr=`
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
- `,Xo=`
78
+ `,hr=`
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
- `,Zo=`
95
+ `,br=`
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
- `,er=`
110
+ `,yr=`
111
111
  query($owner: String!, $repo: String!) {
112
112
  repository(owner: $owner, name: $repo) {
113
113
  projectsV2(first: 10) {
@@ -135,18 +135,18 @@ query($owner: String!, $repo: String!) {
135
135
  }
136
136
  }
137
137
  }
138
- `});import{execFile as Gs}from"child_process";import{readdirSync as ir,readFileSync as or,existsSync as rr}from"fs";import{join as Dt}from"path";async function $e(e){if(!await xe(e,["--version"]))return null;let s=await ar(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 cr(e))return null;let o=await qs(e),r=[],a=[],c=[],l=[],p=[],d=!1;if(o)try{let j=await Ts(e,s,{includeIssues:!0,includePRs:!0,includeMilestones:!0,includeReleases:!0,includeProjects:!0,limit:50});r=j.issues||[],a=j.pull_requests||[],c=j.milestones||[],l=j.releases||[],p=j.project_boards||[],d=!0}catch{}d||(r=await lr(e),a=await pr(e),c=await gr(e));let[m]=await Promise.all([hr(e)]),y=kr(r),b=wr(r),x=yr(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:x,manual:[]}}}function xe(e,t){return new Promise(s=>{Gs("gh",t,{cwd:e,timeout:3e4},(n,i)=>{s(n?"":i.trim())})})}function ar(e,t,s){return new Promise(n=>{Gs(t,s,{cwd:e,timeout:1e4},(i,o)=>{n(i?"":o.trim())})})}async function cr(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 lr(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(ur)}catch{return[]}}function ur(e){let t=e.labels||[],s=e.assignees||[],n=e.milestone,i=e.body||"";return{number:e.number,title:L(e.title,200),state:e.state?.toLowerCase()==="open"?"open":"closed",labels:t.map(o=>L(o.name,50)).filter(Boolean),assignee:L(s[0]?.login,100)||null,milestone:L(n?.title,200)||null,created_at:e.createdAt,updated_at:e.updatedAt,effort:dr(i),body:L(e.body||"",2e3)}}function dr(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 pr(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(mr)}catch{return[]}}function mr(e){let t=e.labels||[],s=e.reviewRequests||[],n=e.author;return{number:e.number,title:L(e.title,200),state:(e.state||"open").toLowerCase(),author:L(n?.login,100)||"unknown",branch:L(e.headRefName,fr),labels:t.map(i=>L(i.name,50)).filter(Boolean),reviewers:s.map(i=>L(i.login||i.name,100)).filter(Boolean),created_at:e.createdAt,updated_at:e.updatedAt}}async function gr(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 hr(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:L(n.title,200),summary:br(n.body||""),date:n.mergedAt,source:`PR #${n.number}`,url:n.url}))}catch{return[]}}function br(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 yr(e){let t=["docs/adr","docs/decisions","adr","decisions","docs/architecture/decisions"],s=[];for(let i of t){let o=Dt(e,i);if(rr(o))try{let r=ir(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=or(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 kr(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 wr(e){return qe(e.filter(t=>t.state==="open"))}var fr,He=D(()=>{"use strict";Hs();Pt();fr=200});import{readFileSync as vr,statSync as $r}from"fs";import{writeFile as xr,rename as jr}from"fs/promises";import{execFile as Sr}from"child_process";import{join as lt}from"path";async function Bs(e){return new Promise(t=>{Sr("git",["rev-parse","HEAD"],{cwd:e,timeout:5e3},(s,n)=>{if(s){t(null);return}t(n.trim())})})}function Js(e){try{let t=vr(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 xr(i,JSON.stringify(n),"utf-8"),await jr(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 Cr)try{let n=$r(lt(e,s));t[s]=n.mtimeMs}catch{}return t}var At,Us,Cr,Vs=D(()=>{"use strict";At=".codebase.cache.json",Us=2,Cr=["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 W(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||R(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||R("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=D(()=>{"use strict";us();Fs();He();M();Vs()});import{resolve as Er,join as _r}from"path";import{writeFile as Rr}from"fs/promises";async function Ge(e){ee(e.quiet);let t=Er(e.path);u(`Scanning ${t}...`);let s=await W(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(`${Pr(r)} (${ut(r,a)})`);let n=_r(t,".codebase.json"),i=JSON.stringify(s,null,2);await Rr(n,i,"utf-8");let o=(Buffer.byteLength(i)/1024).toFixed(1);u(`
142
- Written: .codebase.json (${o} KB)`)}function Pr(e){return e.charAt(0).toUpperCase()+e.slice(1)}var Ot=D(()=>{"use strict";je();M()});import{readFileSync as It,writeFileSync as Qs,existsSync as Nt}from"fs";import{join as dt}from"path";function Ir(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 Nr(e){let t=Ir(e);if(!t)return Or;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(`
138
+ `});import{execFile as rn}from"child_process";import{readdirSync as $r,readFileSync as Sr,existsSync as xr}from"fs";import{join as Jt}from"path";async function Ee(e){if(!await _e(e,["--version"]))return null;let s=await jr(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 Cr(e))return null;let o=await nn(e),r=[],a=[],c=[],l=[],p=[],d=!1;if(o)try{let k=await sn(e,s,{includeIssues:!0,includePRs:!0,includeMilestones:!0,includeReleases:!0,includeProjects:!0,limit:50});r=k.issues||[],a=k.pull_requests||[],c=k.milestones||[],l=k.releases||[],p=k.project_boards||[],d=!0}catch{}d||(r=await Er(e),a=await Pr(e),c=await Ar(e));let[f]=await Promise.all([Nr(e)]),$=Fr(r),h=Mr(r),b=Lr(e);return{status:{synced_at:new Date().toISOString(),github_available:!0,issues:r,pull_requests:a,kanban:$,priorities:h,releases:l,project_boards:p},roadmap:{milestones:c},decisions:{from_prs:f,from_adrs:b,manual:[]}}}function _e(e,t){return new Promise(s=>{rn("gh",t,{cwd:e,timeout:3e4},(n,i)=>{s(n?"":i.trim())})})}function jr(e,t,s){return new Promise(n=>{rn(t,s,{cwd:e,timeout:1e4},(i,o)=>{n(i?"":o.trim())})})}async function Cr(e){try{let t=await _e(e,["api","rate_limit"]);return t?(JSON.parse(t).resources?.core?.remaining??100)>10:!0}catch{return!0}}async function Er(e){let t=await _e(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(_r)}catch{return[]}}function _r(e){let t=e.labels||[],s=e.assignees||[],n=e.milestone,i=e.body||"";return{number:e.number,title:F(e.title,200),state:e.state?.toLowerCase()==="open"?"open":"closed",labels:t.map(o=>F(o.name,50)).filter(Boolean),assignee:F(s[0]?.login,100)||null,milestone:F(n?.title,200)||null,created_at:e.createdAt,updated_at:e.updatedAt,effort:Rr(i),body:F(e.body||"",2e3)}}function Rr(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 Pr(e){let t=await _e(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(Or)}catch{return[]}}function Or(e){let t=e.labels||[],s=e.reviewRequests||[],n=e.author;return{number:e.number,title:F(e.title,200),state:(e.state||"open").toLowerCase(),author:F(n?.login,100)||"unknown",branch:F(e.headRefName,Dr),labels:t.map(i=>F(i.name,50)).filter(Boolean),reviewers:s.map(i=>F(i.login||i.name,100)).filter(Boolean),created_at:e.createdAt,updated_at:e.updatedAt}}async function Ar(e){let t=await _e(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 Nr(e){let t=await _e(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:F(n.title,200),summary:Ir(n.body||""),date:n.mergedAt,source:`PR #${n.number}`,url:n.url}))}catch{return[]}}function Ir(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 Lr(e){let t=["docs/adr","docs/decisions","adr","decisions","docs/architecture/decisions"],s=[];for(let i of t){let o=Jt(e,i);if(xr(o))try{let r=$r(o).filter(a=>a.endsWith(".md")).map(a=>Jt(i,a));s.push(...r)}catch{}}let n=[];for(let i of s.slice(0,20))try{let a=Sr(Jt(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 Fr(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 Ve(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 Mr(e){return Ve(e.filter(t=>t.state==="open"))}var Dr,Qe=I(()=>{"use strict";on();Bt();Dr=200});import{readFileSync as Tr,statSync as qr}from"fs";import{writeFile as Hr,rename as Gr}from"fs/promises";import{execFile as Ur}from"child_process";import{join as wt}from"path";async function cn(e){return new Promise(t=>{Ur("git",["rev-parse","HEAD"],{cwd:e,timeout:5e3},(s,n)=>{if(s){t(null);return}t(n.trim())})})}function ln(e){try{let t=Tr(wt(e,Wt),"utf-8"),s=JSON.parse(t);return s.cache_version!==an?null:s}catch{return null}}async function un(e,t,s){let n={cache_version:an,timestamp:new Date().toISOString(),git_sha:await cn(e),file_count:t,file_mtimes:pn(e),manifest:s};try{let i=wt(e,Wt+".tmp");await Hr(i,JSON.stringify(n),"utf-8"),await Gr(i,wt(e,Wt))}catch{}}async function dn(e,t,s){let n=await cn(e);if(n&&t.git_sha)return n===t.git_sha;if(t.file_count!==s)return!1;let i=pn(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 pn(e){let t={};for(let s of Br)try{let n=qr(wt(e,s));t[s]=n.mtimeMs}catch{}return t}var Wt,an,Br,fn=I(()=>{"use strict";Wt=".codebase.cache.json",an=2,Br=["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 V(e,t={}){let s=await js(e,{depth:t.depth});if(t.incremental){let a=ln(e);if(a&&await dn(e,a,s.files.length))return a.manifest}let n=Ut;t.categories?.length&&(n=Ut.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||D(c)}if(r.length>0&&(o._warnings=r),t.sync)try{let a=await Ee(e);a&&(o.status=a.status,o.roadmap=a.roadmap,o.decisions=a.decisions)}catch{t.quiet||D("GitHub sync failed (is `gh` CLI installed and authenticated?)")}return t.incremental&&await un(e,s.files.length,o),o}function vt(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 Re=I(()=>{"use strict";Es();en();Qe();M();fn()});import{resolve as Jr,join as Wr}from"path";import{writeFile as Kr}from"fs/promises";async function Ye(e){K(e.quiet);let t=Jr(e.path);u(`Scanning ${t}...`);let s=await V(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||w(`${zr(r)} (${vt(r,a)})`);let n=Wr(t,".codebase.json"),i=JSON.stringify(s,null,2);await Kr(n,i,"utf-8");let o=(Buffer.byteLength(i)/1024).toFixed(1);u(`
142
+ Written: .codebase.json (${o} KB)`)}function zr(e){return e.charAt(0).toUpperCase()+e.slice(1)}var Kt=I(()=>{"use strict";Re();M()});import{readFileSync as zt,writeFileSync as mn,existsSync as Vt}from"fs";import{join as $t}from"path";function Xr(e){try{let t=zt($t(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 Zr(e){let t=Xr(e);if(!t)return Yr;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 |
146
146
  |---|---|
147
147
  ${o}
148
148
  `:"";return`
149
- ${Ue}
149
+ ${Xe}
150
150
  ## Project Context (auto-generated by codebase)
151
151
 
152
152
  **${t.name}**${t.description?` \u2014 ${t.description}`:""}
@@ -169,6 +169,8 @@ Returns: project identity, tech stack, commands, structure, current status, next
169
169
  | \`npx codebase query <path>\` | Any data point (e.g. \`stack.languages\`, \`commands.test\`) |
170
170
  | \`npx codebase issue create "title"\` | Track a bug, feature, or TODO |
171
171
  | \`npx codebase issue close <n> --reason "why"\` | Close an issue after fixing it |
172
+ | \`npx codebase handoff\` | Generate HANDOFF.md \u2014 session transfer for next agent |
173
+ | \`npx codebase tokens\` | Show token budget report for this project |
172
174
 
173
175
  ### Maintenance
174
176
  | Command | What it does |
@@ -184,28 +186,27 @@ Returns: project identity, tech stack, commands, structure, current status, next
184
186
  - **Close issues when you fix them** \u2014 with a reason so the team knows why
185
187
  - **If any command fails, run \`codebase doctor\` then \`codebase fix\`** \u2014 self-heal before asking for help
186
188
 
187
- ### Vibekit Workflow
188
- \`\`\`
189
- /simulate \u2192 /build \u2192 /launch
190
- \`\`\`
191
- - \`/simulate\` \u2014 agent-browser customer journeys find & fix bugs inline. Creates GitHub issues for arch problems.
192
- - \`/build\` \u2014 Implements architectural issues autonomously. Runs until all \`arch\`+\`vibekit\` issues are closed.
193
- - \`/launch\` \u2014 Gates on open bugs, generates GTM artifacts, creates GitHub release, merges to main.
194
-
195
- ### MCP Tools (for IDE/agent integrations)
196
- If using MCP instead of CLI: call \`project_brief\` (not \`npx codebase brief\`), \`get_next_task\`, \`refresh_status\`, \`list_skills\`. Full tool list via \`list_commands\` and \`list_skills\`.
189
+ ### Workflow Tips
190
+ - **Subagents for isolation**: use Task tool for large refactors \u2014 keeps main session clean
191
+ - **Session hygiene**: keep sessions focused; start fresh rather than pushing through context limits
192
+ - **Commit often**: detailed commit messages serve as memory between sessions
193
+ - **End of session**: run \`codebase handoff\` before closing to save state for the next agent
194
+ - **Model selection**: Opus for architecture/security decisions; Sonnet for implementation/iteration
195
+ - **Rewind mistakes**: ESC ESC after a bad edit \u2014 reverts and lets you try a different approach
197
196
 
198
- ### Browser Automation (agent-browser)
199
- Commands: \`open <url>\`, \`snapshot -i\` (\u2192 \`@e1\`/\`@e2\` refs), \`click @e1\`, \`fill @e2 "text"\`, \`screenshot\`, \`auth save/login <profile>\`, \`state save/load <name>\`.
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,`
197
+ ### Where to Find More
198
+ - Vibekit loop: see \`.claude/commands/\` for /simulate, /build, /launch
199
+ - MCP tools: call \`list_commands\` or \`list_skills\` via MCP server
200
+ - Browser automation: see \`~/.claude/skills/simulate/SKILL.md\`
201
+ ${Pe}`}function gn(e,t){return Vt($t(e,t))}function hn(e,t){let s=$t(e,t),n=Vt(s)?zt(s,"utf-8"):"";if(n.includes(Xe)){let i=n.indexOf(Xe),o=n.indexOf(Pe);i!==-1&&o!==-1&&(n=n.slice(0,i)+n.slice(o+Pe.length),n=n.replace(/\n{3,}/g,`
201
202
 
202
- `).trimEnd())}Qs(s,n.trimEnd()+`
203
- `+Nr(e)+`
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,`
203
+ `).trimEnd())}mn(s,n.trimEnd()+`
204
+ `+Zr(e)+`
205
+ `,"utf-8")}function bn(e,t){let s=$t(e,t);if(!Vt(s))return;let n=zt(s,"utf-8"),i=n.indexOf(Xe),o=n.indexOf(Pe);i!==-1&&o!==-1&&(n=n.slice(0,i)+n.slice(o+Pe.length),n=n.replace(/\n{3,}/g,`
205
206
 
206
207
  `).trim()+`
207
- `,Qs(s,n,"utf-8"))}var Ue,Se,Dr,Ar,Or,Xl,en=D(()=>{"use strict";Ue="<!-- codebase:start -->",Se="<!-- codebase:end -->",Dr="# codebase:start",Ar="# codebase:end",Or=`
208
- ${Ue}
208
+ `,mn(s,n,"utf-8"))}var Xe,Pe,Vr,Qr,Yr,Pu,yn=I(()=>{"use strict";Xe="<!-- codebase:start -->",Pe="<!-- codebase:end -->",Vr="# codebase:start",Qr="# codebase:end",Yr=`
209
+ ${Xe}
209
210
  ## Project Context (auto-generated by codebase)
210
211
 
211
212
  **This project uses \`codebase\` for AI context. Run commands below instead of exploring files.**
@@ -225,6 +226,8 @@ Returns: project identity, tech stack, commands, structure, current status, next
225
226
  | \`npx codebase query <path>\` | Any data point (e.g. \`stack.languages\`, \`commands.test\`) |
226
227
  | \`npx codebase issue create "title"\` | Track a bug, feature, or TODO |
227
228
  | \`npx codebase issue close <n> --reason "why"\` | Close an issue after fixing it |
229
+ | \`npx codebase handoff\` | Generate HANDOFF.md \u2014 session transfer for next agent |
230
+ | \`npx codebase tokens\` | Show token budget report for this project |
228
231
 
229
232
  ### Maintenance
230
233
  | Command | What it does |
@@ -240,21 +243,20 @@ Returns: project identity, tech stack, commands, structure, current status, next
240
243
  - **Close issues when you fix them** \u2014 with a reason so the team knows why
241
244
  - **If any command fails, run \`codebase doctor\` then \`codebase fix\`** \u2014 self-heal before asking for help
242
245
 
243
- ### Vibekit Workflow
244
- \`\`\`
245
- /simulate \u2192 /build \u2192 /launch
246
- \`\`\`
247
- - \`/simulate\` \u2014 agent-browser customer journeys find & fix bugs inline. Creates GitHub issues for arch problems.
248
- - \`/build\` \u2014 Implements architectural issues autonomously. Runs until all \`arch\`+\`vibekit\` issues are closed.
249
- - \`/launch\` \u2014 Gates on open bugs, generates GTM artifacts, creates GitHub release, merges to main.
250
-
251
- ### MCP Tools (for IDE/agent integrations)
252
- If using MCP instead of CLI: call \`project_brief\` (not \`npx codebase brief\`), \`get_next_task\`, \`refresh_status\`, \`list_skills\`. Full tool list via \`list_commands\` and \`list_skills\`.
253
-
254
- ### Browser Automation (agent-browser)
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
- ${Se}`,Xl=`
257
- ${Dr}
246
+ ### Workflow Tips
247
+ - **Subagents for isolation**: use Task tool for large refactors \u2014 keeps main session clean
248
+ - **Session hygiene**: keep sessions focused; start fresh rather than pushing through context limits
249
+ - **Commit often**: detailed commit messages serve as memory between sessions
250
+ - **End of session**: run \`codebase handoff\` before closing to save state for the next agent
251
+ - **Model selection**: Opus for architecture/security decisions; Sonnet for implementation/iteration
252
+ - **Rewind mistakes**: ESC ESC after a bad edit \u2014 reverts and lets you try a different approach
253
+
254
+ ### Where to Find More
255
+ - Vibekit loop: see \`.claude/commands/\` for /simulate, /build, /launch
256
+ - MCP tools: call \`list_commands\` or \`list_skills\` via MCP server
257
+ - Browser automation: see \`~/.claude/skills/simulate/SKILL.md\`
258
+ ${Pe}`,Pu=`
259
+ ${Vr}
258
260
  # Project Context (auto-generated by codebase)
259
261
  #
260
262
  # This project uses \`codebase\` for AI context. Run commands instead of exploring files.
@@ -269,6 +271,8 @@ ${Dr}
269
271
  # npx codebase query <path> \u2192 Any data (e.g. stack.languages)
270
272
  # npx codebase issue create "title" \u2192 Track bugs/features/TODOs
271
273
  # npx codebase issue close <n> --reason "why" \u2192 Close after fixing
274
+ # npx codebase handoff \u2192 Generate HANDOFF.md for next agent
275
+ # npx codebase tokens \u2192 Show token budget report
272
276
  #
273
277
  # MAINTENANCE:
274
278
  # codebase doctor \u2192 Health check \u2014 diagnose broken setup
@@ -282,14 +286,20 @@ ${Dr}
282
286
  # - Close issues when fixed \u2014 with a reason
283
287
  # - If any command fails, run doctor then fix \u2014 self-heal before asking for help
284
288
  #
289
+ # WORKFLOW TIPS:
290
+ # - Use subagents/Task tool for isolation \u2014 keeps main session token-efficient
291
+ # - Commit often with detailed messages \u2014 git history is your session memory
292
+ # - Run handoff before closing \u2014 saves state for the next agent
293
+ # - Opus for architecture decisions; Sonnet for implementation
294
+ #
285
295
  # MCP TOOLS (for IDE/agent integrations):
286
296
  # If using MCP: call project_brief, get_next_task, refresh_status, list_skills
287
- ${Ar}`});var tn={};Vt(tn,{claudeIntegration:()=>ae});var ae,Be=D(()=>{"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 Lr,writeFileSync as Fr,existsSync as Mr}from"fs";import{join as Tr}from"path";function Ce(e){let t=Tr(e,".gitignore"),s=Mr(t)?Lr(t,"utf-8"):"",n=!s.includes(sn),i=!s.includes(nn);if(!n&&!i)return;let o="";(n||i)&&(o+=`
297
+ ${Qr}`});var kn={};Ft(kn,{claudeIntegration:()=>me});var me,Ze=I(()=>{"use strict";yn();me={name:"claude",detect:e=>gn(e,"CLAUDE.md"),async inject(e){try{return hn(e,"CLAUDE.md"),{ok:!0}}catch(t){return{ok:!1,message:t.message}}},remove:e=>bn(e,"CLAUDE.md")}});import{readFileSync as ea,writeFileSync as ta,existsSync as sa}from"fs";import{join as na}from"path";function De(e){let t=na(e,".gitignore"),s=sa(t)?ea(t,"utf-8"):"",n=!s.includes(wn),i=!s.includes(vn);if(!n&&!i)return;let o="";(n||i)&&(o+=`
288
298
  # AI context manifest
289
- `,n&&(o+=`${sn}
290
- `),i&&(o+=`${nn}
291
- `)),Fr(t,s.trimEnd()+o,"utf-8")}var sn,nn,pt=D(()=>{"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),qr(e),!0}function qr(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
- ${on}
299
+ `,n&&(o+=`${wn}
300
+ `),i&&(o+=`${vn}
301
+ `)),ta(t,s.trimEnd()+o,"utf-8")}var wn,vn,St=I(()=>{"use strict";wn=".codebase.json",vn=".codebase.cache.json"});import{readFileSync as Qt,writeFileSync as tt,existsSync as Oe,mkdirSync as xn,chmodSync as jn,unlinkSync as Fu}from"fs";import{join as Ae}from"path";function Ne(e,t=!1){if(!Oe(Ae(e,".git")))return!1;let n=`npx --yes codebase scan-only --incremental --quiet${t?" --sync":""}`;return Sn(e,"post-commit",n),Sn(e,"post-checkout",n),ia(e),!0}function ia(e){let t=Ae(e,".git","hooks"),s=Ae(t,"pre-commit");Oe(t)||xn(t,{recursive:!0});let n=Ae(e,"package.json");if(!Oe(n))return;let i=!1,o=!1,r=!1;try{let l=JSON.parse(Qt(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
302
+ ${$n}
293
303
  # Run typecheck + lint before every commit. Fix errors before committing.
294
304
  if [ -f package.json ]; then
295
305
  ${a} || {
@@ -300,21 +310,21 @@ if [ -f package.json ]; then
300
310
  exit 1
301
311
  }
302
312
  fi
303
- `;if(Ee(s)){let l=Lt(s,"utf-8");l.includes(on)||We(s,l.trimEnd()+`
313
+ `;if(Oe(s)){let l=Qt(s,"utf-8");l.includes($n)||tt(s,l.trimEnd()+`
304
314
 
305
- `+c,"utf-8")}else We(s,c,"utf-8");cn(s,493)}function rn(e,t,s){let n=_e(e,".git","hooks"),i=_e(n,t);if(Ee(n)||an(n,{recursive:!0}),Ee(i)){let o=Lt(i,"utf-8");if(o.includes(Je)){let r=o.replace(new RegExp(`${Je}\\n.*`,"m"),`${Je}
306
- ${s}`);We(i,r,"utf-8");return}We(i,o.trimEnd()+`
315
+ `+c,"utf-8")}else tt(s,c,"utf-8");jn(s,493)}function Sn(e,t,s){let n=Ae(e,".git","hooks"),i=Ae(n,t);if(Oe(n)||xn(n,{recursive:!0}),Oe(i)){let o=Qt(i,"utf-8");if(o.includes(et)){let r=o.replace(new RegExp(`${et}\\n.*`,"m"),`${et}
316
+ ${s}`);tt(i,r,"utf-8");return}tt(i,o.trimEnd()+`
307
317
 
308
- ${Je}
318
+ ${et}
309
319
  ${s}
310
- `,"utf-8")}else We(i,`#!/bin/sh
320
+ `,"utf-8")}else tt(i,`#!/bin/sh
311
321
 
312
- ${Je}
322
+ ${et}
313
323
  ${s}
314
- `,"utf-8");cn(i,493)}var Je,on,ft=D(()=>{"use strict";Je="# codebase-auto-update";on="# codebase-pre-commit"});var ht={};Vt(ht,{installClaudeCommandsForFix:()=>Gr,installClaudeHooksForFix:()=>Br,installClaudeSkillsForFix:()=>Ur,runSetup:()=>Tt});import{resolve as Hr,dirname as ln,join as N}from"path";import{writeFileSync as ce,existsSync as K,mkdirSync as Ke,readFileSync as le,chmodSync as Mt,readdirSync as un,copyFileSync as mt}from"fs";import{execFile as Pe}from"child_process";async function Tt(e){let t=Hr(e.path);await Ge({...e,sync:!0}),S("Claude Code Integration"),K(N(t,"CLAUDE.md"))||ce(N(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=N(t,".vibekit");K(n)?h(".vibekit/ already exists"):(Ke(n,{recursive:!0}),g(".vibekit/ directory created")),S("GitHub Labels"),await zr()?(await Vr(t),await Qr(t)):(R("gh CLI not authenticated \u2014 skipping label/issue setup"),R("Run: gh auth login then codebase setup")),S("Product Brief");let o=N(t,"docs");K(o)||Ke(o,{recursive:!0});let r=N(o,"PRODUCT.md");K(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(`
324
+ `,"utf-8");jn(i,493)}var et,$n,xt=I(()=>{"use strict";et="# codebase-auto-update";$n="# codebase-pre-commit"});var st={};Ft(st,{installClaudeCommandsForFix:()=>ca,installClaudeHooksForFix:()=>da,installClaudeSkillsForFix:()=>la,installSessionStartHookForFix:()=>pa,runSetup:()=>Xt});import{resolve as oa,dirname as Cn,join as O}from"path";import{writeFileSync as ne,existsSync as U,mkdirSync as Le,readFileSync as ce,chmodSync as jt,readdirSync as En,copyFileSync as Ct,rmSync as ra}from"fs";import{execFile as Ie,execFileSync as aa}from"child_process";async function Xt(e){let t=oa(e.path);await Ye({...e,sync:!0}),R("Claude Code Integration"),U(O(t,"CLAUDE.md"))||ne(O(t,"CLAUDE.md"),`# Project Rules
325
+ `,"utf-8"),me.inject(t),w("CLAUDE.md - added .codebase.json reference"),R("Git Hooks"),Ne(t,!1)?(w("post-commit hook (auto-updates .codebase.json)"),w("pre-commit hook (runs typecheck + lint before every commit)"),fa(t),w("commit-msg hook (blocks direct commits to main/master)")):v("Not a git repository - skipping hooks"),R("Claude Code Hooks"),Pn(t),Dn(t),R("Browser Automation"),await ga(),R("Claude Commands"),_n(t),R("Claude Skills"),Rn(t),De(t),ma(t,[".vibekit/daemon.lock",".vibekit/daemon.log",".vibekit/build.lock",".vibekit/milestone.env",".mcp.json"]),w(".gitignore updated"),R("Vibekit Bootstrap");let n=O(t,".vibekit");U(n)?v(".vibekit/ already exists"):(Le(n,{recursive:!0}),w(".vibekit/ directory created")),R("GitHub Labels"),await ha()?(await ba(t),await ya(t)):(D("gh CLI not authenticated \u2014 skipping label/issue setup"),D("Run: gh auth login then codebase setup")),R("Product Brief");let o=O(t,"docs");U(o)||Le(o,{recursive:!0});let r=O(o,"PRODUCT.md");U(r)?v("docs/PRODUCT.md already exists \u2014 skipping (delete to regenerate)"):(ka(t,r),w("docs/PRODUCT.md generated \u2014 review and fill in [INFERRED] sections")),u(`
316
326
  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 Gr(e){dn(e)}function dn(e){let t=N(ln(new URL(import.meta.url).pathname),"..","commands");if(!K(t)){R("Claude commands not found in package \u2014 skipping");return}let s=un(t).filter(r=>r.endsWith(".md")),n=[{dir:N(e,".claude","commands"),label:".claude/commands/"},{dir:N(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=N(t,m),b=N(r,m);if(K(b)){let x=le(y,"utf-8"),j=le(b,"utf-8");x!==j?(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 Ur(e){pn(e)}function pn(e){let t=N(ln(new URL(import.meta.url).pathname),"../..","skills");if(!K(t)){R("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:N(e,".claude","skills"),label:".claude/skills/"},{dir:N(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=N(t,y),x=N(a,y);if(K(x)){let j=le(b),E=le(x);j.equals(E)?d++:(mt(b,x),p++)}else mt(b,x),l++}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=N(e,".claude","hooks");Ke(t,{recursive:!0});let s=N(t,"git-guard.sh");ce(s,`#!/bin/bash
327
+ 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 ca(e){_n(e)}function _n(e){let t=O(Cn(new URL(import.meta.url).pathname),"..","commands");if(!U(t)){D("Claude commands not found in package \u2014 skipping");return}let s=En(t).filter(r=>r.endsWith(".md")),n=[{dir:O(e,".claude","commands"),label:".claude/commands/"},{dir:O(process.env.HOME??"~",".claude","commands"),label:"~/.claude/commands/"}],i=0,o=0;for(let{dir:r,label:a}of n){Le(r,{recursive:!0});let c=0,l=0,p=0;for(let f of s){let $=O(t,f),h=O(r,f);if(U(h)){let b=ce($,"utf-8"),k=ce(h,"utf-8");b!==k?(Ct($,h),l++):p++}else Ct($,h),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?w(`Claude commands \u2192 ${a} (${d.join(", ")})`):v(`Claude commands up to date \u2192 ${a}`),i+=c,o+=l}(i>0||o>0)&&(v("Available: /setup /simulate /build /launch /review /vibeloop"),v("Tip: commit .claude/commands/ to share these with your team"))}function la(e){Rn(e)}function ua(e,t){let s=e.split("/").pop().replace(/\.skill$/,""),n=O(t,s);try{return U(n)&&ra(n,{recursive:!0,force:!0}),aa("unzip",["-o","-q",e,"-d",t],{timeout:3e4}),U(n)}catch{return!1}}function Rn(e){let t=O(Cn(new URL(import.meta.url).pathname),"../..","skills");if(!U(t)){D("Skills not found in package \u2014 skipping");return}let s=En(t).filter(a=>a.endsWith(".skill"));if(s.length===0){v("No skill files found in package");return}let n=[{dir:O(e,".claude","skills"),label:".claude/skills/"},{dir:O(process.env.HOME??"~",".claude","skills"),label:"~/.claude/skills/"}],i=0,o=0;for(let{dir:a,label:c}of n){Le(a,{recursive:!0});let l=0,p=0,d=0;for(let $ of s){let h=O(t,$),b=O(a,$),k=!1;if(U(b)){let x=ce(h),m=ce(b);if(!x.equals(m))Ct(h,b),k=!0,p++;else{let g=$.replace(/\.skill$/,"");U(O(a,g,"SKILL.md"))?d++:k=!0}}else Ct(h,b),k=!0,l++;k&&(ua(b,a)||D(`Failed to unzip ${$} \u2014 skill may not work until manually extracted`))}let f=[];l>0&&f.push(`${l} new`),p>0&&f.push(`${p} updated`),d>0&&f.push(`${d} unchanged`),l>0||p>0?w(`Skills \u2192 ${c} (${f.join(", ")})`):v(`Skills up to date \u2192 ${c}`),i+=l,o+=p}let r=s.map(a=>a.replace(/\.skill$/,"")).join(", ");i>0||o>0?(v(`Available: ${r}`),v("Tip: commit .claude/skills/ to share these with your team")):v(`Available: ${r}`)}function da(e){Pn(e)}function pa(e){Dn(e)}function Pn(e){let t=O(e,".claude","hooks");Le(t,{recursive:!0});let s=O(t,"git-guard.sh");ne(s,`#!/bin/bash
318
328
  # codebase git-guard \u2014 PreToolUse hook
319
329
  # Reads Claude tool input JSON from stdin, enforces git safety rules.
320
330
 
@@ -381,7 +391,7 @@ if echo "$CMD" | grep -qE "^git commit|&& git commit| git commit"; then
381
391
  fi
382
392
 
383
393
  exit 0
384
- `,"utf-8"),Mt(s,493),g(".claude/hooks/git-guard.sh (PreToolUse \u2014 blocks unsafe git ops)");let i=N(t,"git-post.sh");ce(i,`#!/bin/bash
394
+ `,"utf-8"),jt(s,493),w(".claude/hooks/git-guard.sh (PreToolUse \u2014 blocks unsafe git ops)");let i=O(t,"git-post.sh");ne(i,`#!/bin/bash
385
395
  # codebase git-post \u2014 PostToolUse hook
386
396
  # Reads Claude tool input JSON from stdin. Reminds to raise PR after branch push.
387
397
 
@@ -403,8 +413,13 @@ if echo "$CMD" | grep -qE "git push origin [a-zA-Z0-9/_-]+"; then
403
413
  fi
404
414
 
405
415
  exit 0
406
- `,"utf-8"),Mt(i,493),g(".claude/hooks/git-post.sh (PostToolUse \u2014 PR reminder after branch push)");let r=N(e,".claude","settings.json"),a={};if(K(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=N(e,".git","hooks"),s=N(t,"commit-msg"),n="# codebase-branch-check",i=`#!/bin/sh
416
+ `,"utf-8"),jt(i,493),w(".claude/hooks/git-post.sh (PostToolUse \u2014 PR reminder after branch push)");let r=O(e,".claude","settings.json"),a={};if(U(r))try{a=JSON.parse(ce(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 $=c.PostToolUse??[];JSON.stringify($).includes("git-post")||$.push({matcher:"Bash",hooks:[{type:"command",command:p}]}),c.PostToolUse=$,a.hooks=c,ne(r,JSON.stringify(a,null,2)+`
417
+ `,"utf-8"),w(".claude/settings.json (PreToolUse + PostToolUse hooks registered)")}function Dn(e){let t=O(e,".claude","hooks");Le(t,{recursive:!0});let s=O(t,"session-start.sh");ne(s,`#!/bin/bash
418
+ # codebase session-start \u2014 fires once per Claude Code session
419
+ # Keeps .codebase.json fresh without blocking Claude startup.
420
+ npx --yes codebase scan-only --quiet 2>/dev/null || true
421
+ `,"utf-8"),jt(s,493);let i=O(e,".claude","settings.json"),o={};if(U(i))try{o=JSON.parse(ce(i,"utf-8"))}catch{}let r=o.hooks??{},a=r.PreToolUse??[];JSON.stringify(a).includes("session-start")||a.push({matcher:"Bash",hooks:[{type:"command",command:"bash .claude/hooks/session-start.sh"}]}),r.PreToolUse=a,o.hooks=r,ne(i,JSON.stringify(o,null,2)+`
422
+ `,"utf-8"),w(".claude/hooks/session-start.sh (PreToolUse \u2014 auto-refresh manifest on session start)")}function fa(e){let t=O(e,".git","hooks"),s=O(t,"commit-msg"),n="# codebase-branch-check",i=`#!/bin/sh
408
423
  ${n}
409
424
  BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
410
425
  if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
@@ -415,18 +430,18 @@ if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
415
430
  echo ""
416
431
  exit 1
417
432
  fi
418
- `;if(K(s)){let o=le(s,"utf-8");o.includes(n)||ce(s,o.trimEnd()+`
433
+ `;if(U(s)){let o=ce(s,"utf-8");o.includes(n)||ne(s,o.trimEnd()+`
419
434
 
420
- `+i,"utf-8")}else ce(s,i,"utf-8");Mt(s,493)}function Wr(e,t){let s=N(e,".gitignore"),n=K(s)?le(s,"utf-8"):"",i=t.filter(o=>!n.includes(o)).join(`
421
- `);i&&ce(s,n.trimEnd()+`
435
+ `+i,"utf-8")}else ne(s,i,"utf-8");jt(s,493)}function ma(e,t){let s=O(e,".gitignore"),n=U(s)?ce(s,"utf-8"):"",i=t.filter(o=>!n.includes(o)).join(`
436
+ `);i&&ne(s,n.trimEnd()+`
422
437
  `+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))})){R("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)"):R("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))})||R("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
- `).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
438
+ `,"utf-8")}function Et(e,t){return new Promise(s=>{Ie("gh",t,{cwd:e,timeout:15e3},(n,i)=>{s({ok:!n,stdout:(i||"").trim()})})})}async function ga(){if(await new Promise(i=>{Ie("agent-browser",["--version"],{timeout:5e3},o=>i(!o))})){v("agent-browser already installed");return}if(u("Installing agent-browser..."),!await new Promise(i=>{Ie("npm",["install","-g","agent-browser"],{timeout:12e4},o=>i(!o))})){D("agent-browser install failed \u2014 run: npm install -g agent-browser");return}await new Promise(i=>{Ie("agent-browser",["install"],{timeout:3e5},o=>i(!o))})?w("agent-browser installed (Chrome for Testing downloaded)"):D("agent-browser installed but Chrome download failed \u2014 run: agent-browser install"),await new Promise(i=>{Ie("agent-browser",["--version"],{timeout:5e3},o=>i(!o))})||D("agent-browser validation failed \u2014 it may not be on PATH. Try: npm install -g agent-browser")}async function ha(){return new Promise(e=>{Ie("gh",["auth","status"],{timeout:5e3},t=>e(!t))})}async function ba(e){let{stdout:t}=await Et(e,["label","list","--limit","100","--json","name","--jq",".[].name"]),s=new Set(t.split(`
439
+ `).filter(Boolean)),n=0;for(let o of Yt){if(s.has(o.name))continue;let{ok:r}=await Et(e,["label","create",o.name,"--color",o.color,"--description",o.description]);r&&n++}let i=Yt.length-n;n>0?w(`${n} GitHub labels created (${i} already existed)`):v(`All ${Yt.length} labels already exist`)}async function ya(e){let{stdout:t}=await Et(e,["issue","list","--search","Highlights Index","--state","all","--limit","1","--json","number","--jq",".[0].number // empty"]);if(t){v("Highlights Index issue already exists");return}let s=`# Product Highlights Index
425
440
 
426
441
  Tracks positive signals from /simulate cycles. Updated automatically \u2014 do not edit manually.
427
442
 
428
443
  ## 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"):R("Could not create Highlights Index issue")}function Yr(e,t){let s=N(e,".codebase.json"),n=null;if(K(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}
444
+ <!-- /simulate appends here -->`,{ok:n}=await Et(e,["issue","create","--title","Highlights Index","--label","highlight","--body",s]);n?w("Highlights Index issue created on GitHub"):D("Could not create Highlights Index issue")}function ka(e,t){let s=O(e,".codebase.json"),n=null;if(U(s))try{n=JSON.parse(ce(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]";ne(t,`# PRODUCT.md \u2014 ${i}
430
445
 
431
446
  > Auto-generated by \`codebase setup\`. Fill in any [INFERRED] sections.
432
447
 
@@ -475,131 +490,140 @@ ${o}
475
490
  ## Known Constraints
476
491
 
477
492
  - [INFERRED: e.g. multi-tenant, RBAC, GDPR]
478
- `,"utf-8")}var Ft,ze=D(()=>{"use strict";Ot();Be();pt();ft();M();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"}]});M();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
- ${w("codebase")} \u2014 One command. Every AI tool understands your project instantly.
480
-
481
- ${w("QUICK START")}
482
- ${$("npx codebase")} \u2190 Run this once. That's it.
483
-
484
- ${w("AI INTERFACE")}
493
+ `,"utf-8")}var Yt,Fe=I(()=>{"use strict";Kt();Ze();St();xt();M();Yt=[{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"}]});var Vn={};Ft(Vn,{runHandoff:()=>ns});import{resolve as ec,join as ss}from"path";import{existsSync as tc,readFileSync as zn,writeFileSync as sc}from"fs";import{execFile as nc}from"child_process";import{promisify as ic}from"util";async function nt(e,t){try{let{stdout:s}=await oc("git",t,{cwd:e,timeout:1e4});return s.trim()}catch{return""}}async function ns(e){K(e.quiet);let t=ec(e.path),[s,n,i,o,r]=await Promise.all([nt(t,["branch","--show-current"]),nt(t,["diff","--stat","HEAD"]),nt(t,["log","--oneline","-10"]),nt(t,["status","--porcelain"]),nt(t,["stash","list"])]),a=i.split(`
494
+ `).map(S=>S.trim()).filter(Boolean),c=n.split(`
495
+ `).map(S=>S.trim()).filter(S=>S&&!S.includes("changed")&&!S.includes("insertion")&&!S.includes("deletion")),l=o.trim().length>0,p=r.split(`
496
+ `).map(S=>S.trim()).filter(Boolean),d=null;try{let S=zn(ss(t,".codebase.json"),"utf-8");d=JSON.parse(S)}catch{}let f=d?.status?.kanban?.in_progress??[],h=(d?.status?.priorities??[])[0]??null,b=(d?.status?.issues??[]).filter(S=>S.state==="open"&&S.labels.some(X=>X.toLowerCase().includes("blocked")||X.toLowerCase().includes("blocker"))),k=ss(t,"PLAN.md"),x="";tc(k)&&(x=zn(k,"utf-8").split(`
497
+ `).slice(0,20).join(`
498
+ `).trim());let m=new Date().toISOString(),g=[];if(g.push("# HANDOFF.md \u2014 Session Transfer"),g.push(""),g.push(`> Generated: ${m} `),g.push(`> Branch: \`${s||"unknown"}\``),g.push(""),g.push("## What Happened"),a.length>0)for(let S of a.slice(0,7))g.push(`- ${S}`);else g.push("- No recent commits");if(g.push(""),c.length>0){g.push("## Files Changed");for(let S of c.slice(0,15))g.push(`- ${S}`);g.push("")}if(g.push("## Current State"),g.push(`- **Branch:** ${s||"unknown"}`),l?g.push("- **Uncommitted changes:** yes \u2014 review before continuing"):g.push("- **Uncommitted changes:** none"),p.length>0){g.push(`- **Stashed work:** ${p.length} stash${p.length>1?"es":""}`);for(let S of p.slice(0,3))g.push(` - ${S}`)}else g.push("- **Stashed work:** none");if(g.push(""),f.length>0){g.push("## In Flight (from GitHub)");for(let S of f)g.push(`- #${S.number}: ${S.title}`);g.push("")}if(h){let S=h.labels.length?` [${h.labels.join(", ")}]`:"";g.push("## Next Priority"),g.push(`#${h.number}: ${h.title}${S}`),g.push("")}if(b.length>0){g.push("## Blockers");for(let S of b)g.push(`- #${S.number}: ${S.title}`);g.push("")}x&&(g.push("## Active Plan (from PLAN.md)"),g.push("```"),g.push(x),g.push("```"),g.push("")),e.message&&(g.push("## Session Notes"),g.push(e.message),g.push("")),g.push("## For Next Session"),g.push("1. Run `codebase brief` to load full project context"),g.push("2. Run `git status` to see any uncommitted work"),s&&g.push(`3. You are on branch \`${s}\``),h&&g.push(`4. Highest priority: #${h.number}`),g.push("");let A=ss(t,"HANDOFF.md");sc(A,g.join(`
499
+ `),"utf-8"),w("HANDOFF.md written"),v(` Branch: ${s||"unknown"}`),v(` Commits captured: ${a.length}`),f.length>0&&v(` In progress: ${f.map(S=>`#${S.number}`).join(", ")}`),h&&v(` Next task: #${h.number}: ${h.title}`)}var oc,is=I(()=>{"use strict";M();oc=ic(nc)});M();var ji={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"},{flag:"--slim",description:"Lightweight ~20-line brief (manifest age, next task, blockers, last commits)"}],seeAlso:["next","status","handoff"]},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"]},handoff:{description:"Generate HANDOFF.md capturing current session state for context transfer",usage:"codebase handoff [options]",examples:[{command:"codebase handoff",description:"Generate HANDOFF.md in project root"},{command:'codebase handoff --message "Finished auth, next: billing"',description:"Include session notes"}],options:[{flag:"--message <text>",description:"Session notes to include in HANDOFF.md"}],seeAlso:["brief"]},tokens:{description:"Estimate per-session token budget across all context sources",usage:"codebase tokens",examples:[{command:"codebase tokens",description:"Show token budget with A/B/C/D grades"}],seeAlso:["doctor"]}};function ms(){console.log(`
500
+ ${j("codebase")} \u2014 One command. Every AI tool understands your project instantly.
501
+
502
+ ${j("QUICK START")}
503
+ ${C("npx codebase")} \u2190 Run this once. That's it.
504
+
505
+ ${j("AI INTERFACE")}
485
506
  These are the commands your AI tools call:
486
507
 
487
- ${$("codebase brief")} Full project briefing \u2014 run this first
488
- ${$("codebase next")} What should I work on next?
489
- ${$("codebase status")} Kanban board, priorities, milestones
490
- ${$("codebase query <path>")} Query any field (e.g. ${Q("stack.languages")})
491
-
492
- ${w("AUTONOMOUS LOOP")}
493
- After ${$("codebase setup")}, these slash commands are available in Claude Code:
494
-
495
- ${$("/vibeloop")} Full autonomous run \u2014 simulate \u2192 build \u2192 launch (zero intervention)
496
- ${$("/setup")} Bootstrap project \u2014 labels, milestone, PRODUCT.md
497
- ${$("/simulate")} AI customer journeys (agent-browser) + UX audit
498
- ${$("/build")} Autonomous loop \u2014 build \u2192 test \u2192 simulate \u2192 repeat
499
- ${$("/launch")} Gate check \u2192 tag \u2192 release \u2192 merge to main
500
- ${$("/review")} Security, quality, deps, accessibility audit
501
-
502
- ${$("codebase skills")} List installed Claude skills
503
-
504
- ${w("HUMAN COMMANDS")}
505
- ${$("codebase init")} Full setup (scan + AI tools + hooks)
506
- ${$("codebase scan")} Update .codebase.json only (lightweight)
507
- ${$("codebase setup")} Wire AI tools + install slash commands
508
- ${$("codebase release")} Gate check \u2192 tag \u2192 develop\u2192main
509
- ${$("codebase doctor")} Health check & diagnostics
510
-
511
- ${w("OPTIONS")}
512
- ${Q("--help, -h")} Show this help or command-specific help
513
- ${Q("--version, -v")} Show version
514
- ${Q("--verbose")} Show detailed progress
515
- ${Q("--quiet")} Suppress output
516
-
517
- ${w("EXAMPLES")}
518
- ${$("npx codebase")} # One-time setup
519
- ${$("codebase brief")} # Project overview
520
- ${$("codebase next")} # Next task
521
- ${$("codebase query commands.test --force | sh")} # Run tests
522
- ${$('codebase issue create "Fix bug"')} # Track work
523
-
524
- ${w("GLOBAL OPTIONS")}
525
- ${Q("--path <dir>")} Target directory (default: current)
526
- ${Q("--verbose")} Show detailed output
527
- ${Q("--quiet")} Minimal output
528
-
529
- ${w("LEARN MORE")}
530
- Docs: ${tt("https://github.com/ZySec-AI/codebase#readme","README.md")}
531
- Issues: ${tt("https://github.com/ZySec-AI/codebase/issues","Report a bug")}
532
- Commands: ${$("codebase <command> --help")} Show command-specific help
533
- `)}function Xt(e){let t=ii[e];t||(console.error(`
534
- ${w("\u2717")} Unknown command: ${e}
535
- `),console.log(` Run ${$("codebase --help")} to see all commands.
508
+ ${C("codebase brief")} Full project briefing \u2014 run this first
509
+ ${C("codebase brief --slim")} Lightweight brief (~20 lines) for session-start hooks
510
+ ${C("codebase next")} What should I work on next?
511
+ ${C("codebase status")} Kanban board, priorities, milestones
512
+ ${C("codebase query <path>")} Query any field (e.g. ${ee("stack.languages")})
513
+ ${C("codebase handoff")} Generate HANDOFF.md for session transfer
514
+
515
+ ${j("AUTONOMOUS LOOP")}
516
+ After ${C("codebase setup")}, these slash commands are available in Claude Code:
517
+
518
+ ${C("/vibeloop")} Full autonomous run \u2014 simulate \u2192 build \u2192 launch (zero intervention)
519
+ ${C("/setup")} Bootstrap project \u2014 labels, milestone, PRODUCT.md
520
+ ${C("/simulate")} AI customer journeys (agent-browser) + UX audit
521
+ ${C("/build")} Autonomous loop \u2014 build \u2192 test \u2192 simulate \u2192 repeat
522
+ ${C("/launch")} Gate check \u2192 tag \u2192 release \u2192 merge to main
523
+ ${C("/review")} Security, quality, deps, accessibility audit
524
+
525
+ ${C("codebase skills")} List installed Claude skills
526
+
527
+ ${j("HUMAN COMMANDS")}
528
+ ${C("codebase init")} Full setup (scan + AI tools + hooks)
529
+ ${C("codebase scan")} Update .codebase.json only (lightweight)
530
+ ${C("codebase setup")} Wire AI tools + install slash commands
531
+ ${C("codebase release")} Gate check \u2192 tag \u2192 develop\u2192main
532
+ ${C("codebase doctor")} Health check & diagnostics
533
+ ${C("codebase tokens")} Token budget report (A/B/C/D grades)
534
+
535
+ ${j("OPTIONS")}
536
+ ${ee("--help, -h")} Show this help or command-specific help
537
+ ${ee("--version, -v")} Show version
538
+ ${ee("--verbose")} Show detailed progress
539
+ ${ee("--quiet")} Suppress output
540
+
541
+ ${j("EXAMPLES")}
542
+ ${C("npx codebase")} # One-time setup
543
+ ${C("codebase brief")} # Project overview
544
+ ${C("codebase next")} # Next task
545
+ ${C("codebase query commands.test --force | sh")} # Run tests
546
+ ${C('codebase issue create "Fix bug"')} # Track work
547
+
548
+ ${j("GLOBAL OPTIONS")}
549
+ ${ee("--path <dir>")} Target directory (default: current)
550
+ ${ee("--verbose")} Show detailed output
551
+ ${ee("--quiet")} Minimal output
552
+
553
+ ${j("LEARN MORE")}
554
+ Docs: ${pt("https://github.com/ZySec-AI/codebase#readme","README.md")}
555
+ Issues: ${pt("https://github.com/ZySec-AI/codebase/issues","Report a bug")}
556
+ Commands: ${C("codebase <command> --help")} Show command-specific help
557
+ `)}function gs(e){let t=ji[e];t||(console.error(`
558
+ ${j("\u2717")} Unknown command: ${e}
559
+ `),console.log(` Run ${C("codebase --help")} to see all commands.
536
560
  `),process.exit(1)),console.log(`
537
- ${w(e)} \u2014 ${t.description}
561
+ ${j(e)} \u2014 ${t.description}
538
562
 
539
- ${w("USAGE")}
540
- ${Q(t.usage)}
563
+ ${j("USAGE")}
564
+ ${ee(t.usage)}
541
565
  ${t.examples.length>0?`
542
- ${w("EXAMPLES")}
543
- ${t.examples.map(s=>` ${$(s.command)}${te(" # "+s.description)}`).join(`
566
+ ${j("EXAMPLES")}
567
+ ${t.examples.map(s=>` ${C(s.command)}${z(" # "+s.description)}`).join(`
544
568
  `)}
545
569
  `:""}${t.options?`
546
- ${w("OPTIONS")}
547
- ${t.options.map(s=>` ${Q(s.flag.padEnd(25))} ${s.description}`).join(`
570
+ ${j("OPTIONS")}
571
+ ${t.options.map(s=>` ${ee(s.flag.padEnd(25))} ${s.description}`).join(`
548
572
  `)}
549
573
  `:""}${t.seeAlso?`
550
- ${w("SEE ALSO")}
551
- ${t.seeAlso.map(s=>$(s)).join(", ")}
552
- `:""}${w("MORE HELP")}
553
- ${$("codebase --help")} Show all commands
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.4"),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)}M();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,spawnSync as ui}from"child_process";var ns=ss(li(),".codebase"),is=ss(ns,"update-check.json"),di=1440*60*1e3,me="codebase-ai",ke=!!process.env.NO_COLOR,C={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 pi(){return"0.3.4"}function fi(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 mi(){try{return JSON.parse(jt(is,"utf8"))}catch{return null}}function gi(e){try{ci(ns,{recursive:!0}),ai(is,JSON.stringify({version:e,checkedAt:Date.now()}))}catch{}}function hi(){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 bi(){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`}function yi(e){let[t,...s]=e.split(" ");return ui(t,s,{stdio:"inherit"}).status===0}function ki(){return new Promise(e=>{let t=process.stdin,s=t.isTTY;s&&t.setRawMode(!0),t.resume(),t.setEncoding("utf8");let n=i=>{s&&t.setRawMode(!1),t.pause(),t.removeListener("data",n),e(i)};t.on("data",n),setTimeout(()=>{s&&t.setRawMode(!1),t.pause(),t.removeListener("data",n),e("n")},1e4)})}async function os(){if(process.env.CI||process.env.NO_UPDATE_CHECK||process.env.CODEBASE_NO_UPDATE_CHECK||!process.stdout.isTTY||!process.stdin.isTTY)return;let e=pi(),t=mi(),s;if(t&&Date.now()-t.checkedAt<di)s=t.version;else try{s=await hi(),gi(s)}catch{return}if(!fi(s,e))return;let n=bi();console.log(`
556
- ${C.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${C.reset}`),console.log(` ${C.yellow}\u2502${C.reset} ${C.bold}Update available${C.reset} ${C.dim}${e}${C.reset} ${C.yellow}\u2192${C.reset} ${C.bold}${C.cyan}${s}${C.reset}`),console.log(` ${C.yellow}\u2502${C.reset} Press ${C.bold}Y${C.reset} to update now, any other key to skip`),console.log(` ${C.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${C.reset}`),process.stdout.write(`
557
- > `);let o=(await ki()).toLowerCase()==="y";if(console.log(o?"Updating\u2026":`Skipped.
558
- `),!o)return;console.log(`
559
- ${C.dim}$ ${n}${C.reset}
560
- `);let r=yi(n);console.log(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(`
568
- 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
-
570
- `,"utf-8"),l=[ae]):u(` Detected: ${l.map(f=>f.name).join(", ")}`);for(let f of l){let P=await f.inject(s);P.ok?g(`${f.name} \u2014 instructions injected`):R(`${f.name} \u2014 injection failed: ${P.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!
574
+ ${j("SEE ALSO")}
575
+ ${t.seeAlso.map(s=>C(s)).join(", ")}
576
+ `:""}${j("MORE HELP")}
577
+ ${C("codebase --help")} Show all commands
578
+ ${pt("https://github.com/ZySec-AI/codebase/docs","Full documentation")}
579
+ `)}var fl={E_NO_GIT:{message:"Not a git repository",suggestion:"Initialize git first: "+C("git init")},E_NO_PACKAGE_JSON:{message:"No package.json found",suggestion:"Initialize project: "+C("npm init")+" or "+C("pnpm init")},E_GH_NOT_AUTHENTICATED:{message:"GitHub CLI not authenticated",suggestion:"Run: "+C("gh auth login")},E_MANIFEST_NOT_FOUND:{message:".codebase.json not found",suggestion:"Run: "+C("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 Ci={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,slim:!1},hs=new Set(["scan","setup","query","mcp","issue","status","init","scan-only","brief","next","doctor","fix","release","plan","skills","serve","handoff","tokens"]);function bs(e){let t={...Ci},s=[];for(let n=0;n<e.length;n++){let i=e[n];if(!i.startsWith("-")&&hs.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&&(ms(),process.exit(0)),(i==="--version"||i==="-v")&&(console.log("codebase 0.3.7"),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==="slim"){t.slim=!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&&hs.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 ys(e){gs(e),process.exit(0)}M();import{get as Ei}from"https";import{readFileSync as Mt,writeFileSync as _i,mkdirSync as Ri}from"fs";import{homedir as Pi}from"os";import{join as ks}from"path";import{execSync as ft}from"child_process";var ws=ks(Pi(),".codebase"),vs=ks(ws,"update-check.json"),Di=1440*60*1e3,ke="codebase-ai",xe=!!process.env.NO_COLOR,H={yellow:xe?"":"\x1B[33m",cyan:xe?"":"\x1B[36m",green:xe?"":"\x1B[32m",bold:xe?"":"\x1B[1m",dim:xe?"":"\x1B[2m",reset:xe?"":"\x1B[0m"};function Oi(){return"0.3.7"}function Ai(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 Ni(){try{return JSON.parse(Mt(vs,"utf8"))}catch{return null}}function Ii(e){try{Ri(ws,{recursive:!0}),_i(vs,JSON.stringify({version:e,checkedAt:Date.now()}))}catch{}}function Li(){return new Promise((e,t)=>{let s=Ei(`https://registry.npmjs.org/${ke}/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 Fi(){try{let e=ft("npm root -g 2>/dev/null",{encoding:"utf8"}).trim();if(e&&Mt(`${e}/${ke}/package.json`,"utf8"))return`npm install -g ${ke}@latest`}catch{}try{ft("pnpm --version 2>/dev/null",{encoding:"utf8"});let e=ft("pnpm root -g 2>/dev/null",{encoding:"utf8"}).trim();if(e&&Mt(`${e}/${ke}/package.json`,"utf8"))return`pnpm add -g ${ke}@latest`}catch{}try{return ft("yarn --version 2>/dev/null",{encoding:"utf8"}),`yarn global add ${ke}@latest`}catch{}return`npm install -g ${ke}@latest`}async function $s(){if(process.env.CI||process.env.NO_UPDATE_CHECK||process.env.CODEBASE_NO_UPDATE_CHECK||!process.stdout.isTTY)return;let e=Oi(),t=Ni(),s;if(t&&Date.now()-t.checkedAt<Di)s=t.version;else try{s=await Li(),Ii(s)}catch{return}if(!Ai(s,e))return;let n=Fi();console.error(`
580
+ ${H.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${H.reset}`),console.error(` ${H.yellow}\u2502${H.reset} ${H.bold}Update available${H.reset} ${H.dim}${e}${H.reset} ${H.yellow}\u2192${H.reset} ${H.bold}${H.cyan}${s}${H.reset}`),console.error(` ${H.yellow}\u2502${H.reset} Run: ${H.bold}${n}${H.reset}`),console.error(` ${H.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${H.reset}
581
+ `)}Kt();Fe();Re();import{resolve as va,join as ve}from"path";import{existsSync as _t,writeFileSync as $a,readFileSync as Nn}from"fs";import{execFile as An}from"child_process";import{writeFile as Zt,rename as Sa}from"fs/promises";import{homedir as xa}from"os";Ze();var wa=[me];function On(e){return wa.filter(t=>t.detect(e))}Ze();St();xt();M();function ja(e){if(!_t(ve(e,".codebase.json")))return!1;let t=ve(e,"CLAUDE.md");if(_t(t))try{let s=Nn(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 In(e){let t=Date.now();K(e.quiet);let s=va(e.path);if(ja(s)&&!e.force){R(`codebase \u2014 refreshing project manifest
582
+ `);let g=await Me()==="authenticated";u(`Scanning ${s}...`);let A=await V(s,{depth:e.depth,categories:e.categories.length?e.categories:void 0,quiet:e.quiet,sync:g}),S=ve(s,".codebase.json"),X=JSON.stringify(A,null,2);await Zt(S,X,"utf-8");let re=(Buffer.byteLength(X)/1024).toFixed(1);w(`Manifest refreshed \u2014 .codebase.json (${re} KB)`),v("Already initialized. Run with --force to force full re-setup.");return}R(`codebase \u2014 activating project intelligence
583
+ `);let n=await Me();n==="authenticated"?w("GitHub CLI \u2014 authenticated"):n==="not-authenticated"?(D("GitHub CLI installed but not logged in"),v("Run: gh auth login"),v("After login, re-run `npx codebase` for full GitHub integration\n")):(v("GitHub CLI not found \u2014 GitHub features disabled"),v(`To enable: brew install gh && gh auth login
584
+ `));let i=n==="authenticated";u(`Scanning ${s}...`);let o=await V(s,{depth:e.depth,categories:e.categories.length?e.categories:void 0,quiet:e.quiet,sync:i});for(let[m,g]of Object.entries(o))m==="version"||m==="generated_at"||typeof g!="object"||g===null||w(`${Ca(m)} (${vt(m,g)})`);let r=ve(s,".codebase.json"),a=JSON.stringify(o,null,2);await Zt(r,a,"utf-8");let c=(Buffer.byteLength(a)/1024).toFixed(1);u(`
585
+ Written: .codebase.json (${c} KB)`),R("AI Tool Integration");let l=On(s),p=Ea(),d=new Set(l.map(m=>m.name));for(let m of p)d.has(m.name)||(l.push(m),d.add(m.name));l.length===0?(v("No AI tool detected in project or system configs"),v("Creating CLAUDE.md as default (works with Claude Code, and readable by all tools)"),$a(ve(s,"CLAUDE.md"),`# Project Rules
586
+
587
+ `,"utf-8"),l=[me]):u(` Detected: ${l.map(m=>m.name).join(", ")}`);for(let m of l){let g=await m.inject(s);g.ok?w(`${m.name} \u2014 instructions injected`):D(`${m.name} \u2014 injection failed: ${g.message||"unknown error"}`)}R("MCP Server (native AI tool access)");let f=await es(s,d);if(f.length){for(let m of f)w(`${m} \u2014 MCP server auto-configured`);v("AI tools can now call project_brief, get_next_task, create_issue, etc. natively")}else v("AI tools will read .codebase.json directly."),v("To enable MCP later, add to your tool's MCP config:"),u(' { "command": "npx", "args": ["codebase", "mcp"] }');if(R("Auto-Update Hooks"),Ne(s,i)?(w("post-commit hook \u2014 manifest updates on every commit"),w("post-checkout hook \u2014 manifest updates on branch switch"),i&&w("hooks include GitHub sync \u2014 issues/PRs stay current")):v("Not a git repository \u2014 skipping hooks"),De(s),w(".gitignore updated"),R(`Ready!
571
588
  `),u(`Your project is now fully activated. Here's what happens automatically:
572
589
  `),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,P=o.status?.pull_requests?.filter(A=>A.state==="open").length||0;(f||P)&&u(` GitHub synced: ${f} open issues, ${P} 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(`
590
+ `),i){let m=o.status?.issues?.filter(A=>A.state==="open").length||0,g=o.status?.pull_requests?.filter(A=>A.state==="open").length||0;(m||g)&&u(` GitHub synced: ${m} open issues, ${g} open PRs`)}let h=o.stack?.languages??[];!(Object.keys(o.commands??{}).length>0)&&h.every(m=>m==="json"||m==="yaml"||m==="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
591
  You don't need to run this again. Everything stays alive.
575
- `);let E=((Date.now()-t)/1e3).toFixed(1);g(`Done (${E}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
- `,"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(`
592
+ `);let x=((Date.now()-t)/1e3).toFixed(1);w(`Done (${x}s)`)}function Ca(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Me(){return new Promise(e=>{An("sh",["-c","which gh 2>/dev/null"],{timeout:5e3},t=>{if(t){e("not-installed");return}An("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 Ea(){let e=xa(),t=[];return _t(ve(e,".claude"))&&t.push(me),t}async function es(e,t){let s=[],n={command:"npx",args:["codebase","mcp"],cwd:e};if(t.has("claude")||t.size===0){let i=ve(e,".mcp.json");await _a(i,"codebase",n)&&s.push("Claude Code (project .mcp.json)")}return s}async function _a(e,t,s){let n={};if(_t(e)){try{n=JSON.parse(Nn(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 Zt(i,JSON.stringify(n,null,2)+`
593
+ `,"utf-8"),await Sa(i,e),!0}import{resolve as Ra,join as Pa}from"path";import{readFile as Da}from"fs/promises";import{existsSync as Oa}from"fs";function Rt(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
594
  Generated: ${e.generated_at}
578
595
  `),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(`
579
596
  `))}if(e.patterns&&(e.patterns.architecture&&n.push(`Architecture: ${e.patterns.architecture}`),e.patterns.state_management&&n.push(`State management: ${e.patterns.state_management}`),e.patterns.api_style&&n.push(`API style: ${e.patterns.api_style}`)),t.push(n.join(`
580
597
  `)),e.commands){let o=Object.entries(e.commands).filter(([,r])=>r);if(o.length){t.push(`
581
598
  ## Commands`);for(let[r,a]of o)t.push(`- ${r}: \`${a}\``)}}if(e.structure&&(t.push(`
582
599
  ## Key Paths`),e.structure.entry_points?.length&&t.push(`Entry points: ${e.structure.entry_points.join(", ")}`),e.patterns?.key_modules&&Object.keys(e.patterns.key_modules).length))for(let[o,r]of Object.entries(e.patterns.key_modules))t.push(`- ${o} \u2192 ${r}`);if(e.status&&e.status.github_available){let o=[],r=e.status.kanban?.in_progress||[];if(r.length){o.push(`
583
- ### In Progress NOW`);for(let m of r){let y=m.assignee?` \u2192 @${m.assignee}`:"",b=m.mapped_files?.length?` (files: ${m.mapped_files.join(", ")})`:"";o.push(`- #${m.number}: ${m.title}${y}${b}`)}}let c=(e.status.priorities||[])[0];if(c){o.push(`
584
- ### NEXT TASK (highest priority)`);let m=c.labels.length?` [${c.labels.join(", ")}]`:"";if(o.push(`#${c.number}: ${c.title}${m}`),c.body){let y=c.body.length>300?c.body.slice(0,300)+"\u2026":c.body;o.push(y)}c.mapped_files?.length&&o.push(`Start in: ${c.mapped_files.join(", ")}`)}let l=e.status.kanban?.backlog||[];if(l.length>0){o.push(`
585
- ### Backlog (${l.length} items)`);for(let m of l.slice(0,5)){let y=m.labels.length?` [${m.labels.join(", ")}]`:"";o.push(`- #${m.number}: ${m.title}${y}`)}l.length>5&&o.push(` ... and ${l.length-5} more`)}let p=(e.status.issues||[]).filter(m=>m.state==="open"&&m.labels.some(y=>y.toLowerCase().includes("blocked")||y.toLowerCase().includes("blocker")));if(p.length){o.push(`
586
- ### BLOCKERS`);for(let m of p)o.push(`- #${m.number}: ${m.title} [${m.labels.join(", ")}]`)}let d=(e.status.pull_requests||[]).filter(m=>m.state==="open");if(d.length){o.push(`
587
- ### Open PRs (${d.length})`);for(let m of d.slice(0,5)){let y=m.reviewers.length?` \u2192 waiting on: ${m.reviewers.join(", ")}`:"";o.push(`- PR #${m.number}: ${m.title} (${m.branch})${y}`)}}o.length>0&&(t.push(`
600
+ ### In Progress NOW`);for(let f of r){let $=f.assignee?` \u2192 @${f.assignee}`:"",h=f.mapped_files?.length?` (files: ${f.mapped_files.join(", ")})`:"";o.push(`- #${f.number}: ${f.title}${$}${h}`)}}let c=(e.status.priorities||[])[0];if(c){o.push(`
601
+ ### NEXT TASK (highest priority)`);let f=c.labels.length?` [${c.labels.join(", ")}]`:"";if(o.push(`#${c.number}: ${c.title}${f}`),c.body){let $=c.body.length>300?c.body.slice(0,300)+"\u2026":c.body;o.push($)}c.mapped_files?.length&&o.push(`Start in: ${c.mapped_files.join(", ")}`)}let l=e.status.kanban?.backlog||[];if(l.length>0){o.push(`
602
+ ### Backlog (${l.length} items)`);for(let f of l.slice(0,5)){let $=f.labels.length?` [${f.labels.join(", ")}]`:"";o.push(`- #${f.number}: ${f.title}${$}`)}l.length>5&&o.push(` ... and ${l.length-5} more`)}let p=(e.status.issues||[]).filter(f=>f.state==="open"&&f.labels.some($=>$.toLowerCase().includes("blocked")||$.toLowerCase().includes("blocker")));if(p.length){o.push(`
603
+ ### BLOCKERS`);for(let f of p)o.push(`- #${f.number}: ${f.title} [${f.labels.join(", ")}]`)}let d=(e.status.pull_requests||[]).filter(f=>f.state==="open");if(d.length){o.push(`
604
+ ### Open PRs (${d.length})`);for(let f of d.slice(0,5)){let $=f.reviewers.length?` \u2192 waiting on: ${f.reviewers.join(", ")}`:"";o.push(`- PR #${f.number}: ${f.title} (${f.branch})${$}`)}}o.length>0&&(t.push(`
588
605
  ## CURRENT STATUS`),t.push(...o))}if(e.roadmap?.milestones?.length){t.push(`
589
606
  ## Roadmap`);for(let o of e.roadmap.milestones){let r=o.due_date?` (due: ${o.due_date.split("T")[0]})`:"";t.push(`- ${o.title}: ${o.progress.percent}% complete (${o.progress.closed}/${o.progress.open+o.progress.closed} done)${r}`)}}let i=[...e.decisions?.from_prs||[],...e.decisions?.from_adrs||[],...e.decisions?.manual||[]];if(i.length){t.push(`
590
607
  ## 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
608
  ## WARNING`),t.push("There are uncommitted changes in the working directory.")),e.git.recent_commits?.length)){t.push(`
592
609
  ## Recent Commits`);for(let o of e.git.recent_commits.slice(0,3))t.push(`- ${o}`)}return t.join(`
593
- `)}M();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&&R("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+`
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)}M();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
- ${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}M();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
- `);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+`
610
+ `)}function Pt(e){let t=[],s=e.project?.name||"Unknown Project",n=e.generated_at?Date.now()-new Date(e.generated_at).getTime():-1,i=n>=0?Math.round(n/6e4):-1,o=i<0?"unknown age":i<60?`${i}m ago`:`${Math.round(i/60)}h ago`;t.push(`# ${s} \u2014 Session Start (manifest: ${o})`),e.git?.uncommitted_changes&&t.push(`
611
+ WARNING: Uncommitted changes in working directory.`);let r=e.status?.kanban?.in_progress||[];if(r.length){t.push(`
612
+ ## In Progress`);for(let l of r)t.push(`- #${l.number}: ${l.title}`)}let a=e.status?.priorities||[];if(a[0]){let l=a[0],p=l.labels.length?` [${l.labels.join(", ")}]`:"";t.push(`
613
+ ## Next Task
614
+ #${l.number}: ${l.title}${p}`)}let c=(e.status?.issues||[]).filter(l=>l.state==="open"&&l.labels.some(p=>p.toLowerCase().includes("blocked")||p.toLowerCase().includes("blocker")));if(c.length){t.push(`
615
+ ## Blockers`);for(let l of c)t.push(`- #${l.number}: ${l.title}`)}if(e.git?.recent_commits?.length){t.push(`
616
+ ## Recent Commits`);for(let l of e.git.recent_commits.slice(0,3))t.push(`- ${l}`)}return t.push("\nFor full context: `codebase brief`"),t.join(`
617
+ `)}M();async function Ln(e){let t=Ra(e.path),s=Pa(t,".codebase.json");Oa(s)||(console.error("No manifest found. Run 'codebase init' to set up this project first."),process.exit(1));let n;try{let r=await Da(s,"utf-8");n=JSON.parse(r)}catch{E("No .codebase.json found (or it's corrupted). Run `npx codebase` first."),process.exit(1)}!e.quiet&&!n.status&&!n.roadmap&&D("GitHub data unavailable (gh not authenticated or --sync not used). Issues, PRs and milestones not included.");let i=n;e.categories.length>0&&(i=Aa(n,e.categories));let o=e.slim?Pt(i):Na(i,e.format);process.stdout.write(o+`
618
+ `)}function Aa(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 Na(e,t){return t==="json"?JSON.stringify(e,null,2):Rt(e)}M();Qe();import{resolve as Ia,join as Fn}from"path";import{readFile as La}from"fs/promises";import{existsSync as Fa}from"fs";function Ma(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 Mn(e){let t=Ia(e.path);Fa(Fn(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 La(Fn(t,".codebase.json"),"utf-8");s=JSON.parse(l)}catch{E("No .codebase.json found (or it's corrupted). Run `npx codebase` first."),process.exit(1)}let n=s.status;if(!n||!n.github_available){v("No GitHub data. Run `npx codebase` with `gh` CLI authenticated.");return}let i=n.kanban?.in_progress||[];if(i.length){u(j("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=Ve(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(j("NEXT TASK:")),u(` #${r.number}: ${r.title}`),r.labels.length&&u(` Labels: ${r.labels.join(", ")}`),u(` Priority: ${Ma(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(`
619
+ ${j("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(`
620
+ ${j("BLOCKERS:")}`);for(let l of c)u(` #${l.number}: ${l.title} [${l.labels.join(", ")}]`)}}import{resolve as Ta,join as qa}from"path";import{readFile as Ha}from"fs/promises";import{existsSync as Ga}from"fs";function Te(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}M();async function Tn(e){let t=Ta(e.path),s=qa(t,".codebase.json");Ga(s)||(console.error("No manifest found. Run 'codebase init' to set up this project first."),process.exit(1));let n;try{let r=await Ha(s,"utf-8");n=JSON.parse(r)}catch{E("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)+`
621
+ `);return}let o=Te(n,i);o===void 0&&(E(`Path "${i}" not found in manifest.`),process.exit(1)),e.force?typeof o=="string"?process.stdout.write(o+`
598
622
  `):Array.isArray(o)?process.stdout.write(o.join(`
599
623
  `)+`
600
624
  `):process.stdout.write(JSON.stringify(o)+`
601
625
  `):process.stdout.write(JSON.stringify(o,null,2)+`
602
- `)}import{resolve as $a}from"path";M();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
626
+ `)}import{resolve as Ba}from"path";M();import{execFile as Ua}from"child_process";function qe(e,t){return new Promise((s,n)=>{Ua("gh",t,{cwd:e,timeout:3e4},(i,o,r)=>{i?n(new Error(r||i.message)):s(o.trim())})})}async function qn(e,t,s,n){let i=s||`## Summary
603
627
 
604
628
  ${t}
605
629
 
@@ -613,20 +637,20 @@ ${t}
613
637
 
614
638
  ## Actual
615
639
 
616
- `,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:**
640
+ `,o=["issue","create","--title",t,"--body",i];n?.length&&o.push("--label",n.join(","));try{let r=await qe(e,o),a=r.split("/").pop()??"";w(`Created #${a} \u2014 ${r}`)}catch(r){E(`Failed to create issue: ${r.message}`)}}async function Hn(e,t,s){try{let n=["issue","close",t];s&&n.push("--comment",s),await qe(e,n);try{let i=await qe(e,["issue","view",t,"--json","title,url"]),{title:o,url:r}=JSON.parse(i);w(`Closed #${t}: ${o}`),u(` ${r}`)}catch{w(`Closed issue #${t}`)}}catch(n){E(`Failed to close issue: ${n.message}`)}}async function Gn(e,t){try{let s=["issue","list","--limit","30"];t==="mine"&&s.push("--assignee","@me");let n=await qe(e,s);n?u(n):u("No issues found.")}catch(s){E(`Failed to list issues: ${s.message}`)}}async function Un(e,t,s){try{let n=await qe(e,["issue","comment",t,"--body",s]);n?w(`Comment added to #${t} \u2014 ${n}`):w(`Comment added to #${t}`)}catch(n){E(`Failed to comment on issue: ${n.message}`)}}async function Bn(e,t,s){try{let n=`**Mapped files:**
617
641
  ${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}`)}}M();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();M();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
- Also try: codebase status milestones | codebase status priorities | codebase status decisions`)}function Ea(e){S("Kanban Board");let{kanban:t}=e;u(`
620
- ${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
- ${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
- ${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
- ${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.4"},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
-
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,x)=>{if(b||!x.trim()){m();return}let j=x.match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!j){m();return}let E=j[1],f=E.match(/^name:\s*(.+)$/m),P=E.match(/^description:\s*(.+)$/m),A=f?f[1].trim():p.replace(/\.skill$/,""),G=P?P[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=`
642
+ `)}`;await qe(e,["issue","comment",t,"--body",n]),w(`Mapped issue #${t} to ${s.length} files`)}catch(n){E(`Failed to map issue: ${n.message}`)}}M();async function Jn(e){let t=Ba(e.path);switch(e.subcommand){case"create":{let s=e.positionals[0];s||(E('Usage: codebase issue create "Issue title" [--message "body"]'),process.exit(1)),await qn(t,s,e.message||void 0);break}case"close":{let s=e.positionals[0];s||(E('Usage: codebase issue close <number> [--reason "reason"]'),process.exit(1)),await Hn(t,s,e.reason||void 0);break}case"comment":{let s=e.positionals[0],n=e.message;(!s||!n)&&(E('Usage: codebase issue comment <number> --message "text"'),process.exit(1)),await Un(t,s,n);break}case"list":{let s=e.positionals[0];await Gn(t,s);break}case"map":{let s=e.positionals[0],n=e.positionals.slice(1);(!s||n.length===0)&&(E("Usage: codebase issue map <number> <file1> <file2> ..."),process.exit(1)),await Bn(t,s,n);break}default:E("Usage: codebase issue create|close|comment|list|map"),process.exit(1)}}Qe();M();import{resolve as Ja,join as ts}from"path";import{readFile as Wn,writeFile as Wa,rename as Ka}from"fs/promises";import{existsSync as za}from"fs";async function Kn(e){let t=Ja(e.path);za(ts(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 Wn(ts(t,".codebase.json"),"utf-8"))}catch{}if(!s?.status){v("Syncing from GitHub...");let o=await Ee(t);if(o||(E("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=ts(t,".codebase.json"),c={...JSON.parse(await Wn(r,"utf-8")),status:o.status,roadmap:o.roadmap,decisions:o.decisions},l=r+".tmp";await Wa(l,JSON.stringify(c,null,2),"utf-8"),await Ka(l,r)}catch{}}}let n=s?.status;if(!n){E("No status data available.");return}let i=e.positionals[0];(i==="kanban"||!i)&&Va(n),(i==="priorities"||!i)&&Qa(n),i==="milestones"&&s?.roadmap&&Ya(s.roadmap),i==="decisions"&&s?.decisions&&Xa(s.decisions),i||z(`
643
+ Also try: codebase status milestones | codebase status priorities | codebase status decisions`)}function Va(e){R("Kanban Board");let{kanban:t}=e;u(`
644
+ ${j("BACKLOG")} (${t.backlog.length})`);for(let n of t.backlog.slice(0,10))u(` #${n.number} ${n.title}`);t.backlog.length>10&&z(` \u2026 and ${t.backlog.length-10} more`),u(`
645
+ ${j("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&&z(` \u2026 and ${t.in_progress.length-10} more`);let s=t.needs_verify??[];if(s.length>0){u(`
646
+ ${j("NEEDS VERIFY")} (${s.length})`);for(let n of s.slice(0,10))u(` #${n.number} ${n.title}`);s.length>10&&z(` \u2026 and ${s.length-10} more`)}u(`
647
+ ${j("DONE")} (${t.done.length} recent)`);for(let n of t.done.slice(0,5))u(` #${n.number} ${n.title}`);t.done.length>5&&z(` \u2026 and ${t.done.length-5} more`)}function Qa(e){R("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 Ya(e){R("Milestones");for(let t of e.milestones){let s=Za(t.progress.percent),n=t.due_date?` (due: ${t.due_date.split("T")[0]})`:"";u(`
648
+ ${j(t.title)} ${s} ${t.progress.percent}%${n}`),u(` ${t.progress.closed}/${t.progress.open+t.progress.closed} issues closed`)}}function Xa(e){R("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 Za(e){let t=Math.round(e/5),s=20-t;return`[${"\u2588".repeat(t)}${"\u2591".repeat(s)}]`}import{resolve as hc}from"path";import{createInterface as rc}from"readline";import{readFile as ot,writeFile as Ot,rename as At}from"fs/promises";import{existsSync as Dt,readdirSync as Qn}from"fs";import{join as te,resolve as Yn}from"path";import{homedir as Xn}from"os";import{execFile as ei}from"child_process";Re();Qe();var ac=[{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:{slim:{type:"boolean",description:"Return a lightweight ~20-line brief (manifest age, next task, blockers, last commits). Faster for session-start hooks or low-context situations."}}}},{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:{}}},{name:"generate_handoff",description:"Generate HANDOFF.md capturing current session state for context transfer. Collects git state (branch, recent commits, diff stat, uncommitted changes, stashes) and manifest data (in-progress issues, next task, blockers). Use at the end of a session to leave a breadcrumb for the next agent or human.",inputSchema:{type:"object",properties:{message:{type:"string",description:"Optional session notes to include in the handoff document."}}}}];async function ti(e){let t=rc({input:process.stdin,terminal:!1});for await(let s of t){if(!s.trim())continue;let n;try{n=JSON.parse(s)}catch{Zn({jsonrpc:"2.0",id:0,error:{code:-32700,message:"Parse error"}});continue}let i=await cc(n,e);i&&Zn(i)}}async function cc(e,t){switch(e.method){case"initialize":return L(e.id,{protocolVersion:"2024-11-05",serverInfo:{name:"codebase",version:"0.3.7"},capabilities:{tools:{}}});case"notifications/initialized":return null;case"tools/list":return L(e.id,{tools:ac});case"tools/call":return lc(e,t);default:return{jsonrpc:"2.0",id:e.id,error:{code:-32601,message:`Method not found: ${e.method}`}}}}async function lc(e,t){let s=e.params||{},n=s.name,i=s.arguments||{};try{switch(n){case"project_brief":{let o=await it(t,!0),a=i.slim?Pt(o):Rt(o);return L(e.id,{content:[{type:"text",text:a}]})}case"get_codebase":{let o=await it(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 L(e.id,{content:[{type:"text",text:JSON.stringify(l,null,2)}]})}return L(e.id,{content:[{type:"text",text:JSON.stringify(c??null,null,2)}]})}return L(e.id,{content:[{type:"text",text:JSON.stringify(o,null,2)}]})}case"query_codebase":{let o=await it(t),r=i.path,a=i.fields,c=Te(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 L(e.id,{content:[{type:"text",text:JSON.stringify(c??null,null,2)}]})}case"get_next_task":{let o=await it(t,!0),r=dc(o);return L(e.id,{content:[{type:"text",text:JSON.stringify(r,null,2)}]})}case"get_blockers":{let o=await it(t,!0),r=pc(o);return L(e.id,{content:[{type:"text",text:JSON.stringify(r,null,2)}]})}case"create_issue":{let o=await fc(t,i);return await rs(t),L(e.id,{content:[{type:"text",text:o}]})}case"close_issue":{let o=await mc(t,i);return await rs(t),L(e.id,{content:[{type:"text",text:o}]})}case"update_issue":{let o=await gc(t,i);return await rs(t),L(e.id,{content:[{type:"text",text:o}]})}case"list_commands":{let o=te(t,".claude","commands"),r=te(Xn(),".claude","commands"),a=new Set,c=[];for(let p of[o,r])if(Dt(p))for(let d of Qn(p))d.endsWith(".md")&&!a.has(d)&&(a.add(d),c.push(d));if(c.length===0)return L(e.id,{content:[{type:"text",text:"No slash commands installed. Run: codebase setup"}]});let l=c.map(p=>"/"+p.replace(/\.md$/,"")).join(", ");return L(e.id,{content:[{type:"text",text:`Installed commands (${c.length}): ${l}
649
+
650
+ Loop: /simulate \u2192 /build \u2192 /launch`}]})}case"list_skills":{let o=te(Xn(),".claude","skills"),r=te(t,".claude","skills"),a=new Set,c=[];for(let p of[r,o])if(Dt(p))for(let d of Qn(p))d.endsWith(".skill")&&!a.has(d)&&(a.add(d),c.push({file:d,dir:p}));if(c.length===0)return L(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(f=>{let $=te(d,p);ei("unzip",["-p",$,"*/SKILL.md"],{timeout:1e4},(h,b)=>{if(h||!b.trim()){f();return}let k=b.match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!k){f();return}let x=k[1],m=x.match(/^name:\s*(.+)$/m),g=x.match(/^description:\s*(.+)$/m),A=m?m[1].trim():p.replace(/\.skill$/,""),S=g?g[1].trim():"";l.push({name:A,description:S,file:p}),f()})}))),L(e.id,{content:[{type:"text",text:JSON.stringify(l,null,2)}]})}case"get_plan":{let o=te(Yn(t),"PLAN.md");if(!Dt(o))return L(e.id,{content:[{type:"text",text:"No PLAN.md found. Use update_plan to create one."}]});let r=await ot(o,"utf-8");return L(e.id,{content:[{type:"text",text:r}]})}case"update_plan":{let o=te(Yn(t),"PLAN.md"),r=i.message,c=`
627
651
  <!-- updated: ${new Date().toISOString().split("T")[0]} -->
628
652
  ${r.trim()}
629
- `,l;if(!kt(o))l=`# PLAN.md \u2014 Autonomous Loop State
653
+ `,l;if(!Dt(o))l=`# PLAN.md \u2014 Autonomous Loop State
630
654
 
631
655
  > Managed by Claude. Updated each build/simulate cycle.
632
656
 
@@ -643,24 +667,26 @@ ${r.trim()}
643
667
 
644
668
 
645
669
  ## Update Log
646
- ${c}`;else{let d=await Qe(o,"utf-8");d.includes("## Update Log")?l=d.replace(/(## Update Log\n)/,`$1${c}`):l=d+`
670
+ ${c}`;else{let d=await ot(o,"utf-8");d.includes("## Update Log")?l=d.replace(/(## Update Log\n)/,`$1${c}`):l=d+`
647
671
  ## 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 W(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 W(e,{quiet:!0,sync:t})}catch{return await W(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)+`
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";M();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
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),F=(I.size/1024).toFixed(1),V=Date.now()-I.mtimeMs,et=Ya(V);n.push({label:"Manifest",ok:!0,detail:`.codebase.json (${F} 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),F=!1;if(H(T(s,"src")))try{Fn(T(s,"src")).mtimeMs>k&&(F=!0)}catch{}F?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"],et=V.filter(ye=>ye in o);if(et.length===V.length)n.push({label:"Detectors",ok:!0,detail:"10/10 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,F=k?.includes("github.com");F&&I===!1?n.push({label:"GitHub Sync",ok:!1,detail:"Repo has GitHub remote but github_available is false"}):!F&&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"),F=Qa(s);if(k&&I){let V=a&&F?" (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&&!F&&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 F=JSON.parse(ne(T(s,"package.json"),"utf-8"));return!!(F.scripts?.check||F.scripts?.typecheck||F.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(F=>F.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"),x=H(m)&&H(y),j=(()=>{if(!H(b))return!1;try{let k=JSON.parse(ne(b,"utf-8")),I=JSON.stringify(k.hooks?.PreToolUse??""),F=JSON.stringify(k.hooks?.PostToolUse??"");return I.includes("git-guard")&&F.includes("git-post")}catch{return!1}})();if(x&&j)n.push({label:"Claude Hooks",ok:!0,detail:"git-guard + git-post wired in settings.json"});else{let k=[];x||k.push("hook scripts"),j||k.push("settings.json wiring"),n.push({label:"Claude Hooks",ok:!1,detail:`Missing: ${k.join(", ")} \u2014 run \`codebase setup\``})}let E=T(s,".gitignore");H(E)?ne(E,"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,P=f?"":"\x1B[32m",A=f?"":"\x1B[31m",G=f?"":"\x1B[0m",_=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 F=k.ok?`${P}\u2713${G}`:`${A}\u2717${G}`;u(` ${k.label.trimStart().padEnd(_)} ${F} ${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 B}from"path";import{homedir as Za}from"os";import{existsSync as J,readFileSync as de,readdirSync as ec}from"fs";import{writeFile as tc}from"fs/promises";ft();pt();M();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
- `);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
- `)):i==="not-authenticated"&&(h("GitHub CLI not authenticated \u2014 run: gh auth login"),h(`(Cannot auto-fix \u2014 requires manual login)
653
- `));let r=B(s,".codebase.json"),a=!1;if(!J(r))a=!0;else try{let _=de(r,"utf-8");JSON.parse(_)}catch{a=!0}if(!a&&J(r))try{let _=de(r,"utf-8"),U=JSON.parse(_),z=U.generated_at?new Date(U.generated_at).getTime():0;if(J(B(s,"src"))){let{statSync:X}=await import("fs");X(B(s,"src")).mtimeMs>z&&(a=!0)}}catch{a=!0}if(a){let _=await W(s,{depth:e.depth,quiet:!0,sync:o}),U=JSON.stringify(_,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 _ of p)ue(`Added MCP entry to ${_}`),n++;if(J(B(s,".git"))){let _=Hn(s,"post-commit"),U=Hn(s,"post-checkout"),z=rc(s),X=ac(s);if(!_||!U||o&&!z||!X){Re(s,o);let oe=[];_||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=B(s,".gitignore");(J(d)?de(d,"utf-8"):"").includes(".codebase.json")||(Ce(s),ue("Added .codebase.json to .gitignore"),n++);let y=B(s,".claude","commands");if(!J(y)){let{installClaudeCommandsForFix:_}=await Promise.resolve().then(()=>(ze(),ht));_(s),ue("Installed Claude commands \u2192 .claude/commands/"),n++}let b=B(Za(),".claude","skills");if(!(J(b)&&ec(b).some(_=>_.endsWith(".skill")))){let{installClaudeSkillsForFix:_}=await Promise.resolve().then(()=>(ze(),ht));_(s),ue("Installed Claude skills \u2192 ~/.claude/skills/"),n++}let j=B(s,".claude","hooks","git-guard.sh"),E=B(s,".claude","hooks","git-post.sh"),f=B(s,".claude","settings.json"),P=J(j)&&J(E),A=(()=>{if(!J(f))return!1;try{let _=JSON.parse(de(f,"utf-8")),U=JSON.stringify(_.hooks?.PreToolUse??""),z=JSON.stringify(_.hooks?.PostToolUse??"");return U.includes("git-guard")&&z.includes("git-post")}catch{return!1}})();if(!P||!A){let{installClaudeHooksForFix:_}=await Promise.resolve().then(()=>(ze(),ht));_(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=B(e,"CLAUDE.md");return J(t)?de(t,"utf-8").includes("<!-- codebase:start -->"):!1}function Hn(e,t){let s=B(e,".git","hooks",t);return J(s)?de(s,"utf-8").includes(sc):!1}function rc(e){let t=B(e,".git","hooks","post-commit");return J(t)?de(t,"utf-8").includes("--sync"):!1}function ac(e){let t=B(e,".git","hooks","pre-commit");return J(t)?de(t,"utf-8").includes("codebase-pre-commit"):!1}M();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(`
654
- Checking launch gates...`);let r=Xe(t,".codebase.json");if(Wt(r)&&!e.dryRun)try{let P=(JSON.parse($t(r,"utf-8")).status?.issues||[]).filter(A=>A.state==="open"&&A.labels.some(G=>G.toLowerCase().includes("bug")));if(P.length>0&&!e.force){v(`Gate 1a FAILED \u2014 ${P.length} open bug issue(s) in manifest`);for(let A of P.slice(0,5))u(` #${A.number}: ${A.title} [${A.labels.join(", ")}]`);u(`
655
- 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
- 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(`
672
+ ${c}`}let p=o+".tmp";return await Ot(p,l,"utf-8"),await At(p,o),L(e.id,{content:[{type:"text",text:"PLAN.md updated."}]})}case"get_issue":{let o=i.number,r=await ie(t,["issue","view",String(o),"--json","number,title,state,body,labels,assignees,milestone,comments,url"]),a=JSON.parse(r);return L(e.id,{content:[{type:"text",text:JSON.stringify(a,null,2)}]})}case"get_pr":{let o=i.number,r=await ie(t,["pr","view",String(o),"--json","number,title,state,body,author,labels,reviewRequests,reviewDecision,statusCheckRollup,additions,deletions,comments,url"]),a=JSON.parse(r);return L(e.id,{content:[{type:"text",text:JSON.stringify(a,null,2)}]})}case"rescan_project":{let o=i.sync!==!1,r=await V(t,{quiet:!0,sync:o,incremental:i.incremental===!0}),a=te(t,".codebase.json"),c=a+".tmp";return await Ot(c,JSON.stringify(r,null,2),"utf-8"),await At(c,a),L(e.id,{content:[{type:"text",text:`Project rescanned. Manifest updated at ${r.generated_at}`}]})}case"refresh_status":{let o=te(t,".codebase.json"),r=await Ee(t);if(r){let a=await ot(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 Ot(p,JSON.stringify(l,null,2),"utf-8"),await At(p,o)}return L(e.id,{content:[{type:"text",text:`GitHub data refreshed at ${new Date().toISOString()}`}]})}case"generate_handoff":{let{runHandoff:o}=await Promise.resolve().then(()=>(is(),Vn));return await o({command:"handoff",subcommand:"",positionals:[],path:t,message:i.message||"",quiet:!0,slim:!1,categories:[],depth:4,format:"text",verbose:!1,incremental:!1,force:!1,port:3e3,tools:[],dryRun:!1,since:"",sync:!1,reason:"",examples:!1,helpCommand:!1}),L(e.id,{content:[{type:"text",text:"HANDOFF.md generated in project root."}]})}default:return{jsonrpc:"2.0",id:e.id,error:{code:-32602,message:`Unknown tool: ${n}`}}}}catch(o){return L(e.id,{content:[{type:"text",text:`Error: ${o.message}`}],isError:!0})}}var os=Number(process.env.CODEBASE_MANIFEST_TTL_HOURS),uc=(Number.isFinite(os)&&os>0?os:24)*60*60*1e3;async function it(e,t=!1){try{let s=await ot(te(e,".codebase.json"),"utf-8"),n=JSON.parse(s);return n.generated_at&&Date.now()-new Date(n.generated_at).getTime()<=uc?n:await V(e,{quiet:!0,sync:t})}catch{return await V(e,{quiet:!0,sync:t})}}function dc(e){let t=(e.status?.issues||[]).filter(c=>c.state==="open"),s=e.status?.priorities?.length?e.status.priorities:Ve(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 pc(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 ie(e,t){return new Promise((s,n)=>{ei("gh",t,{cwd:e,timeout:3e4},(i,o,r)=>{i?n(new Error(r||i.message)):s(o.trim())})})}async function fc(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 ie(e,o)}`}async function mc(e,t){let s=t.number,n=t.comment;return n&&await ie(e,["issue","comment",String(s),"--body",n]),await ie(e,["issue","close",String(s)]),`Issue #${s} closed.`}async function gc(e,t){let s=t.number,n=t.add_labels,i=t.remove_labels,o=t.assignee,r=[];if(n?.length&&(await ie(e,["issue","edit",String(s),"--add-label",n.join(",")]),r.push(`added labels: ${n.join(", ")}`)),i?.length&&(await ie(e,["issue","edit",String(s),"--remove-label",i.join(",")]),r.push(`removed labels: ${i.join(", ")}`)),o!==void 0)if(o===""){let a=await ie(e,["issue","view",String(s),"--json","assignees"]),{assignees:c}=JSON.parse(a);for(let l of c)await ie(e,["issue","edit",String(s),"--remove-assignee",l.login]);r.push("unassigned all assignees")}else await ie(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 rs(e){try{let t=te(e,".codebase.json"),s=await ot(t,"utf-8"),n=JSON.parse(s);n.generated_at="1970-01-01T00:00:00.000Z";let i=t+".tmp";await Ot(i,JSON.stringify(n,null,2),"utf-8"),await At(i,t)}catch{}}function L(e,t){return{jsonrpc:"2.0",id:e,result:t}}function Zn(e){process.stdout.write(JSON.stringify(e)+`
673
+ `)}async function si(e){let t=hc(e.path);await ti(t)}import{resolve as bc,join as T}from"path";import{homedir as yc}from"os";import{existsSync as q,readFileSync as Q,statSync as ni,readdirSync as ii}from"fs";M();function ge(e){return Math.ceil(e.length/3.8)}function as(e,t){return e<=t.a?"A":e<=t.b?"B":e<=t.c?"C":"D"}var kc="# codebase-auto-update";async function ri(e){let t=Date.now();K(e.quiet);let s=bc(e.path),n=[];R(`codebase doctor
674
+ `);let i=T(s,".codebase.json"),o=null;if(q(i))try{let y=Q(i,"utf-8");o=JSON.parse(y);let _=ni(i),P=(_.size/1024).toFixed(1),W=Date.now()-_.mtimeMs,de=jc(W),Ue=ge(y);n.push({label:"Manifest",ok:!0,detail:`.codebase.json (${P} KB, ~${Ue} tokens, ${de})`})}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 y=o.generated_at?new Date(o.generated_at).getTime():0,_=(Date.now()-y)/(1e3*60*60),P=["src","lib","app","docs","package.json","tsconfig.json"],W=null;for(let pe of P){let dt=T(s,pe);if(q(dt))try{if(ni(dt).mtimeMs>y){W=pe;break}}catch{}}W?n.push({label:"Freshness",ok:!1,detail:`Stale \u2014 ${W} changed since last scan (${Math.round(_)}h ago)`}):n.push({label:"Freshness",ok:!0,detail:"Up to date"});let de=["project","repo","structure","stack","commands","dependencies","config","git","quality","patterns","api_docs"],Ue=de.filter(pe=>pe in o);if(Ue.length===de.length)n.push({label:"Detectors",ok:!0,detail:"11/11 categories present"});else{let pe=de.filter(dt=>!Ue.includes(dt));n.push({label:"Detectors",ok:!1,detail:`Missing: ${pe.join(", ")}`})}let be=o._warnings;if(Array.isArray(be)&&be.length>0)for(let pe of be)n.push({label:"Detector Warning",ok:!1,detail:`(non-fatal) ${pe}`})}let r=await Me(),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 y=o.repo?.url,_=o.status?.github_available,P=y?.includes("github.com");P&&_===!1?n.push({label:"GitHub Sync",ok:!1,detail:"Repo has GitHub remote but github_available is false"}):!P&&_===!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=wc(s);n.push({label:"Claude Code",ok:c,detail:c?"CLAUDE.md injected":"CLAUDE.md injection missing \u2014 run `codebase fix`"});let l=vc(s);if(n.push({label:"MCP",ok:l,detail:l?".mcp.json configured":".mcp.json missing \u2014 run `codebase fix`"}),q(T(s,".git"))){let y=oi(s,"post-commit"),_=oi(s,"post-checkout"),P=xc(s);if(y&&_){let W=a&&P?" (with --sync)":"";n.push({label:"Git Hooks",ok:!0,detail:`post-commit + post-checkout${W}`})}else{let W=[];y||W.push("post-commit"),_||W.push("post-checkout"),n.push({label:"Git Hooks",ok:!1,detail:`${W.join(" + ")} missing`})}a&&y&&!P&&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(q(T(s,".git"))&&($c(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`"})),q(T(s,".git"))){let y=Sc(s);(()=>{try{let P=JSON.parse(Q(T(s,"package.json"),"utf-8"));return!!(P.scripts?.check||P.scripts?.typecheck||P.scripts?.lint)}catch{return!1}})()?y?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(q(p)){let y=ii(p).filter(_=>_.endsWith(".md"));n.push({label:"Claude Commands",ok:y.length>0,detail:`${y.length} commands in .claude/commands/`})}else n.push({label:"Claude Commands",ok:!1,detail:".claude/commands/ missing \u2014 run `codebase setup`"});let d=T(yc(),".claude","skills");if(q(d)){let y=ii(d).filter(_=>_.endsWith(".skill"));if(y.length>0){let _=y.map(P=>P.replace(/\.skill$/,"")).join(", ");n.push({label:"Claude Skills",ok:!0,detail:`${y.length} skill${y.length>1?"s":""} installed: ${_}`})}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 f=T(s,".claude","settings.json"),$=T(s,".claude","hooks","git-guard.sh"),h=T(s,".claude","hooks","git-post.sh"),b=q($)&&q(h),k=(()=>{if(!q(f))return!1;try{let y=JSON.parse(Q(f,"utf-8")),_=JSON.stringify(y.hooks?.PreToolUse??""),P=JSON.stringify(y.hooks?.PostToolUse??"");return _.includes("git-guard")&&P.includes("git-post")}catch{return!1}})();if(b&&k)n.push({label:"Claude Hooks",ok:!0,detail:"git-guard + git-post wired in settings.json"});else{let y=[];b||y.push("hook scripts"),k||y.push("settings.json wiring"),n.push({label:"Claude Hooks",ok:!1,detail:`Missing: ${y.join(", ")} \u2014 run \`codebase setup\``})}let x=T(s,"CLAUDE.md");if(q(x)){let y=Q(x,"utf-8"),_=y.split(`
675
+ `).length,P=ge(y);_>500?n.push({label:"CLAUDE.md Size",ok:!1,detail:`${_} lines, ~${P} tokens \u2014 trim to under 300 lines`}):_>300?n.push({label:"CLAUDE.md Size",ok:!0,detail:`${_} lines, ~${P} tokens \u2014 consider trimming`}):n.push({label:"CLAUDE.md Size",ok:!0,detail:`${_} lines, ~${P} tokens`});let W=y.indexOf("<!-- codebase:start -->"),de=y.indexOf("<!-- codebase:end -->");if(W!==-1&&de!==-1){let be=y.slice(W,de+21).split(`
676
+ `).length;be>80?n.push({label:"Injection Block",ok:!1,detail:`${be} lines \u2014 bloated, run \`codebase fix\` to re-inject`}):n.push({label:"Injection Block",ok:!0,detail:`${be} lines`})}}let m=T(s,".mcp.json");if(q(m))try{let y=JSON.parse(Q(m,"utf-8")),_=Object.keys(y.mcpServers??{}),P=_.length;P>5?n.push({label:"MCP Servers",ok:!1,detail:`${P} servers \u2014 each adds ~10k tokens; remove unused ones`}):P>3?n.push({label:"MCP Servers",ok:!0,detail:`${P} servers \u2014 ${_.join(", ")} (consider trimming)`}):n.push({label:"MCP Servers",ok:!0,detail:`${P} server${P!==1?"s":""}: ${_.join(", ")||"none"}`})}catch{}let g=T(s,".claude","hooks","session-start.sh"),A=q(g),S=(()=>{if(!q(f))return!1;try{let y=JSON.parse(Q(f,"utf-8"));return JSON.stringify(y.hooks?.PreToolUse??"").includes("session-start")}catch{return!1}})();if(A&&S)n.push({label:"Session Hook",ok:!0,detail:"session-start.sh installed + wired"});else{let y=[];A||y.push("script"),S||y.push("settings.json wiring"),n.push({label:"Session Hook",ok:!1,detail:`Missing: ${y.join(", ")} \u2014 run \`codebase fix\``})}let X=T(s,".gitignore");q(X)?Q(X,"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 re=!!process.env.NO_COLOR,N=re?"":"\x1B[32m",Y=re?"":"\x1B[31m",Z=re?"":"\x1B[0m",Se=20;function It(y){return["Manifest","Freshness","Detectors","Detector Warning"].includes(y)?"MANIFEST":["GitHub CLI","GitHub Sync"].includes(y)?"GITHUB":["Claude Code","MCP","Claude Commands","Claude Skills","Claude Hooks"].includes(y)?"AI TOOLS":["CLAUDE.md Size","Injection Block","MCP Servers","Session Hook"].includes(y)?"TOKEN HEALTH":"GIT"}let ae=null;for(let y of n){let _=It(y.label.trimStart());_!==ae&&(u(""),z(` ${_}`),ae=_);let P=y.ok?`${N}\u2713${Z}`:`${Y}\u2717${Z}`;u(` ${y.label.trimStart().padEnd(Se)} ${P} ${y.detail}`)}let Ge=n.filter(y=>!y.ok),Lt=n.length,ps=Lt-Ge.length;u(""),Ge.length===0?u(` ${j(`Health: ${ps}/${Lt}`)} \u2014 All checks passed.`):u(` ${j(`Health: ${ps}/${Lt}`)} \u2014 ${Ge.length} issue${Ge.length>1?"s":""} found. Run \`codebase fix\` to repair.`),u("");let $i=((Date.now()-t)/1e3).toFixed(1);w(`Done (${$i}s)`),Ge.length>0&&process.exit(1)}function wc(e){let t=T(e,"CLAUDE.md");return q(t)?Q(t,"utf-8").includes("<!-- codebase:start -->"):!1}function vc(e){let t=T(e,".mcp.json");if(!q(t))return!1;try{return!!JSON.parse(Q(t,"utf-8")).mcpServers?.codebase}catch{return!1}}function oi(e,t){let s=T(e,".git","hooks",t);return q(s)?Q(s,"utf-8").includes(kc):!1}function $c(e){let t=T(e,".git","hooks","commit-msg");return q(t)?Q(t,"utf-8").includes("codebase-branch-check"):!1}function Sc(e){let t=T(e,".git","hooks","pre-commit");return q(t)?Q(t,"utf-8").includes("codebase-pre-commit"):!1}function xc(e){let t=T(e,".git","hooks","post-commit");return q(t)?Q(t,"utf-8").includes("--sync"):!1}function jc(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`}Re();import{resolve as Cc,join as J}from"path";import{homedir as Ec}from"os";import{existsSync as B,readFileSync as ue,readdirSync as _c}from"fs";import{writeFile as Rc}from"fs/promises";xt();St();M();var Pc="# codebase-auto-update",ci=!!process.env.NO_COLOR,Dc=ci?"":"\x1B[32m",Oc=ci?"":"\x1B[0m";function le(e){console.log(` ${Dc}\u2713${Oc} ${e}`)}async function li(e){let t=Date.now();K(e.quiet);let s=Cc(e.path),n=0;R(`codebase fix
677
+ `);let i=await Me(),o=i==="authenticated";i==="not-installed"?(v("GitHub CLI not installed \u2014 install with: brew install gh"),v(`(Cannot auto-fix \u2014 requires manual installation)
678
+ `)):i==="not-authenticated"&&(v("GitHub CLI not authenticated \u2014 run: gh auth login"),v(`(Cannot auto-fix \u2014 requires manual login)
679
+ `));let r=J(s,".codebase.json"),a=!1;if(!B(r))a=!0;else try{let N=ue(r,"utf-8");JSON.parse(N)}catch{a=!0}if(!a&&B(r))try{let N=ue(r,"utf-8"),Y=JSON.parse(N),Z=Y.generated_at?new Date(Y.generated_at).getTime():0;if(B(J(s,"src"))){let{statSync:Se}=await import("fs");Se(J(s,"src")).mtimeMs>Z&&(a=!0)}}catch{a=!0}if(a){let N=await V(s,{depth:e.depth,quiet:!0,sync:o}),Y=JSON.stringify(N,null,2);await Rc(r,Y,"utf-8");let Z=(Buffer.byteLength(Y)/1024).toFixed(1);le(`Re-scanned project \u2192 .codebase.json (${Z} KB)`),n++}let{claudeIntegration:c}=await Promise.resolve().then(()=>(Ze(),kn));Ac(s)||(c.inject(s),le("Re-injected Claude Code instructions into CLAUDE.md"),n++);let p=await es(s,new Set(["claude"]));for(let N of p)le(`Added MCP entry to ${N}`),n++;if(B(J(s,".git"))){let N=ai(s,"post-commit"),Y=ai(s,"post-checkout"),Z=Nc(s),Se=Ic(s);if(!N||!Y||o&&!Z||!Se){Ne(s,o);let ae=[];N||ae.push("post-commit"),Y||ae.push("post-checkout"),o&&!Z&&ae.push("--sync flag"),Se||ae.push("pre-commit"),le(`Installed ${ae.join(" + ")} hook${ae.length>1?"s":""}`),n++}}let d=J(s,".gitignore");(B(d)?ue(d,"utf-8"):"").includes(".codebase.json")||(De(s),le("Added .codebase.json to .gitignore"),n++);let $=J(s,".claude","commands");if(!B($)){let{installClaudeCommandsForFix:N}=await Promise.resolve().then(()=>(Fe(),st));N(s),le("Installed Claude commands \u2192 .claude/commands/"),n++}let h=J(Ec(),".claude","skills");if(!(B(h)&&_c(h).some(N=>N.endsWith(".skill")))){let{installClaudeSkillsForFix:N}=await Promise.resolve().then(()=>(Fe(),st));N(s),le("Installed Claude skills \u2192 ~/.claude/skills/"),n++}let k=J(s,".claude","hooks","git-guard.sh"),x=J(s,".claude","hooks","git-post.sh"),m=J(s,".claude","hooks","session-start.sh"),g=J(s,".claude","settings.json"),A=B(k)&&B(x),S=(()=>{if(!B(g))return!1;try{let N=JSON.parse(ue(g,"utf-8")),Y=JSON.stringify(N.hooks?.PreToolUse??""),Z=JSON.stringify(N.hooks?.PostToolUse??"");return Y.includes("git-guard")&&Z.includes("git-post")}catch{return!1}})();if(!A||!S){let{installClaudeHooksForFix:N}=await Promise.resolve().then(()=>(Fe(),st));N(s),le("Installed Claude Code hooks \u2192 .claude/hooks/ + settings.json"),n++}if(!(()=>{if(!B(m)||!B(g))return!1;try{let N=JSON.parse(ue(g,"utf-8"));return JSON.stringify(N.hooks?.PreToolUse??"").includes("session-start")}catch{return!1}})()){let{installSessionStartHookForFix:N}=await Promise.resolve().then(()=>(Fe(),st));N(s),le("Installed session-start hook \u2192 .claude/hooks/session-start.sh"),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 re=((Date.now()-t)/1e3).toFixed(1);w(`Done (${re}s)`)}function Ac(e){let t=J(e,"CLAUDE.md");return B(t)?ue(t,"utf-8").includes("<!-- codebase:start -->"):!1}function ai(e,t){let s=J(e,".git","hooks",t);return B(s)?ue(s,"utf-8").includes(Pc):!1}function Nc(e){let t=J(e,".git","hooks","post-commit");return B(t)?ue(t,"utf-8").includes("--sync"):!1}function Ic(e){let t=J(e,".git","hooks","pre-commit");return B(t)?ue(t,"utf-8").includes("codebase-pre-commit"):!1}M();import{resolve as Lc,join as at}from"path";import{execFile as ct}from"child_process";import{existsSync as ls,readFileSync as Nt,writeFileSync as Fc}from"fs";async function ui(e){let t=Lc(e.path),s=e.dryRun,n=e.positionals[0]??null;R(`codebase release${s?" (dry run)":""}`),await Mc()||(E("gh CLI not authenticated. Run: gh auth login"),process.exit(1)),await rt(t,"remote","get-url","origin")||(E("No git remote. Run: git remote add origin <url>"),process.exit(1)),u(`
680
+ Checking launch gates...`);let r=at(t,".codebase.json");if(ls(r)&&!e.dryRun)try{let g=(JSON.parse(Nt(r,"utf-8")).status?.issues||[]).filter(A=>A.state==="open"&&A.labels.some(S=>S.toLowerCase().includes("bug")));if(g.length>0&&!e.force){E(`Gate 1a FAILED \u2014 ${g.length} open bug issue(s) in manifest`);for(let A of g.slice(0,5))u(` #${A.number}: ${A.title} [${A.labels.join(", ")}]`);u(`
681
+ Fix: resolve open bugs or run /simulate. Use --force to skip this gate.`),process.exit(1)}}catch{}let[a,c]=await Promise.all([cs(t,["bug","critical"]),cs(t,["bug","high"])]);(a>0||c>0)&&(E("Gate 1a FAILED \u2014 open blocking bugs:"),a>0&&u(` Critical: ${a}`),c>0&&u(` High: ${c}`),u(`
682
+ Fix: run /simulate, or close with wontfix label`),process.exit(1)),w("Gate 1a \u2014 no open bugs");let l=Tc(t);if(l){let m=await qc(t,l);m.ok||(E("Gate 1b FAILED \u2014 test suite has failures"),u(m.output.split(`
657
683
  `).slice(-10).join(`
658
684
  `)),u(`
659
- Fix: run /review to repair failing tests`),process.exit(1)),g(`Gate 1b \u2014 tests pass (${l})`)}else R("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`):R("Gate 1c \u2014 no simulation data yet (run /simulate first)");let d=await Jt(t,["carry"]);d>0?R(`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
- All gates passed.`);let b=n??await mc(t);u(`
661
- Release version: ${b}`);let x=await gc(t,b,d);if(s){u(`
662
- --- DRY RUN \u2014 release notes preview ---`),u(x),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:j,stdout:E}=await ie(t,["release","create",b,"--title",b,"--notes",x,"--target","develop"]);j?g(`GitHub release: ${E}`):R("Could not create GitHub release \u2014 tag and merge succeeded"),await hc(t),u(`
663
- 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}
685
+ Fix: run /review to repair failing tests`),process.exit(1)),w(`Gate 1b \u2014 tests pass (${l})`)}else D("Gate 1b \u2014 no test runner detected (skipping)");let p=await Hc(t);p!==null&&p<7&&(E(`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?w(`Gate 1c \u2014 world-class score ${p}/10`):D("Gate 1c \u2014 no simulation data yet (run /simulate first)");let d=await cs(t,["carry"]);d>0?D(`Gate 2 \u2014 ${d} carry bug(s) will appear in release notes`):w("Gate 2 \u2014 no carry bugs");let f=await rt(t,"status","--short");f&&(E("Gate 3 FAILED \u2014 uncommitted changes"),u(f),process.exit(1)),await rt(t,"fetch","origin","develop"),await rt(t,"log","HEAD..origin/develop","--oneline")&&(E("Gate 3 FAILED \u2014 branch is behind origin/develop"),u(" Fix: git pull origin develop"),process.exit(1)),w("Gate 3 \u2014 branch clean and current"),u(`
686
+ All gates passed.`);let h=n??await Gc(t);u(`
687
+ Release version: ${h}`);let b=await Uc(t,h,d);if(s){u(`
688
+ --- DRY RUN \u2014 release notes preview ---`),u(b),u("--- DRY RUN \u2014 no tag, no merge, no GitHub release created ---");return}await $e(t,["tag","-a",h,"-m",`Release ${h}`]),await $e(t,["push","origin",h]),w(`Tagged ${h}`),await $e(t,["checkout","main"]),await $e(t,["pull","origin","main"]),await $e(t,["merge","develop","--no-ff","-m",`Release ${h}`]),await $e(t,["push","origin","main"]),await $e(t,["checkout","develop"]),w("Merged develop \u2192 main");let{ok:k,stdout:x}=await oe(t,["release","create",h,"--title",h,"--notes",b,"--target","develop"]);k?w(`GitHub release: ${x}`):D("Could not create GitHub release \u2014 tag and merge succeeded"),await Bc(t),u(`
689
+ codebase release ${h} complete.`),u("develop \u2192 main merged. Tag pushed. Ready.")}function rt(e,...t){return new Promise(s=>{ct("git",t,{cwd:e,timeout:3e4},(n,i)=>{s(n?"":i.trim())})})}function $e(e,t){return new Promise((s,n)=>{ct("git",t,{cwd:e,timeout:3e4},(i,o,r)=>{i?n(new Error(r||i.message)):s()})})}function oe(e,t){return new Promise(s=>{ct("gh",t,{cwd:e,timeout:3e4},(n,i)=>{s({ok:!n,stdout:(i||"").trim()})})})}async function Mc(){return new Promise(e=>{ct("gh",["auth","status"],{timeout:5e3},t=>e(!t))})}async function cs(e,t){let{stdout:s}=await oe(e,["issue","list","--label",t.join(","),"--state","open","--limit","100","--json","number","--jq","length"]);return parseInt(s,10)||0}function Tc(e){try{let t=JSON.parse(Nt(at(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(ls(at(e,"pyproject.toml")))try{if(Nt(at(e,"pyproject.toml"),"utf-8").includes("pytest"))return"uv run pytest"}catch{}return null}function qc(e,t){let[s,...n]=t.split(" ");return new Promise(i=>{ct(s,n,{cwd:e,timeout:3e5},(o,r,a)=>{i({ok:!o,output:r+a})})})}async function Hc(e){let{stdout:t}=await oe(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 Gc(e){let t=await rt(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 Uc(e,t,s){let n=new Date().toISOString().split("T")[0],[i,o,r,a]=await Promise.all([oe(e,["issue","list","--label","arch","--state","closed","--limit","50","--json","number,title","--jq",'.[] | "- #(.number) (.title)"']),oe(e,["issue","list","--label","bug,sim","--state","closed","--limit","50","--json","number,title","--jq",'.[] | "- #(.number) (.title)"']),oe(e,["issue","list","--label","carry","--state","open","--limit","20","--json","number,title","--jq",'.[] | "- #(.number) (.title)"']),oe(e,["issue","list","--label","arch","--state","open","--limit","20","--json","number,title","--jq",'.[] | "- #(.number) (.title)"'])]),c=`# Release ${t} \u2014 ${n}
664
690
 
665
691
  `;return i.stdout&&(c+=`## What's New
666
692
 
@@ -678,12 +704,12 @@ ${r.stdout}
678
704
  `),a.stdout&&(c+=`### Pending Architecture
679
705
  ${a.stdout}
680
706
 
681
- `)),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}
707
+ `)),c}async function Bc(e){let t=at(e,".vibekit","milestone.env");if(!ls(t))return;let s=Nt(t,"utf-8"),n=s.match(/MILESTONE_NUMBER=(\d+)/),i=s.match(/MILESTONE_TITLE=(v[\d.]+)/);if(!n||!i)return;let{stdout:o}=await oe(e,["repo","view","--json","nameWithOwner","--jq",".nameWithOwner"]);if(!o)return;await oe(e,["api",`repos/${o}/milestones/${n[1]}`,"-X","PATCH","-f","state=closed"]),v(`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 oe(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&&(Fc(t,`MILESTONE_NUMBER=${c}
682
708
  MILESTONE_TITLE=${a}
683
- `,"utf-8"),g(`Next milestone created: ${a}`))}M();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=`
709
+ `,"utf-8"),w(`Next milestone created: ${a}`))}M();import{resolve as Jc,join as Wc}from"path";import{readFile as pi,writeFile as di}from"fs/promises";import{existsSync as fi}from"fs";var Kc="PLAN.md";async function mi(e){let t=Jc(e.path),s=Wc(t,Kc);if(e.message){await zc(s,e.message);return}if(!fi(s)){v("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 pi(s,"utf-8");R("PLAN.md"),u(n)}async function zc(e,t){let n=`
684
710
  <!-- updated: ${new Date().toISOString().split("T")[0]} -->
685
711
  ${t.trim()}
686
- `;if(!Kn(e)){let o=`# PLAN.md \u2014 Autonomous Loop State
712
+ `;if(!fi(e)){let o=`# PLAN.md \u2014 Autonomous Loop State
687
713
 
688
714
  > Managed by Claude. Updated each build/simulate cycle.
689
715
 
@@ -700,10 +726,12 @@ ${t.trim()}
700
726
 
701
727
 
702
728
  ## Update Log
703
- ${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+=`
729
+ ${n}`;await di(e,o,"utf-8"),u(`${j("Created")} PLAN.md`);return}let i=await pi(e,"utf-8");i.includes("## Update Log")?i=i.replace(/(## Update Log\n)/,`$1${n}`):i+=`
704
730
  ## Update Log
705
- ${n}`,await Jn(e,i,"utf-8"),u(`${w("Updated")} PLAN.md`)}M();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(`
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$/,""),x="";try{let j=await Sc(y),E=Cc(j);E.name&&(b=E.name),E.description&&(x=E.description)}catch{}o.push({name:b,description:x,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(`
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.4"}};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 W(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
- 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)});
731
+ ${n}`,await di(e,i,"utf-8"),u(`${j("Updated")} PLAN.md`)}M();import{join as us,resolve as Vc}from"path";import{existsSync as Qc,readdirSync as Yc}from"fs";import{execFile as Xc}from"child_process";function Zc(e){return new Promise((t,s)=>{Xc("unzip",["-p",e,"*/SKILL.md"],(n,i)=>{n&&!i?s(n):t(i??"")})})}function el(e){let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!t)return{};let s={};for(let n of t[1].split(`
732
+ `)){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 gi(e){let t=us(process.env.HOME??"~",".claude","skills"),s=us(Vc(e.path??"."),".claude","skills"),n=new Set,i=[];for(let d of[s,t])if(Qc(d))for(let f of Yc(d))f.endsWith(".skill")&&!n.has(f)&&(n.add(f),i.push({file:f,dir:d}));if(i.length===0){u("No skills installed. Run: codebase setup");return}let o=[];for(let{file:d,dir:f}of i){let $=us(f,d),h=d.replace(/\.skill$/,""),b="";try{let k=await Zc($),x=el(k);x.name&&(h=x.name),x.description&&(b=x.description)}catch{}o.push({name:h,description:b,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,f)=>d.padEnd(f),p=` ${"\u2500".repeat(r)} ${"\u2500".repeat(a)} ${"\u2500".repeat(c)}`;v(`
733
+ ${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("")}M();import{resolve as tl,join as He}from"path";import{existsSync as lt,readFileSync as ut,readdirSync as sl,statSync as nl}from"fs";var hi={a:15e3,b:3e4,c:6e4};async function bi(e){K(e.quiet);let t=tl(e.path);R(`codebase tokens
734
+ `);let s=[],n=He(t,"CLAUDE.md");if(lt(n)){let b=ut(n,"utf-8"),k=ge(b),x=b.split(`
735
+ `).length;s.push({label:"CLAUDE.md",tokens:k,detail:`${x} lines`})}let i=He(t,".codebase.json");if(lt(i)){let b=ut(i,"utf-8"),k=ge(b),x=(nl(i).size/1024).toFixed(1);s.push({label:".codebase.json",tokens:k,detail:`${x} KB`})}let o=He(t,".mcp.json");if(lt(o))try{let b=JSON.parse(ut(o,"utf-8")),k=Object.keys(b.mcpServers??{});if(k.length>0){let x=k.length*1e4;s.push({label:`MCP servers (${k.length})`,tokens:x,detail:k.join(", ")})}}catch{}let r=He(t,".claude","commands");if(lt(r)){let b=sl(r).filter(k=>k.endsWith(".md"));if(b.length>0){let k=b.reduce((x,m)=>{try{return x+ge(ut(He(r,m),"utf-8"))}catch{return x}},0);s.push({label:`Slash commands (${b.length})`,tokens:k,detail:b.map(x=>x.replace(".md","")).join(", ")})}}let a=He(t,".claude","settings.json");if(lt(a)){let b=ut(a,"utf-8"),k=ge(b);s.push({label:"settings.json",tokens:k,detail:""})}if(s.length===0){u(" No codebase context found. Run `codebase init` first.\n");return}let c=28,l=8;u(` ${"Source".padEnd(c)} ${"Tokens".padStart(l)} Grade`),z(` ${"\u2500".repeat(c+l+12)}`);let p=s.reduce((b,k)=>b+k.tokens,0);for(let b of s){let k=as(b.tokens,hi),x=b.tokens.toLocaleString().padStart(l);u(` ${b.label.padEnd(c)} ${x} ${k}`)}z(` ${"\u2500".repeat(c+l+12)}`);let d=as(p,hi);u(` ${j("Estimated session startup".padEnd(c))} ${j(p.toLocaleString().padStart(l))} ${j(d)}`),u(""),z(" Grades: A (<15k) | B (<30k) | C (<60k) | D (>60k)"),u("");let f=[],$=s.find(b=>b.label==="CLAUDE.md");$&&$.tokens>2e3&&f.push(`CLAUDE.md is large (~${$.tokens.toLocaleString()} tokens) \u2014 trim to <300 lines`);let h=s.find(b=>b.label.startsWith("MCP"));if(h&&h.tokens>3e4&&f.push("Many MCP servers \u2014 remove unused ones to save tokens"),f.length>0){u(" Recommendations:");for(let b of f)u(` - ${b}`);u("")}w("Done")}is();import{createServer as rl}from"http";Re();import{readFile as il,writeFile as ol}from"fs/promises";import{join as yi}from"path";async function ki(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.7"}};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 ds(s);return r?{status:200,body:Te(r,o)??null}:{status:404,body:{error:"No manifest. POST /codebase/scan first."}}}if(i==="/codebase/scan"&&t==="POST"){let o=await V(s,{quiet:!0});return await ol(yi(s,".codebase.json"),JSON.stringify(o,null,2),"utf-8"),{status:200,body:o}}if(i==="/codebase"&&t==="GET"){let o=await ds(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 ds(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 ds(e){try{let t=await il(yi(e,".codebase.json"),"utf-8");return JSON.parse(t)}catch{return null}}function wi(e,t){let s=rl(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 ki(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(`
736
+ 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 he=bs(process.argv.slice(2));K(he.quiet);fs(he.verbose);he.helpCommand&&he.command&&ys(he.command);var al={scan:Ye,init:In,brief:Ln,next:Mn,setup:Xt,query:Tn,issue:Jn,status:Kn,mcp:si,doctor:ri,fix:li,release:ui,plan:mi,skills:gi,tokens:bi,handoff:ns,serve:e=>(wi(e.path,e.port??3e3),Promise.resolve()),"scan-only":Ye};$s().catch(()=>{});var[cl]=process.versions.node.split(".").map(Number);cl<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 vi=al[he.command];vi||(E(`Unknown command: ${he.command}`),v(`Run ${j("codebase --help")} to see all commands.`),process.exit(1));vi(he).catch(e=>{E(`Error: ${e.message}`);let t=e.message.toLowerCase();t.includes("not a git repository")?v(`Initialize git first: ${j("git init")}`):t.includes("permission denied")?v("Check file permissions or run with appropriate access"):t.includes("enoent")&&t.includes("gh")?v(`GitHub CLI (gh) is not installed. Install it: ${j("brew install gh && gh auth login")}`):t.includes("no such file")?v("Check that the path is correct"):t.includes("github")&&(v(`Ensure GitHub CLI is installed: ${j("gh --version")}`),v(`Authenticate: ${j("gh auth login")}`)),process.exit(1)});
709
737
  //# sourceMappingURL=index.js.map