glenn-code 1.0.26 → 1.0.27
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/adapters/signalr/index.js +1 -1
- package/dist/cli.js +1 -1
- package/package.json +1 -1
|
@@ -1369,7 +1369,7 @@ ${d.join(`
|
|
|
1369
1369
|
|
|
1370
1370
|
`)}
|
|
1371
1371
|
|
|
1372
|
-
File paths like "src/..." are relative to the package directory shown in parentheses.`}):(console.log("[TypeCheck] \u2713 All type checks passed"),{passed:!0})}async function bt(n,e,t,o,s){if(!await n.hasChanges()){console.log("[Git] No changes to commit");return}console.log("[Git] Committing changes...");let i=await n.commitAndPush(o,s);if(i.noChanges)console.log("[Git] No changes to commit");else if(i.pushFailed){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.error(`[Git] \u274C Push failed: ${i.error}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"push_failed",content:`Committed locally but failed to push to ${a}. Your changes are NOT on GitHub. Error: ${i.error}`,isError:!0}).catch(l=>{console.error("[Git] Failed to report push failure:",l)})}else if(i.success){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.log(`[Git] \u2192 Pushed to ${a}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"committed",content:`Changes committed to ${a}`,isError:!1}).catch(l=>{console.error("[Git] Failed to report commit:",l)})}else console.error(`[Git] \u274C Git error: ${i.error}`)}import*as V from"fs";import*as Be from"path";var He=class{constructor(e,t,o,s,r=!0,i=!0,a,c,l=!0){this.connection=e;this.lifecycle=t;this.serviceManager=o;this.workspaceDir=s;this.enableAutoTypecheck=r;this.enableAutoCommit=i;this.setupPlanningTransport=a;this.projectConfig=c;this.useDefaultStack=l;this.gitManager=Ne(s),this.claudeSessionIdMap=this.loadSessionMap()}currentSession=null;claudeSessionIdMap=new Map;currentAbortController=null;gitManager;get sessionMapPath(){return Be.join(this.workspaceDir,".sdd","claude-session-map.json")}loadSessionMap(){try{if(V.existsSync(this.sessionMapPath)){let e=JSON.parse(V.readFileSync(this.sessionMapPath,"utf-8")),t=new Map(Object.entries(e));return console.log(`[Receiver] Loaded ${t.size} claude session mappings from disk`),t}}catch(e){console.warn("[Receiver] Failed to load session map from disk:",e)}return new Map}persistSessionMap(){try{let e=Be.dirname(this.sessionMapPath);V.existsSync(e)||V.mkdirSync(e,{recursive:!0});let t=Object.fromEntries(this.claudeSessionIdMap);V.writeFileSync(this.sessionMapPath,JSON.stringify(t,null,2))}catch(e){console.warn("[Receiver] Failed to persist session map to disk:",e)}}async initSession(e){console.log(`[Receiver] InitSession for session ${e.sessionId}`),this.setupPlanningTransport&&e.projectId&&this.setupPlanningTransport(e.projectId),e.projectId&&await this.fetchProjectPrompt(e.projectId),this.currentSession={sessionId:e.sessionId,projectId:e.projectId,branchName:e.branchName,model:e.model==="auto"?void 0:e.model||"claude-haiku-4-5-20251001",debugMode:e.debugMode},await this.lifecycle.handleInitSession(e),e.prompt&&await this.runPrompt(e.sessionId,e.prompt,e.claudeSessionId)}async runPrompt(e,t,o,s=!1){let r=ge(t);if(console.log(`[Receiver] RunPrompt for session ${e}${o?` (ClaudeSessionId: ${o})`:""}${s?" [DEBUG MODE]":""}: ${r.substring(0,50)}...`),(!this.currentSession||this.currentSession.sessionId!==e)&&(console.log(`[Receiver] Session mismatch: expected ${this.currentSession?.sessionId}, got ${e}, switching...`),await this.switchSession(e),!this.currentSession)){console.error("[Receiver] Failed to create session context");return}let i=this.claudeSessionIdMap.get(e);if(o&&i!==o){console.warn(`[Receiver] Claude session not found in container: ${o}`);let l=this.connection.getHubProxy();await l.reportSessionOutput(process.env.CONTAINER_ID||"unknown",e,{type:"System",event:"sessionNotFound",content:o,isError:!0}),await this.connection.reportStatus("Ready","Session lost - summary needed",e,this.currentSession.projectId),await l.sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}await this.connection.reportStatus("Active",void 0,e,this.currentSession.projectId),this.currentSession.debugMode=s,this.currentAbortController=new AbortController;let a=i||null,c=new Set;try{let l=await je(r,{model:this.currentSession.model,sessionId:a||null,projectId:this.currentSession.projectId||null,apiUrl:this.connection.getMasterUrl(),debugLog:!0,debugMode:s,abortController:this.currentAbortController,projectConfig:this.projectConfig,useDefaultStack:this.useDefaultStack,callbacks:zt(this.connection,e,{onClaudeSessionId:g=>{this.claudeSessionIdMap.set(e,g),this.persistSessionMap()},onFileModified:g=>{c.add(g)}})}),u=Xt(this.workspaceDir,e);if(u&&u.length>0){console.log(`[Receiver] ${u.length} pending questions found, waiting for user answers`),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}if(this.enableAutoTypecheck&&!l.error&&!l.aborted){let g=await Zt(this.serviceManager,c,this.workspaceDir,this.projectConfig);if(!g.passed&&g.errorPrompt){console.log("[Receiver] Type errors detected, auto-correcting..."),await this.runPrompt(e,g.errorPrompt,o);return}}this.enableAutoCommit&&!l.error&&!l.aborted?await bt(this.gitManager,this.connection,e,t,!1):(l.error||l.aborted)&&this.enableAutoCommit&&await bt(this.gitManager,this.connection,e,t,!0),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,l.error?1:0)}catch(l){let u=l instanceof Error&&l.name==="AbortError",d=l instanceof Error?l.message:"Unknown error";u?console.log(`[Receiver] Agent aborted for session ${e}`):(console.error("[Receiver] Agent error:",d),await this.connection.reportStatus("Error",d,e,this.currentSession.projectId)),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,u?0:1)}finally{this.currentAbortController=null}}async setModel(e){console.log(`[Receiver] Model changed to: ${e}`),this.currentSession&&(this.currentSession.model=e==="auto"?void 0:e)}async stopAgent(){console.log("[Receiver] Stop command received"),this.currentAbortController&&this.currentAbortController.abort()}async ping(){await this.connection.getConnection().invoke("Pong",process.env.CONTAINER_ID||"unknown")}async switchSession(e){console.log(`[Receiver] SwitchSession to ${e}`),this.currentSession?this.currentSession.sessionId=e:(console.log(`[Receiver] Creating new session context for ${e}`),this.currentSession={sessionId:e,projectId:process.env.PROJECT_ID||"unknown",branchName:"main",model:void 0,debugMode:!1})}async projectPromptUpdated(e){console.log(`[Receiver] ProjectPromptUpdated received (${e.length} chars)`),ze(e)}async fetchProjectPrompt(e){try{let t=this.connection.getMasterUrl(),o=this.connection.getProjectKey(),s=await fetch(`${t}/api/projects/${e}/prompt`,{method:"GET",headers:{"Content-Type":"application/json","X-Project-Key":o}});if(!s.ok){console.log(`[Receiver] Failed to fetch project prompt: ${s.status}`);return}let r=await s.json();r.prompt?(ze(r.prompt),console.log(`[Receiver] Initial project prompt loaded (${r.prompt.length} chars)`)):console.log(`[Receiver] No project prompt set for project ${e}`)}catch(t){console.error("[Receiver] Error fetching project prompt:",t)}}};process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT=process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT||"60000";var en=z.dirname($n(import.meta.url));function Hn(){let n=[z.resolve(en,"../package.json"),z.resolve(en,"../../../package.json")];for(let e of n)try{if(M.existsSync(e)){let t=JSON.parse(M.readFileSync(e,"utf-8"));if(t.name==="glenn-code")return t.version||"unknown"}}catch{}return"unknown"}function Bn(n){let{useDefaultStack:e,projectConfig:t,configSource:o,tunnelPort:s,enableAutoTypecheck:r,enableAutoCommit:i}=n;if(console.log(`
|
|
1372
|
+
File paths like "src/..." are relative to the package directory shown in parentheses.`}):(console.log("[TypeCheck] \u2713 All type checks passed"),{passed:!0})}async function bt(n,e,t,o,s){if(!await n.hasChanges()){console.log("[Git] No changes to commit");return}console.log("[Git] Committing changes...");let i=await n.commitAndPush(o,s);if(i.noChanges)console.log("[Git] No changes to commit");else if(i.pushFailed){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.error(`[Git] \u274C Push failed: ${i.error}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"push_failed",content:`Committed locally but failed to push to ${a}. Your changes are NOT on GitHub. Error: ${i.error}`,isError:!0}).catch(l=>{console.error("[Git] Failed to report push failure:",l)})}else if(i.success){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.log(`[Git] \u2192 Pushed to ${a}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"committed",content:`Changes committed to ${a}`,isError:!1}).catch(l=>{console.error("[Git] Failed to report commit:",l)})}else console.error(`[Git] \u274C Git error: ${i.error}`)}import*as V from"fs";import*as Be from"path";var He=class{constructor(e,t,o,s,r=!0,i=!0,a,c,l=!0){this.connection=e;this.lifecycle=t;this.serviceManager=o;this.workspaceDir=s;this.enableAutoTypecheck=r;this.enableAutoCommit=i;this.setupPlanningTransport=a;this.projectConfig=c;this.useDefaultStack=l;this.gitManager=Ne(s),this.claudeSessionIdMap=this.loadSessionMap()}currentSession=null;claudeSessionIdMap=new Map;currentAbortController=null;gitManager;get sessionMapPath(){return Be.join(this.workspaceDir,".sdd","claude-session-map.json")}loadSessionMap(){try{if(V.existsSync(this.sessionMapPath)){let e=JSON.parse(V.readFileSync(this.sessionMapPath,"utf-8")),t=new Map(Object.entries(e));return console.log(`[Receiver] Loaded ${t.size} claude session mappings from disk`),t}else return console.log("[Receiver] No session map found on disk"),new Map}catch(e){console.warn("[Receiver] Failed to load session map from disk:",e)}return new Map}persistSessionMap(){try{let e=Be.dirname(this.sessionMapPath);V.existsSync(e)||V.mkdirSync(e,{recursive:!0});let t=Object.fromEntries(this.claudeSessionIdMap);V.writeFileSync(this.sessionMapPath,JSON.stringify(t,null,2))}catch(e){console.warn("[Receiver] Failed to persist session map to disk:",e)}}async initSession(e){console.log(`[Receiver] InitSession for session ${e.sessionId}`),this.setupPlanningTransport&&e.projectId&&this.setupPlanningTransport(e.projectId),e.projectId&&await this.fetchProjectPrompt(e.projectId),this.currentSession={sessionId:e.sessionId,projectId:e.projectId,branchName:e.branchName,model:e.model==="auto"?void 0:e.model||"claude-haiku-4-5-20251001",debugMode:e.debugMode},await this.lifecycle.handleInitSession(e),e.prompt&&await this.runPrompt(e.sessionId,e.prompt,e.claudeSessionId)}async runPrompt(e,t,o,s=!1){let r=ge(t);if(console.log(`[Receiver] RunPrompt for session ${e}${o?` (ClaudeSessionId: ${o})`:""}${s?" [DEBUG MODE]":""}: ${r.substring(0,50)}...`),(!this.currentSession||this.currentSession.sessionId!==e)&&(console.log(`[Receiver] Session mismatch: expected ${this.currentSession?.sessionId}, got ${e}, switching...`),await this.switchSession(e),!this.currentSession)){console.error("[Receiver] Failed to create session context");return}let i=this.claudeSessionIdMap.get(e);if(o&&i!==o){console.warn(`[Receiver] Claude session not found in container: ${o}`);let l=this.connection.getHubProxy();await l.reportSessionOutput(process.env.CONTAINER_ID||"unknown",e,{type:"System",event:"sessionNotFound",content:o,isError:!0}),await this.connection.reportStatus("Ready","Session lost - summary needed",e,this.currentSession.projectId),await l.sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}await this.connection.reportStatus("Active",void 0,e,this.currentSession.projectId),this.currentSession.debugMode=s,this.currentAbortController=new AbortController;let a=i||null,c=new Set;try{let l=await je(r,{model:this.currentSession.model,sessionId:a||null,projectId:this.currentSession.projectId||null,apiUrl:this.connection.getMasterUrl(),debugLog:!0,debugMode:s,abortController:this.currentAbortController,projectConfig:this.projectConfig,useDefaultStack:this.useDefaultStack,callbacks:zt(this.connection,e,{onClaudeSessionId:g=>{this.claudeSessionIdMap.set(e,g),this.persistSessionMap()},onFileModified:g=>{c.add(g)}})}),u=Xt(this.workspaceDir,e);if(u&&u.length>0){console.log(`[Receiver] ${u.length} pending questions found, waiting for user answers`),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}if(this.enableAutoTypecheck&&!l.error&&!l.aborted){let g=await Zt(this.serviceManager,c,this.workspaceDir,this.projectConfig);if(!g.passed&&g.errorPrompt){console.log("[Receiver] Type errors detected, auto-correcting..."),await this.runPrompt(e,g.errorPrompt,o);return}}this.enableAutoCommit&&!l.error&&!l.aborted?await bt(this.gitManager,this.connection,e,t,!1):(l.error||l.aborted)&&this.enableAutoCommit&&await bt(this.gitManager,this.connection,e,t,!0),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,l.error?1:0)}catch(l){let u=l instanceof Error&&l.name==="AbortError",d=l instanceof Error?l.message:"Unknown error";u?console.log(`[Receiver] Agent aborted for session ${e}`):(console.error("[Receiver] Agent error:",d),await this.connection.reportStatus("Error",d,e,this.currentSession.projectId)),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,u?0:1)}finally{this.currentAbortController=null}}async setModel(e){console.log(`[Receiver] Model changed to: ${e}`),this.currentSession&&(this.currentSession.model=e==="auto"?void 0:e)}async stopAgent(){console.log("[Receiver] Stop command received"),this.currentAbortController&&this.currentAbortController.abort()}async ping(){await this.connection.getConnection().invoke("Pong",process.env.CONTAINER_ID||"unknown")}async switchSession(e){console.log(`[Receiver] SwitchSession to ${e}`),this.currentSession?this.currentSession.sessionId=e:(console.log(`[Receiver] Creating new session context for ${e}`),this.currentSession={sessionId:e,projectId:process.env.PROJECT_ID||"unknown",branchName:"main",model:void 0,debugMode:!1})}async projectPromptUpdated(e){console.log(`[Receiver] ProjectPromptUpdated received (${e.length} chars)`),ze(e)}async fetchProjectPrompt(e){try{let t=this.connection.getMasterUrl(),o=this.connection.getProjectKey(),s=await fetch(`${t}/api/projects/${e}/prompt`,{method:"GET",headers:{"Content-Type":"application/json","X-Project-Key":o}});if(!s.ok){console.log(`[Receiver] Failed to fetch project prompt: ${s.status}`);return}let r=await s.json();r.prompt?(ze(r.prompt),console.log(`[Receiver] Initial project prompt loaded (${r.prompt.length} chars)`)):console.log(`[Receiver] No project prompt set for project ${e}`)}catch(t){console.error("[Receiver] Error fetching project prompt:",t)}}};process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT=process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT||"60000";var en=z.dirname($n(import.meta.url));function Hn(){let n=[z.resolve(en,"../package.json"),z.resolve(en,"../../../package.json")];for(let e of n)try{if(M.existsSync(e)){let t=JSON.parse(M.readFileSync(e,"utf-8"));if(t.name==="glenn-code")return t.version||"unknown"}}catch{}return"unknown"}function Bn(n){let{useDefaultStack:e,projectConfig:t,configSource:o,tunnelPort:s,enableAutoTypecheck:r,enableAutoCommit:i}=n;if(console.log(`
|
|
1373
1373
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`),console.log("\u2551 AGENT CONFIGURATION \u2551"),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),e?(console.log("\u2551 Mode: DEFAULT STACK (.NET/React) \u2551"),console.log("\u2551 Agents: scaffolding, backend, frontend, debugger, \u2551"),console.log("\u2551 planning, project-context \u2551")):(console.log("\u2551 Mode: CUSTOM STACK (generic agents only) \u2551"),console.log("\u2551 Agents: debugger, planning, project-context \u2551")),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log(`\u2551 Config source: ${o.padEnd(42)}\u2551`),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log("\u2551 SERVICES: \u2551"),t.services?.backend){let a=t.services.backend;console.log(`\u2551 Backend: port ${a.port}, extensions: ${a.extensions?.join(", ")||"N/A"}`.padEnd(62)+"\u2551")}else console.log("\u2551 Backend: not configured \u2551");if(t.services?.frontend){let a=t.services.frontend;console.log(`\u2551 Frontend: port ${a.port}, extensions: ${a.extensions?.join(", ")||"N/A"}`.padEnd(62)+"\u2551")}else console.log("\u2551 Frontend: not configured \u2551");t.techStack&&(console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log("\u2551 TECH STACK: \u2551"),t.techStack.backend?.length&&console.log(`\u2551 Backend: ${t.techStack.backend.join(", ")}`.padEnd(62)+"\u2551"),t.techStack.frontend?.length&&console.log(`\u2551 Frontend: ${t.techStack.frontend.join(", ")}`.padEnd(62)+"\u2551"),t.techStack.patterns?.length&&console.log(`\u2551 Patterns: ${t.techStack.patterns.join(", ")}`.padEnd(62)+"\u2551")),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log("\u2551 SETTINGS: \u2551"),console.log(`\u2551 Tunnel port: ${s}`.padEnd(62)+"\u2551"),console.log(`\u2551 Auto-typecheck: ${r?"enabled":"disabled"}`.padEnd(62)+"\u2551"),console.log(`\u2551 Auto-commit: ${i?"enabled":"disabled"}`.padEnd(62)+"\u2551"),console.log(`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1374
1374
|
`)}var qn=".sdd/local-signalr-config.json";function wt(n){return z.join(n,qn)}function Gn(n){try{let e=wt(n);if(!M.existsSync(e))return null;let t=M.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function St(n,e){let t=z.dirname(wt(n));M.existsSync(t)||M.mkdirSync(t,{recursive:!0}),M.writeFileSync(wt(n),JSON.stringify(e,null,2))}function qe(){return`local-${nn.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${Date.now().toString(36)}`}function Wn(n){return!!(n.version||n.paths||n.services||n.techStack)}function Kn(n,e){return Wn(n)?{version:n.version||"1.0",paths:n.paths||{workspace:e},services:n.services,techStack:n.techStack,tunnel:n.tunnel,scaffold:n.scaffold,git:n.git}:null}async function Yn(n){console.log(`
|
|
1375
1375
|
\u{1F527} Interactive Project Config Builder
|
package/dist/cli.js
CHANGED
|
@@ -1369,7 +1369,7 @@ ${d.join(`
|
|
|
1369
1369
|
|
|
1370
1370
|
`)}
|
|
1371
1371
|
|
|
1372
|
-
File paths like "src/..." are relative to the package directory shown in parentheses.`}):(console.log("[TypeCheck] \u2713 All type checks passed"),{passed:!0})}async function bt(n,e,t,o,s){if(!await n.hasChanges()){console.log("[Git] No changes to commit");return}console.log("[Git] Committing changes...");let i=await n.commitAndPush(o,s);if(i.noChanges)console.log("[Git] No changes to commit");else if(i.pushFailed){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.error(`[Git] \u274C Push failed: ${i.error}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"push_failed",content:`Committed locally but failed to push to ${a}. Your changes are NOT on GitHub. Error: ${i.error}`,isError:!0}).catch(l=>{console.error("[Git] Failed to report push failure:",l)})}else if(i.success){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.log(`[Git] \u2192 Pushed to ${a}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"committed",content:`Changes committed to ${a}`,isError:!1}).catch(l=>{console.error("[Git] Failed to report commit:",l)})}else console.error(`[Git] \u274C Git error: ${i.error}`)}import*as V from"fs";import*as Be from"path";var He=class{constructor(e,t,o,s,r=!0,i=!0,a,c,l=!0){this.connection=e;this.lifecycle=t;this.serviceManager=o;this.workspaceDir=s;this.enableAutoTypecheck=r;this.enableAutoCommit=i;this.setupPlanningTransport=a;this.projectConfig=c;this.useDefaultStack=l;this.gitManager=Ne(s),this.claudeSessionIdMap=this.loadSessionMap()}currentSession=null;claudeSessionIdMap=new Map;currentAbortController=null;gitManager;get sessionMapPath(){return Be.join(this.workspaceDir,".sdd","claude-session-map.json")}loadSessionMap(){try{if(V.existsSync(this.sessionMapPath)){let e=JSON.parse(V.readFileSync(this.sessionMapPath,"utf-8")),t=new Map(Object.entries(e));return console.log(`[Receiver] Loaded ${t.size} claude session mappings from disk`),t}}catch(e){console.warn("[Receiver] Failed to load session map from disk:",e)}return new Map}persistSessionMap(){try{let e=Be.dirname(this.sessionMapPath);V.existsSync(e)||V.mkdirSync(e,{recursive:!0});let t=Object.fromEntries(this.claudeSessionIdMap);V.writeFileSync(this.sessionMapPath,JSON.stringify(t,null,2))}catch(e){console.warn("[Receiver] Failed to persist session map to disk:",e)}}async initSession(e){console.log(`[Receiver] InitSession for session ${e.sessionId}`),this.setupPlanningTransport&&e.projectId&&this.setupPlanningTransport(e.projectId),e.projectId&&await this.fetchProjectPrompt(e.projectId),this.currentSession={sessionId:e.sessionId,projectId:e.projectId,branchName:e.branchName,model:e.model==="auto"?void 0:e.model||"claude-haiku-4-5-20251001",debugMode:e.debugMode},await this.lifecycle.handleInitSession(e),e.prompt&&await this.runPrompt(e.sessionId,e.prompt,e.claudeSessionId)}async runPrompt(e,t,o,s=!1){let r=ge(t);if(console.log(`[Receiver] RunPrompt for session ${e}${o?` (ClaudeSessionId: ${o})`:""}${s?" [DEBUG MODE]":""}: ${r.substring(0,50)}...`),(!this.currentSession||this.currentSession.sessionId!==e)&&(console.log(`[Receiver] Session mismatch: expected ${this.currentSession?.sessionId}, got ${e}, switching...`),await this.switchSession(e),!this.currentSession)){console.error("[Receiver] Failed to create session context");return}let i=this.claudeSessionIdMap.get(e);if(o&&i!==o){console.warn(`[Receiver] Claude session not found in container: ${o}`);let l=this.connection.getHubProxy();await l.reportSessionOutput(process.env.CONTAINER_ID||"unknown",e,{type:"System",event:"sessionNotFound",content:o,isError:!0}),await this.connection.reportStatus("Ready","Session lost - summary needed",e,this.currentSession.projectId),await l.sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}await this.connection.reportStatus("Active",void 0,e,this.currentSession.projectId),this.currentSession.debugMode=s,this.currentAbortController=new AbortController;let a=i||null,c=new Set;try{let l=await je(r,{model:this.currentSession.model,sessionId:a||null,projectId:this.currentSession.projectId||null,apiUrl:this.connection.getMasterUrl(),debugLog:!0,debugMode:s,abortController:this.currentAbortController,projectConfig:this.projectConfig,useDefaultStack:this.useDefaultStack,callbacks:zt(this.connection,e,{onClaudeSessionId:g=>{this.claudeSessionIdMap.set(e,g),this.persistSessionMap()},onFileModified:g=>{c.add(g)}})}),u=Xt(this.workspaceDir,e);if(u&&u.length>0){console.log(`[Receiver] ${u.length} pending questions found, waiting for user answers`),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}if(this.enableAutoTypecheck&&!l.error&&!l.aborted){let g=await Zt(this.serviceManager,c,this.workspaceDir,this.projectConfig);if(!g.passed&&g.errorPrompt){console.log("[Receiver] Type errors detected, auto-correcting..."),await this.runPrompt(e,g.errorPrompt,o);return}}this.enableAutoCommit&&!l.error&&!l.aborted?await bt(this.gitManager,this.connection,e,t,!1):(l.error||l.aborted)&&this.enableAutoCommit&&await bt(this.gitManager,this.connection,e,t,!0),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,l.error?1:0)}catch(l){let u=l instanceof Error&&l.name==="AbortError",d=l instanceof Error?l.message:"Unknown error";u?console.log(`[Receiver] Agent aborted for session ${e}`):(console.error("[Receiver] Agent error:",d),await this.connection.reportStatus("Error",d,e,this.currentSession.projectId)),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,u?0:1)}finally{this.currentAbortController=null}}async setModel(e){console.log(`[Receiver] Model changed to: ${e}`),this.currentSession&&(this.currentSession.model=e==="auto"?void 0:e)}async stopAgent(){console.log("[Receiver] Stop command received"),this.currentAbortController&&this.currentAbortController.abort()}async ping(){await this.connection.getConnection().invoke("Pong",process.env.CONTAINER_ID||"unknown")}async switchSession(e){console.log(`[Receiver] SwitchSession to ${e}`),this.currentSession?this.currentSession.sessionId=e:(console.log(`[Receiver] Creating new session context for ${e}`),this.currentSession={sessionId:e,projectId:process.env.PROJECT_ID||"unknown",branchName:"main",model:void 0,debugMode:!1})}async projectPromptUpdated(e){console.log(`[Receiver] ProjectPromptUpdated received (${e.length} chars)`),ze(e)}async fetchProjectPrompt(e){try{let t=this.connection.getMasterUrl(),o=this.connection.getProjectKey(),s=await fetch(`${t}/api/projects/${e}/prompt`,{method:"GET",headers:{"Content-Type":"application/json","X-Project-Key":o}});if(!s.ok){console.log(`[Receiver] Failed to fetch project prompt: ${s.status}`);return}let r=await s.json();r.prompt?(ze(r.prompt),console.log(`[Receiver] Initial project prompt loaded (${r.prompt.length} chars)`)):console.log(`[Receiver] No project prompt set for project ${e}`)}catch(t){console.error("[Receiver] Error fetching project prompt:",t)}}};process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT=process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT||"60000";var en=z.dirname($n(import.meta.url));function Hn(){let n=[z.resolve(en,"../package.json"),z.resolve(en,"../../../package.json")];for(let e of n)try{if(M.existsSync(e)){let t=JSON.parse(M.readFileSync(e,"utf-8"));if(t.name==="glenn-code")return t.version||"unknown"}}catch{}return"unknown"}function Bn(n){let{useDefaultStack:e,projectConfig:t,configSource:o,tunnelPort:s,enableAutoTypecheck:r,enableAutoCommit:i}=n;if(console.log(`
|
|
1372
|
+
File paths like "src/..." are relative to the package directory shown in parentheses.`}):(console.log("[TypeCheck] \u2713 All type checks passed"),{passed:!0})}async function bt(n,e,t,o,s){if(!await n.hasChanges()){console.log("[Git] No changes to commit");return}console.log("[Git] Committing changes...");let i=await n.commitAndPush(o,s);if(i.noChanges)console.log("[Git] No changes to commit");else if(i.pushFailed){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.error(`[Git] \u274C Push failed: ${i.error}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"push_failed",content:`Committed locally but failed to push to ${a}. Your changes are NOT on GitHub. Error: ${i.error}`,isError:!0}).catch(l=>{console.error("[Git] Failed to report push failure:",l)})}else if(i.success){let a=await n.getCurrentBranch();console.log(`[Git] \u2713 Committed ${i.commitHash||""}`),console.log(`[Git] \u2192 Pushed to ${a}`),await e.getHubProxy().reportSessionOutput(process.env.CONTAINER_ID||"unknown",t,{type:"System",event:"committed",content:`Changes committed to ${a}`,isError:!1}).catch(l=>{console.error("[Git] Failed to report commit:",l)})}else console.error(`[Git] \u274C Git error: ${i.error}`)}import*as V from"fs";import*as Be from"path";var He=class{constructor(e,t,o,s,r=!0,i=!0,a,c,l=!0){this.connection=e;this.lifecycle=t;this.serviceManager=o;this.workspaceDir=s;this.enableAutoTypecheck=r;this.enableAutoCommit=i;this.setupPlanningTransport=a;this.projectConfig=c;this.useDefaultStack=l;this.gitManager=Ne(s),this.claudeSessionIdMap=this.loadSessionMap()}currentSession=null;claudeSessionIdMap=new Map;currentAbortController=null;gitManager;get sessionMapPath(){return Be.join(this.workspaceDir,".sdd","claude-session-map.json")}loadSessionMap(){try{if(V.existsSync(this.sessionMapPath)){let e=JSON.parse(V.readFileSync(this.sessionMapPath,"utf-8")),t=new Map(Object.entries(e));return console.log(`[Receiver] Loaded ${t.size} claude session mappings from disk`),t}else return console.log("[Receiver] No session map found on disk"),new Map}catch(e){console.warn("[Receiver] Failed to load session map from disk:",e)}return new Map}persistSessionMap(){try{let e=Be.dirname(this.sessionMapPath);V.existsSync(e)||V.mkdirSync(e,{recursive:!0});let t=Object.fromEntries(this.claudeSessionIdMap);V.writeFileSync(this.sessionMapPath,JSON.stringify(t,null,2))}catch(e){console.warn("[Receiver] Failed to persist session map to disk:",e)}}async initSession(e){console.log(`[Receiver] InitSession for session ${e.sessionId}`),this.setupPlanningTransport&&e.projectId&&this.setupPlanningTransport(e.projectId),e.projectId&&await this.fetchProjectPrompt(e.projectId),this.currentSession={sessionId:e.sessionId,projectId:e.projectId,branchName:e.branchName,model:e.model==="auto"?void 0:e.model||"claude-haiku-4-5-20251001",debugMode:e.debugMode},await this.lifecycle.handleInitSession(e),e.prompt&&await this.runPrompt(e.sessionId,e.prompt,e.claudeSessionId)}async runPrompt(e,t,o,s=!1){let r=ge(t);if(console.log(`[Receiver] RunPrompt for session ${e}${o?` (ClaudeSessionId: ${o})`:""}${s?" [DEBUG MODE]":""}: ${r.substring(0,50)}...`),(!this.currentSession||this.currentSession.sessionId!==e)&&(console.log(`[Receiver] Session mismatch: expected ${this.currentSession?.sessionId}, got ${e}, switching...`),await this.switchSession(e),!this.currentSession)){console.error("[Receiver] Failed to create session context");return}let i=this.claudeSessionIdMap.get(e);if(o&&i!==o){console.warn(`[Receiver] Claude session not found in container: ${o}`);let l=this.connection.getHubProxy();await l.reportSessionOutput(process.env.CONTAINER_ID||"unknown",e,{type:"System",event:"sessionNotFound",content:o,isError:!0}),await this.connection.reportStatus("Ready","Session lost - summary needed",e,this.currentSession.projectId),await l.sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}await this.connection.reportStatus("Active",void 0,e,this.currentSession.projectId),this.currentSession.debugMode=s,this.currentAbortController=new AbortController;let a=i||null,c=new Set;try{let l=await je(r,{model:this.currentSession.model,sessionId:a||null,projectId:this.currentSession.projectId||null,apiUrl:this.connection.getMasterUrl(),debugLog:!0,debugMode:s,abortController:this.currentAbortController,projectConfig:this.projectConfig,useDefaultStack:this.useDefaultStack,callbacks:zt(this.connection,e,{onClaudeSessionId:g=>{this.claudeSessionIdMap.set(e,g),this.persistSessionMap()},onFileModified:g=>{c.add(g)}})}),u=Xt(this.workspaceDir,e);if(u&&u.length>0){console.log(`[Receiver] ${u.length} pending questions found, waiting for user answers`),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,0);return}if(this.enableAutoTypecheck&&!l.error&&!l.aborted){let g=await Zt(this.serviceManager,c,this.workspaceDir,this.projectConfig);if(!g.passed&&g.errorPrompt){console.log("[Receiver] Type errors detected, auto-correcting..."),await this.runPrompt(e,g.errorPrompt,o);return}}this.enableAutoCommit&&!l.error&&!l.aborted?await bt(this.gitManager,this.connection,e,t,!1):(l.error||l.aborted)&&this.enableAutoCommit&&await bt(this.gitManager,this.connection,e,t,!0),await this.connection.reportStatus("Ready",void 0,e,this.currentSession.projectId),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,l.error?1:0)}catch(l){let u=l instanceof Error&&l.name==="AbortError",d=l instanceof Error?l.message:"Unknown error";u?console.log(`[Receiver] Agent aborted for session ${e}`):(console.error("[Receiver] Agent error:",d),await this.connection.reportStatus("Error",d,e,this.currentSession.projectId)),await this.connection.getHubProxy().sessionCompleted(process.env.CONTAINER_ID||"unknown",e,u?0:1)}finally{this.currentAbortController=null}}async setModel(e){console.log(`[Receiver] Model changed to: ${e}`),this.currentSession&&(this.currentSession.model=e==="auto"?void 0:e)}async stopAgent(){console.log("[Receiver] Stop command received"),this.currentAbortController&&this.currentAbortController.abort()}async ping(){await this.connection.getConnection().invoke("Pong",process.env.CONTAINER_ID||"unknown")}async switchSession(e){console.log(`[Receiver] SwitchSession to ${e}`),this.currentSession?this.currentSession.sessionId=e:(console.log(`[Receiver] Creating new session context for ${e}`),this.currentSession={sessionId:e,projectId:process.env.PROJECT_ID||"unknown",branchName:"main",model:void 0,debugMode:!1})}async projectPromptUpdated(e){console.log(`[Receiver] ProjectPromptUpdated received (${e.length} chars)`),ze(e)}async fetchProjectPrompt(e){try{let t=this.connection.getMasterUrl(),o=this.connection.getProjectKey(),s=await fetch(`${t}/api/projects/${e}/prompt`,{method:"GET",headers:{"Content-Type":"application/json","X-Project-Key":o}});if(!s.ok){console.log(`[Receiver] Failed to fetch project prompt: ${s.status}`);return}let r=await s.json();r.prompt?(ze(r.prompt),console.log(`[Receiver] Initial project prompt loaded (${r.prompt.length} chars)`)):console.log(`[Receiver] No project prompt set for project ${e}`)}catch(t){console.error("[Receiver] Error fetching project prompt:",t)}}};process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT=process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT||"60000";var en=z.dirname($n(import.meta.url));function Hn(){let n=[z.resolve(en,"../package.json"),z.resolve(en,"../../../package.json")];for(let e of n)try{if(M.existsSync(e)){let t=JSON.parse(M.readFileSync(e,"utf-8"));if(t.name==="glenn-code")return t.version||"unknown"}}catch{}return"unknown"}function Bn(n){let{useDefaultStack:e,projectConfig:t,configSource:o,tunnelPort:s,enableAutoTypecheck:r,enableAutoCommit:i}=n;if(console.log(`
|
|
1373
1373
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`),console.log("\u2551 AGENT CONFIGURATION \u2551"),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),e?(console.log("\u2551 Mode: DEFAULT STACK (.NET/React) \u2551"),console.log("\u2551 Agents: scaffolding, backend, frontend, debugger, \u2551"),console.log("\u2551 planning, project-context \u2551")):(console.log("\u2551 Mode: CUSTOM STACK (generic agents only) \u2551"),console.log("\u2551 Agents: debugger, planning, project-context \u2551")),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log(`\u2551 Config source: ${o.padEnd(42)}\u2551`),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log("\u2551 SERVICES: \u2551"),t.services?.backend){let a=t.services.backend;console.log(`\u2551 Backend: port ${a.port}, extensions: ${a.extensions?.join(", ")||"N/A"}`.padEnd(62)+"\u2551")}else console.log("\u2551 Backend: not configured \u2551");if(t.services?.frontend){let a=t.services.frontend;console.log(`\u2551 Frontend: port ${a.port}, extensions: ${a.extensions?.join(", ")||"N/A"}`.padEnd(62)+"\u2551")}else console.log("\u2551 Frontend: not configured \u2551");t.techStack&&(console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log("\u2551 TECH STACK: \u2551"),t.techStack.backend?.length&&console.log(`\u2551 Backend: ${t.techStack.backend.join(", ")}`.padEnd(62)+"\u2551"),t.techStack.frontend?.length&&console.log(`\u2551 Frontend: ${t.techStack.frontend.join(", ")}`.padEnd(62)+"\u2551"),t.techStack.patterns?.length&&console.log(`\u2551 Patterns: ${t.techStack.patterns.join(", ")}`.padEnd(62)+"\u2551")),console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"),console.log("\u2551 SETTINGS: \u2551"),console.log(`\u2551 Tunnel port: ${s}`.padEnd(62)+"\u2551"),console.log(`\u2551 Auto-typecheck: ${r?"enabled":"disabled"}`.padEnd(62)+"\u2551"),console.log(`\u2551 Auto-commit: ${i?"enabled":"disabled"}`.padEnd(62)+"\u2551"),console.log(`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1374
1374
|
`)}var qn=".sdd/local-signalr-config.json";function wt(n){return z.join(n,qn)}function Gn(n){try{let e=wt(n);if(!M.existsSync(e))return null;let t=M.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function St(n,e){let t=z.dirname(wt(n));M.existsSync(t)||M.mkdirSync(t,{recursive:!0}),M.writeFileSync(wt(n),JSON.stringify(e,null,2))}function qe(){return`local-${nn.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${Date.now().toString(36)}`}function Wn(n){return!!(n.version||n.paths||n.services||n.techStack)}function Kn(n,e){return Wn(n)?{version:n.version||"1.0",paths:n.paths||{workspace:e},services:n.services,techStack:n.techStack,tunnel:n.tunnel,scaffold:n.scaffold,git:n.git}:null}async function Yn(n){console.log(`
|
|
1375
1375
|
\u{1F527} Interactive Project Config Builder
|