@constellationdev/cli 1.3.0 → 1.3.1
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/main.js +4 -4
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -80,15 +80,15 @@ To resolve:`),this.reporter.log(" 1. Fix the conflicted files manually"),this.r
|
|
|
80
80
|
Please check your internet connection and try again
|
|
81
81
|
`):e.message.includes("Authentication")&&this.reporter.log(`
|
|
82
82
|
Please check your git credentials and try again
|
|
83
|
-
`)),e}finally{this.reporter.resume();}}async determineIndexScope(e){if(e)return {isIncremental:false,upToDate:false};this.reporter.detail("Determining index scope...");try{let r=(await this.apiClient.getProjectState())?.latestCommit;if(!r)return this.reporter.detail("No previous index found, performing full index"),{isIncremental:!1,upToDate:!1};let o=await this.git.getLatestCommitHash();return r===o?(this.reporter.detail("Already up to date"),{isIncremental:!0,upToDate:!0}):(this.reporter.detail(`Last indexed commit: ${r.substring(0,8)}`),this.reporter.detail(`Current commit: ${o.substring(0,8)}`),this.reporter.detail(`Performing incremental index starting from commit ${r.substring(0,8)}`),{isIncremental:!0,upToDate:!1})}catch(t){if(t instanceof H)throw t;return this.reporter.warn(`Could not determine last index (${t instanceof Error?t.message:"unknown error"}), performing full index`),{isIncremental:false,upToDate:false}}}async discoverFiles(e){this.reporter.detail("Analyzing codebase...");let t;if(e)try{let r=await this.apiClient.getProjectState();if(!r?.latestCommit)this.reporter.warn("Cannot determine changes (no latestCommit in project state), falling back to full scan"),t=await this.scanner.scanFiles(this.config);else {let o=await this.git.getChangedFiles(r.latestCommit),s=[...o.added,...o.modified,...o.renamed.map(l=>l.to)];this.reporter.detail(`Found ${s.length} changed files`),t=await this.scanner.scanSpecificFiles(s,this.config);let a=[...o.deleted,...o.renamed.map(l=>l.from)];if(a.length>0){let l=o.deleted.length,c=o.renamed.length,u=c>0?`${ve} Removing ${l} deleted file(s) and ${c} renamed file(s) from graph`:`${ve} Removing ${l} deleted file(s) from graph`;this.reporter.log(u),await this.apiClient.deleteFiles(a);}}}catch(r){if(r instanceof H)throw r;this.reporter.warn(`Cannot determine changes (${r instanceof Error?r.message:"unknown"}), falling back to full scan`),t=await this.scanner.scanFiles(this.config);}else this.reporter.detail("Scanning all project files..."),t=await this.scanner.scanFiles(this.config);return this.reporter.detail(`Found ${t.length} files to index`),t}async*generateASTs(e,t,r,o){let s=e.length,a=0,l=0;o?.(0,s),this.reporter.detail(`Processing ${s} files...`);let c=await this.git.getLatestCommitHash(),u=s>1e4?5:s>5e3?7:10;u<10&&this.reporter.detail(`Large project detected, using concurrency of ${u} to optimize memory usage`);let d=new Qe(u,{preserveOrder:true}).run(e,async(m,g)=>{let h=Math.round((g+1)/s*100);this.reporter.detail(`Analyzing file ${m.path.replace(process.cwd()+"/","")} (${h}%)...`);try{let{tree:b,classificationMap:y,content:S}=await this.parser.parseFile(m.path,m.language),E=this.symbolExtractor.extract(b,m.language);E.length>0&&this.parseSymbols.set(this.normalizePathToCanonical(m.relativePath),E),S!==void 0&&this.parseContent.set(this.normalizePathToCanonical(m.relativePath),S),y.entries.length>5e4&&this.reporter.warn(`Large classification map for ${m.relativePath}: ${y.entries.length} entries`);let w=this.langRegistry.getPlugin(m.language),P;if(w?.getImportResolver){let K=this.buildConfigManagers.get(m.language),ye=K?await K.getConfigForFile(m.path):null,J=w.getImportResolver(m.path,ye);if(J){let{ImportExtractor:M}=await Promise.resolve().then(()=>(Ys(),qs));P=await new M().extractImportResolutions(b,m.path,m.language,J);}}let{serializeASTStream:N}=await Promise.resolve().then(()=>(ni(),da)),I=N(b.rootNode,void 0,m.language),v=await this.compressor.compressStream(I),R=this.normalizePathToCanonical(m.relativePath),_={file:R,language:m.language,commit:c,timestamp:t,ast:v,importResolutions:P,classificationMap:{filePath:R,entries:y.entries}},O=vs.safeParse(_);if(!O.success)throw new Error(`Index validation failed: ${O.error.issues[0].message}`);return a++,o?.(a,s),O.data}catch(b){throw l++,o?.(a+l,s),this.reporter.warn(`Failed to parse ${m.relativePath}: ${b.message}`,{code:"PARSE_FAILURE"}),b}});for await(let m of d)yield m;l>0?this.reporter.warn(`Completed parsing with ${l} parsing errors`):this.reporter.detail("All files analyzed successfully"),r&&r();}async uploadToAPI(e,t,r,o){if(!await this.apiClient.streamToApi(e,"ast",this.config.projectId,this.config.branch,t,r,o))throw new Error("Failed to upload data to Constellation Service");this.reporter.detail("Data uploaded to Constellation Service, indexing in progress");}async*createIndexPipeline(e,t,r,o,s){let a=await this.discoverFiles(e);this.discoveredFiles=a,o(a),yield*this.generateASTs(a,t,r,s);}async handleQueuedUpload(e,t,r,o){this.reporter.log("Generating index data for queue upload...");let s=this.createIndexPipeline(t,o,()=>{},()=>{});await this.apiClient.uploadToQueue(s,this.config.projectId,this.config.branch,r,e),this.reporter.detail("Changes queued for indexing behind the current operation.");}normalizePathToCanonical(e){return ar(e)}isLanguageLspEligible(e){let t=this.config.languages[e];return t?.lspEnrichment===false?false:!!t?.lsp||Te.has(e)}getEnrichmentEligibleLanguages(e,t){if(e)return this.reporter.detail("Index enrichment skipped"),null;if(this.config.lspEnrichment===false)return this.reporter.detail("Index enrichment disabled in constellation.json"),null;let r=new Set(t.map(s=>s.language)),o=[...r].filter(s=>this.isLanguageLspEligible(s));if(o.length===0){let s=[...r].filter(a=>a).map(te).join(", ");return this.reporter.detail(s?`Index enrichment skipped: no LSP enrichment configured for scanned language(s): ${s}`:"Index enrichment skipped: no language-tagged files were found to enrich"),null}return this.reporter.detail(`Index enrichment enabled for: ${o.map(te).join(", ")}`),new Set(o)}async runLspEnrichment(e,t,r,o,s,a,l){let c=this.reporter,u={log:d=>c.detail(d),warn:d=>c.warn(d,{verboseOnly:true}),error:d=>c.error(d,{verboseOnly:true})},p=new ur(process.cwd(),u);try{if(s?.aborted)return null;this.reporter.detail("Starting index enrichment...");let d=new Map,m=new Map;for(let w of e){if(!t.has(w.language))continue;let P=d.get(w.language)||[];P.push(this.normalizePathToCanonical(w.relativePath)),d.set(w.language,P);}let g=d.size,h=!1;for(let w of [...d.keys()]){if(s?.aborted)return null;let P=this.langRegistry?.getPlugin(w);if(!P?.preflightLsp)continue;let N;try{N=await P.preflightLsp(process.cwd());}catch(I){let v=I instanceof Error?I.message:String(I);this.reporter.warn(`LSP pre-flight failed for ${te(w)} (${v}); proceeding without skip.`);continue}N.skip&&(this.reporter.warn(N.message),d.delete(w),h=!0);}let b=h&&d.size===0&&g>0;for(let w of d.keys()){if(m.has(w))continue;let N=this.config.languages[w]?.lsp;l?.(w,"initializing");let I=null;try{I=await p.startServer(w,N),I&&m.set(w,I);}finally{l?.(w,I?"ready":"failed");}}if(m.size===0)return b||this.reporter.warn("No language servers started, index enrichment skipped"),null;if(s?.aborted)return p.destroyAll(),null;this.reporter.detail(`Language servers started: ${[...m.keys()].map(te).join(", ")}`);let y=new lr(process.cwd(),this.reporter),S=s?new Promise((w,P)=>{s.addEventListener("abort",()=>{p.destroyAll(),P(s.reason||new Error("Indexing aborted"));},{once:!0});}):null,E=await(S?Promise.race([y.enrich(d,r,m,o,a),S]):y.enrich(d,r,m,o,a)),T=E.reduce((w,P)=>w+P.symbols.length,0);return this.reporter.detail(`Index enrichment analysis completed: ${T} symbols across ${E.length} files`),E.length>0?E:null}catch(d){return this.reporter.warn(`Index enrichment failed: ${d instanceof Error?d.message:String(d)}`,{code:"ENRICHMENT_FAILED"}),null}finally{await p.shutdownAll();}}};});function ai(n){return stringify({name:"Constellation Index",on:{push:{branches:[n]}},permissions:{contents:"read"},jobs:{index:{"runs-on":"ubuntu-latest",steps:[{uses:"actions/checkout@v4",with:{"fetch-depth":0}},{uses:"ShiftinBits/constellation-github@v1",with:{"access-key":"${{ secrets.CONSTELLATION_ACCESS_KEY }}"}}]}}},{lineWidth:0})}function Hr(n){return {includeEntry:{component:"gitlab.com/shiftinbits/constellation-gitlab/constellation-index@1",inputs:{access_key:"$CONSTELLATION_ACCESS_KEY"}},job:{variables:{GIT_DEPTH:"0"},rules:[{if:`$CI_COMMIT_BRANCH == "${n}"`}]}}}function zr(n){let{includeEntry:e,job:t}=Hr(n);return stringify({include:[e],"constellation-index":t},{lineWidth:0})}var li=f(()=>{});var Gt,ya=f(()=>{le();li();Gt=class{constructor(e){this.gitRoot=e;}async detectPlatforms(){let e=[],[t,r]=await Promise.all([C.directoryExists(k__default.join(this.gitRoot,".github","workflows")),C.fileIsReadable(k__default.join(this.gitRoot,".gitlab-ci.yml"))]);return t&&e.push("github"),r&&e.push("gitlab"),e}async githubWorkflowExists(){return C.fileIsReadable(k__default.join(this.gitRoot,".github","workflows","constellation-index.yml"))}async gitlabJobExists(){let e=k__default.join(this.gitRoot,".gitlab-ci.yml");if(!await C.fileIsReadable(e))return false;try{let r=await C.readFile(e),s=parseDocument(r).contents;return isMap(s)&&s.has("constellation-index")}catch{return false}}async createGitHubWorkflow(e){let t=k__default.join(this.gitRoot,".github","workflows");await se__default.mkdir(t,{recursive:true});let r=k__default.join(t,"constellation-index.yml");return await C.writeFile(r,ai(e)),r}async createOrMergeGitLabCI(e){let t=k__default.join(this.gitRoot,".gitlab-ci.yml");if(!await C.fileIsReadable(t))return await C.writeFile(t,zr(e)),t;let o=await C.readFile(t),s=parseDocument(o);if(!isMap(s.contents))return await C.writeFile(t,zr(e)),t;let{includeEntry:a,job:l}=Hr(e);return this.mergeIncludeEntry(s,a),s.set("constellation-index",l),await C.writeFile(t,s.toString()),t}mergeIncludeEntry(e,t){let r=e.get("include");if(!r){e.set("include",[t]);return}if(isSeq(r)){let o=r.items.filter(s=>{if(isMap(s)){let a=s.get("component");return typeof a!="string"||!a.includes("constellation-gitlab")}return true});r.items=o,r.items.push(e.createNode(t));return}e.set("include",[r,t]);}};});var va=f(()=>{ya();li();});function pi(n){if(n.installedBinaryPath!==void 0)return existsSync(n.installedBinaryPath)?{ok:true,path:n.installedBinaryPath}:{ok:false,reason:"not-installed"};if(!ae(n.prerequisite))return {ok:false,reason:"not-installed"};let e;try{e=execFileSync(n.verifyCommand[0],[...n.verifyCommand.slice(1)],{stdio:["ignore","pipe","pipe"],timeout:Md,maxBuffer:Od}).toString();}catch{return {ok:false,reason:"not-installed"}}let t=e.trim().split(/\r?\n/)[0]?.trim()??"";if(!t||!k.isAbsolute(t))return {ok:false,reason:"invalid-stdout"};let r=k.resolve(n.allowedRootPrefix),o;try{o=realpathSync(t);}catch{return {ok:false,reason:"not-installed"}}return o!==r&&!o.startsWith(r+k.sep)?{ok:false,reason:"untrusted-path"}:{ok:true,path:o}}var Od,Md,ba=f(()=>{le();Od=4096,Md=1e4;});function Sa(n,e){let t=He__default.homedir(),r=process.platform,o=Gd[n];switch(r){case "darwin":return k__default.join(t,"Library/Application Support",o,"User/globalStorage",e);case "win32":return k__default.join(process.env.APPDATA||k__default.join(t,"AppData/Roaming"),o,"User/globalStorage",e);default:return k__default.join(t,".config",o,"User/globalStorage",e)}}function wa(){let n="saoudrizwan.claude-dev";return ["stable","insiders"].map(t=>({variant:t,displayName:t==="stable"?"VS Code":"VS Code Insiders",settingsPath:k__default.join(Sa(t,n),"settings","cline_mcp_settings.json")}))}function _a(){return k__default.join(Sa("stable","saoudrizwan.claude-dev"),"settings","cline_mcp_settings.json")}var Gd,xa=f(()=>{Gd={stable:"Code",insiders:"Code - Insiders"};});function Ea(n){return ui.find(e=>e.id===n)}var Ca,Bd,ui,di=f(()=>{xa();Ca={command:"npx",args:["-y","@constellationdev/mcp@latest"]},Bd={extraKnownMarketplaces:{"constellation-plugins":{source:{source:"github",repo:"ShiftinBits/constellation-claude"},autoUpdate:true}},enabledPlugins:{"constellation@constellation-plugins":true}},ui=[{id:"claude-code",displayName:"Claude Code",configPath:".mcp.json",format:"json",skipMcpServer:true,permissionsConfig:{filePath:".claude/settings.json",allowKeyPath:["permissions","allow"],allowValue:"mcp__plugin_constellation_*"},marketplaceConfig:{filePath:".claude/settings.json",config:Bd},mcpServersKeyPath:["mcpServers"]},{id:"cline",displayName:"Cline",configPath:_a(),isGlobalConfig:true,getGlobalConfigPaths:wa,format:"json",mcpServersKeyPath:["mcpServers"],mcpServerExtras:{alwaysAllow:["code_intel"],disabled:false}},{id:"codex-cli",displayName:"Codex CLI",configPath:".codex/config.toml",format:"toml",mcpServersKeyPath:["mcp_servers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"$CONSTELLATION_ACCESS_KEY"},mcpServerExtras:{enabled_tools:["code_intel"]},envPolicyConfig:{includeOnlyKeyPath:["shell_environment_policy","include_only"],envVarsToAllow:["CONSTELLATION_ACCESS_KEY"],globalConfigPath:"~/.codex/config.toml"}},{id:"copilot-cli",displayName:"Copilot CLI",configPath:"",format:"json",mcpServersKeyPath:[],skipMcpServer:true,pluginInstallCommand:{command:"copilot",args:["plugin","marketplace","add","ShiftinBits/constellation-copilot"]},pluginPostInstallCommands:[{command:"copilot",args:["plugin","install","constellation@constellation-plugins"]}]},{id:"cursor",displayName:"Cursor",configPath:".cursor/mcp.json",format:"json",mcpServersKeyPath:["mcpServers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"${env:CONSTELLATION_ACCESS_KEY}"}},{id:"gemini-cli",displayName:"Gemini CLI",configPath:"",format:"json",mcpServersKeyPath:[],skipMcpServer:true,pluginInstallCommand:{command:"gemini",args:["extensions","install","https://github.com/ShiftinBits/constellation-gemini"]},pluginUpdateCommand:{command:"gemini",args:["extensions","update","constellation"]},pluginPostInstallCommands:[{command:"gemini",args:["extensions","disable","--scope","user","constellation"]},{command:"gemini",args:["extensions","enable","--scope","workspace","constellation"]}]},{id:"jetbrains-ai",displayName:"JetBrains",configPath:".ai/mcp/mcp.json",format:"json",mcpServersKeyPath:["mcpServers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"CONSTELLATION_ACCESS_KEY"},mcpServerExtras:{tools:["code_intel"]}},{id:"kilo-code",displayName:"Kilo Code",configPath:".kilocode/mcp.json",format:"json",permissionsConfig:{filePath:".kilocode/mcp.json",allowKeyPath:["mcpServers","constellation","alwaysAllow"],allowValue:"code_intel"},mcpServersKeyPath:["mcpServers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"${env:CONSTELLATION_ACCESS_KEY}"}},{id:"opencode",displayName:"OpenCode",configPath:"opencode.jsonc",format:"jsonc",mcpServersKeyPath:["mcp"],skipMcpServer:true,pluginConfig:{pluginKeyPath:["plugin"],pluginValue:"@constellationdev/opencode"},configDefaults:{$schema:"https://opencode.ai/config.json"}},{id:"tabnine",displayName:"Tabnine",configPath:".tabnine/mcp_servers.json",format:"json",mcpServersKeyPath:["mcpServers"]},{id:"vscode-copilot",displayName:"VSCode",configPath:".vscode/mcp.json",format:"json",mcpServersKeyPath:["servers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"CONSTELLATION_ACCESS_KEY"},mcpServerExtras:{tools:["code_intel"]}}];});async function Pa(){if(!mi)try{let n=await import('@iarna/toml');mi={parse:n.parse,stringify:n.stringify};}catch{throw new Error("TOML support requires @iarna/toml package. Install with: npm install @iarna/toml")}return mi}function Wd(n){let e="",t=0,r=n.length;for(;t<r;)if(n[t]==='"'){for(e+='"',t++;t<r&&n[t]!=='"';)n[t]==="\\"?(e+=n[t++],t<r&&(e+=n[t++])):e+=n[t++];t<r&&(e+=n[t++]);}else if(n[t]==="/"&&t+1<r&&n[t+1]==="/")for(t+=2;t<r&&n[t]!==`
|
|
84
|
-
`;)t++;else if(n[t]==="/"&&t+1<r&&n[t+1]==="*"){for(t+=2;t<r&&!(n[t]==="*"&&t+1<r&&n[t+1]==="/");)t++;t<r&&(t+=2);}else e+=n[t++];return e.replace(/,(\s*[}\]])/g,"$1")}var mi,Wr,Ia=f(()=>{le();di();mi=null;Wr=class{cwd;constructor(e=process.cwd()){this.cwd=e;}async configureTool(e){try{let t=k__default.join(this.cwd,e.configPath),r=!e.skipMcpServer||!!e.pluginConfig||!!e.configDefaults;if(r){await this.ensureDirectoryExists(t);let s=await this.readConfig(t,e.format);if(e.configDefaults)for(let[a,l]of Object.entries(e.configDefaults))a in s||(s[a]=l);e.pluginConfig&&(s=this.addPluginToArray(s,e.pluginConfig)),e.skipMcpServer||(s=this.addConstellationServer(s,e),await this.configureEnvPolicy(s,e)),await this.writeConfig(t,s,e.format);}e.permissionsConfig&&await this.configurePermissions(e.permissionsConfig),e.marketplaceConfig&&await this.configureMarketplace(e.marketplaceConfig);let o;return r?o=t:e.permissionsConfig?o=k__default.join(this.cwd,e.permissionsConfig.filePath):e.marketplaceConfig?o=k__default.join(this.cwd,e.marketplaceConfig.filePath):o=t,{tool:e,success:!0,configuredPath:o}}catch(t){return {tool:e,success:false,error:t instanceof Error?t.message:String(t)}}}async configureGlobalTool(e){if(!e.getGlobalConfigPaths)return [{tool:e,success:false,error:"No global config paths defined"}];let t=e.getGlobalConfigPaths(),r=[];for(let{displayName:o,settingsPath:s}of t)try{await this.ensureDirectoryExists(s);let a=await this.readConfig(s,e.format);a=this.addConstellationServer(a,e),await this.writeConfig(s,a,e.format),r.push({tool:{...e,displayName:`${e.displayName} (${o})`},success:!0,configuredPath:s});}catch(a){let l=a instanceof Error?a.message:String(a);l.includes("ENOENT")||l.includes("no such file")||r.push({tool:{...e,displayName:`${e.displayName} (${o})`},success:false,error:l});}return r}async ensureDirectoryExists(e){let t=k__default.dirname(e);await se__default.mkdir(t,{recursive:true});}async readConfig(e,t){try{if(!await C.fileIsReadable(e))return {};let o=await C.readFile(e);return t==="json"?JSON.parse(o):t==="jsonc"?JSON.parse(Wd(o)):(await Pa()).parse(o)}catch{return {}}}addConstellationServer(e,t){let r=e;for(let a=0;a<t.mcpServersKeyPath.length-1;a++){let l=t.mcpServersKeyPath[a];(!r[l]||typeof r[l]!="object")&&(r[l]={}),r=r[l];}let o=t.mcpServersKeyPath[t.mcpServersKeyPath.length-1];(!r[o]||typeof r[o]!="object")&&(r[o]={});let s=r[o];if(!s.constellation){let a=t.mcpServerConfigOverride??Ca,l={...a};if(t.mcpServerExtras&&Object.assign(l,t.mcpServerExtras),t.mcpEnv){let c=t.mcpEnvKey??"env",u=a[c];l[c]={...u,...t.mcpEnv};}s.constellation=l;}return e}async writeConfig(e,t,r){let o;r==="json"||r==="jsonc"?o=JSON.stringify(t,null,2):o=(await Pa()).stringify(t),o=o.replace(/\r\n/g,`
|
|
83
|
+
`)),e}finally{this.reporter.resume();}}async determineIndexScope(e){if(e)return {isIncremental:false,upToDate:false};this.reporter.detail("Determining index scope...");try{let r=(await this.apiClient.getProjectState())?.latestCommit;if(!r)return this.reporter.detail("No previous index found, performing full index"),{isIncremental:!1,upToDate:!1};let o=await this.git.getLatestCommitHash();return r===o?(this.reporter.detail("Already up to date"),{isIncremental:!0,upToDate:!0}):(this.reporter.detail(`Last indexed commit: ${r.substring(0,8)}`),this.reporter.detail(`Current commit: ${o.substring(0,8)}`),this.reporter.detail(`Performing incremental index starting from commit ${r.substring(0,8)}`),{isIncremental:!0,upToDate:!1})}catch(t){if(t instanceof H)throw t;return this.reporter.warn(`Could not determine last index (${t instanceof Error?t.message:"unknown error"}), performing full index`),{isIncremental:false,upToDate:false}}}async discoverFiles(e){this.reporter.detail("Analyzing codebase...");let t;if(e)try{let r=await this.apiClient.getProjectState();if(!r?.latestCommit)this.reporter.warn("Cannot determine changes (no latestCommit in project state), falling back to full scan"),t=await this.scanner.scanFiles(this.config);else {let o=await this.git.getChangedFiles(r.latestCommit),s=[...o.added,...o.modified,...o.renamed.map(l=>l.to)];this.reporter.detail(`Found ${s.length} changed files`),t=await this.scanner.scanSpecificFiles(s,this.config);let a=[...o.deleted,...o.renamed.map(l=>l.from)];if(a.length>0){let l=o.deleted.length,c=o.renamed.length,u=c>0?`${ve} Removing ${l} deleted file(s) and ${c} renamed file(s) from graph`:`${ve} Removing ${l} deleted file(s) from graph`;this.reporter.log(u),await this.apiClient.deleteFiles(a);}}}catch(r){if(r instanceof H)throw r;this.reporter.warn(`Cannot determine changes (${r instanceof Error?r.message:"unknown"}), falling back to full scan`),t=await this.scanner.scanFiles(this.config);}else this.reporter.detail("Scanning all project files..."),t=await this.scanner.scanFiles(this.config);return this.reporter.detail(`Found ${t.length} files to index`),t}async*generateASTs(e,t,r,o){let s=e.length,a=0,l=0;o?.(0,s),this.reporter.detail(`Processing ${s} files...`);let c=await this.git.getLatestCommitHash(),u=s>1e4?5:s>5e3?7:10;u<10&&this.reporter.detail(`Large project detected, using concurrency of ${u} to optimize memory usage`);let d=new Qe(u,{preserveOrder:true}).run(e,async(m,g)=>{let h=Math.round((g+1)/s*100);this.reporter.detail(`Analyzing file ${m.path.replace(process.cwd()+"/","")} (${h}%)...`);try{let{tree:b,classificationMap:y,content:S}=await this.parser.parseFile(m.path,m.language),E=this.symbolExtractor.extract(b,m.language);E.length>0&&this.parseSymbols.set(this.normalizePathToCanonical(m.relativePath),E),S!==void 0&&this.parseContent.set(this.normalizePathToCanonical(m.relativePath),S),y.entries.length>5e4&&this.reporter.warn(`Large classification map for ${m.relativePath}: ${y.entries.length} entries`);let w=this.langRegistry.getPlugin(m.language),P;if(w?.getImportResolver){let K=this.buildConfigManagers.get(m.language),ye=K?await K.getConfigForFile(m.path):null,J=w.getImportResolver(m.path,ye);if(J){let{ImportExtractor:M}=await Promise.resolve().then(()=>(Ys(),qs));P=await new M().extractImportResolutions(b,m.path,m.language,J);}}let{serializeASTStream:N}=await Promise.resolve().then(()=>(ni(),da)),I=N(b.rootNode,void 0,m.language),v=await this.compressor.compressStream(I),R=this.normalizePathToCanonical(m.relativePath),_={file:R,language:m.language,commit:c,timestamp:t,ast:v,importResolutions:P,classificationMap:{filePath:R,entries:y.entries}},O=vs.safeParse(_);if(!O.success)throw new Error(`Index validation failed: ${O.error.issues[0].message}`);return a++,o?.(a,s),O.data}catch(b){throw l++,o?.(a+l,s),this.reporter.warn(`Failed to parse ${m.relativePath}: ${b.message}`,{code:"PARSE_FAILURE"}),b}});for await(let m of d)yield m;l>0?this.reporter.warn(`Completed parsing with ${l} parsing errors`):this.reporter.detail("All files analyzed successfully"),r&&r();}async uploadToAPI(e,t,r,o){if(!await this.apiClient.streamToApi(e,"ast",this.config.projectId,this.config.branch,t,r,o))throw new Error("Failed to upload data to Constellation Service");this.reporter.detail("Data uploaded to Constellation Service, indexing in progress");}async*createIndexPipeline(e,t,r,o,s){let a=await this.discoverFiles(e);this.discoveredFiles=a,o(a),yield*this.generateASTs(a,t,r,s);}async handleQueuedUpload(e,t,r,o){this.reporter.log("Generating index data for queue upload...");let s=this.createIndexPipeline(t,o,()=>{},()=>{});await this.apiClient.uploadToQueue(s,this.config.projectId,this.config.branch,r,e),this.reporter.detail("Changes queued for indexing behind the current operation.");}normalizePathToCanonical(e){return ar(e)}isLanguageLspEligible(e){let t=this.config.languages[e];return t?.lspEnrichment===false?false:!!t?.lsp||Te.has(e)}getEnrichmentEligibleLanguages(e,t){if(e)return this.reporter.detail("Index enrichment skipped"),null;if(this.config.lspEnrichment===false)return this.reporter.detail("Index enrichment disabled in constellation.json"),null;let r=new Set(t.map(s=>s.language)),o=[...r].filter(s=>this.isLanguageLspEligible(s));if(o.length===0){let s=[...r].filter(a=>a).map(te).join(", ");return this.reporter.detail(s?`Index enrichment skipped: no LSP enrichment configured for scanned language(s): ${s}`:"Index enrichment skipped: no language-tagged files were found to enrich"),null}return this.reporter.detail(`Index enrichment enabled for: ${o.map(te).join(", ")}`),new Set(o)}async runLspEnrichment(e,t,r,o,s,a,l){let c=this.reporter,u={log:d=>c.detail(d),warn:d=>c.warn(d,{verboseOnly:true}),error:d=>c.error(d,{verboseOnly:true})},p=new ur(process.cwd(),u);try{if(s?.aborted)return null;this.reporter.detail("Starting index enrichment...");let d=new Map,m=new Map;for(let w of e){if(!t.has(w.language))continue;let P=d.get(w.language)||[];P.push(this.normalizePathToCanonical(w.relativePath)),d.set(w.language,P);}let g=d.size,h=!1;for(let w of [...d.keys()]){if(s?.aborted)return null;let P=this.langRegistry?.getPlugin(w);if(!P?.preflightLsp)continue;let N;try{N=await P.preflightLsp(process.cwd());}catch(I){let v=I instanceof Error?I.message:String(I);this.reporter.warn(`LSP pre-flight failed for ${te(w)} (${v}); proceeding without skip.`);continue}N.skip&&(this.reporter.warn(N.message),d.delete(w),h=!0);}let b=h&&d.size===0&&g>0;for(let w of d.keys()){if(m.has(w))continue;let N=this.config.languages[w]?.lsp;l?.(w,"initializing");let I=null;try{I=await p.startServer(w,N),I&&m.set(w,I);}finally{l?.(w,I?"ready":"failed");}}if(m.size===0)return b||this.reporter.warn("No language servers started, index enrichment skipped"),null;if(s?.aborted)return p.destroyAll(),null;this.reporter.detail(`Language servers started: ${[...m.keys()].map(te).join(", ")}`);let y=new lr(process.cwd(),this.reporter),S=s?new Promise((w,P)=>{s.addEventListener("abort",()=>{p.destroyAll(),P(s.reason||new Error("Indexing aborted"));},{once:!0});}):null,E=await(S?Promise.race([y.enrich(d,r,m,o,a),S]):y.enrich(d,r,m,o,a)),T=E.reduce((w,P)=>w+P.symbols.length,0);return this.reporter.detail(`Index enrichment analysis completed: ${T} symbols across ${E.length} files`),E.length>0?E:null}catch(d){return this.reporter.warn(`Index enrichment failed: ${d instanceof Error?d.message:String(d)}`,{code:"ENRICHMENT_FAILED"}),null}finally{await p.shutdownAll();}}};});function ai(n){return stringify({name:"Constellation Index",on:{push:{branches:[n]}},permissions:{contents:"read"},jobs:{index:{"runs-on":"ubuntu-latest",steps:[{uses:"actions/checkout@v4",with:{"fetch-depth":0}},{uses:"ShiftinBits/constellation-github@v1",with:{"access-key":"${{ secrets.CONSTELLATION_ACCESS_KEY }}"}}]}}},{lineWidth:0})}function Hr(n){return {includeEntry:{component:"gitlab.com/shiftinbits/constellation-gitlab/constellation-index@1",inputs:{access_key:"$CONSTELLATION_ACCESS_KEY"}},job:{variables:{GIT_DEPTH:"0"},rules:[{if:`$CI_COMMIT_BRANCH == "${n}"`}]}}}function zr(n){let{includeEntry:e,job:t}=Hr(n);return stringify({include:[e],"constellation-index":t},{lineWidth:0})}var li=f(()=>{});var Gt,ya=f(()=>{le();li();Gt=class{constructor(e){this.gitRoot=e;}async detectPlatforms(){let e=[],[t,r]=await Promise.all([C.directoryExists(k__default.join(this.gitRoot,".github","workflows")),C.fileIsReadable(k__default.join(this.gitRoot,".gitlab-ci.yml"))]);return t&&e.push("github"),r&&e.push("gitlab"),e}async githubWorkflowExists(){return C.fileIsReadable(k__default.join(this.gitRoot,".github","workflows","constellation-index.yml"))}async gitlabJobExists(){let e=k__default.join(this.gitRoot,".gitlab-ci.yml");if(!await C.fileIsReadable(e))return false;try{let r=await C.readFile(e),s=parseDocument(r).contents;return isMap(s)&&s.has("constellation-index")}catch{return false}}async createGitHubWorkflow(e){let t=k__default.join(this.gitRoot,".github","workflows");await se__default.mkdir(t,{recursive:true});let r=k__default.join(t,"constellation-index.yml");return await C.writeFile(r,ai(e)),r}async createOrMergeGitLabCI(e){let t=k__default.join(this.gitRoot,".gitlab-ci.yml");if(!await C.fileIsReadable(t))return await C.writeFile(t,zr(e)),t;let o=await C.readFile(t),s=parseDocument(o);if(!isMap(s.contents))return await C.writeFile(t,zr(e)),t;let{includeEntry:a,job:l}=Hr(e);return this.mergeIncludeEntry(s,a),s.set("constellation-index",l),await C.writeFile(t,s.toString()),t}mergeIncludeEntry(e,t){let r=e.get("include");if(!r){e.set("include",[t]);return}if(isSeq(r)){let o=r.items.filter(s=>{if(isMap(s)){let a=s.get("component");return typeof a!="string"||!a.includes("constellation-gitlab")}return true});r.items=o,r.items.push(e.createNode(t));return}e.set("include",[r,t]);}};});var va=f(()=>{ya();li();});function pi(n){if(n.installedBinaryPath!==void 0)return existsSync(n.installedBinaryPath)?{ok:true,path:n.installedBinaryPath}:{ok:false,reason:"not-installed"};if(!ae(n.prerequisite))return {ok:false,reason:"not-installed"};let e;try{e=execFileSync(n.verifyCommand[0],[...n.verifyCommand.slice(1)],{stdio:["ignore","pipe","pipe"],timeout:Md,maxBuffer:Od}).toString();}catch{return {ok:false,reason:"not-installed"}}let t=e.trim().split(/\r?\n/)[0]?.trim()??"";if(!t||!k.isAbsolute(t))return {ok:false,reason:"invalid-stdout"};let r=k.resolve(n.allowedRootPrefix),o;try{o=realpathSync(t);}catch{return {ok:false,reason:"not-installed"}}return o!==r&&!o.startsWith(r+k.sep)?{ok:false,reason:"untrusted-path"}:{ok:true,path:o}}var Od,Md,ba=f(()=>{le();Od=4096,Md=1e4;});function Sa(n,e){let t=He__default.homedir(),r=process.platform,o=Gd[n];switch(r){case "darwin":return k__default.join(t,"Library/Application Support",o,"User/globalStorage",e);case "win32":return k__default.join(process.env.APPDATA||k__default.join(t,"AppData/Roaming"),o,"User/globalStorage",e);default:return k__default.join(t,".config",o,"User/globalStorage",e)}}function wa(){let n="saoudrizwan.claude-dev";return ["stable","insiders"].map(t=>({variant:t,displayName:t==="stable"?"VS Code":"VS Code Insiders",settingsPath:k__default.join(Sa(t,n),"settings","cline_mcp_settings.json")}))}function _a(){return k__default.join(Sa("stable","saoudrizwan.claude-dev"),"settings","cline_mcp_settings.json")}var Gd,xa=f(()=>{Gd={stable:"Code",insiders:"Code - Insiders"};});function Ea(n){return ui.find(e=>e.id===n)}var Ca,Bd,ui,di=f(()=>{xa();Ca={command:"npx",args:["-y","@constellationdev/mcp@latest"]},Bd={extraKnownMarketplaces:{"constellation-plugins":{source:{source:"github",repo:"ShiftinBits/constellation-claude"},autoUpdate:true}},enabledPlugins:{"constellation@constellation-plugins":true}},ui=[{id:"antigravity",displayName:"Antigravity CLI",configPath:"",format:"json",mcpServersKeyPath:[],skipMcpServer:true,pluginInstallCommand:{command:"agy",args:["plugin","install","https://github.com/ShiftinBits/constellation-antigravity"]}},{id:"claude-code",displayName:"Claude Code",configPath:".mcp.json",format:"json",skipMcpServer:true,permissionsConfig:{filePath:".claude/settings.json",allowKeyPath:["permissions","allow"],allowValue:"mcp__plugin_constellation_*"},marketplaceConfig:{filePath:".claude/settings.json",config:Bd},mcpServersKeyPath:["mcpServers"]},{id:"cline",displayName:"Cline",configPath:_a(),isGlobalConfig:true,getGlobalConfigPaths:wa,format:"json",mcpServersKeyPath:["mcpServers"],mcpServerExtras:{alwaysAllow:["code_intel"],disabled:false}},{id:"codex-cli",displayName:"Codex CLI",configPath:".codex/config.toml",format:"toml",mcpServersKeyPath:["mcp_servers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"$CONSTELLATION_ACCESS_KEY"},mcpServerExtras:{enabled_tools:["code_intel"]},envPolicyConfig:{includeOnlyKeyPath:["shell_environment_policy","include_only"],envVarsToAllow:["CONSTELLATION_ACCESS_KEY"],globalConfigPath:"~/.codex/config.toml"},featureFlagsConfig:{flagKeyPath:["features","hooks"],deprecatedRootKeys:["codex_hooks"]}},{id:"copilot-cli",displayName:"Copilot CLI",configPath:"",format:"json",mcpServersKeyPath:[],skipMcpServer:true,pluginInstallCommand:{command:"copilot",args:["plugin","marketplace","add","ShiftinBits/constellation-copilot"]},pluginPostInstallCommands:[{command:"copilot",args:["plugin","install","constellation@constellation-plugins"]}]},{id:"cursor",displayName:"Cursor",configPath:".cursor/mcp.json",format:"json",mcpServersKeyPath:["mcpServers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"${env:CONSTELLATION_ACCESS_KEY}"}},{id:"jetbrains-ai",displayName:"JetBrains",configPath:".ai/mcp/mcp.json",format:"json",mcpServersKeyPath:["mcpServers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"CONSTELLATION_ACCESS_KEY"},mcpServerExtras:{tools:["code_intel"]}},{id:"kilo-code",displayName:"Kilo Code",configPath:".kilocode/mcp.json",format:"json",permissionsConfig:{filePath:".kilocode/mcp.json",allowKeyPath:["mcpServers","constellation","alwaysAllow"],allowValue:"code_intel"},mcpServersKeyPath:["mcpServers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"${env:CONSTELLATION_ACCESS_KEY}"}},{id:"opencode",displayName:"OpenCode",configPath:"opencode.jsonc",format:"jsonc",mcpServersKeyPath:["mcp"],skipMcpServer:true,pluginConfig:{pluginKeyPath:["plugin"],pluginValue:"@constellationdev/opencode"},configDefaults:{$schema:"https://opencode.ai/config.json"}},{id:"tabnine",displayName:"Tabnine",configPath:".tabnine/mcp_servers.json",format:"json",mcpServersKeyPath:["mcpServers"]},{id:"vscode-copilot",displayName:"VSCode",configPath:".vscode/mcp.json",format:"json",mcpServersKeyPath:["servers"],mcpEnv:{CONSTELLATION_ACCESS_KEY:"CONSTELLATION_ACCESS_KEY"},mcpServerExtras:{tools:["code_intel"]}}];});async function Pa(){if(!mi)try{let n=await import('@iarna/toml');mi={parse:n.parse,stringify:n.stringify};}catch{throw new Error("TOML support requires @iarna/toml package. Install with: npm install @iarna/toml")}return mi}function Wd(n){let e="",t=0,r=n.length;for(;t<r;)if(n[t]==='"'){for(e+='"',t++;t<r&&n[t]!=='"';)n[t]==="\\"?(e+=n[t++],t<r&&(e+=n[t++])):e+=n[t++];t<r&&(e+=n[t++]);}else if(n[t]==="/"&&t+1<r&&n[t+1]==="/")for(t+=2;t<r&&n[t]!==`
|
|
84
|
+
`;)t++;else if(n[t]==="/"&&t+1<r&&n[t+1]==="*"){for(t+=2;t<r&&!(n[t]==="*"&&t+1<r&&n[t+1]==="/");)t++;t<r&&(t+=2);}else e+=n[t++];return e.replace(/,(\s*[}\]])/g,"$1")}var mi,Wr,Ia=f(()=>{le();di();mi=null;Wr=class{cwd;constructor(e=process.cwd()){this.cwd=e;}async configureTool(e){try{let t=k__default.join(this.cwd,e.configPath),r=!e.skipMcpServer||!!e.pluginConfig||!!e.configDefaults||!!e.featureFlagsConfig;if(r){await this.ensureDirectoryExists(t);let s=await this.readConfig(t,e.format);if(e.configDefaults)for(let[a,l]of Object.entries(e.configDefaults))a in s||(s[a]=l);e.pluginConfig&&(s=this.addPluginToArray(s,e.pluginConfig)),e.featureFlagsConfig&&this.applyFeatureFlags(s,e.featureFlagsConfig),e.skipMcpServer||(s=this.addConstellationServer(s,e),await this.configureEnvPolicy(s,e)),await this.writeConfig(t,s,e.format);}e.permissionsConfig&&await this.configurePermissions(e.permissionsConfig),e.marketplaceConfig&&await this.configureMarketplace(e.marketplaceConfig);let o;return r?o=t:e.permissionsConfig?o=k__default.join(this.cwd,e.permissionsConfig.filePath):e.marketplaceConfig?o=k__default.join(this.cwd,e.marketplaceConfig.filePath):o=t,{tool:e,success:!0,configuredPath:o}}catch(t){return {tool:e,success:false,error:t instanceof Error?t.message:String(t)}}}async configureGlobalTool(e){if(!e.getGlobalConfigPaths)return [{tool:e,success:false,error:"No global config paths defined"}];let t=e.getGlobalConfigPaths(),r=[];for(let{displayName:o,settingsPath:s}of t)try{await this.ensureDirectoryExists(s);let a=await this.readConfig(s,e.format);a=this.addConstellationServer(a,e),await this.writeConfig(s,a,e.format),r.push({tool:{...e,displayName:`${e.displayName} (${o})`},success:!0,configuredPath:s});}catch(a){let l=a instanceof Error?a.message:String(a);l.includes("ENOENT")||l.includes("no such file")||r.push({tool:{...e,displayName:`${e.displayName} (${o})`},success:false,error:l});}return r}async ensureDirectoryExists(e){let t=k__default.dirname(e);await se__default.mkdir(t,{recursive:true});}async readConfig(e,t){try{if(!await C.fileIsReadable(e))return {};let o=await C.readFile(e);return t==="json"?JSON.parse(o):t==="jsonc"?JSON.parse(Wd(o)):(await Pa()).parse(o)}catch{return {}}}addConstellationServer(e,t){let r=e;for(let a=0;a<t.mcpServersKeyPath.length-1;a++){let l=t.mcpServersKeyPath[a];(!r[l]||typeof r[l]!="object")&&(r[l]={}),r=r[l];}let o=t.mcpServersKeyPath[t.mcpServersKeyPath.length-1];(!r[o]||typeof r[o]!="object")&&(r[o]={});let s=r[o];if(!s.constellation){let a=t.mcpServerConfigOverride??Ca,l={...a};if(t.mcpServerExtras&&Object.assign(l,t.mcpServerExtras),t.mcpEnv){let c=t.mcpEnvKey??"env",u=a[c];l[c]={...u,...t.mcpEnv};}s.constellation=l;}return e}async writeConfig(e,t,r){let o;r==="json"||r==="jsonc"?o=JSON.stringify(t,null,2):o=(await Pa()).stringify(t),o=o.replace(/\r\n/g,`
|
|
85
85
|
`),o.endsWith(`
|
|
86
86
|
`)||(o+=`
|
|
87
87
|
`),await C.writeFile(e,o);}async configurePermissions(e){let t=k__default.join(this.cwd,e.filePath);await this.ensureDirectoryExists(t);let r={};try{if(await C.fileIsReadable(t)){let c=await C.readFile(t);r=JSON.parse(c);}}catch{}let o=r;for(let l=0;l<e.allowKeyPath.length-1;l++){let c=e.allowKeyPath[l];(!o[c]||typeof o[c]!="object")&&(o[c]={}),o=o[c];}let s=e.allowKeyPath[e.allowKeyPath.length-1];Array.isArray(o[s])||(o[s]=[]);let a=o[s];a.includes(e.allowValue)||a.push(e.allowValue),await C.writeFile(t,JSON.stringify(r,null," ")+`
|
|
88
88
|
`);}async configureMarketplace(e){let t=k__default.join(this.cwd,e.filePath);await this.ensureDirectoryExists(t);let r={};try{if(await C.fileIsReadable(t)){let s=await C.readFile(t);r=JSON.parse(s);}}catch{}r=this.deepMerge(r,e.config),await C.writeFile(t,JSON.stringify(r,null," ")+`
|
|
89
|
-
`);}deepMerge(e,t){let r={...e};for(let o of Object.keys(t)){let s=t[o],a=e[o];s&&typeof s=="object"&&!Array.isArray(s)&&a&&typeof a=="object"&&!Array.isArray(a)?r[o]=this.deepMerge(a,s):r[o]=s;}return r}addPluginToArray(e,t){let r=e;for(let a=0;a<t.pluginKeyPath.length-1;a++){let l=t.pluginKeyPath[a];(!r[l]||typeof r[l]!="object")&&(r[l]={}),r=r[l];}let o=t.pluginKeyPath[t.pluginKeyPath.length-1];Array.isArray(r[o])||(r[o]=[]);let s=r[o];return s.includes(t.pluginValue)||s.push(t.pluginValue),e}async configureEnvPolicy(e,t){if(!t.envPolicyConfig)return;let{includeOnlyKeyPath:r,envVarsToAllow:o,globalConfigPath:s}=t.envPolicyConfig;this.addToEnvPolicyWhitelist(e,r,o),s&&await this.updateGlobalEnvPolicy(s,r,o,t.format);}addToEnvPolicyWhitelist(e,t,r){let o=e;for(let l=0;l<t.length-1;l++){let c=t[l];if(!o[c]||typeof o[c]!="object")return;o=o[c];}let s=t[t.length-1];if(!Array.isArray(o[s]))return;let a=o[s];for(let l of r)a.includes(l)||a.push(l);}async updateGlobalEnvPolicy(e,t,r,o){let s=e.replace(/^~/,He__default.homedir()),a=await this.readConfig(s,o);if(Object.keys(a).length===0)return;let l=JSON.stringify(a);this.addToEnvPolicyWhitelist(a,t,r);let c=JSON.stringify(a);l!==c&&await this.writeConfig(s,a,o);}};});function Kr(n,e){let t=k__default.normalize(n),r=k__default.normalize(e);return t.startsWith(r+k__default.sep)?k__default.relative(e,n):n}var Yd,Bt,La=f(()=>{va();nt();ba();Pn();Rr();Ia();di();le();q();er();Xt();Yd=promisify(execFile);Bt=class extends Ie{async run(e={}){try{if(this.reporter.log(`${Ee} Initializing project configuration...
|
|
89
|
+
`);}deepMerge(e,t){let r={...e};for(let o of Object.keys(t)){let s=t[o],a=e[o];s&&typeof s=="object"&&!Array.isArray(s)&&a&&typeof a=="object"&&!Array.isArray(a)?r[o]=this.deepMerge(a,s):r[o]=s;}return r}addPluginToArray(e,t){let r=e;for(let a=0;a<t.pluginKeyPath.length-1;a++){let l=t.pluginKeyPath[a];(!r[l]||typeof r[l]!="object")&&(r[l]={}),r=r[l];}let o=t.pluginKeyPath[t.pluginKeyPath.length-1];Array.isArray(r[o])||(r[o]=[]);let s=r[o];return s.includes(t.pluginValue)||s.push(t.pluginValue),e}applyFeatureFlags(e,t){let{flagKeyPath:r,deprecatedRootKeys:o}=t,s=e;for(let a=0;a<r.length-1;a++){let l=r[a];(!s[l]||typeof s[l]!="object")&&(s[l]={}),s=s[l];}s[r[r.length-1]]=true;for(let a of o??[])delete e[a];}async configureEnvPolicy(e,t){if(!t.envPolicyConfig)return;let{includeOnlyKeyPath:r,envVarsToAllow:o,globalConfigPath:s}=t.envPolicyConfig;this.addToEnvPolicyWhitelist(e,r,o),s&&await this.updateGlobalEnvPolicy(s,r,o,t.format);}addToEnvPolicyWhitelist(e,t,r){let o=e;for(let l=0;l<t.length-1;l++){let c=t[l];if(!o[c]||typeof o[c]!="object")return;o=o[c];}let s=t[t.length-1];if(!Array.isArray(o[s]))return;let a=o[s];for(let l of r)a.includes(l)||a.push(l);}async updateGlobalEnvPolicy(e,t,r,o){let s=e.replace(/^~/,He__default.homedir()),a=await this.readConfig(s,o);if(Object.keys(a).length===0)return;let l=JSON.stringify(a);this.addToEnvPolicyWhitelist(a,t,r);let c=JSON.stringify(a);l!==c&&await this.writeConfig(s,a,o);}};});function Kr(n,e){let t=k__default.normalize(n),r=k__default.normalize(e);return t.startsWith(r+k__default.sep)?k__default.relative(e,n):n}var Yd,Bt,La=f(()=>{va();nt();ba();Pn();Rr();Ia();di();le();q();er();Xt();Yd=promisify(execFile);Bt=class extends Ie{async run(e={}){try{if(this.reporter.log(`${Ee} Initializing project configuration...
|
|
90
90
|
`),!await this.git.isGitAvailable())throw new Error("Could not find git client installation. Constellation requires git \u2014 install it from https://git-scm.com/downloads and try again.");let r=k__default.join(process.cwd(),"constellation.json"),o=null,s=await C.fileIsReadable(r);if(s)try{let v=await C.readFile(r);o=JSON.parse(v),this.reporter.info("Found existing constellation.json, current values will be used as defaults.");}catch{this.reporter.warn("Existing constellation.json is invalid, starting fresh.");}if(!await this.git.isGitRepository())throw new Error("Current directory is not a git repository. Run this command from the root directory of a git repository.");let l=await this.git.getRootDir(),[c,u]=await Promise.all([this.git.status(),this.git.listBranches()]),{currentBranch:p}=c,d=u.filter(v=>v!==p),m=p?[p,...d]:d,g=await input({message:"Constellation Project ID:",default:o?.projectId??"",validate:v=>v.trim().length>0||"Project ID is required",theme:B}),h=await select({message:"Branch to index:",choices:m.map(v=>({name:v,value:v})),default:o?.branch??m[0],theme:B}),y=(await checkbox({message:"Select Language(s):",choices:this.buildLanguageChoices(o),required:!0,theme:B})).reduce((v,R)=>(v[R]={fileExtensions:Me[R]||[]},v),{});this.reporter.log(""),this.reporter.info("Checking for LSP servers...");let S=(await this.env?.getKey("CONSTELLATION_AUTO_INSTALL_LSP")??"").trim().toLowerCase(),E=["1","true","yes","on"].includes(S),T=this.env?.isCI()??!1,w=[];for(let[v,R]of Object.entries(y)){let _=Te.get(v);if(!_)continue;let O=!1,K="";if(ae(_.command)&&(O=!0,K="system"),!O){let M=k__default.join(rt,_.command);existsSync(M)&&(O=!0,K="managed");}let ye=_.manualInstall?.autoInstall,J;if(!O&&ye){let M=pi(ye);M.ok&&(J=M.path,O=!0,K="managed");}if(O)this.reporter.log(`${x} ${v}: Found ${_.command} (${K})`),R.lsp={command:K==="managed"&&J!==void 0?J:_.command,args:_.args};else if(_.npmPackages.length===0&&_.manualInstall){let M=_.manualInstall.autoInstall;if(M&&ae(M.prerequisite)){if(M.installedBinaryPath!==void 0){let D=k__default.resolve(tt),A=k__default.resolve(M.installedBinaryPath);if(!A.startsWith(D+k__default.sep)){this.reporter.error(`${v}: installedBinaryPath (${A}) is outside the managed directory; refusing to install. Report this as a bug.`),R.lspEnrichment=!1;continue}}if(await confirm({message:`${v}: ${_.command} not found. Install via \`${_.manualInstall.command}\`?`,default:!0,theme:B}))try{this.reporter.info(`${v}: Installing ${_.command} via \`${M.argv.join(" ")}\` (this may take a minute)...`),execFileSync(M.argv[0],[...M.argv.slice(1)],{stdio:"pipe",env:{...process.env,...M.env??{}}});let D=pi(M);D.ok?(this.reporter.log(`${x} ${v}: Installed ${_.command} (${D.path})`),R.lsp={command:D.path,args:_.args}):D.reason==="untrusted-path"?(this.reporter.error(`${v}: Install completed but the resolved binary path is outside the allowed prefix; refusing to wire it. Report this as a bug.`),R.lspEnrichment=!1):D.reason==="invalid-stdout"?(this.reporter.error(`${v}: Install completed but the verify command produced no usable absolute path. Try running manually: \`${_.manualInstall.command}\`.`),R.lspEnrichment=!1):(this.reporter.error(`${v}: Install command exited 0 but ${_.command} wasn't found afterwards. Try running manually: \`${_.manualInstall.command}\`.`),R.lspEnrichment=!1);}catch(D){let A=D.stderr?.toString().trim();this.reporter.error(`${v}: Installation failed${A?`: ${A}`:""}`),R.lspEnrichment=!1;}else this.reporter.info(`${v}: To install manually: \`${_.manualInstall.command}\``),this.reporter.info(`${v}: Indexing will continue without LSP enrichment.`),R.lspEnrichment=!1;}else _.manualInstall.verifyToolchain?await this.installManualOnlyServer(v,R,_,_.manualInstall,_.manualInstall.verifyToolchain,{autoInstall:E,nonInteractive:T},w):(this.reporter.info(`${v}: ${_.command} not found. Requires ${_.manualInstall.requires}. Install with: ${_.manualInstall.command}`),_.manualInstall.pathNote&&this.reporter.info(`${v}: ${_.manualInstall.pathNote}`),this.reporter.info(`${v}: Indexing will continue without LSP enrichment.`),R.lspEnrichment=!1);}else if(await confirm({message:`${v}: ${_.command} not found. Install to ~/.constellation/lsp-servers/?`,default:!0,theme:B}))try{this.reporter.info(`Installing ${_.npmPackages.join(", ")}...`),execFileSync("npm",["install","--prefix",tt,..._.npmPackages],{stdio:"pipe"}),this.reporter.log(`${x} ${v}: Installed ${_.command}`),R.lsp={command:_.command,args:_.args};}catch{this.reporter.error(`${v}: Installation failed`),R.lspEnrichment=!1;}else R.lspEnrichment=!1;}if(w.length>0){let v=ye=>w.filter(J=>ye.includes(J.outcome)).map(J=>J.command).join(", "),R=v(["installed","installed-pathnote"]),_=v(["already-installed"]),O=v(["prereq-missing","prereq-too-old","declined","ci-skipped"]),K=v(["failed"]);R&&this.reporter.info(`LSP servers installed: ${R}`),_&&this.reporter.info(`LSP servers already present: ${_}`),O&&this.reporter.info(`LSP servers skipped: ${O}`),K&&this.reporter.warn(`LSP servers failed to install: ${K}`);}let P=Object.entries(y).filter(([,v])=>v.lspEnrichment!==!1).map(([v])=>v);P.length>0?this.reporter.log(`${x} Index enrichment enabled for: ${P.map(te).join(", ")}`):this.reporter.warn("No language servers configured. Index enrichment will be skipped.");let N={projectId:g.trim(),branch:h,languages:{...y},...P.length>0&&{lspEnrichment:!0}},I=JSON.stringify(N,void 0,2);await C.writeFile(r,I),this.reporter.log(`${x} ${s?"Updated":"Initialized"} configuration file at ${Kr(r,process.cwd())}`),await this.git.stageFile(r),this.reporter.log(`${x} Added constellation.json to staged changes in git`),e.skipMcp||await this.configureMCPServers(),!e.skipCi&&l&&await this.configureCICD(h,l);}catch(t){if(t instanceof Error&&t.name==="ExitPromptError")return;let r=t.message??"An unexpected error occurred";this.reporter.error(`Failed to initialize configuration file.
|
|
91
|
-
${r}`);}}async installManualOnlyServer(e,t,r,o,s,a,l){let c=h=>l.push({lang:e,command:r.command,outcome:h}),u=En(r);if(u){this.reporter.log(`${x} ${e}: Already installed ${r.command}`),t.lsp={command:u,args:r.args},c("already-installed");return}let p=_o(s);if(!p.ok){if(p.reason==="missing"){this.reporter.info(`${e}: ${r.command} install skipped \u2014 ${o.requires} required (not detected). Install it, then re-run \`constellation init\`.`),t.lspEnrichment=false,c("prereq-missing");return}if(p.reason==="too-old"){this.reporter.info(`${e}: ${r.command} install skipped \u2014 detected ${p.detected}, requires ${p.required} or later.`),t.lspEnrichment=false,c("prereq-too-old");return}t.lspEnrichment=false,c("prereq-missing");return}if(a.nonInteractive&&!a.autoInstall){this.reporter.info(`${e}: ${r.command} not installed \u2014 non-interactive run cannot prompt. Install manually with \`${o.command}\` or set CONSTELLATION_AUTO_INSTALL_LSP=1 to bypass the prompt.`),c("ci-skipped");return}if(!(a.autoInstall||await confirm({message:`${e}: ${r.command} not found. Required for ${te(e)} LSP enrichment. Install with \`${o.command}\`?`,default:true,theme:B}))){this.reporter.info(`${e}: skipped \u2014 indexing will continue without LSP enrichment.`),t.lspEnrichment=false,c("declined");return}this.reporter.info(`${e}: Installing ${r.command} via \`${o.command}\`...`);let m=xo(r);if(!m.ok){"exitCode"in m?(this.reporter.error(`${e}: ${r.command} install failed (exit ${m.exitCode??"unknown"}). Run \`${o.command}\` manually for details.`),m.stderr&&this.reporter.detail(`${e}: install stderr: ${m.stderr}`)):(this.reporter.error(`${e}: ${r.command} install failed to start. Run \`${o.command}\` manually for details.`),this.reporter.detail(`${e}: install error: ${m.spawnError}`)),t.lspEnrichment=false,c("failed");return}let g=En(r);if(g){this.reporter.log(`${x} ${e}: Installed ${r.command} (${g})`),t.lsp={command:g,args:r.args},c("installed");return}this.reporter.info(`${e}: ${r.command} installed but not yet on PATH.`),o.pathNote&&this.reporter.info(`${e}: ${o.pathNote}`),c("installed-pathnote");}async configureMCPServers(){if(!await confirm({message:"Automatically configure Constellation for AI coding assistants?",default:true,theme:B}))return;let t=await checkbox({message:"Select AI coding assistants to configure:",choices:ui.map(p=>({name:p.displayName,value:p.id})),required:true,theme:B}),r=new Wr(process.cwd()),o=[];for(let p of t){let d=Ea(p);if(d)if(this.reporter.info(`Configuring ${d.displayName}...`),d.pluginInstallCommand){let m=await this.executePluginInstall(d);o.push(m),m.success?this.reporter.log(`${x} ${d.displayName} plugin installed successfully`):this.reporter.warn(`${d.displayName}: ${m.error}`);}else if(d.isGlobalConfig&&d.getGlobalConfigPaths){let m=await r.configureGlobalTool(d),g=false;for(let h of m)o.push(h),h.success?(g=true,this.reporter.log(`${x} ${h.tool.displayName} configured at ${Kr(h.configuredPath,process.cwd())}`)):h.error&&this.reporter.warn(`${h.tool.displayName}: ${h.error}`);if(g){let h=d.id==="cline"?"global VS Code settings":"global settings";this.reporter.info(`Note: ${d.displayName} uses ${h} (not project-level)`);}if(m.length===0){let h=d.id==="cline"?"No VS Code installations found":"Configuration directory not found";this.reporter.warn(`${d.displayName}: ${h}`);}}else {let m=await r.configureTool(d);o.push(m),m.success?(this.reporter.log(`${x} ${d.displayName} configured at ${Kr(m.configuredPath,process.cwd())}`),d.permissionsConfig&&this.reporter.log(`${x} ${d.displayName} permissions set in ${d.permissionsConfig.filePath}`)):this.reporter.warn(`${d.displayName}: ${m.error}`);}}if(o.find(p=>p.tool.id==="claude-code"&&p.success)){let p=k__default.join(process.cwd(),".claude/settings.json");try{await this.git.stageFile(p),this.reporter.log(`${x} Added .claude/settings.json to staged changes in git`);}catch{this.reporter.warn("Could not stage .claude/settings.json in git");}}if(o.find(p=>p.tool.id==="codex-cli"&&p.success)){let p=k__default.join(process.cwd(),".codex/config.toml");try{await this.git.stageFile(p),this.reporter.log(`${x} Added .codex/config.toml to staged changes in git`);}catch{}}if(o.find(p=>p.tool.id==="opencode"&&p.success)){let p=k__default.join(process.cwd(),"opencode.jsonc");try{await this.git.stageFile(p),this.reporter.log(`${x} Added opencode.jsonc to staged changes in git`);}catch{}}let c=o.filter(p=>p.success).length,u=o.filter(p=>!p.success).length;this.reporter.log(`${x} Plugin + MCP configuration complete: ${c} configured`),u>0&&this.reporter.warn(`${u} tool(s) could not be configured`),this.reporter.info("Some tools may require restart to pick up new configuration.");}async executePluginInstall(e){let t=e.pluginInstallCommand;try{await this.runPluginCommand(t);}catch(r){let o=r;if(
|
|
91
|
+
${r}`);}}async installManualOnlyServer(e,t,r,o,s,a,l){let c=h=>l.push({lang:e,command:r.command,outcome:h}),u=En(r);if(u){this.reporter.log(`${x} ${e}: Already installed ${r.command}`),t.lsp={command:u,args:r.args},c("already-installed");return}let p=_o(s);if(!p.ok){if(p.reason==="missing"){this.reporter.info(`${e}: ${r.command} install skipped \u2014 ${o.requires} required (not detected). Install it, then re-run \`constellation init\`.`),t.lspEnrichment=false,c("prereq-missing");return}if(p.reason==="too-old"){this.reporter.info(`${e}: ${r.command} install skipped \u2014 detected ${p.detected}, requires ${p.required} or later.`),t.lspEnrichment=false,c("prereq-too-old");return}t.lspEnrichment=false,c("prereq-missing");return}if(a.nonInteractive&&!a.autoInstall){this.reporter.info(`${e}: ${r.command} not installed \u2014 non-interactive run cannot prompt. Install manually with \`${o.command}\` or set CONSTELLATION_AUTO_INSTALL_LSP=1 to bypass the prompt.`),c("ci-skipped");return}if(!(a.autoInstall||await confirm({message:`${e}: ${r.command} not found. Required for ${te(e)} LSP enrichment. Install with \`${o.command}\`?`,default:true,theme:B}))){this.reporter.info(`${e}: skipped \u2014 indexing will continue without LSP enrichment.`),t.lspEnrichment=false,c("declined");return}this.reporter.info(`${e}: Installing ${r.command} via \`${o.command}\`...`);let m=xo(r);if(!m.ok){"exitCode"in m?(this.reporter.error(`${e}: ${r.command} install failed (exit ${m.exitCode??"unknown"}). Run \`${o.command}\` manually for details.`),m.stderr&&this.reporter.detail(`${e}: install stderr: ${m.stderr}`)):(this.reporter.error(`${e}: ${r.command} install failed to start. Run \`${o.command}\` manually for details.`),this.reporter.detail(`${e}: install error: ${m.spawnError}`)),t.lspEnrichment=false,c("failed");return}let g=En(r);if(g){this.reporter.log(`${x} ${e}: Installed ${r.command} (${g})`),t.lsp={command:g,args:r.args},c("installed");return}this.reporter.info(`${e}: ${r.command} installed but not yet on PATH.`),o.pathNote&&this.reporter.info(`${e}: ${o.pathNote}`),c("installed-pathnote");}async configureMCPServers(){if(!await confirm({message:"Automatically configure Constellation for AI coding assistants?",default:true,theme:B}))return;let t=await checkbox({message:"Select AI coding assistants to configure:",choices:ui.map(p=>({name:p.displayName,value:p.id})),required:true,theme:B}),r=new Wr(process.cwd()),o=[];for(let p of t){let d=Ea(p);if(d)if(this.reporter.info(`Configuring ${d.displayName}...`),d.pluginInstallCommand){let m=await this.executePluginInstall(d);o.push(m),m.success?this.reporter.log(`${x} ${d.displayName} plugin installed successfully`):this.reporter.warn(`${d.displayName}: ${m.error}`);}else if(d.isGlobalConfig&&d.getGlobalConfigPaths){let m=await r.configureGlobalTool(d),g=false;for(let h of m)o.push(h),h.success?(g=true,this.reporter.log(`${x} ${h.tool.displayName} configured at ${Kr(h.configuredPath,process.cwd())}`)):h.error&&this.reporter.warn(`${h.tool.displayName}: ${h.error}`);if(g){let h=d.id==="cline"?"global VS Code settings":"global settings";this.reporter.info(`Note: ${d.displayName} uses ${h} (not project-level)`);}if(m.length===0){let h=d.id==="cline"?"No VS Code installations found":"Configuration directory not found";this.reporter.warn(`${d.displayName}: ${h}`);}}else {let m=await r.configureTool(d);o.push(m),m.success?(this.reporter.log(`${x} ${d.displayName} configured at ${Kr(m.configuredPath,process.cwd())}`),d.permissionsConfig&&this.reporter.log(`${x} ${d.displayName} permissions set in ${d.permissionsConfig.filePath}`)):this.reporter.warn(`${d.displayName}: ${m.error}`);}}if(o.find(p=>p.tool.id==="claude-code"&&p.success)){let p=k__default.join(process.cwd(),".claude/settings.json");try{await this.git.stageFile(p),this.reporter.log(`${x} Added .claude/settings.json to staged changes in git`);}catch{this.reporter.warn("Could not stage .claude/settings.json in git");}}if(o.find(p=>p.tool.id==="codex-cli"&&p.success)){let p=k__default.join(process.cwd(),".codex/config.toml");try{await this.git.stageFile(p),this.reporter.log(`${x} Added .codex/config.toml to staged changes in git`);}catch{}}if(o.find(p=>p.tool.id==="opencode"&&p.success)){let p=k__default.join(process.cwd(),"opencode.jsonc");try{await this.git.stageFile(p),this.reporter.log(`${x} Added opencode.jsonc to staged changes in git`);}catch{}}let c=o.filter(p=>p.success).length,u=o.filter(p=>!p.success).length;this.reporter.log(`${x} Plugin + MCP configuration complete: ${c} configured`),u>0&&this.reporter.warn(`${u} tool(s) could not be configured`),this.reporter.info("Some tools may require restart to pick up new configuration.");}async executePluginInstall(e){let t=e.pluginInstallCommand;try{await this.runPluginCommand(t);}catch(r){let o=r;if(this.isAlreadyInstalledError(o)){let s=(e.pluginPostInstallCommands?.length??0)>0;this.reporter.info(s?`${e.displayName} plugin source already configured, continuing...`:`${e.displayName} plugin already installed`);}else return {tool:e,success:false,error:this.formatPluginCommandError(t.command,o)}}for(let r of e.pluginPostInstallCommands??[])try{await this.runPluginCommand(r);}catch(o){let s=o;return {tool:e,success:false,error:this.formatPluginCommandError(r.command,s)}}return {tool:e,success:true}}async runPluginCommand(e){await Yd(e.command,e.args,{timeout:3e4,env:process.env});}isAlreadyInstalledError(e){let t=`${e.message??""}
|
|
92
92
|
${e.stderr??""}`.toLowerCase();return t.includes("already installed")||t.includes("already exists")||t.includes("already registered")}formatPluginCommandError(e,t){return t.code==="ENOENT"?`${e} not found. Is ${e} installed and on your PATH?`:t.killed?"Plugin installation timed out after 30 seconds":t.stderr?`Plugin installation failed: ${t.stderr.trim()}`:`Plugin installation failed: ${t.message}`}async configureCICD(e,t){if(!await confirm({message:"Set up a CI/CD pipeline to automatically index your project?",default:true,theme:B}))return;let o=new Gt(t),s=await o.detectPlatforms(),a;if(s.length===1){let p=s[0]==="github"?"GitHub Actions":"GitLab CI";if(!await confirm({message:`Detected ${p}. Configure Constellation CI/CD for this platform?`,default:true,theme:B}))return;a=s[0];}else a=await select({message:"Select CI/CD platform:",choices:[{name:"GitHub Actions",value:"github"},{name:"GitLab CI",value:"gitlab"}],theme:B});let l=a==="github"?await o.githubWorkflowExists():await o.gitlabJobExists();if(l&&!await confirm({message:"Constellation CI/CD configuration already exists. Overwrite?",default:false,theme:B})){this.reporter.info("Skipping CI/CD configuration");return}let c;try{c=a==="github"?await o.createGitHubWorkflow(e):await o.createOrMergeGitLabCI(e);}catch(p){this.reporter.warn(`Failed to configure CI/CD pipeline: ${p.message}`);return}let u=Kr(c,process.cwd());a==="github"?this.reporter.log(`${x} Created ${u}`):this.reporter.log(`${x} ${l?"Updated":"Created"} ${u} with Constellation indexing`);try{await this.git.stageFile(c),this.reporter.log(`${x} Added ${u} to staged changes in git`);}catch{this.reporter.warn(`Could not stage ${u} in git`);}a==="github"?this.reporter.info(`Add your access key as a repository secret:
|
|
93
93
|
Settings \u2192 Secrets and variables \u2192 Actions \u2192 New repository secret
|
|
94
94
|
Name: CONSTELLATION_ACCESS_KEY`):this.reporter.info(`Add your access key as a CI/CD variable:
|