glenn-code 1.0.33 → 1.0.35
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 +69 -69
- package/dist/cli.js +69 -69
- package/dist/core.js +33 -33
- package/dist/index.js +49 -49
- package/package.json +3 -3
package/dist/core.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Glenn Code - Bundled and minified
|
|
2
2
|
// (c) DNM Lab - All rights reserved
|
|
3
3
|
|
|
4
|
-
import{createSdkMcpServer as pt}from"@anthropic-ai/claude-agent-sdk";import{tool as
|
|
4
|
+
import{createSdkMcpServer as pt}from"@anthropic-ai/claude-agent-sdk";import{tool as ie}from"@anthropic-ai/claude-agent-sdk";import{z as ae}from"zod";import*as ce from"fs";import*as Oe from"path";var O=null;function De(e){O=e}function _e(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}var It=ie("save_specification",`Save a specification to the database.
|
|
5
5
|
|
|
6
6
|
IMPORTANT: First write the specification content to a file using the Write tool, then call this with the file path.
|
|
7
7
|
|
|
@@ -12,17 +12,17 @@ Workflow:
|
|
|
12
12
|
|
|
13
13
|
Example:
|
|
14
14
|
1. Write tool \u2192 save to /tmp/user-auth-spec.md
|
|
15
|
-
2. save_specification(name: "User Authentication", filePath: "/tmp/user-auth-spec.md")`,{name:
|
|
15
|
+
2. save_specification(name: "User Authentication", filePath: "/tmp/user-auth-spec.md")`,{name:ae.string().describe("Specification name (e.g., 'User Authentication')"),filePath:ae.string().describe("Path to the file containing the specification content (written via Write tool)")},async e=>{if(!O)return{content:[{type:"text",text:"\u274C Planning transport not initialized"}]};let t=Oe.resolve(e.filePath);if(!ce.existsSync(t))return{content:[{type:"text",text:`\u274C File not found: ${e.filePath}. Use Write tool first to create the file.`}]};let n=ce.readFileSync(t,"utf-8"),a=_e(e.name);return await O.saveSpecification(a,n),{content:[{type:"text",text:`\u2705 Saved specification: ${a}.spec.md`}]}}),Ot=ie("read_specification","Read the content of a specification.",{name:ae.string().describe("Name of the specification to read")},async e=>{if(!O)return{content:[{type:"text",text:"\u274C Planning transport not initialized"}]};let t=_e(e.name),n=await O.getSpecification(t);return n?{content:[{type:"text",text:n}]}:{content:[{type:"text",text:`\u274C Specification "${e.name}" not found.`}]}}),Dt=ie("list_specifications","List all specifications.",{},async()=>{if(!O)return{content:[{type:"text",text:"\u274C Planning transport not initialized"}]};let e=await O.listSpecifications();return e.length===0?{content:[{type:"text",text:"\u{1F4CB} No specifications found."}]}:{content:[{type:"text",text:`\u{1F4CB} Specifications:
|
|
16
16
|
|
|
17
17
|
${e.map(n=>`- ${n.name} (${n.slug}.spec.md)`).join(`
|
|
18
|
-
`)}`}]}}),Ft=
|
|
18
|
+
`)}`}]}}),Ft=ie("delete_specification","Delete a specification.",{name:ae.string().describe("Name of the specification to delete")},async e=>{if(!O)return{content:[{type:"text",text:"\u274C Planning transport not initialized"}]};let t=_e(e.name);return await O.deleteSpecification(t)?{content:[{type:"text",text:`\u{1F5D1}\uFE0F Deleted: ${t}.spec.md`}]}:{content:[{type:"text",text:`\u274C Specification "${e.name}" not found.`}]}});import{tool as j}from"@anthropic-ai/claude-agent-sdk";import{z as V}from"zod";var y=null;function Fe(e){y=e}var Ue=j("restart_services",`Rebuild and restart services. Call this after making backend changes (.cs files) to apply them.
|
|
19
19
|
|
|
20
20
|
Parameters:
|
|
21
21
|
- target: "backend" (default) | "frontend" | "both"
|
|
22
22
|
|
|
23
23
|
Use target="backend" after .cs file changes (faster, only restarts .NET).
|
|
24
24
|
Use target="frontend" if Vite is stuck (rare, HMR usually works).
|
|
25
|
-
Use target="both" if unsure or both need restart.`,{target:
|
|
25
|
+
Use target="both" if unsure or both need restart.`,{target:V.enum(["backend","frontend","both"]).default("backend").describe("Which service to restart")},async e=>{if(!y)return{content:[{type:"text",text:"\u274C Service manager not initialized"}]};let t=e.target||"backend";console.log(`[MCP] restart_services called (target: ${t})`);let n=await y.restartServices(t);if(!n.success){let s=[];return n.backendError&&s.push(`Backend: ${n.backendError}`),n.frontendError&&s.push(`Frontend: ${n.frontendError}`),{content:[{type:"text",text:`\u274C Restart failed:
|
|
26
26
|
${s.join(`
|
|
27
27
|
|
|
28
28
|
`)}`}]}}return{content:[{type:"text",text:`\u2705 ${t==="both"?"Backend and frontend":t==="backend"?"Backend":"Frontend"} restarted successfully.`}]}}),Ne=j("stop_services",`Stop running services. Call this BEFORE running scaffold to prevent port conflicts and ensure clean migrations.
|
|
@@ -30,12 +30,12 @@ ${s.join(`
|
|
|
30
30
|
Parameters:
|
|
31
31
|
- target: "backend" (default) | "frontend" | "both"
|
|
32
32
|
|
|
33
|
-
Use target="backend" before running scaffold (required for migrations).`,{target:
|
|
33
|
+
Use target="backend" before running scaffold (required for migrations).`,{target:V.enum(["backend","frontend","both"]).default("backend").describe("Which service to stop")},async e=>{if(!y)return{content:[{type:"text",text:"\u274C Service manager not initialized"}]};let t=e.target||"backend";console.log(`[MCP] stop_services called (target: ${t})`);let n=t==="backend"||t==="both",a=t==="frontend"||t==="both";n&&await y.stopBackend(),a&&await y.stopFrontend();let s=5e3,o=Date.now(),r=!n,f=!a;for(;Date.now()-o<s;){let u=await y.checkHealth();if(n&&!u.api&&(r=!0),a&&!u.web&&(f=!0),r&&f)break;await new Promise(T=>setTimeout(T,500))}let _=t==="both"?"Backend and frontend":t==="backend"?"Backend":"Frontend";return{content:[{type:"text",text:r&&f?`\u2705 ${_} stopped successfully.`:`\u26A0\uFE0F ${_} stop requested but health check still shows running. Proceeding anyway.`}]}}),Le=j("start_services",`Start services. Call this AFTER running scaffold to bring services back up.
|
|
34
34
|
|
|
35
35
|
Parameters:
|
|
36
36
|
- target: "backend" (default) | "frontend" | "both"
|
|
37
37
|
|
|
38
|
-
Use target="backend" after running scaffold.`,{target:
|
|
38
|
+
Use target="backend" after running scaffold.`,{target:V.enum(["backend","frontend","both"]).default("backend").describe("Which service to start")},async e=>{if(!y)return{content:[{type:"text",text:"\u274C Service manager not initialized"}]};let t=e.target||"backend";console.log(`[MCP] start_services called (target: ${t})`);let n=t==="backend"||t==="both",a=t==="frontend"||t==="both";n&&await y.startBackend(),a&&await y.startFrontend();let s=await y.waitForHealth(15e3),o=!n||s.api,r=!a||s.web,f=o&&r,_=t==="both"?"Backend and frontend":t==="backend"?"Backend":"Frontend";if(!f){let g=[];return n&&!s.api&&g.push("Backend failed to start"),a&&!s.web&&g.push("Frontend failed to start"),{content:[{type:"text",text:`\u274C ${_} failed to start: ${g.join(", ")}`}]}}return{content:[{type:"text",text:`\u2705 ${_} started successfully.`}]}}),je=j("check_service_health",`Check if services are running and healthy. Returns current status of backend API and frontend.
|
|
39
39
|
Note: This only checks if ports are responding, NOT build/type errors. Use check_backend_build or check_frontend_types for that.`,{},async()=>{if(!y)return{content:[{type:"text",text:"\u274C Service manager not initialized"}]};let e=await y.checkHealth();return{content:[{type:"text",text:`Service Health:
|
|
40
40
|
\u{1F5A5}\uFE0F Backend API: ${e.api?"\u2705 running":"\u274C not running"}
|
|
41
41
|
\u{1F310} Frontend: ${e.web?"\u2705 running":"\u274C not running"}`}]}}),Me=j("check_backend_build","Run dotnet build to check for C# compilation errors. Use this after fixing backend code to verify the fix works.",{},async()=>{if(!y)return{content:[{type:"text",text:"\u274C Service manager not initialized"}]};console.log("[MCP] check_backend_build called");let e=await y.checkBackendBuild();return e.success?{content:[{type:"text",text:"\u2705 Backend build succeeded - no errors"}]}:{content:[{type:"text",text:`\u274C Backend build failed:
|
|
@@ -46,18 +46,18 @@ ${e.errors}`}]}}),jt=j("tail_service_log",`Get the last N lines of service logs.
|
|
|
46
46
|
|
|
47
47
|
Parameters:
|
|
48
48
|
- target: "backend" | "frontend"
|
|
49
|
-
- lines: number (default 50)`,{target:
|
|
49
|
+
- lines: number (default 50)`,{target:V.enum(["backend","frontend"]).describe("Which log to read"),lines:V.number().default(50).describe("Number of lines to read")},async e=>{if(!y)return{content:[{type:"text",text:"\u274C Service manager not initialized"}]};let t=await y.tailLogs(e.target,e.lines);return{content:[{type:"text",text:`Last ${e.lines} lines of ${e.target} log:
|
|
50
50
|
|
|
51
51
|
${t.join(`
|
|
52
52
|
`)}`}]}}),Mt=j("check_swagger_endpoints",`Search for endpoints in the generated swagger.json. Use this to verify that new backend endpoints are correctly exposed.
|
|
53
53
|
|
|
54
54
|
Parameters:
|
|
55
|
-
- pattern: string (e.g., "users", "api/reports")`,{pattern:
|
|
55
|
+
- pattern: string (e.g., "users", "api/reports")`,{pattern:V.string().describe("Text to search for in endpoint paths")},async e=>{if(!y)return{content:[{type:"text",text:"\u274C Service manager not initialized"}]};let t=await y.checkSwaggerEndpoints(e.pattern);return t.foundEndpoints.length===0?{content:[{type:"text",text:`\u274C No endpoints found matching "${e.pattern}" (Total endpoints: ${t.totalEndpoints})`}]}:{content:[{type:"text",text:`\u2705 Found ${t.foundEndpoints.length} matching endpoints:
|
|
56
56
|
|
|
57
57
|
${t.foundEndpoints.join(`
|
|
58
|
-
`)}`}]}});import*as P from"fs";import*as
|
|
59
|
-
`,"utf-8")},async reportProgress(n,a,s){let o=
|
|
60
|
-
`,"utf-8")}}}function
|
|
58
|
+
`)}`}]}});import*as P from"fs";import*as J from"path";var qe="/tmp";function ke(e){let t=e?J.join(e,".sdd","insights"):J.join(process.cwd(),".sdd","insights");return{async reportInsight(n,a){P.mkdirSync(t,{recursive:!0});let s=a.type==="learning"?"learnings.jsonl":"bugs.jsonl",o=J.join(t,s);P.appendFileSync(o,JSON.stringify(a)+`
|
|
59
|
+
`,"utf-8")},async reportProgress(n,a,s){let o=J.join(qe,`agent-progress-${n}.json`),r={timestamp:new Date().toISOString(),event:a,data:s};P.appendFileSync(o,JSON.stringify(r)+`
|
|
60
|
+
`,"utf-8")}}}function we(e){let t=J.join(qe,`agent-questions-${e}.json`);if(!P.existsSync(t))return null;try{let n=P.readFileSync(t,"utf-8");return P.unlinkSync(t),JSON.parse(n)}catch{return null}}import*as S from"fs";import*as le from"path";function Se(e){let t=le.join(e,".sdd","specifications");function n(){S.existsSync(t)||S.mkdirSync(t,{recursive:!0})}function a(s){return le.join(t,`${s}.spec.md`)}return{async saveSpecification(s,o){n(),S.writeFileSync(a(s),o,"utf-8")},async getSpecification(s){n();let o=a(s);return S.existsSync(o)?S.readFileSync(o,"utf-8"):null},async listSpecifications(){return n(),S.readdirSync(t).filter(o=>o.endsWith(".spec.md")).map(o=>{let r=S.readFileSync(le.join(t,o),"utf-8"),f=r.match(/name: "([^"]+)"/),_=r.match(/status: (\w+)/),g=r.match(/version: "([^"]+)"/);return{slug:o.replace(".spec.md",""),name:f?.[1]||o,status:_?.[1]||"unknown",version:g?.[1]||"1.0.0"}})},async deleteSpecification(s){n();let o=a(s);return S.existsSync(o)?(S.unlinkSync(o),!0):!1},async specificationExists(s){return n(),S.existsSync(a(s))}}}function ve(){return pt({name:"agent-insights",version:"1.0.0",tools:[Ue,Ne,Le,je,Me,Be]})}import{query as Tt}from"@anthropic-ai/claude-agent-sdk";var Te={description:"Delegate to this agent when scaffolding new entities or creating CRUD features. This agent handles entity generation using the scaffold CLI with multi-entity support.",model:"inherit",prompt:`You are a scaffolding specialist. Your ONLY job is:
|
|
61
61
|
1. Read the spec if referenced in the card description
|
|
62
62
|
2. Check existing features (quick ls)
|
|
63
63
|
3. Write ALL entities to ONE /tmp/scaffold.json (big bang, no phasing!)
|
|
@@ -264,7 +264,7 @@ DO NOT phase/split into multiple runs - that's slower and error-prone.
|
|
|
264
264
|
- Enrollment depends on Student + CourseOffering - CLI handles it
|
|
265
265
|
- ONE scaffold run creates ALL 6 entities with correct FK relationships
|
|
266
266
|
|
|
267
|
-
REMEMBER: Read spec (if referenced) \u2192 ls \u2192 Write \u2192 Run \u2192 Restart \u2192 STOP. No verification needed.`};var
|
|
267
|
+
REMEMBER: Read spec (if referenced) \u2192 ls \u2192 Write \u2192 Run \u2192 Restart \u2192 STOP. No verification needed.`};var de={description:"Delegate to this agent to fix errors, type issues, or bugs in the code",model:"inherit",prompt:`You are a bug-fixing specialist. Your job is to FIX errors, not just report them.
|
|
268
268
|
|
|
269
269
|
## Process
|
|
270
270
|
1. Read the error message carefully - understand WHAT and WHERE
|
|
@@ -294,7 +294,7 @@ REMEMBER: Read spec (if referenced) \u2192 ls \u2192 Write \u2192 Run \u2192 Res
|
|
|
294
294
|
- Fix the ROOT CAUSE, not symptoms
|
|
295
295
|
- Make minimal changes
|
|
296
296
|
- Don't add unnecessary code
|
|
297
|
-
- If multiple files have the same issue, fix all of them`};var
|
|
297
|
+
- If multiple files have the same issue, fix all of them`};var pe={description:"Delegate to this agent for specification-driven development. Use when the user wants to plan, specify, or design a feature before implementation.",model:"inherit",prompt:`You are a Product Discovery & Specification specialist.
|
|
298
298
|
|
|
299
299
|
You think like a product person, not a developer. You create specifications that describe WHAT to build and WHY \u2014 using scenarios, user stories, and clear scope. Technical implementation details belong in Kanban cards, not in the spec.
|
|
300
300
|
|
|
@@ -458,7 +458,7 @@ Save your spec. The spec will appear in the user's UI.
|
|
|
458
458
|
- Maximum 7 questions - don't exhaust the user!
|
|
459
459
|
- Write like a PRODUCT PERSON, not an engineer
|
|
460
460
|
- Scenarios should make the reader SEE the product
|
|
461
|
-
- Technical details belong in Kanban cards, not here`};var
|
|
461
|
+
- Technical details belong in Kanban cards, not here`};var Ee={description:"Delegate to this agent for writing new backend features (non-scaffold). Custom endpoints, queries, commands, business logic.",model:"inherit",prompt:`You are a backend specialist for .NET 9 / ASP.NET Core.
|
|
462
462
|
|
|
463
463
|
## YOUR ROLE
|
|
464
464
|
Write custom backend code that goes BEYOND what scaffold generates:
|
|
@@ -550,7 +550,7 @@ public class Get{EntityB}LookupHandler : IQueryHandler<Get{EntityB}LookupQuery,
|
|
|
550
550
|
2. If build succeeds, generate swagger: \`mcp__agent-insights__restart_services\` (this regenerates swagger)
|
|
551
551
|
3. Report what you created and STOP
|
|
552
552
|
|
|
553
|
-
**\u26A0\uFE0F CRITICAL:** Always generate swagger before frontend work begins!`};var
|
|
553
|
+
**\u26A0\uFE0F CRITICAL:** Always generate swagger before frontend work begins!`};var Ce={description:"Delegate to this agent for writing frontend features. Components, hooks, pages using generated API hooks.",model:"inherit",prompt:`You are a frontend specialist for React 19 + TypeScript + MUI.
|
|
554
554
|
|
|
555
555
|
## YOUR ROLE
|
|
556
556
|
Write frontend code using GENERATED API hooks (never manual fetch):
|
|
@@ -643,7 +643,7 @@ queryClient.invalidateQueries({ queryKey: getGetApi{Entities}QueryKey() })
|
|
|
643
643
|
## WHEN DONE
|
|
644
644
|
1. Run typecheck: \`cd /workspace/packages/backoffice-web && npx tsc --noEmit\`
|
|
645
645
|
2. If errors, fix them
|
|
646
|
-
3. Report what you created and STOP`};var
|
|
646
|
+
3. Report what you created and STOP`};var ue={description:"Delegate to this agent to help the user write or improve their project context. This agent researches the codebase, asks strategic questions about product goals and users, then writes comprehensive project context.",model:"inherit",prompt:`You are a Project Context Specialist - an expert at understanding codebases and extracting the essential context that helps AI agents work effectively on projects.
|
|
647
647
|
|
|
648
648
|
## \u26D4 CRITICAL RULES - READ FIRST
|
|
649
649
|
|
|
@@ -837,11 +837,11 @@ Before saving, verify your context:
|
|
|
837
837
|
3. **Show patterns** - Include small code examples for common tasks
|
|
838
838
|
4. **Prioritize** - Put most critical info in <critical_rules>
|
|
839
839
|
5. **Keep it scannable** - Use bullets, clear sections
|
|
840
|
-
6. **Update, don't replace** - If context exists, improve it rather than starting fresh`};import*as
|
|
840
|
+
6. **Update, don't replace** - If context exists, improve it rather than starting fresh`};import*as X from"fs";import*as We from"path";var ge=class{buffer=[];flushInterval=null;sessionId=null;outputDir;flushIntervalMs;constructor(t){this.outputDir=t.outputDir||"/tmp/agent-debug",this.flushIntervalMs=t.flushIntervalMs||3e3,t.enabled&&(this.ensureOutputDir(),this.startFlushInterval())}ensureOutputDir(){X.existsSync(this.outputDir)||X.mkdirSync(this.outputDir,{recursive:!0})}startFlushInterval(){this.flushInterval=setInterval(()=>{this.flush()},this.flushIntervalMs)}setSessionId(t){this.sessionId=t}log(t){let a={timestamp:new Date().toISOString(),message:t};this.buffer.push(JSON.stringify(a,null,2)+`
|
|
841
841
|
---
|
|
842
|
-
`)}getLogFilePath(){let n=(this.sessionId||"unknown").replace(/[^a-zA-Z0-9-]/g,"_").slice(0,50),a=new Date().toISOString().split("T")[0];return
|
|
843
|
-
`)}function Je(e){let t=[];return e.paths.backend&&t.push(`- Backend: ${F(e)}`),e.paths.frontend&&t.push(`- Frontend: ${U(e)}`),e.paths.features?.backend&&t.push(`- Backend Features: ${
|
|
844
|
-
`)}function
|
|
842
|
+
`)}getLogFilePath(){let n=(this.sessionId||"unknown").replace(/[^a-zA-Z0-9-]/g,"_").slice(0,50),a=new Date().toISOString().split("T")[0];return We.join(this.outputDir,`session-${a}-${n}.log`)}flush(){if(this.buffer.length===0)return;let t=this.buffer.join("");this.buffer=[];let n=this.getLogFilePath();X.appendFileSync(n,t)}stop(){this.flushInterval&&(clearInterval(this.flushInterval),this.flushInterval=null),this.flush()}};function $e(e){return e?typeof e=="boolean"?e?new ge({enabled:!0}):null:e.enabled?new ge(e):null:null}import{z as c}from"zod";import*as Z from"fs/promises";import*as E from"path";var Ge=c.object({port:c.number(),startCommand:c.string(),buildCommand:c.string().optional(),typecheckCommand:c.string().optional(),logFile:c.string().optional(),healthEndpoint:c.string().optional(),extensions:c.array(c.string())}),ut=c.object({port:c.number(),type:c.enum(["postgres","mysql","sqlite","mongodb"])}),gt=c.object({command:c.string(),schemaPath:c.string().optional()}),ft=c.object({email:c.string().optional(),name:c.string().optional(),commitPrefix:c.string().optional()}),ht=c.object({enabled:c.boolean(),port:c.number().optional()}),ne=c.object({version:c.literal("1.0"),paths:c.object({workspace:c.string(),backend:c.string().optional(),frontend:c.string().optional(),features:c.object({backend:c.string().optional(),frontend:c.string().optional()}).optional()}),services:c.object({backend:Ge.optional(),frontend:Ge.optional(),database:ut.optional()}).optional(),scaffold:gt.optional(),git:ft.optional(),techStack:c.object({backend:c.array(c.string()).optional(),frontend:c.array(c.string()).optional(),patterns:c.array(c.string()).optional()}).optional(),tunnel:ht.optional()});function D(e){return{version:"1.0",paths:{workspace:e||process.env.WORKSPACE_DIR||"/workspace",backend:"packages/dotnet-api",frontend:"packages/backoffice-web",features:{backend:"Source/Features",frontend:"src/applications/super-admin/features"}},services:{backend:{port:5338,startCommand:"dotnet run",buildCommand:"dotnet build",typecheckCommand:"dotnet build --no-restore",logFile:"/tmp/api.log",healthEndpoint:"http://localhost:5338",extensions:[".cs",".csproj"]},frontend:{port:5173,startCommand:"npm run dev",typecheckCommand:"npx tsc -p tsconfig.app.json --noEmit",logFile:"/tmp/web.log",healthEndpoint:"http://localhost:5173",extensions:[".ts",".tsx",".json"]},database:{port:43594,type:"postgres"}},scaffold:{command:"scaffold --schema /tmp/scaffold.json --output /workspace --force --full",schemaPath:"/tmp/scaffold.json"},git:{email:"agent@dotnetmentor.se",name:"Agent",commitPrefix:"[agent]"},techStack:{backend:[".NET 9","PostgreSQL","MediatR (CQRS)","EF Core"],frontend:["React 19","TypeScript","Vite","MUI","TanStack Query"],patterns:["Vertical slices","CQRS","Soft delete","Timestamps"]},tunnel:{enabled:!0,port:5173}}}var He="project-config.json",Ye=".sdd";async function Ke(e){let{workspaceDir:t,providedConfig:n,requireConfig:a}=e;if(n)return{config:ne.parse(n),source:"provided"};let s=E.join(t,Ye,He);try{let o=await Z.readFile(s,"utf-8"),r=JSON.parse(o);return{config:ne.parse(r),source:"file",configPath:s}}catch(o){o instanceof Error&&"code"in o&&o.code!=="ENOENT"&&console.warn(`[Config] Warning: Invalid project-config.json at ${s}:`,o instanceof c.ZodError?o.issues:o.message)}if(a)throw new Error(`No project configuration found at ${s} and requireConfig is true`);return{config:D(t),source:"default"}}async function ze(e,t){let n=E.join(e,Ye),a=E.join(n,He);await Z.mkdir(n,{recursive:!0});let s=ne.parse(t);return await Z.writeFile(a,JSON.stringify(s,null,2),"utf-8"),a}function fe(e,t){if(t)return E.isAbsolute(t)?t:E.join(e.paths.workspace,t)}function F(e){return fe(e,e.paths.backend)}function U(e){return fe(e,e.paths.frontend)}function se(e){let t=F(e);if(!(!t||!e.paths.features?.backend))return E.join(t,e.paths.features.backend)}function ee(e){let t=U(e);if(!(!t||!e.paths.features?.frontend))return E.join(t,e.paths.features.frontend)}function Qe(e,t){if(!e.services?.backend?.extensions)return!1;let n=E.extname(t).toLowerCase();return e.services.backend.extensions.includes(n)}function Ve(e,t){if(!e.services?.frontend?.extensions)return!1;let n=E.extname(t).toLowerCase();return e.services.frontend.extensions.includes(n)}function he(e){let t=[];return e.techStack?.backend?.length&&t.push(`**Backend:** ${e.techStack.backend.join(", ")}`),e.techStack?.frontend?.length&&t.push(`**Frontend:** ${e.techStack.frontend.join(", ")}`),e.techStack?.patterns?.length&&t.push(`**Patterns:** ${e.techStack.patterns.join(", ")}`),t.join(`
|
|
843
|
+
`)}function Je(e){let t=[];return e.paths.backend&&t.push(`- Backend: ${F(e)}`),e.paths.frontend&&t.push(`- Frontend: ${U(e)}`),e.paths.features?.backend&&t.push(`- Backend Features: ${se(e)}`),e.paths.features?.frontend&&t.push(`- Frontend Features: ${ee(e)}`),t.join(`
|
|
844
|
+
`)}function me(e){let t=[];return e.services?.backend&&t.push(`| Backend | ${F(e)} | ${e.services.backend.port} | ${e.services.backend.logFile||"N/A"} |`),e.services?.frontend&&t.push(`| Frontend | ${U(e)} | ${e.services.frontend.port} | ${e.services.frontend.logFile||"N/A"} |`),e.services?.database&&t.push(`| Database (${e.services.database.type}) | localhost | ${e.services.database.port} | - |`),t.length===0?"":`| Service | Location | Port | Logs |
|
|
845
845
|
|---------|----------|------|------|
|
|
846
846
|
${t.join(`
|
|
847
847
|
`)}`}function Xe(e={}){let{debugMode:t=!1,projectPrompt:n=null,isLocal:a=!1,projectConfig:s=D(),useDefaultStack:o=!0}=e,r=n?`
|
|
@@ -889,7 +889,7 @@ Then STOP. Do not continue. Do not try to fix it. Wait for user.
|
|
|
889
889
|
|
|
890
890
|
---
|
|
891
891
|
|
|
892
|
-
`:"",_=mt(s),g=yt(s,a),u=kt(s,o),
|
|
892
|
+
`:"",_=mt(s),g=yt(s,a),u=kt(s,o),T=bt(o),I=o?wt(s):"",B=o?St(s,a):"",N=_t(o);return`${r}${f}# Agent Instructions
|
|
893
893
|
|
|
894
894
|
## \u26D4 CRITICAL: EVERYTHING IS A KANBAN TASK
|
|
895
895
|
|
|
@@ -1013,7 +1013,7 @@ When user asks to build ANY feature, your FIRST action is to delegate to @planni
|
|
|
1013
1013
|
- Use EnterPlanMode or any built-in planning
|
|
1014
1014
|
- Skip the @planning step
|
|
1015
1015
|
|
|
1016
|
-
${
|
|
1016
|
+
${T}
|
|
1017
1017
|
|
|
1018
1018
|
---
|
|
1019
1019
|
|
|
@@ -1041,12 +1041,12 @@ ${g}
|
|
|
1041
1041
|
|
|
1042
1042
|
${u}
|
|
1043
1043
|
|
|
1044
|
-
${
|
|
1044
|
+
${N}
|
|
1045
1045
|
|
|
1046
|
-
${
|
|
1046
|
+
${I}
|
|
1047
1047
|
|
|
1048
1048
|
${B}
|
|
1049
|
-
`}function mt(e){let t=
|
|
1049
|
+
`}function mt(e){let t=he(e),n=F(e),a=U(e),s=se(e),o=ee(e),r=[];s&&r.push(`- Backend: "${s}/{Entity}/"`),o&&r.push(`- Frontend: "${o}/{entity}/"`);let f=e.techStack?.patterns?.length?`
|
|
1050
1050
|
**Key patterns:**
|
|
1051
1051
|
${e.techStack.patterns.map(u=>`- ${u}`).join(`
|
|
1052
1052
|
`)}`:"",g=e.techStack?.backend?.some(u=>u.includes(".NET")||u.includes("C#"))??!1?`
|
|
@@ -1079,7 +1079,7 @@ The user is responsible for:
|
|
|
1079
1079
|
</environment>`:`<environment>
|
|
1080
1080
|
Docker container with pre-started services:
|
|
1081
1081
|
|
|
1082
|
-
${
|
|
1082
|
+
${me(e)}
|
|
1083
1083
|
${e.tunnel?.enabled?"| Tunnel | - | - | Exposes frontend to user |":""}
|
|
1084
1084
|
|
|
1085
1085
|
User sees app through **Cloudflare tunnel** (live preview in browser).
|
|
@@ -1271,7 +1271,7 @@ queryClient.invalidateQueries({ queryKey: getGetApiPeopleQueryKey() })
|
|
|
1271
1271
|
|
|
1272
1272
|
Check the project's existing patterns for API calls and data fetching.
|
|
1273
1273
|
Look for existing feature code to understand the correct patterns before writing new API calls.
|
|
1274
|
-
</frontend-api>`:""}function St(e,t){if(!e.services?.frontend)return"";let n=e.services.frontend.port,a=
|
|
1274
|
+
</frontend-api>`:""}function St(e,t){if(!e.services?.frontend)return"";let n=e.services.frontend.port,a=ee(e),s=`http://localhost:${n}`;return`<ui-verification>
|
|
1275
1275
|
## \u{1F50D} UI Verification with Playwright
|
|
1276
1276
|
|
|
1277
1277
|
You have access to **Playwright MCP** tools to verify the UI works correctly after making changes.
|
|
@@ -1353,13 +1353,13 @@ You have access to **Playwright MCP** tools to verify the UI works correctly aft
|
|
|
1353
1353
|
- **Multi-tab apps**: Use \`browser_tabs\` to manage multiple windows/tabs in legacy applications
|
|
1354
1354
|
- **Large snapshots**: For pages with huge dropdowns (e.g., country lists), use \`browser_evaluate\` to collapse them first
|
|
1355
1355
|
- ${t?"In local mode, the browser window will be visible to you":"In container mode, browser runs headless"}
|
|
1356
|
-
</ui-verification>`}function Ze(e){return e&&e.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,"\uFFFD")}var vt=null;function et(){return Ze(vt)}import*as
|
|
1356
|
+
</ui-verification>`}function Ze(e){return e&&e.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,"\uFFFD")}var vt=null;function et(){return Ze(vt)}import*as G from"path";import*as ye from"fs";import{fileURLToPath as Et}from"url";var Ct=ve(),Pe=G.dirname(Et(import.meta.url)),tt=[G.resolve(Pe,"../mcps/stdio-server.js"),G.resolve(Pe,"./adapters/mcps/stdio-server.js")],re=tt.find(e=>ye.existsSync(e))||tt[0];console.log("[MCP] Stdio server path resolved:",re);console.log("[MCP] __dirname:",Pe);console.log("[MCP] File exists:",ye.existsSync(re));async function nt(e,t={}){let{model:n,sessionId:a=null,projectId:s=null,apiUrl:o=null,callbacks:r={},debugLog:f,abortController:_,debugMode:g=!1,isLocal:u=process.env.LOCAL_MODE==="true",projectConfig:T=D(process.env.WORKSPACE_DIR||process.cwd()),useDefaultStack:I=!0,anthropicApiKey:B}=t,N=$e(f),K=new Set,z=a||"",q,C,A,te=!1,W=!1,$=process.env.WORKSPACE_DIR||process.cwd();console.log("[MCP] Configuring agent-planning stdio server:"),console.log("[MCP] Command: node"),console.log("[MCP] Args:",[re]),console.log("[MCP] Env: API_URL=",process.env.API_URL||"http://localhost:5338",", PROJECT_ID=",s||process.env.PROJECT_ID||"",", PROJECT_KEY=",process.env.PROJECT_KEY?"***set***":"(not set)",", WORKSPACE_DIR=",$),console.log("[MCP] File exists check:",re);try{for await(let d of Tt({prompt:e,options:{abortController:_,cwd:$,resume:a??void 0,allowedTools:["Bash","Read","Write","Edit","MultiEdit","Glob","Grep","LS","WebFetch","NotebookRead","NotebookEdit","Skill","mcp__agent-insights__check_backend_build","mcp__agent-insights__check_frontend_types","mcp__agent-insights__check_service_health",...u?[]:["mcp__agent-insights__stop_services","mcp__agent-insights__start_services","mcp__agent-insights__restart_services"],"mcp__agent-planning__start_question_session","mcp__agent-planning__ask_question","mcp__agent-planning__end_question_session","mcp__agent-planning__save_specification","mcp__agent-planning__list_specifications","mcp__agent-planning__read_specification","mcp__agent-planning__delete_specification","mcp__agent-planning__report_learning","mcp__agent-planning__report_bug","mcp__agent-planning__report_debug_insight","mcp__agent-planning__get_kanban_board","mcp__agent-planning__get_column_cards","mcp__agent-planning__get_card_details","mcp__agent-planning__create_kanban_card","mcp__agent-planning__update_kanban_card","mcp__agent-planning__move_kanban_card","mcp__agent-planning__delete_kanban_card","mcp__agent-planning__create_subtask","mcp__agent-planning__toggle_subtask","mcp__agent-planning__delete_subtask","mcp__agent-planning__get_project_prompt","mcp__agent-planning__update_project_prompt","mcp__agent-planning__create_command","mcp__agent-planning__get_test_suites","mcp__agent-planning__get_test_suite_details","mcp__agent-planning__get_test_details","mcp__agent-planning__run_test","mcp__agent-planning__run_test_suite","mcp__agent-planning__report_test_status","mcp__agent-planning__create_test_suite","mcp__agent-planning__create_test","mcp__agent-planning__update_test","mcp__agent-planning__reference_projects_list","mcp__agent-planning__reference_project_tree","mcp__agent-planning__reference_project_read_file","mcp__agent-planning__reference_project_download","mcp__agent-planning__reference_project_update_status","mcp__playwright__browser_navigate","mcp__playwright__browser_snapshot","mcp__playwright__browser_take_screenshot","mcp__playwright__browser_click","mcp__playwright__browser_type","mcp__playwright__browser_scroll_down","mcp__playwright__browser_scroll_up","mcp__playwright__browser_go_back","mcp__playwright__browser_go_forward","mcp__playwright__browser_wait","mcp__playwright__browser_fill_form","mcp__playwright__browser_select_option","mcp__playwright__browser_press_key","mcp__playwright__browser_hover","mcp__playwright__browser_drag","mcp__playwright__browser_file_upload","mcp__playwright__browser_handle_dialog","mcp__playwright__browser_close","mcp__playwright__browser_resize","mcp__playwright__browser_console_messages","mcp__playwright__browser_network_requests","mcp__playwright__browser_screen_capture","mcp__playwright__browser_screen_move_mouse","mcp__playwright__browser_screen_click","mcp__playwright__browser_screen_drag","mcp__playwright__browser_screen_type","mcp__playwright__browser_evaluate","mcp__playwright__browser_run_code","mcp__playwright__browser_tabs","mcp__playwright__browser_tab_list","mcp__playwright__browser_tab_new","mcp__playwright__browser_tab_select","mcp__playwright__browser_tab_close"],model:n,env:(()=>{if(ye.existsSync("/tmp/.use-own-subscription")){let{ANTHROPIC_API_KEY:oe,...Q}=process.env;return Q}if(B!==void 0){if(B)return{...process.env,ANTHROPIC_API_KEY:B};let{ANTHROPIC_API_KEY:oe,...Q}=process.env;return Q}})(),mcpServers:{"agent-insights":Ct,"agent-planning":{type:"stdio",command:"node",args:[re],env:{WORKSPACE_DIR:$,API_URL:o||process.env.API_URL||process.env.MASTER_URL||"http://localhost:5338",PROJECT_ID:s||process.env.PROJECT_ID||"",PROJECT_KEY:process.env.PROJECT_KEY||""}},playwright:{type:"stdio",command:"npx",args:["@playwright/mcp@latest",...u?[]:["--browser=firefox"],"--caps=vision",`--user-data-dir=${G.join($,".playwright-data")}`,...u?[]:["--headless"]]}},settingSources:["project"],disallowedTools:["AskUserQuestion","TodoWrite","EnterPlanMode"],agents:I?{scaffolding:Te,debugger:de,planning:pe,backend:Ee,frontend:Ce,"project-context":ue}:{debugger:de,planning:pe,"project-context":ue},systemPrompt:Xe({debugMode:g,projectPrompt:et(),isLocal:u,projectConfig:T,useDefaultStack:I})}}))if(!(!d.uuid||K.has(d.uuid))){switch(K.add(d.uuid),N?.log(d),r.onRawMessage?.(d),d.type){case"assistant":if(d.message?.content)for(let w of d.message.content)w.type==="text"?r.onAssistantText?.(w.text):w.type==="tool_use"?r.onAssistantToolUse?.(w.name,w.input):w.type==="tool_result"&&r.onAssistantToolResult?.(w.tool_use_id,w.content);break;case"user":r.onUserMessage?.(d);break;case"result":if(d.subtype==="success")q=d.result,C=d.total_cost_usd,r.onResult?.(d.result,d.total_cost_usd);else{let w=`Agent error: ${d.subtype}`;A=w,r.onError?.(w)}W=!0;break;case"system":switch(d.subtype){case"init":z=d.session_id,N?.setSessionId(d.session_id),r.onSystemInit?.(d.session_id);break;case"status":r.onSystemStatus?.(JSON.stringify(d));break;case"compact_boundary":break;case"hook_response":break}break;case"stream_event":r.onStreamEvent?.(d);break;case"tool_progress":r.onToolProgress?.(d);break;case"auth_status":r.onAuthStatus?.(d);break}if(W)break}}catch(d){d instanceof Error&&d.name==="AbortError"||d instanceof Error&&d.message.includes("aborted by user")?(te=!0,r.onAborted?.()):(A=d instanceof Error?d.message:String(d),r.onError?.(A))}finally{N?.stop()}return console.log("after try"),{sessionId:z,result:q,cost:C,error:A,aborted:te}}function st(e){return`User answered the questions:
|
|
1357
1357
|
|
|
1358
1358
|
${Object.entries(e).map(([n,a])=>{let s=Array.isArray(a)?a.join(", "):a;return`${n}: ${s}`}).join(`
|
|
1359
|
-
`)}`}import{spawn as rt,execSync as
|
|
1360
|
-
`).filter(Boolean);console.log(`[Services] Killing ${p.length} process(es) on port ${l}: ${p.join(", ")}`);for(let h of p)try{process.kill(parseInt(h,10),"SIGKILL")}catch{}}}catch{try{
|
|
1361
|
-
`);v=
|
|
1359
|
+
`)}`}import{spawn as rt,execSync as H}from"child_process";import*as b from"fs";import*as ot from"http";import*as M from"path";function at(e){let{workspaceDir:t,apiPort:n,webPort:a,onBackendError:s,onFrontendError:o,projectConfig:r=D(t)}=e,f=n??r.services?.backend?.port??5338,_=a??r.services?.frontend?.port??5173,g=F(r),u=U(r),T=r.services?.backend?.startCommand??"dotnet run",I=r.services?.backend?.buildCommand??"dotnet build",B=r.services?.backend?.typecheckCommand??"dotnet build --no-restore",N=r.services?.frontend?.startCommand??"npm run dev",K=r.services?.frontend?.typecheckCommand??"npx tsc -p tsconfig.app.json --noEmit",z=r.services?.backend?.logFile??"/tmp/api.log",q=r.services?.frontend?.logFile??"/tmp/web.log",C=null,A=null,te=l=>new Promise(i=>{let p=setTimeout(()=>i(!1),3e3);ot.get(`http://localhost:${l}`,v=>{clearTimeout(p),i(v.statusCode!==void 0&&v.statusCode<500)}).on("error",()=>{clearTimeout(p),i(!1)})}),W=l=>{try{let i=H(`lsof -ti:${l} 2>/dev/null || true`,{encoding:"utf-8"}).trim();if(i){let p=i.split(`
|
|
1360
|
+
`).filter(Boolean);console.log(`[Services] Killing ${p.length} process(es) on port ${l}: ${p.join(", ")}`);for(let h of p)try{process.kill(parseInt(h,10),"SIGKILL")}catch{}}}catch{try{H(`fuser -k ${l}/tcp 2>/dev/null || true`,{encoding:"utf-8"})}catch{}}},$=(l,i)=>new Promise(p=>{if(!l||!l.pid){p();return}console.log(`[Services] Stopping ${i} (PID: ${l.pid})...`);try{process.kill(-l.pid,"SIGTERM")}catch{try{l.kill("SIGTERM")}catch{}}setTimeout(p,500)}),d=async()=>{if(!g||!b.existsSync(g)){console.log("[Services] No backend found, skipping backend start");return}W(f),console.log(`[Services] Starting backend with: ${T}...`);let l=M.dirname(z);b.existsSync(l)||b.mkdirSync(l,{recursive:!0});let i=b.createWriteStream(z,{flags:"a"}),[p,...h]=T.split(" ");C=rt(p,h,{cwd:g,stdio:["ignore","pipe","pipe"],detached:!0,shell:!0});let v="",k=m=>{let L=m.toString();i.write(L);let x=(v+L).split(`
|
|
1361
|
+
`);v=x.pop()||"";for(let R of x)R&&Pt(R)&&s&&s(R)};C.stdout?.on("data",k),C.stderr?.on("data",k),C.on("exit",m=>{i.end(),m!==0&&m!==null&&s&&s(`Process exited with code ${m}`)}),C.unref()},w=async()=>{if(!u||!b.existsSync(M.join(u,"package.json"))){console.log("[Services] No frontend found, skipping frontend start");return}W(_),console.log(`[Services] Starting frontend with: ${N}...`);let l=M.dirname(q);b.existsSync(l)||b.mkdirSync(l,{recursive:!0});let[i,...p]=N.split(" ");A=rt(i,p,{cwd:u,stdio:["ignore",b.openSync(q,"w"),b.openSync(q,"w")],detached:!0,shell:!0}),A.unref()},oe=async()=>{await $(C,"backend"),C=null,W(f)},Q=async()=>{await $(A,"frontend"),A=null,W(_)},be=async()=>{let[l,i]=await Promise.all([te(f),te(_)]);return{api:l,web:i}},Ae=async(l=15e3)=>{let i=Date.now(),p=1e3,h=0,v=null,k=null;for(console.log(`[Services] Waiting for health (timeout: ${l}ms)...`);Date.now()-i<l;){h++;let x=await be(),R=Date.now()-i;if(x.web&&k===null&&(k=R,console.log(`[Services] \u2713 Frontend (Vite) ready after ${R}ms`)),x.api&&v===null&&(v=R,console.log(`[Services] \u2713 Backend (dotnet) ready after ${R}ms`)),console.log(`[Services] Health poll #${h} (${R}ms): api=${x.api}, web=${x.web}`),x.api&&x.web)return console.log(`[Services] \u2713 Both services healthy after ${R}ms (${h} polls)`),x;await new Promise(dt=>setTimeout(dt,p))}let m=await be(),L=Date.now()-i;return m.web&&k===null&&console.log(`[Services] \u2713 Frontend (Vite) ready after ${L}ms`),m.api&&v===null&&console.log(`[Services] \u2713 Backend (dotnet) ready after ${L}ms`),console.log(`[Services] \u26A0 Health timeout after ${L}ms: api=${m.api}, web=${m.web}`),m},ct=async l=>{console.log(`[Services] Restarting ${l}...`);let i={success:!0},p=l==="backend"||l==="both",h=l==="frontend"||l==="both";if(p&&await oe(),h&&await Q(),p&&g&&b.existsSync(g)){console.log(`[Services] Building backend with: ${I}...`);try{H(I,{cwd:g,stdio:"pipe",timeout:12e4,encoding:"utf-8"}),console.log("[Services] \u2713 Backend build succeeded")}catch(k){let m=k;i.success=!1,i.backendError=m.stderr||m.stdout||"Build failed",console.error("[Services] \u2717 Backend build failed")}}if(h&&u&&b.existsSync(M.join(u,"package.json"))){console.log(`[Services] Type-checking frontend with: ${K}...`);try{H(K,{cwd:u,stdio:"pipe",timeout:6e4,encoding:"utf-8"}),console.log("[Services] \u2713 Frontend types OK")}catch(k){let m=k;i.success=!1,i.frontendError=m.stderr||m.stdout||"Type check failed",console.error("[Services] \u2717 Frontend type check failed")}}console.log(`[Services] Starting ${l}...`),p&&await d(),h&&await w();let v=await Ae(1e4);if(p&&!v.api){i.success=!1;let k=await Ie("backend",20),m=k.length>0?`
|
|
1362
1362
|
Recent logs:
|
|
1363
1363
|
${k.join(`
|
|
1364
|
-
`)}`:"";i.backendError||(i.backendError=`Backend failed to start.${m}`)}return h&&!v.web&&(i.success=!1,i.frontendError||(i.frontendError="Frontend failed to start")),i},xe=async()=>{if(!g||!b.existsSync(g))return{success:!0};try{return
|
|
1365
|
-
`).filter(Boolean)}catch(h){return[`Error reading logs: ${h instanceof Error?h.message:String(h)}`]}};return{startBackend:
|
|
1364
|
+
`)}`:"";i.backendError||(i.backendError=`Backend failed to start.${m}`)}return h&&!v.web&&(i.success=!1,i.frontendError||(i.frontendError="Frontend failed to start")),i},xe=async()=>{if(!g||!b.existsSync(g))return{success:!0};try{return H(B,{cwd:g,stdio:"pipe",timeout:12e4,encoding:"utf-8"}),{success:!0}}catch(l){let i=l;return{success:!1,errors:i.stdout||i.stderr||"Build failed"}}},Re=async()=>{if(!u||!b.existsSync(M.join(u,"package.json")))return{success:!0};try{return H(K,{cwd:u,stdio:"pipe",timeout:6e4,encoding:"utf-8"}),{success:!0}}catch(l){let i=l;return{success:!1,errors:i.stdout||i.stderr||"Type check failed"}}},lt=async()=>{let[l,i]=await Promise.all([xe(),Re()]);return{backend:l,frontend:i}},Ie=async(l,i)=>{let p=l==="backend"?z:q;if(!b.existsSync(p))return[`Log file not found: ${p}`];try{return H(`tail -n ${i} ${p}`,{encoding:"utf-8"}).split(`
|
|
1365
|
+
`).filter(Boolean)}catch(h){return[`Error reading logs: ${h instanceof Error?h.message:String(h)}`]}};return{startBackend:d,startFrontend:w,stopBackend:oe,stopFrontend:Q,restartServices:ct,checkHealth:be,waitForHealth:Ae,getProcesses:()=>({backend:C,frontend:A}),checkBackendBuild:xe,checkFrontendTypes:Re,runTypeChecks:lt,tailLogs:Ie,checkSwaggerEndpoints:async l=>{let i=M.join(t,"swagger.json");if(!b.existsSync(i))return{foundEndpoints:["Error: swagger.json not found"],totalEndpoints:0};try{let p=JSON.parse(b.readFileSync(i,"utf-8")),h=Object.keys(p.paths||{}),v=[];for(let k of h)if(k.toLowerCase().includes(l.toLowerCase())){let m=Object.keys(p.paths[k]);for(let L of m)v.push(`${L.toUpperCase()} ${k}`)}return{foundEndpoints:v,totalEndpoints:h.length}}catch(p){return{foundEndpoints:[`Error parsing swagger.json: ${p instanceof Error?p.message:String(p)}`],totalEndpoints:0}}}}}function Pt(e){let t=e.toLowerCase();return t.includes("exception")||t.includes("fail:")||t.includes("[err]")||t.includes("[error]")}import{execSync as Y}from"child_process";function it(e){let t=async()=>{try{return Y("git status --porcelain",{cwd:e,encoding:"utf-8"}).trim().length>0}catch{return!1}},n=async()=>{try{return Y("git branch --show-current",{cwd:e,encoding:"utf-8"}).trim()}catch{return"unknown"}};return{hasChanges:t,commitAndPush:async(s,o)=>{try{if(!await t())return{success:!0,noChanges:!0};let r=s.length>60?s.substring(0,60)+"...":s,_=`${o?"[agent] (partial)":"[agent]"} ${r}`;Y("git add -A",{cwd:e}),Y(`git commit -m "${_.replace(/"/g,'\\"')}"`,{cwd:e,encoding:"utf-8"});let g=Y("git rev-parse --short HEAD",{cwd:e,encoding:"utf-8"}).trim();try{Y("git push",{cwd:e,stdio:"pipe"})}catch(u){let T=u instanceof Error?u.message:String(u);if(T.includes("no upstream branch")){let I=await n();Y(`git push --set-upstream origin ${I}`,{cwd:e,stdio:"pipe"})}else return console.error("[Git] Push failed:",T),{success:!1,commitHash:g,commitSucceeded:!0,pushFailed:!0,error:T}}return{success:!0,commitHash:g}}catch(r){let f=r instanceof Error?r.message:String(r);return console.error("[Git] Error:",f),{success:!1,error:f}}},getCurrentBranch:n}}export{ne as ProjectConfigSchema,Se as createFilePlanningTransport,ke as createFileTransport,it as createLocalGitManager,at as createLocalServiceManager,ve as createMcpServer,st as formatAnswersAsPrompt,se as getBackendFeaturesPath,F as getBackendPath,D as getDefaultConfig,ee as getFrontendFeaturesPath,U as getFrontendPath,Je as getPathsDescription,me as getServicesDescription,he as getTechStackDescription,Qe as isBackendFile,Ve as isFrontendFile,Ke as loadProjectConfig,we as readPendingQuestions,fe as resolveConfigPath,nt as runAgent,ze as saveProjectConfig,De as setPlanningTransport,Fe as setServiceManager};
|