@task-shepherd/agent 1.0.7 → 1.0.11

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.
Files changed (80) hide show
  1. package/dist/cli/index.js +1054 -86
  2. package/dist/index.js +1 -1
  3. package/dist/meta.json +358 -67
  4. package/package.json +2 -2
  5. package/shared/dist/index.d.ts +0 -15
  6. package/shared/dist/index.js +0 -12
  7. package/shared/dist/mcp-client/client.d.ts +0 -18
  8. package/shared/dist/mcp-client/client.js +0 -49
  9. package/shared/dist/mcp-client/index.d.ts +0 -7
  10. package/shared/dist/mcp-client/index.js +0 -7
  11. package/shared/dist/mcp-client/types.d.ts +0 -822
  12. package/shared/dist/mcp-client/types.js +0 -193
  13. package/shared/dist/schema/index.d.ts +0 -189
  14. package/shared/dist/schema/index.js +0 -142
  15. package/shared/dist/schema/mcp-mappings.d.ts +0 -50
  16. package/shared/dist/schema/mcp-mappings.js +0 -563
  17. package/shared/dist/schema/validation.d.ts +0 -91
  18. package/shared/dist/schema/validation.js +0 -282
  19. package/shared/dist/work-queue/index.d.ts +0 -7
  20. package/shared/dist/work-queue/index.js +0 -7
  21. package/shared/dist/work-queue/types.d.ts +0 -147
  22. package/shared/dist/work-queue/types.js +0 -4
  23. package/shared/dist/work-queue/validation.d.ts +0 -24
  24. package/shared/dist/work-queue/validation.js +0 -160
  25. package/shared/dist/workspace/constants.d.ts +0 -148
  26. package/shared/dist/workspace/constants.js +0 -432
  27. package/shared/dist/workspace/index.d.ts +0 -10
  28. package/shared/dist/workspace/index.js +0 -10
  29. package/shared/dist/workspace/types.d.ts +0 -477
  30. package/shared/dist/workspace/types.js +0 -9
  31. package/shared/dist/workspace/utils.d.ts +0 -79
  32. package/shared/dist/workspace/utils.js +0 -334
  33. package/shared/dist/workspace/validation.d.ts +0 -1312
  34. package/shared/dist/workspace/validation.js +0 -467
  35. package/shared/graphql/generated-internal.ts +0 -3629
  36. package/shared/graphql/generated-public.ts +0 -773
  37. package/shared/graphql/generated.d.ts +0 -7456
  38. package/shared/graphql/generated.js +0 -11799
  39. package/shared/graphql/generated.ts +0 -27569
  40. package/shared/graphql/generated.ts.backup +0 -16531
  41. package/shared/graphql/generated.ts.working +0 -4828
  42. package/shared/graphql/introspection-internal.json +0 -15845
  43. package/shared/graphql/introspection-public.json +0 -9658
  44. package/shared/graphql/introspection.json +0 -44263
  45. package/shared/graphql/operations/ai-service.graphql +0 -131
  46. package/shared/graphql/operations/ai-work-queue.graphql +0 -31
  47. package/shared/graphql/operations/analytics.graphql +0 -283
  48. package/shared/graphql/operations/analytics.ts +0 -3
  49. package/shared/graphql/operations/api-keys.graphql +0 -126
  50. package/shared/graphql/operations/attachments.graphql +0 -53
  51. package/shared/graphql/operations/attachments.ts +0 -39
  52. package/shared/graphql/operations/audit.graphql +0 -46
  53. package/shared/graphql/operations/auth.graphql +0 -83
  54. package/shared/graphql/operations/claude-usage.graphql +0 -178
  55. package/shared/graphql/operations/comments.graphql +0 -4
  56. package/shared/graphql/operations/dashboard.graphql +0 -29
  57. package/shared/graphql/operations/development-plans.graphql +0 -408
  58. package/shared/graphql/operations/early-access.graphql.disabled +0 -21
  59. package/shared/graphql/operations/errors.graphql.disabled +0 -83
  60. package/shared/graphql/operations/internal-api.graphql +0 -931
  61. package/shared/graphql/operations/notifications.graphql +0 -4
  62. package/shared/graphql/operations/organization-invites.graphql.disabled +0 -32
  63. package/shared/graphql/operations/performance.graphql +0 -4
  64. package/shared/graphql/operations/project-reviews.graphql +0 -610
  65. package/shared/graphql/operations/projects.graphql +0 -98
  66. package/shared/graphql/operations/settings.graphql +0 -4
  67. package/shared/graphql/operations/stories.graphql +0 -113
  68. package/shared/graphql/operations/subscriptions.graphql +0 -235
  69. package/shared/graphql/operations/subscriptions.graphql.disabled +0 -96
  70. package/shared/graphql/operations/tasks.graphql +0 -257
  71. package/shared/graphql/operations/team.graphql +0 -111
  72. package/shared/graphql/operations/team.ts +0 -226
  73. package/shared/graphql/operations/time-tracking.graphql.disabled +0 -96
  74. package/shared/graphql/operations/work-queue.graphql +0 -210
  75. package/shared/graphql/operations/work-queue.graphql.disabled +0 -474
  76. package/shared/graphql/operations/workspace.graphql +0 -146
  77. package/shared/graphql/schema-internal.graphql +0 -1085
  78. package/shared/graphql/schema-public.graphql +0 -709
  79. package/shared/graphql/schema.graphql +0 -3473
  80. package/shared/package.json +0 -23
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var $t=Object.create;var ue=Object.defineProperty;var Vt=Object.getOwnPropertyDescriptor;var Kt=Object.getOwnPropertyNames;var zt=Object.getPrototypeOf,qt=Object.prototype.hasOwnProperty;var A=(a,t)=>()=>(a&&(t=a(a=0)),t);var Bt=(a,t)=>()=>(t||a((t={exports:{}}).exports,t),t.exports),Q=(a,t)=>{for(var e in t)ue(a,e,{get:t[e],enumerable:!0})},it=(a,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Kt(t))!qt.call(a,s)&&s!==e&&ue(a,s,{get:()=>t[s],enumerable:!(r=Vt(t,s))||r.enumerable});return a};var h=(a,t,e)=>(e=a!=null?$t(zt(a)):{},it(t||!a||!a.__esModule?ue(e,"default",{value:a,enumerable:!0}):e,a)),ot=a=>it(ue({},"__esModule",{value:!0}),a);var g,Gt,at,Jt,Yt,Qt,Xt,Zt,er,tr,rr,sr,nr,ir,or,ar,cr,ct,Oe,Le=A(()=>{"use strict";g=require("zod"),Gt=g.z.enum(["development","staging","production","test"]),at=g.z.enum(["error","warn","info","debug","verbose"]),Jt=g.z.object({port:g.z.number().int().min(1).max(65535).default(8547),host:g.z.string().default("localhost"),environment:Gt.default("development"),logLevel:at.default("info"),requestTimeout:g.z.number().int().min(1e3).max(6e5).default(3e4),maxRequestSize:g.z.string().default("10mb"),enableCors:g.z.boolean().default(!0),enableHelmet:g.z.boolean().default(!0),enableCompression:g.z.boolean().default(!0)}),Yt=g.z.object({apiUrl:g.z.string().url(),apiKey:g.z.string().optional(),timeout:g.z.number().int().min(1e3).max(6e4).default(3e4),retries:g.z.number().int().min(0).max(10).default(3),retryDelay:g.z.number().int().min(100).max(1e4).default(1e3)}),Qt=g.z.object({url:g.z.string().default("redis://localhost:6379"),host:g.z.string().optional(),port:g.z.number().int().min(1).max(65535).optional(),password:g.z.string().optional(),database:g.z.number().int().min(0).max(15).default(0),keyPrefix:g.z.string().default("ai-agent:"),connectTimeout:g.z.number().int().min(1e3).max(3e4).default(1e4),maxRetriesPerRequest:g.z.number().int().min(0).max(10).default(3)}),Xt=g.z.object({apiKey:g.z.string().optional(),baseUrl:g.z.string().url().optional(),model:g.z.string().default("claude-3-5-sonnet-20241022"),maxRetries:g.z.number().int().min(0).max(10).default(3),timeoutMs:g.z.number().int().min(1e3).max(3e5).default(6e4),maxTokens:g.z.number().int().min(100).max(8192).default(4096),temperature:g.z.number().min(0).max(1).default(.7),commandPath:g.z.string().default("claude")}),Zt=g.z.object({tokenLimit:g.z.number().int().min(1e3).max(1e6).default(1e4),requestsPerMinute:g.z.number().int().min(1).max(1e3).default(60),requestsPerHour:g.z.number().int().min(1).max(1e4).default(1e3),burstLimit:g.z.number().int().min(1).max(100).default(10),windowSizeMs:g.z.number().int().min(1e3).max(36e5).default(6e4)}),er=g.z.enum(["project_review","implementation_plan","story_implementation","task_completion","code_review","review_application"]),tr=g.z.object({maxConcurrentJobs:g.z.number().int().min(1).max(10).default(3),jobTimeout:g.z.number().int().min(3e4).max(18e5).default(3e5),retryAttempts:g.z.number().int().min(0).max(5).default(2),retryDelay:g.z.number().int().min(1e3).max(6e4).default(5e3),healthCheckInterval:g.z.number().int().min(5e3).max(3e5).default(3e4),enabledCapabilities:g.z.array(er).default(["project_review","implementation_plan","story_implementation","task_completion","code_review","review_application"])}),rr=g.z.object({path:g.z.string().default("./data/ai-agent.db"),backupEnabled:g.z.boolean().default(!0),backupInterval:g.z.number().int().min(36e5).max(864e5).default(36e5),maxBackups:g.z.number().int().min(1).max(30).default(7),vacuumInterval:g.z.number().int().min(864e5).max(6048e5).default(864e5)}),sr=g.z.object({enableApiKeyAuth:g.z.boolean().default(!1),apiKeys:g.z.array(g.z.string()).default([]),allowedOrigins:g.z.array(g.z.string()).default(["http://localhost:3000","http://localhost:5173"]),enableHttps:g.z.boolean().default(!1),httpsOptions:g.z.object({keyPath:g.z.string().optional(),certPath:g.z.string().optional()}).optional(),sessionSecret:g.z.string().min(32).optional()}),nr=g.z.object({enableMetrics:g.z.boolean().default(!0),metricsPort:g.z.number().int().min(1).max(65535).default(9090),enableHealthChecks:g.z.boolean().default(!0),healthCheckPath:g.z.string().default("/health"),enableProfiling:g.z.boolean().default(!1)}),ir=g.z.object({level:at.default("info"),enableConsole:g.z.boolean().default(!0),enableFile:g.z.boolean().default(!0),logDirectory:g.z.string().default("./logs"),maxFileSize:g.z.string().default("100MB"),maxFiles:g.z.number().int().min(1).max(100).default(10),datePattern:g.z.string().default("YYYY-MM-DD"),enableRotation:g.z.boolean().default(!0),enableJson:g.z.boolean().default(!1)}),or=g.z.object({enableWebInterface:g.z.boolean().default(!0),enableApiDocumentation:g.z.boolean().default(!0),enableMetricsApi:g.z.boolean().default(!0),enableWorkspaceAnalysis:g.z.boolean().default(!0),enableMultiWorkspace:g.z.boolean().default(!0),enableClaudeApiIntegration:g.z.boolean().default(!0),enableExperimentalFeatures:g.z.boolean().default(!1)}),ar=g.z.object({id:g.z.string().min(1),name:g.z.string().min(1),domain:g.z.string().optional(),apiUrl:g.z.string().url(),wsUrl:g.z.string().url().optional(),apiKey:g.z.string().min(1),enabled:g.z.boolean().default(!0),metadata:g.z.object({description:g.z.string().optional(),color:g.z.string().optional(),logo:g.z.string().url().optional(),addedAt:g.z.string().optional()}).optional()}),cr=g.z.object({setupCompleted:g.z.boolean().default(!1),defaultOrganization:g.z.string().optional(),organizations:g.z.record(g.z.string(),ar).default({})}),ct=g.z.object({server:Jt,taskShepherd:Yt,redis:Qt,claude:Xt,rateLimit:Zt,worker:tr,database:rr,security:sr,monitoring:nr,logging:ir,features:or,multiOrg:cr.default({})}),Oe={server:{port:8547,host:"localhost",environment:"development",logLevel:"info",requestTimeout:3e4,maxRequestSize:"10mb",enableCors:!0,enableHelmet:!0,enableCompression:!0},taskShepherd:{apiUrl:"",timeout:3e4,retries:3,retryDelay:1e3},redis:{url:"redis://localhost:6379",database:0,keyPrefix:"ai-agent:",connectTimeout:1e4,maxRetriesPerRequest:3},claude:{model:"claude-3-5-sonnet-20241022",maxRetries:3,timeoutMs:6e4,maxTokens:4096,temperature:.7,commandPath:"claude"},rateLimit:{tokenLimit:1e4,requestsPerMinute:60,requestsPerHour:1e3,burstLimit:10,windowSizeMs:6e4},worker:{maxConcurrentJobs:3,jobTimeout:3e5,retryAttempts:2,retryDelay:5e3,healthCheckInterval:3e4,enabledCapabilities:["project_review","implementation_plan","story_implementation","task_completion","code_review","review_application"]},database:{path:"./data/ai-agent.db",backupEnabled:!0,backupInterval:36e5,maxBackups:7,vacuumInterval:864e5},security:{enableApiKeyAuth:!1,apiKeys:[],allowedOrigins:["http://localhost:3000","http://localhost:5173"],enableHttps:!1},monitoring:{enableMetrics:!0,metricsPort:9090,enableHealthChecks:!0,healthCheckPath:"/health",enableProfiling:!1},logging:{level:"info",enableConsole:!0,enableFile:!0,logDirectory:"./logs",maxFileSize:"100MB",maxFiles:10,datePattern:"YYYY-MM-DD",enableRotation:!0,enableJson:!1},features:{enableWebInterface:!0,enableApiDocumentation:!0,enableMetricsApi:!0,enableWorkspaceAnalysis:!0,enableMultiWorkspace:!0,enableClaudeApiIntegration:!0,enableExperimentalFeatures:!1},multiOrg:{setupCompleted:!1,organizations:{}}}});function He(a){return Fe||(Fe=new Me(a)),Fe}function ge(){return He().getConfig()}var q,$,lt,Me,Fe,me=A(()=>{"use strict";q=h(require("fs")),$=h(require("path")),lt=require("events");Le();Me=class extends lt.EventEmitter{constructor(e={}){super();this.watchers=new Map;this.lastValidation=null;this.options={configDir:$.resolve(process.cwd(),"config"),environment:e.environment||"production",enableHotReload:!1,hotReloadInterval:1e3,additionalConfigFiles:[],strictValidation:!1,...e},this.config={...Oe},this.configMetadata={config:this.config,sources:{},validatedAt:new Date,environment:this.options.environment},this.loadConfiguration()}getConfig(){return{...this.config}}getConfigWithMetadata(){return{...this.configMetadata}}get(e){return this.config[e]}getLastValidation(){return this.lastValidation}async reloadConfiguration(){return this.loadConfiguration()}validateConfiguration(){return this.validateConfig(this.config)}loadConfiguration(){try{let e={},r={...Oe};this.trackConfigSources(r,e,"default","built-in defaults",0);let s=this.loadConfigFile("config.json",e,1);s&&(r=this.mergeConfig(r,s));let n=this.loadConfigFile(`config.${this.options.environment}.json`,e,2);n&&(r=this.mergeConfig(r,n)),this.options.additionalConfigFiles.forEach((l,u)=>{let m=this.loadConfigFile(l,e,3+u);m&&(r=this.mergeConfig(r,m))});let i=this.loadEnvironmentOverrides();Object.keys(i).length>0&&(r=this.mergeConfig(r,i),this.trackConfigSources(i,e,"environment","environment variables",100));let o=this.validateConfig(r);if(o.success&&o.data){let l={...this.config};this.config=o.data,this.configMetadata={config:this.config,sources:e,validatedAt:new Date,environment:this.options.environment},JSON.stringify(l)!==JSON.stringify(this.config)&&this.emit("configurationChanged",{oldConfig:l,newConfig:this.config,sources:e})}return this.lastValidation=o,this.options.enableHotReload&&this.setupHotReloading(),o}catch(e){return console.error("Critical error in configuration loading:",e),{success:!1,errors:[{path:"configuration",message:`Configuration loading failed: ${e instanceof Error?e.message:"Unknown error"}`,code:"CONFIG_LOAD_ERROR"}],warnings:[]}}}loadConfigFile(e,r,s){let n=$.isAbsolute(e)?e:$.join(this.options.configDir,e);try{if(!q.existsSync(n))return null;let i=q.readFileSync(n,"utf-8"),o=JSON.parse(i);return this.trackConfigSources(o,r,"file",n,s),o}catch(i){return console.warn(`Failed to load configuration file ${n}:`,i),null}}loadEnvironmentOverrides(){let e={};if(process.env.PORT&&(e.server={...e.server,port:parseInt(process.env.PORT)}),process.env.HOST&&(e.server={...e.server,host:process.env.HOST}),process.env.LOG_LEVEL&&(e.server={...e.server,logLevel:process.env.LOG_LEVEL}),e.server={...e.server,environment:"production"},process.env.TASK_SHEPHERD_API_URL&&(e.taskShepherd={...e.taskShepherd,apiUrl:process.env.TASK_SHEPHERD_API_URL}),process.env.TASK_SHEPHERD_API_KEY&&(e.taskShepherd={...e.taskShepherd,apiKey:process.env.TASK_SHEPHERD_API_KEY}),process.env.TASK_SHEPHERD_WS_URL&&(e.taskShepherd={...e.taskShepherd,wsUrl:process.env.TASK_SHEPHERD_WS_URL}),process.env.TASK_SHEPHERD_ENABLE_WEBSOCKET!==void 0&&(e.taskShepherd={...e.taskShepherd,enableWebSocket:process.env.TASK_SHEPHERD_ENABLE_WEBSOCKET==="true"}),process.env.REDIS_URL&&(e.redis={...e.redis,url:process.env.REDIS_URL}),process.env.REDIS_HOST&&(e.redis={...e.redis,host:process.env.REDIS_HOST}),process.env.REDIS_PORT&&(e.redis={...e.redis,port:parseInt(process.env.REDIS_PORT)}),process.env.REDIS_PASSWORD&&(e.redis={...e.redis,password:process.env.REDIS_PASSWORD}),process.env.ANTHROPIC_API_KEY&&(e.claude={...e.claude,apiKey:process.env.ANTHROPIC_API_KEY}),process.env.ANTHROPIC_BASE_URL&&(e.claude={...e.claude,baseUrl:process.env.ANTHROPIC_BASE_URL}),process.env.CLAUDE_MODEL&&(e.claude={...e.claude,model:process.env.CLAUDE_MODEL}),process.env.CLAUDE_COMMAND_PATH&&(e.claude={...e.claude,commandPath:process.env.CLAUDE_COMMAND_PATH}),process.env.MAX_CONCURRENT_JOBS&&(e.worker={...e.worker,maxConcurrentJobs:parseInt(process.env.MAX_CONCURRENT_JOBS)}),process.env.JOB_TIMEOUT&&(e.worker={...e.worker,jobTimeout:parseInt(process.env.JOB_TIMEOUT)}),process.env.CAPABILITIES||process.env.AGENT_CAPABILITIES){let r=(process.env.CAPABILITIES||process.env.AGENT_CAPABILITIES||"").split(",").map(s=>s.trim());e.worker={...e.worker,enabledCapabilities:r}}if(process.env.TOKEN_RATE_LIMIT&&(e.rateLimit={...e.rateLimit,tokenLimit:parseInt(process.env.TOKEN_RATE_LIMIT)}),process.env.DB_PATH&&(e.database={...e.database,path:process.env.DB_PATH}),process.env.API_KEYS){let r=process.env.API_KEYS.split(",").map(s=>s.trim());e.security={...e.security,apiKeys:r,enableApiKeyAuth:!0}}return e}trackConfigSources(e,r,s,n,i){let o=(l,u="")=>{for(let[m,p]of Object.entries(l)){let f=u?`${u}.${m}`:m;p&&typeof p=="object"&&!Array.isArray(p)?o(p,f):r[f]={type:s,source:n,priority:i}}};o(e)}mergeConfig(e,r){let s={...e};for(let[n,i]of Object.entries(r))i&&typeof i=="object"&&!Array.isArray(i)?s[n]=this.mergeConfig(e[n]||{},i):s[n]=i;return s}validateConfig(e){let r=ct.safeParse(e);return r.success?{success:!0,data:r.data,errors:[],warnings:this.generateWarnings(r.data)}:{success:!1,errors:r.error.issues.map(s=>({path:s.path.join("."),message:s.message,code:s.code})),warnings:[]}}generateWarnings(e){let r=[];return e.server.environment==="development"&&(!e.claude.apiKey&&!e.claude.commandPath&&r.push({path:"claude.apiKey",message:"No Claude API key or command path configured",suggestion:"Set ANTHROPIC_API_KEY environment variable or ensure Claude CLI is installed"}),e.security.enableHttps&&r.push({path:"security.enableHttps",message:"HTTPS enabled in development mode",suggestion:"Consider disabling HTTPS for local development"})),e.server.environment==="production"&&(e.security.enableHttps||r.push({path:"security.enableHttps",message:"HTTPS disabled in production",suggestion:"Enable HTTPS for production deployment"}),e.security.enableApiKeyAuth||r.push({path:"security.enableApiKeyAuth",message:"API key authentication disabled in production",suggestion:"Enable API key authentication for production security"}),(e.server.logLevel==="debug"||e.server.logLevel==="verbose")&&r.push({path:"server.logLevel",message:"Debug logging enabled in production",suggestion:'Use "info" or "warn" log level for production'})),r}setupHotReloading(){this.watchers.forEach(r=>r.close()),this.watchers.clear(),[$.join(this.options.configDir,"config.json"),$.join(this.options.configDir,`config.${this.options.environment}.json`),...this.options.additionalConfigFiles].forEach(r=>{if(q.existsSync(r)){let s=q.watch(r,n=>{n==="change"&&setTimeout(()=>{console.log(`Configuration file changed: ${r}`);let i=this.loadConfiguration();i.success?(console.log("Configuration reloaded successfully"),this.emit("configurationReloaded",this.config)):(console.error("Configuration reload failed:",i.errors),this.emit("configurationError",i.errors))},this.options.hotReloadInterval)});this.watchers.set(r,s)}})}destroy(){this.watchers.forEach(e=>e.close()),this.watchers.clear(),this.removeAllListeners()}},Fe=null});var pt={};Q(pt,{detectClaude:()=>lr,detectClaudeSync:()=>Ue,getClaudeCommandPath:()=>pr});function lr(a="claude"){return Ue(a)}function Ue(a="claude"){if(ie(a))return{available:!0,path:a,method:"direct"};if(a==="claude"){let t=[process.env.HOME+"/.claude/local/claude","/usr/local/bin/claude","/opt/homebrew/bin/claude"].filter(e=>e);for(let e of t)if(ie(e))return{available:!0,path:e,method:"direct"};try{let e=(0,he.execSync)('bash -c "which claude"',{encoding:"utf8",stdio:"pipe"}).trim();if(e&&!e.includes("aliased to")&&ie(e))return{available:!0,path:e,method:"which"};if(e.includes("aliased to ")){let r=e.split("aliased to ")[1];if(r&&ie(r))return{available:!0,path:r,method:"which"}}}catch{}try{let r=(0,he.execSync)("where claude",{encoding:"utf8",stdio:"pipe"}).trim().split(`
3
- `)[0];if(r&&ie(r))return{available:!0,path:r,method:"where"}}catch{}}return{available:!1,method:"none"}}function ie(a){try{return(0,he.execSync)(`"${a}" --version`,{stdio:"pipe"}),!0}catch{return!1}}function pr(a="claude"){return Ue(a).path||a}var he,dt=A(()=>{"use strict";he=require("child_process")});function gt(a){return $e.validateConfiguration(a)}var V,ut,$e,Ve=A(()=>{"use strict";V=h(require("fs")),ut=h(require("path")),$e=class{static validateConfiguration(t){let e=[],r=[];return this.isMultiOrgMode()?{valid:!0,errors:[],warnings:[]}:(this.validateServerConfig(t,e,r),this.validateTaskShepherdConfig(t,e,r),this.validateRedisConfig(t,e,r),this.validateClaudeConfig(t,e,r),this.validateDatabaseConfig(t,e,r),this.validateSecurityConfig(t,e,r),this.validateLoggingConfig(t,e,r),this.validateConfigurationDependencies(t,e,r),{valid:e.length===0,errors:e,warnings:r})}static isMultiOrgMode(){let t=require("fs"),e=require("path"),r=require("os"),s=e.join(r.homedir(),".task-shepherd-agent","config.json");return t.existsSync(s)}static validateServerConfig(t,e,r){let{server:s}=t;s.port<1024&&typeof process.getuid=="function"&&process.getuid()!==0&&r.push({path:"server.port",message:`Port ${s.port} requires root privileges`,code:"PRIVILEGED_PORT",severity:"warning",suggestion:"Use a port number above 1024 for non-root users"}),s.environment==="production"&&(s.logLevel==="debug"||s.logLevel==="verbose")&&r.push({path:"server.logLevel",message:"Debug logging enabled in production",code:"PRODUCTION_DEBUG_LOG",severity:"warning",suggestion:'Use "info" or "warn" log level for production'}),s.requestTimeout<5e3&&r.push({path:"server.requestTimeout",message:"Request timeout is very low",code:"LOW_REQUEST_TIMEOUT",severity:"warning",suggestion:"Consider increasing timeout for AI operations"})}static validateTaskShepherdConfig(t,e,r){let{taskShepherd:s}=t;if(s){try{new URL(s.apiUrl)}catch{e.push({path:"taskShepherd.apiUrl",message:"Invalid Task Shepherd API URL format",code:"INVALID_URL",severity:"error",suggestion:"Provide a valid HTTP/HTTPS URL"})}t.server.environment==="production"&&!s.apiKey&&r.push({path:"taskShepherd.apiKey",message:"No API key configured for production",code:"MISSING_API_KEY",severity:"warning",suggestion:"Set TASK_SHEPHERD_API_KEY environment variable"}),s.timeout>6e4&&r.push({path:"taskShepherd.timeout",message:"Task Shepherd API timeout is very high",code:"HIGH_TIMEOUT",severity:"warning",suggestion:"Consider reducing timeout to improve responsiveness"})}}static validateRedisConfig(t,e,r){let{redis:s}=t;if(!s){e.push({path:"redis",message:"Redis configuration is missing",code:"MISSING_REDIS_CONFIG",severity:"error"});return}s.url&&!s.url.startsWith("redis://")&&!s.url.startsWith("rediss://")&&e.push({path:"redis.url",message:"Invalid Redis URL format",code:"INVALID_REDIS_URL",severity:"error",suggestion:"Use redis:// or rediss:// protocol"}),(s.database<0||s.database>15)&&e.push({path:"redis.database",message:"Redis database number must be between 0 and 15",code:"INVALID_DB_NUMBER",severity:"error"}),s.connectTimeout<1e3&&r.push({path:"redis.connectTimeout",message:"Redis connection timeout is very low",code:"LOW_CONNECT_TIMEOUT",severity:"warning",suggestion:"Consider increasing timeout for reliable connections"})}static validateClaudeConfig(t,e,r){let{claude:s}=t;if(!s.apiKey&&!this.isClaudeCliAvailable(s.commandPath)&&e.push({path:"claude.apiKey",message:"No Claude API key configured and CLI not available",code:"MISSING_CLAUDE_AUTH",severity:"error",suggestion:"Set ANTHROPIC_API_KEY or install Claude CLI"}),s.baseUrl)try{new URL(s.baseUrl)}catch{e.push({path:"claude.baseUrl",message:"Invalid Claude base URL format",code:"INVALID_BASE_URL",severity:"error"})}let n=["claude-3-5-sonnet-20241022","claude-3-haiku-20240307","claude-3-opus-20240229"];s.model&&!n.includes(s.model)&&r.push({path:"claude.model",message:"Unknown Claude model specified",code:"UNKNOWN_MODEL",severity:"warning",suggestion:`Use one of: ${n.join(", ")}`}),s.timeoutMs<3e4&&r.push({path:"claude.timeoutMs",message:"Claude timeout is very low for AI operations",code:"LOW_AI_TIMEOUT",severity:"warning",suggestion:"Consider at least 30 seconds for AI operations"}),(s.temperature<0||s.temperature>1)&&e.push({path:"claude.temperature",message:"Claude temperature must be between 0 and 1",code:"INVALID_TEMPERATURE",severity:"error"})}static validateDatabaseConfig(t,e,r){let{database:s}=t;if(!s){e.push({path:"database",message:"Database configuration is missing",code:"MISSING_DATABASE_CONFIG",severity:"error"});return}let n=ut.dirname(s.path);try{V.existsSync(n)||V.mkdirSync(n,{recursive:!0})}catch{e.push({path:"database.path",message:`Cannot create database directory: ${n}`,code:"INVALID_DB_PATH",severity:"error",suggestion:"Ensure the directory is writable"})}s.backupEnabled&&s.maxBackups<1&&e.push({path:"database.maxBackups",message:"Maximum backups must be at least 1 when backup is enabled",code:"INVALID_BACKUP_COUNT",severity:"error"}),s.backupEnabled&&s.backupInterval<6e4&&r.push({path:"database.backupInterval",message:"Backup interval is very frequent",code:"FREQUENT_BACKUP",severity:"warning",suggestion:"Consider longer intervals to reduce I/O overhead"})}static validateSecurityConfig(t,e,r){let{security:s}=t;if(!s){e.push({path:"security",message:"Security configuration is missing",code:"MISSING_SECURITY_CONFIG",severity:"error"});return}if(t.server.environment==="production"&&(s.enableHttps||r.push({path:"security.enableHttps",message:"HTTPS disabled in production",code:"PRODUCTION_HTTP",severity:"warning",suggestion:"Enable HTTPS for production deployment"}),s.enableApiKeyAuth||r.push({path:"security.enableApiKeyAuth",message:"API key authentication disabled in production",code:"PRODUCTION_NO_AUTH",severity:"warning",suggestion:"Enable API key authentication for security"})),s.enableHttps&&s.httpsOptions){let{keyPath:n,certPath:i}=s.httpsOptions;n&&!V.existsSync(n)&&e.push({path:"security.httpsOptions.keyPath",message:"SSL private key file not found",code:"MISSING_SSL_KEY",severity:"error"}),i&&!V.existsSync(i)&&e.push({path:"security.httpsOptions.certPath",message:"SSL certificate file not found",code:"MISSING_SSL_CERT",severity:"error"})}s.enableApiKeyAuth&&s.apiKeys.length===0&&e.push({path:"security.apiKeys",message:"API key authentication enabled but no keys configured",code:"NO_API_KEYS",severity:"error",suggestion:"Configure API keys or disable authentication"}),s.sessionSecret&&s.sessionSecret.length<32&&r.push({path:"security.sessionSecret",message:"Session secret should be at least 32 characters",code:"WEAK_SESSION_SECRET",severity:"warning",suggestion:"Use a longer, randomly generated secret"})}static validateLoggingConfig(t,e,r){let{logging:s}=t;if(s.enableFile)try{V.existsSync(s.logDirectory)||V.mkdirSync(s.logDirectory,{recursive:!0})}catch{e.push({path:"logging.logDirectory",message:`Cannot create log directory: ${s.logDirectory}`,code:"INVALID_LOG_DIR",severity:"error",suggestion:"Ensure the directory is writable"})}s.maxFiles<1&&e.push({path:"logging.maxFiles",message:"Maximum log files must be at least 1",code:"INVALID_MAX_FILES",severity:"error"}),/^(\d+)(KB|MB|GB)$/i.test(s.maxFileSize)||e.push({path:"logging.maxFileSize",message:"Invalid log file size format",code:"INVALID_FILE_SIZE",severity:"error",suggestion:'Use format like "100MB", "1GB", etc.'})}static validateConfigurationDependencies(t,e,r){let s=t.worker.maxConcurrentJobs,n=t.rateLimit.requestsPerMinute;s*10>n&&r.push({path:"rateLimit.requestsPerMinute",message:"Rate limit may be too low for configured concurrent jobs",code:"RATE_LIMIT_TOO_LOW",severity:"warning",suggestion:"Increase rate limit or reduce concurrent jobs"}),t.monitoring.metricsPort===t.server.port&&e.push({path:"monitoring.metricsPort",message:"Metrics port conflicts with server port",code:"PORT_CONFLICT",severity:"error",suggestion:"Use different ports for metrics and main server"}),t.features.enableMetricsApi&&!t.monitoring.enableMetrics&&r.push({path:"features.enableMetricsApi",message:"Metrics API enabled but metrics collection disabled",code:"METRICS_DEPENDENCY",severity:"warning",suggestion:"Enable metrics collection or disable metrics API"})}static isClaudeCliAvailable(t){let{detectClaudeSync:e}=(dt(),ot(pt));return e(t).available}}});function dr(){let a=ge();return{port:a.server.port,nodeEnv:a.server.environment,taskShepherdApiUrl:a.taskShepherd.apiUrl,taskShepherdApiKey:a.taskShepherd.apiKey,redisUrl:a.redis.url,claudeCommandPath:a.claude.commandPath,claudeApiKey:a.claude.apiKey,claudeBaseUrl:a.claude.baseUrl,claudeModel:a.claude.model,claudeMaxRetries:a.claude.maxRetries,claudeTimeoutMs:a.claude.timeoutMs,maxConcurrentJobs:a.worker.maxConcurrentJobs,tokenRateLimit:a.rateLimit.tokenLimit,logLevel:a.server.logLevel}}var Ke,ur,X,mt=A(()=>{"use strict";Le();me();Ve();me();Ve();Ke=dr(),ur=He(),X={warnings:[]};if(X=gt(ur.getConfig()),!X.valid&&(console.error("Configuration validation failed:"),X.errors.forEach(a=>{console.error(` - ${a.path}: ${a.message}`)}),X.errors.some(a=>a.severity==="error")))throw new Error("Configuration contains critical errors. Please fix them before starting the service.");X.warnings.length>0&&(console.warn("Configuration warnings:"),X.warnings.forEach(a=>{console.warn(` - ${a.path}: ${a.message}`),a.suggestion&&console.warn(` Suggestion: ${a.suggestion}`)}))});var L,c,R=A(()=>{"use strict";L=h(require("winston"));mt();c=L.default.createLogger({level:Ke.nodeEnv==="development"?"debug":"info",format:L.default.format.combine(L.default.format.timestamp(),L.default.format.errors({stack:!0}),L.default.format.json()),defaultMeta:{service:"agent"},transports:[new L.default.transports.File({filename:"logs/error.log",level:"error",maxsize:100*1024*1024,maxFiles:5,tailable:!0}),new L.default.transports.File({filename:"logs/combined.log",maxsize:100*1024*1024,maxFiles:5,tailable:!0})]});Ke.nodeEnv!=="production"&&c.add(new L.default.transports.Console({format:L.default.format.combine(L.default.format.colorize(),L.default.format.simple())}))});var vt=Bt((cs,gr)=>{gr.exports={name:"@task-shepherd/agent",version:"1.0.7",description:"Simplified AI agent service for Task Shepherd project analysis",main:"dist/index.js",bin:{"task-shepherd-agent":"dist/cli/index.js"},files:["dist","mcp-agent","shared","web/dist","README.md","LICENSE.md"],engines:{node:">=18.0.0"},scripts:{dev:"ts-node-dev --respawn --transpile-only src/index.ts",build:"node build.js","build:dev":"node build-dev.js","build:tsc":"tsc","build:prod":"npm run build && npm run build:web",start:"node dist/index.js","type-check":"tsc --noEmit",lint:"eslint src/**/*.ts --fix",kill:"(lsof -ti:8547,8548 | xargs kill -9 2>/dev/null) || pkill -f 'node.*agent|ts-node-dev.*agent' || echo 'AI agent service stopped'",test:"jest",prepublishOnly:"npm run build","test:workqueue":"jest --config jest.workqueue.config.js","test:workqueue:watch":"jest --config jest.workqueue.config.js --watch","test:workqueue:coverage":"jest --config jest.workqueue.config.js --coverage","dev:web":"cd web && npm run dev","build:web":"cd web && npm run build","dev:all":'concurrently "npm run dev" "npm run dev:web"',codegen:"graphql-codegen --config codegen.yml","agent:init":"ts-node src/cli/index.ts init","agent:status":"ts-node src/cli/index.ts status","reset:config":"node reset-org-config.js","agent:identity:show":"ts-node src/cli/index.ts identity show","agent:identity:reset":"ts-node src/cli/index.ts identity reset","agent:identity:strategies":"ts-node src/cli/index.ts identity strategies","agent:heartbeat:test":"ts-node src/cli/index.ts heartbeat test","agent:config:validate":"ts-node src/cli/index.ts config validate","agent:config:show":"ts-node src/cli/index.ts config show","agent:cli:help":"ts-node src/cli/index.ts --help"},dependencies:{"@anthropic-ai/sdk":"^0.56.0","@graphql-typed-document-node/core":"^3.2.0",chalk:"^4.1.2",commander:"^11.0.0",compression:"^1.7.4",cors:"^2.8.5",dotenv:"^16.3.1",express:"^4.18.2",glob:"^11.0.3",graphql:"^16.8.0","graphql-request":"^6.1.0","graphql-ws":"^6.0.5",helmet:"^7.0.0",joi:"^17.9.2",prompts:"^2.4.2",semver:"^7.5.4",sqlite3:"^5.1.6",uuid:"^11.1.0",winston:"^3.10.0",ws:"^8.14.2",zod:"^3.22.4"},devDependencies:{"@graphql-codegen/cli":"^5.0.0","@graphql-codegen/client-preset":"^4.1.0","@graphql-codegen/introspection":"^4.0.0","@graphql-codegen/typed-document-node":"^5.0.1","@graphql-codegen/typescript":"^4.0.1","@graphql-codegen/typescript-operations":"^4.0.1","@types/compression":"^1.7.2","@types/cors":"^2.8.13","@types/express":"^4.17.17","@types/glob":"^8.1.0","@types/jest":"^30.0.0","@types/nock":"^10.0.3","@types/node":"^20.4.5","@types/prompts":"^2.4.9","@types/semver":"^7.5.4","@types/uuid":"^9.0.8","@types/ws":"^8.5.8","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0",concurrently:"^8.2.0",esbuild:"^0.19.0",eslint:"^8.45.0","javascript-obfuscator":"^4.1.1",jest:"^29.6.1",nock:"^14.0.7","ts-jest":"^29.1.1","ts-node-dev":"^2.0.0",typescript:"^5.1.6"},keywords:["ai","project-analysis","claude","task-management","ai-agent","project-management","code-analysis"],author:"Task Shepherd Team",license:"SEE LICENSE IN LICENSE.md",repository:{type:"git",url:"https://github.com/taskshepherd/task-shepherd.git",directory:"packages/agent"},bugs:{url:"https://github.com/taskshepherd/task-shepherd/issues"},homepage:"https://taskshepherd.com",publishConfig:{access:"public"}}});function kt(){return Be||(Be=new Ge),Be}var mr,j,Ge,Be,bt=A(()=>{"use strict";R();mr=vt(),j={version:mr.version||"1.0.0",buildTimestamp:process.env.BUILD_TIMESTAMP||new Date().toISOString(),commitHash:process.env.GIT_COMMIT_HASH||"dev",compatibility:{minBackendVersion:"1.0.0",maxBackendVersion:"3.0.0",supportedBackendMajors:[1,2]},features:{workspaceAutoDiscovery:!0,realTimeUpdates:!0,multiProjectAnalysis:!1,advancedReporting:!0},releaseChannel:process.env.RELEASE_CHANNEL||"stable",releaseNotes:"See CHANGELOG.md for detailed release notes",deprecationWarnings:[]},Ge=class{getVersionMetadata(){return{...j}}getVersion(){return j.version}getBuildInfo(){return{version:j.version,buildTimestamp:j.buildTimestamp,commitHash:j.commitHash,releaseChannel:j.releaseChannel}}getCompatibilityRequirements(){return{...j.compatibility}}getFeatureCapabilities(){return{...j.features}}logVersionInfo(){c.info("Agent version information",{version:j.version,buildTimestamp:j.buildTimestamp,commitHash:j.commitHash,releaseChannel:j.releaseChannel,compatibilityRequirements:j.compatibility,features:j.features})}},Be=null});function te(a){return c.debug("getGraphQLHttpClient called",{hasExistingClient:!!ae,hasOptions:!!a,optionsProvided:a?JSON.stringify(a,null,2):"none"}),ae||(c.info("Creating new HTTP client singleton via getGraphQLHttpClient"),ae=new ce(a)),c.debug("Returning HTTP client",{clientExists:!!ae}),ae}var St,ce,ae,ke=A(()=>{"use strict";St=require("events");R();me();bt();ce=class extends St.EventEmitter{constructor(e={}){super();this.healthCheckTimer=null;this.isHealthy=!1;this.circuitBreakerOpen=!1;this.failureCount=0;this.lastHealthCheck=0;let r=ge();c.info("GraphQL HTTP Client constructor called",{providedOptionsApiKey:e.apiKey?e.apiKey.substring(0,12)+"...":"none",configApiKey:r.taskShepherd.apiKey?r.taskShepherd.apiKey.substring(0,12)+"...":"none",configApiUrl:r.taskShepherd.apiUrl});let s=e.apiKey||r.taskShepherd.apiKey;s||c.error("CRITICAL: No API key available for GraphQL HTTP Client",{providedOptionsApiKey:e.apiKey?e.apiKey.substring(0,12)+"...":"none",configApiKey:r.taskShepherd.apiKey?r.taskShepherd.apiKey.substring(0,12)+"...":"none",configKeys:Object.keys(r.taskShepherd||{})});let n=r.taskShepherd.apiUrl,o={maxRetries:5,baseDelay:1e3,maxDelay:3e4,timeout:6e4,healthCheckInterval:3e4,enableCircuitBreaker:!0,baseUrl:e.baseUrl||n||"http://localhost:4002/api/graphql"};this.options={...o,...e,apiKey:e.apiKey!==void 0?e.apiKey:s},c.info("GraphQL HTTP Client initialized with options",{hasApiKey:!!this.options.apiKey,apiKeyLength:this.options.apiKey?.length||0,apiKeyPrefix:this.options.apiKey?this.options.apiKey.substring(0,12)+"...":"none",baseUrl:this.options.baseUrl,optionsKeys:Object.keys(this.options)}),this.startHealthChecking()}async query(e){if(this.circuitBreakerOpen)throw new Error("Circuit breaker is open - backend is unavailable");let r=null;for(let s=1;s<=this.options.maxRetries;s++)try{let n=await this.executeRequest(e,s);return this.failureCount=0,this.circuitBreakerOpen&&(this.circuitBreakerOpen=!1,c.info("Circuit breaker closed - backend is healthy again"),this.emit("circuitBreakerClosed")),n}catch(n){if(r=n instanceof Error?n:new Error(String(n)),c.warn(`GraphQL request attempt ${s}/${this.options.maxRetries} failed`,{error:r.message,operationName:e.operationName,willRetry:s<this.options.maxRetries}),s<this.options.maxRetries){let i=this.calculateRetryDelay(s);await this.sleep(i)}}throw this.failureCount++,this.options.enableCircuitBreaker&&this.failureCount>=5&&!this.circuitBreakerOpen&&(this.circuitBreakerOpen=!0,c.error("Circuit breaker opened - too many backend failures"),this.emit("circuitBreakerOpened"),setTimeout(()=>{this.circuitBreakerOpen=!1,this.failureCount=0,c.info("Circuit breaker half-open - testing backend"),this.emit("circuitBreakerHalfOpen")},6e4)),r||new Error("All GraphQL request attempts failed")}async mutate(e){return this.query(e)}async post(e){return this.query(e)}async registerWorkspace(e){let s=await this.mutate({query:`
2
+ "use strict";var ji=Object.create;var mt=Object.defineProperty;var Fi=Object.getOwnPropertyDescriptor;var Li=Object.getOwnPropertyNames;var Ui=Object.getPrototypeOf,zi=Object.prototype.hasOwnProperty;var M=(l,r)=>()=>(l&&(r=l(l=0)),r);var Hi=(l,r)=>()=>(r||l((r={exports:{}}).exports,r),r.exports),be=(l,r)=>{for(var e in r)mt(l,e,{get:r[e],enumerable:!0})},Zr=(l,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of Li(r))!zi.call(l,a)&&a!==e&&mt(l,a,{get:()=>r[a],enumerable:!(t=Fi(r,a))||t.enumerable});return l};var A=(l,r,e)=>(e=l!=null?ji(Ui(l)):{},Zr(r||!l||!l.__esModule?mt(e,"default",{value:l,enumerable:!0}):e,l)),ea=l=>Zr(mt({},"__esModule",{value:!0}),l);var v,$i,ta,qi,Bi,Gi,Vi,Ki,Qi,Ji,Yi,Xi,Zi,en,tn,rn,an,ra,or,cr=M(()=>{"use strict";v=require("zod"),$i=v.z.enum(["development","staging","production","test"]),ta=v.z.enum(["error","warn","info","debug","verbose"]),qi=v.z.object({port:v.z.number().int().min(1).max(65535).default(8547),host:v.z.string().default("localhost"),environment:$i.default("development"),logLevel:ta.default("info"),requestTimeout:v.z.number().int().min(1e3).max(6e5).default(3e4),maxRequestSize:v.z.string().default("10mb"),enableCors:v.z.boolean().default(!0),enableHelmet:v.z.boolean().default(!0),enableCompression:v.z.boolean().default(!0)}),Bi=v.z.object({apiUrl:v.z.string().url(),apiKey:v.z.string().optional(),timeout:v.z.number().int().min(1e3).max(6e4).default(3e4),retries:v.z.number().int().min(0).max(10).default(3),retryDelay:v.z.number().int().min(100).max(1e4).default(1e3)}),Gi=v.z.object({url:v.z.string().default("redis://localhost:6379"),host:v.z.string().optional(),port:v.z.number().int().min(1).max(65535).optional(),password:v.z.string().optional(),database:v.z.number().int().min(0).max(15).default(0),keyPrefix:v.z.string().default("ai-agent:"),connectTimeout:v.z.number().int().min(1e3).max(3e4).default(1e4),maxRetriesPerRequest:v.z.number().int().min(0).max(10).default(3)}),Vi=v.z.object({apiKey:v.z.string().optional(),baseUrl:v.z.string().url().optional(),model:v.z.string().default("claude-3-5-sonnet-20241022"),maxRetries:v.z.number().int().min(0).max(10).default(3),timeoutMs:v.z.number().int().min(1e3).max(3e5).default(6e4),maxTokens:v.z.number().int().min(100).max(8192).default(4096),temperature:v.z.number().min(0).max(1).default(.7),commandPath:v.z.string().default("claude")}),Ki=v.z.object({tokenLimit:v.z.number().int().min(1e3).max(1e6).default(1e4),requestsPerMinute:v.z.number().int().min(1).max(1e3).default(60),requestsPerHour:v.z.number().int().min(1).max(1e4).default(1e3),burstLimit:v.z.number().int().min(1).max(100).default(10),windowSizeMs:v.z.number().int().min(1e3).max(36e5).default(6e4)}),Qi=v.z.enum(["project_review","implementation_plan","story_implementation","task_completion","code_review","review_application"]),Ji=v.z.object({maxConcurrentJobs:v.z.number().int().min(1).max(10).default(3),jobTimeout:v.z.number().int().min(3e4).max(18e5).default(3e5),retryAttempts:v.z.number().int().min(0).max(5).default(2),retryDelay:v.z.number().int().min(1e3).max(6e4).default(5e3),healthCheckInterval:v.z.number().int().min(5e3).max(3e5).default(3e4),enabledCapabilities:v.z.array(Qi).default(["project_review","implementation_plan","story_implementation","task_completion","code_review","review_application"])}),Yi=v.z.object({path:v.z.string().default("./data/ai-agent.db"),backupEnabled:v.z.boolean().default(!0),backupInterval:v.z.number().int().min(36e5).max(864e5).default(36e5),maxBackups:v.z.number().int().min(1).max(30).default(7),vacuumInterval:v.z.number().int().min(864e5).max(6048e5).default(864e5)}),Xi=v.z.object({enableApiKeyAuth:v.z.boolean().default(!1),apiKeys:v.z.array(v.z.string()).default([]),allowedOrigins:v.z.array(v.z.string()).default(["http://localhost:3000","http://localhost:5173"]),enableHttps:v.z.boolean().default(!1),httpsOptions:v.z.object({keyPath:v.z.string().optional(),certPath:v.z.string().optional()}).optional(),sessionSecret:v.z.string().min(32).optional()}),Zi=v.z.object({enableMetrics:v.z.boolean().default(!0),metricsPort:v.z.number().int().min(1).max(65535).default(9090),enableHealthChecks:v.z.boolean().default(!0),healthCheckPath:v.z.string().default("/health"),enableProfiling:v.z.boolean().default(!1)}),en=v.z.object({level:ta.default("info"),enableConsole:v.z.boolean().default(!0),enableFile:v.z.boolean().default(!0),logDirectory:v.z.string().default("./logs"),maxFileSize:v.z.string().default("100MB"),maxFiles:v.z.number().int().min(1).max(100).default(10),datePattern:v.z.string().default("YYYY-MM-DD"),enableRotation:v.z.boolean().default(!0),enableJson:v.z.boolean().default(!1)}),tn=v.z.object({enableWebInterface:v.z.boolean().default(!0),enableApiDocumentation:v.z.boolean().default(!0),enableMetricsApi:v.z.boolean().default(!0),enableWorkspaceAnalysis:v.z.boolean().default(!0),enableMultiWorkspace:v.z.boolean().default(!0),enableClaudeApiIntegration:v.z.boolean().default(!0),enableExperimentalFeatures:v.z.boolean().default(!1)}),rn=v.z.object({id:v.z.string().min(1),name:v.z.string().min(1),domain:v.z.string().optional(),apiUrl:v.z.string().url(),wsUrl:v.z.string().url().optional(),apiKey:v.z.string().min(1),enabled:v.z.boolean().default(!0),metadata:v.z.object({description:v.z.string().optional(),color:v.z.string().optional(),logo:v.z.string().url().optional(),addedAt:v.z.string().optional()}).optional()}),an=v.z.object({setupCompleted:v.z.boolean().default(!1),defaultOrganization:v.z.string().optional(),organizations:v.z.record(v.z.string(),rn).default({})}),ra=v.z.object({server:qi,taskShepherd:Bi,redis:Gi,claude:Vi,rateLimit:Ki,worker:Ji,database:Yi,security:Xi,monitoring:Zi,logging:en,features:tn,multiOrg:an.default({})}),or={server:{port:8547,host:"localhost",environment:"development",logLevel:"info",requestTimeout:3e4,maxRequestSize:"10mb",enableCors:!0,enableHelmet:!0,enableCompression:!0},taskShepherd:{apiUrl:"",timeout:3e4,retries:3,retryDelay:1e3},redis:{url:"redis://localhost:6379",database:0,keyPrefix:"ai-agent:",connectTimeout:1e4,maxRetriesPerRequest:3},claude:{model:"claude-3-5-sonnet-20241022",maxRetries:3,timeoutMs:6e4,maxTokens:4096,temperature:.7,commandPath:"claude"},rateLimit:{tokenLimit:1e4,requestsPerMinute:60,requestsPerHour:1e3,burstLimit:10,windowSizeMs:6e4},worker:{maxConcurrentJobs:3,jobTimeout:3e5,retryAttempts:2,retryDelay:5e3,healthCheckInterval:3e4,enabledCapabilities:["project_review","implementation_plan","story_implementation","task_completion","code_review","review_application"]},database:{path:"./data/ai-agent.db",backupEnabled:!0,backupInterval:36e5,maxBackups:7,vacuumInterval:864e5},security:{enableApiKeyAuth:!1,apiKeys:[],allowedOrigins:["http://localhost:3000","http://localhost:5173"],enableHttps:!1},monitoring:{enableMetrics:!0,metricsPort:9090,enableHealthChecks:!0,healthCheckPath:"/health",enableProfiling:!1},logging:{level:"info",enableConsole:!0,enableFile:!0,logDirectory:"./logs",maxFileSize:"100MB",maxFiles:10,datePattern:"YYYY-MM-DD",enableRotation:!0,enableJson:!1},features:{enableWebInterface:!0,enableApiDocumentation:!0,enableMetricsApi:!0,enableWorkspaceAnalysis:!0,enableMultiWorkspace:!0,enableClaudeApiIntegration:!0,enableExperimentalFeatures:!1},multiOrg:{setupCompleted:!1,organizations:{}}}});function ur(l){return lr||(lr=new pr(l)),lr}function yt(){return ur().getConfig()}var Me,Ae,aa,pr,lr,ht=M(()=>{"use strict";Me=A(require("fs")),Ae=A(require("path")),aa=require("events");cr();pr=class extends aa.EventEmitter{constructor(e={}){super();this.watchers=new Map;this.lastValidation=null;this.options={configDir:Ae.resolve(process.cwd(),"config"),environment:e.environment||"production",enableHotReload:!1,hotReloadInterval:1e3,additionalConfigFiles:[],strictValidation:!1,...e},this.config={...or},this.configMetadata={config:this.config,sources:{},validatedAt:new Date,environment:this.options.environment},this.loadConfiguration()}getConfig(){return{...this.config}}getConfigWithMetadata(){return{...this.configMetadata}}get(e){return this.config[e]}getLastValidation(){return this.lastValidation}async reloadConfiguration(){return this.loadConfiguration()}validateConfiguration(){return this.validateConfig(this.config)}loadConfiguration(){try{let e={},t={...or};this.trackConfigSources(t,e,"default","built-in defaults",0);let a=this.loadConfigFile("config.json",e,1);a&&(t=this.mergeConfig(t,a));let i=this.loadConfigFile(`config.${this.options.environment}.json`,e,2);i&&(t=this.mergeConfig(t,i)),this.options.additionalConfigFiles.forEach((c,d)=>{let p=this.loadConfigFile(c,e,3+d);p&&(t=this.mergeConfig(t,p))});let n=this.loadEnvironmentOverrides();Object.keys(n).length>0&&(t=this.mergeConfig(t,n),this.trackConfigSources(n,e,"environment","environment variables",100));let o=this.validateConfig(t);if(o.success&&o.data){let c={...this.config};this.config=o.data,this.configMetadata={config:this.config,sources:e,validatedAt:new Date,environment:this.options.environment},JSON.stringify(c)!==JSON.stringify(this.config)&&this.emit("configurationChanged",{oldConfig:c,newConfig:this.config,sources:e})}return this.lastValidation=o,this.options.enableHotReload&&this.setupHotReloading(),o}catch(e){return console.error("Critical error in configuration loading:",e),{success:!1,errors:[{path:"configuration",message:`Configuration loading failed: ${e instanceof Error?e.message:"Unknown error"}`,code:"CONFIG_LOAD_ERROR"}],warnings:[]}}}loadConfigFile(e,t,a){let i=Ae.isAbsolute(e)?e:Ae.join(this.options.configDir,e);try{if(!Me.existsSync(i))return null;let n=Me.readFileSync(i,"utf-8"),o=JSON.parse(n);return this.trackConfigSources(o,t,"file",i,a),o}catch(n){return console.warn(`Failed to load configuration file ${i}:`,n),null}}loadEnvironmentOverrides(){let e={};if(process.env.PORT&&(e.server={...e.server,port:parseInt(process.env.PORT)}),process.env.HOST&&(e.server={...e.server,host:process.env.HOST}),process.env.LOG_LEVEL&&(e.server={...e.server,logLevel:process.env.LOG_LEVEL}),e.server={...e.server,environment:"production"},process.env.TASK_SHEPHERD_API_URL&&(e.taskShepherd={...e.taskShepherd,apiUrl:process.env.TASK_SHEPHERD_API_URL}),process.env.TASK_SHEPHERD_API_KEY&&(e.taskShepherd={...e.taskShepherd,apiKey:process.env.TASK_SHEPHERD_API_KEY}),process.env.TASK_SHEPHERD_WS_URL&&(e.taskShepherd={...e.taskShepherd,wsUrl:process.env.TASK_SHEPHERD_WS_URL}),process.env.TASK_SHEPHERD_ENABLE_WEBSOCKET!==void 0&&(e.taskShepherd={...e.taskShepherd,enableWebSocket:process.env.TASK_SHEPHERD_ENABLE_WEBSOCKET==="true"}),process.env.REDIS_URL&&(e.redis={...e.redis,url:process.env.REDIS_URL}),process.env.REDIS_HOST&&(e.redis={...e.redis,host:process.env.REDIS_HOST}),process.env.REDIS_PORT&&(e.redis={...e.redis,port:parseInt(process.env.REDIS_PORT)}),process.env.REDIS_PASSWORD&&(e.redis={...e.redis,password:process.env.REDIS_PASSWORD}),process.env.ANTHROPIC_API_KEY&&(e.claude={...e.claude,apiKey:process.env.ANTHROPIC_API_KEY}),process.env.ANTHROPIC_BASE_URL&&(e.claude={...e.claude,baseUrl:process.env.ANTHROPIC_BASE_URL}),process.env.CLAUDE_MODEL&&(e.claude={...e.claude,model:process.env.CLAUDE_MODEL}),process.env.CLAUDE_COMMAND_PATH&&(e.claude={...e.claude,commandPath:process.env.CLAUDE_COMMAND_PATH}),process.env.MAX_CONCURRENT_JOBS&&(e.worker={...e.worker,maxConcurrentJobs:parseInt(process.env.MAX_CONCURRENT_JOBS)}),process.env.JOB_TIMEOUT&&(e.worker={...e.worker,jobTimeout:parseInt(process.env.JOB_TIMEOUT)}),process.env.CAPABILITIES||process.env.AGENT_CAPABILITIES){let t=(process.env.CAPABILITIES||process.env.AGENT_CAPABILITIES||"").split(",").map(a=>a.trim());e.worker={...e.worker,enabledCapabilities:t}}if(process.env.TOKEN_RATE_LIMIT&&(e.rateLimit={...e.rateLimit,tokenLimit:parseInt(process.env.TOKEN_RATE_LIMIT)}),process.env.DB_PATH&&(e.database={...e.database,path:process.env.DB_PATH}),process.env.API_KEYS){let t=process.env.API_KEYS.split(",").map(a=>a.trim());e.security={...e.security,apiKeys:t,enableApiKeyAuth:!0}}return e}trackConfigSources(e,t,a,i,n){let o=(c,d="")=>{for(let[p,u]of Object.entries(c)){let h=d?`${d}.${p}`:p;u&&typeof u=="object"&&!Array.isArray(u)?o(u,h):t[h]={type:a,source:i,priority:n}}};o(e)}mergeConfig(e,t){let a={...e};for(let[i,n]of Object.entries(t))n&&typeof n=="object"&&!Array.isArray(n)?a[i]=this.mergeConfig(e[i]||{},n):a[i]=n;return a}validateConfig(e){let t=ra.safeParse(e);return t.success?{success:!0,data:t.data,errors:[],warnings:this.generateWarnings(t.data)}:{success:!1,errors:t.error.issues.map(a=>({path:a.path.join("."),message:a.message,code:a.code})),warnings:[]}}generateWarnings(e){let t=[];return e.server.environment==="development"&&(!e.claude.apiKey&&!e.claude.commandPath&&t.push({path:"claude.apiKey",message:"No Claude API key or command path configured",suggestion:"Set ANTHROPIC_API_KEY environment variable or ensure Claude CLI is installed"}),e.security.enableHttps&&t.push({path:"security.enableHttps",message:"HTTPS enabled in development mode",suggestion:"Consider disabling HTTPS for local development"})),e.server.environment==="production"&&(e.security.enableHttps||t.push({path:"security.enableHttps",message:"HTTPS disabled in production",suggestion:"Enable HTTPS for production deployment"}),e.security.enableApiKeyAuth||t.push({path:"security.enableApiKeyAuth",message:"API key authentication disabled in production",suggestion:"Enable API key authentication for production security"}),(e.server.logLevel==="debug"||e.server.logLevel==="verbose")&&t.push({path:"server.logLevel",message:"Debug logging enabled in production",suggestion:'Use "info" or "warn" log level for production'})),t}setupHotReloading(){this.watchers.forEach(t=>t.close()),this.watchers.clear(),[Ae.join(this.options.configDir,"config.json"),Ae.join(this.options.configDir,`config.${this.options.environment}.json`),...this.options.additionalConfigFiles].forEach(t=>{if(Me.existsSync(t)){let a=Me.watch(t,i=>{i==="change"&&setTimeout(()=>{console.log(`Configuration file changed: ${t}`);let n=this.loadConfiguration();n.success?(console.log("Configuration reloaded successfully"),this.emit("configurationReloaded",this.config)):(console.error("Configuration reload failed:",n.errors),this.emit("configurationError",n.errors))},this.options.hotReloadInterval)});this.watchers.set(t,a)}})}destroy(){this.watchers.forEach(e=>e.close()),this.watchers.clear(),this.removeAllListeners()}},lr=null});var ia={};be(ia,{detectClaude:()=>nn,detectClaudeSync:()=>dr,getClaudeCommandPath:()=>gr});function nn(l="claude"){return dr(l)}function dr(l="claude"){if(Xe(l))return{available:!0,path:l,method:"direct"};if(l==="claude"){let r=[process.env.HOME+"/.claude/local/claude","/usr/local/bin/claude","/opt/homebrew/bin/claude"].filter(e=>e);for(let e of r)if(Xe(e))return{available:!0,path:e,method:"direct"};try{let e=(0,St.execSync)('bash -c "which claude"',{encoding:"utf8",stdio:"pipe"}).trim();if(e&&!e.includes("aliased to")&&Xe(e))return{available:!0,path:e,method:"which"};if(e.includes("aliased to ")){let t=e.split("aliased to ")[1];if(t&&Xe(t))return{available:!0,path:t,method:"which"}}}catch{}try{let t=(0,St.execSync)("where claude",{encoding:"utf8",stdio:"pipe"}).trim().split(`
3
+ `)[0];if(t&&Xe(t))return{available:!0,path:t,method:"where"}}catch{}}return{available:!1,method:"none"}}function Xe(l){try{return(0,St.execSync)(`"${l}" --version`,{stdio:"pipe"}),!0}catch{return!1}}function gr(l="claude"){return dr(l).path||l}var St,mr=M(()=>{"use strict";St=require("child_process")});function sa(l){return yr.validateConfiguration(l)}var Ee,na,yr,hr=M(()=>{"use strict";Ee=A(require("fs")),na=A(require("path")),yr=class{static validateConfiguration(r){let e=[],t=[];return this.isMultiOrgMode()?{valid:!0,errors:[],warnings:[]}:(this.validateServerConfig(r,e,t),this.validateTaskShepherdConfig(r,e,t),this.validateRedisConfig(r,e,t),this.validateClaudeConfig(r,e,t),this.validateDatabaseConfig(r,e,t),this.validateSecurityConfig(r,e,t),this.validateLoggingConfig(r,e,t),this.validateConfigurationDependencies(r,e,t),{valid:e.length===0,errors:e,warnings:t})}static isMultiOrgMode(){let r=require("fs"),e=require("path"),t=require("os"),a=e.join(t.homedir(),".task-shepherd-agent","config.json");return r.existsSync(a)}static validateServerConfig(r,e,t){let{server:a}=r;a.port<1024&&typeof process.getuid=="function"&&process.getuid()!==0&&t.push({path:"server.port",message:`Port ${a.port} requires root privileges`,code:"PRIVILEGED_PORT",severity:"warning",suggestion:"Use a port number above 1024 for non-root users"}),a.environment==="production"&&(a.logLevel==="debug"||a.logLevel==="verbose")&&t.push({path:"server.logLevel",message:"Debug logging enabled in production",code:"PRODUCTION_DEBUG_LOG",severity:"warning",suggestion:'Use "info" or "warn" log level for production'}),a.requestTimeout<5e3&&t.push({path:"server.requestTimeout",message:"Request timeout is very low",code:"LOW_REQUEST_TIMEOUT",severity:"warning",suggestion:"Consider increasing timeout for AI operations"})}static validateTaskShepherdConfig(r,e,t){let{taskShepherd:a}=r;if(a){try{new URL(a.apiUrl)}catch{e.push({path:"taskShepherd.apiUrl",message:"Invalid Task Shepherd API URL format",code:"INVALID_URL",severity:"error",suggestion:"Provide a valid HTTP/HTTPS URL"})}r.server.environment==="production"&&!a.apiKey&&t.push({path:"taskShepherd.apiKey",message:"No API key configured for production",code:"MISSING_API_KEY",severity:"warning",suggestion:"Set TASK_SHEPHERD_API_KEY environment variable"}),a.timeout>6e4&&t.push({path:"taskShepherd.timeout",message:"Task Shepherd API timeout is very high",code:"HIGH_TIMEOUT",severity:"warning",suggestion:"Consider reducing timeout to improve responsiveness"})}}static validateRedisConfig(r,e,t){let{redis:a}=r;if(!a){e.push({path:"redis",message:"Redis configuration is missing",code:"MISSING_REDIS_CONFIG",severity:"error"});return}a.url&&!a.url.startsWith("redis://")&&!a.url.startsWith("rediss://")&&e.push({path:"redis.url",message:"Invalid Redis URL format",code:"INVALID_REDIS_URL",severity:"error",suggestion:"Use redis:// or rediss:// protocol"}),(a.database<0||a.database>15)&&e.push({path:"redis.database",message:"Redis database number must be between 0 and 15",code:"INVALID_DB_NUMBER",severity:"error"}),a.connectTimeout<1e3&&t.push({path:"redis.connectTimeout",message:"Redis connection timeout is very low",code:"LOW_CONNECT_TIMEOUT",severity:"warning",suggestion:"Consider increasing timeout for reliable connections"})}static validateClaudeConfig(r,e,t){let{claude:a}=r;if(!a.apiKey&&!this.isClaudeCliAvailable(a.commandPath)&&e.push({path:"claude.apiKey",message:"No Claude API key configured and CLI not available",code:"MISSING_CLAUDE_AUTH",severity:"error",suggestion:"Set ANTHROPIC_API_KEY or install Claude CLI"}),a.baseUrl)try{new URL(a.baseUrl)}catch{e.push({path:"claude.baseUrl",message:"Invalid Claude base URL format",code:"INVALID_BASE_URL",severity:"error"})}let i=["claude-3-5-sonnet-20241022","claude-3-haiku-20240307","claude-3-opus-20240229"];a.model&&!i.includes(a.model)&&t.push({path:"claude.model",message:"Unknown Claude model specified",code:"UNKNOWN_MODEL",severity:"warning",suggestion:`Use one of: ${i.join(", ")}`}),a.timeoutMs<3e4&&t.push({path:"claude.timeoutMs",message:"Claude timeout is very low for AI operations",code:"LOW_AI_TIMEOUT",severity:"warning",suggestion:"Consider at least 30 seconds for AI operations"}),(a.temperature<0||a.temperature>1)&&e.push({path:"claude.temperature",message:"Claude temperature must be between 0 and 1",code:"INVALID_TEMPERATURE",severity:"error"})}static validateDatabaseConfig(r,e,t){let{database:a}=r;if(!a){e.push({path:"database",message:"Database configuration is missing",code:"MISSING_DATABASE_CONFIG",severity:"error"});return}let i=na.dirname(a.path);try{Ee.existsSync(i)||Ee.mkdirSync(i,{recursive:!0})}catch{e.push({path:"database.path",message:`Cannot create database directory: ${i}`,code:"INVALID_DB_PATH",severity:"error",suggestion:"Ensure the directory is writable"})}a.backupEnabled&&a.maxBackups<1&&e.push({path:"database.maxBackups",message:"Maximum backups must be at least 1 when backup is enabled",code:"INVALID_BACKUP_COUNT",severity:"error"}),a.backupEnabled&&a.backupInterval<6e4&&t.push({path:"database.backupInterval",message:"Backup interval is very frequent",code:"FREQUENT_BACKUP",severity:"warning",suggestion:"Consider longer intervals to reduce I/O overhead"})}static validateSecurityConfig(r,e,t){let{security:a}=r;if(!a){e.push({path:"security",message:"Security configuration is missing",code:"MISSING_SECURITY_CONFIG",severity:"error"});return}if(r.server.environment==="production"&&(a.enableHttps||t.push({path:"security.enableHttps",message:"HTTPS disabled in production",code:"PRODUCTION_HTTP",severity:"warning",suggestion:"Enable HTTPS for production deployment"}),a.enableApiKeyAuth||t.push({path:"security.enableApiKeyAuth",message:"API key authentication disabled in production",code:"PRODUCTION_NO_AUTH",severity:"warning",suggestion:"Enable API key authentication for security"})),a.enableHttps&&a.httpsOptions){let{keyPath:i,certPath:n}=a.httpsOptions;i&&!Ee.existsSync(i)&&e.push({path:"security.httpsOptions.keyPath",message:"SSL private key file not found",code:"MISSING_SSL_KEY",severity:"error"}),n&&!Ee.existsSync(n)&&e.push({path:"security.httpsOptions.certPath",message:"SSL certificate file not found",code:"MISSING_SSL_CERT",severity:"error"})}a.enableApiKeyAuth&&a.apiKeys.length===0&&e.push({path:"security.apiKeys",message:"API key authentication enabled but no keys configured",code:"NO_API_KEYS",severity:"error",suggestion:"Configure API keys or disable authentication"}),a.sessionSecret&&a.sessionSecret.length<32&&t.push({path:"security.sessionSecret",message:"Session secret should be at least 32 characters",code:"WEAK_SESSION_SECRET",severity:"warning",suggestion:"Use a longer, randomly generated secret"})}static validateLoggingConfig(r,e,t){let{logging:a}=r;if(a.enableFile)try{Ee.existsSync(a.logDirectory)||Ee.mkdirSync(a.logDirectory,{recursive:!0})}catch{e.push({path:"logging.logDirectory",message:`Cannot create log directory: ${a.logDirectory}`,code:"INVALID_LOG_DIR",severity:"error",suggestion:"Ensure the directory is writable"})}a.maxFiles<1&&e.push({path:"logging.maxFiles",message:"Maximum log files must be at least 1",code:"INVALID_MAX_FILES",severity:"error"}),/^(\d+)(KB|MB|GB)$/i.test(a.maxFileSize)||e.push({path:"logging.maxFileSize",message:"Invalid log file size format",code:"INVALID_FILE_SIZE",severity:"error",suggestion:'Use format like "100MB", "1GB", etc.'})}static validateConfigurationDependencies(r,e,t){let a=r.worker.maxConcurrentJobs,i=r.rateLimit.requestsPerMinute;a*10>i&&t.push({path:"rateLimit.requestsPerMinute",message:"Rate limit may be too low for configured concurrent jobs",code:"RATE_LIMIT_TOO_LOW",severity:"warning",suggestion:"Increase rate limit or reduce concurrent jobs"}),r.monitoring.metricsPort===r.server.port&&e.push({path:"monitoring.metricsPort",message:"Metrics port conflicts with server port",code:"PORT_CONFLICT",severity:"error",suggestion:"Use different ports for metrics and main server"}),r.features.enableMetricsApi&&!r.monitoring.enableMetrics&&t.push({path:"features.enableMetricsApi",message:"Metrics API enabled but metrics collection disabled",code:"METRICS_DEPENDENCY",severity:"warning",suggestion:"Enable metrics collection or disable metrics API"})}static isClaudeCliAvailable(r){let{detectClaudeSync:e}=(mr(),ea(ia));return e(r).available}}});function sn(){let l=yt();return{port:l.server.port,nodeEnv:l.server.environment,taskShepherdApiUrl:l.taskShepherd.apiUrl,taskShepherdApiKey:l.taskShepherd.apiKey,redisUrl:l.redis.url,claudeCommandPath:l.claude.commandPath,claudeApiKey:l.claude.apiKey,claudeBaseUrl:l.claude.baseUrl,claudeModel:l.claude.model,claudeMaxRetries:l.claude.maxRetries,claudeTimeoutMs:l.claude.timeoutMs,maxConcurrentJobs:l.worker.maxConcurrentJobs,tokenRateLimit:l.rateLimit.tokenLimit,logLevel:l.server.logLevel}}var Sr,on,je,oa=M(()=>{"use strict";cr();ht();hr();ht();hr();Sr=sn(),on=ur(),je={warnings:[]};if(je=sa(on.getConfig()),!je.valid&&(console.error("Configuration validation failed:"),je.errors.forEach(l=>{console.error(` - ${l.path}: ${l.message}`)}),je.errors.some(l=>l.severity==="error")))throw new Error("Configuration contains critical errors. Please fix them before starting the service.");je.warnings.length>0&&(console.warn("Configuration warnings:"),je.warnings.forEach(l=>{console.warn(` - ${l.path}: ${l.message}`),l.suggestion&&console.warn(` Suggestion: ${l.suggestion}`)}))});var le,s,j=M(()=>{"use strict";le=A(require("winston"));oa();s=le.default.createLogger({level:Sr.nodeEnv==="development"?"debug":"info",format:le.default.format.combine(le.default.format.timestamp(),le.default.format.errors({stack:!0}),le.default.format.json()),defaultMeta:{service:"agent"},transports:[new le.default.transports.File({filename:"logs/error.log",level:"error",maxsize:100*1024*1024,maxFiles:5,tailable:!0}),new le.default.transports.File({filename:"logs/combined.log",maxsize:100*1024*1024,maxFiles:5,tailable:!0})]});Sr.nodeEnv!=="production"&&s.add(new le.default.transports.Console({format:le.default.format.combine(le.default.format.colorize(),le.default.format.simple())}))});var Fe,fr,Q,ft,Z,Ze=M(()=>{"use strict";Fe=require("fs"),fr=A(require("path")),Q=A(require("os")),ft=A(require("crypto"));j();Z=class{constructor(r){this.configDir=r||fr.default.join(Q.default.homedir(),".task-shepherd-agent"),this.identityFile=fr.default.join(this.configDir,"agent-identity.json")}async initializeIdentity(r){let e=await this.loadExistingIdentity();if(e&&r.persistent!==!1)return e.lastUsed=new Date().toISOString(),await this.saveIdentity(e),s.info("Using existing agent identity",{agentId:e.agentId,agentName:e.agentName,service:"identity"}),this.currentIdentity=e,e;let t=await this.generateNewIdentity(r);return r.persistent!==!1&&await this.saveIdentity(t),this.currentIdentity=t,s.info("Generated new agent identity",{agentId:t.agentId,agentName:t.agentName,strategy:r.strategy,service:"identity"}),t}async generateNewIdentity(r){let e=Q.default.hostname(),t=Q.default.platform(),a=Q.default.userInfo().username,i="production",n,o;switch(r.strategy){case"hostname":n=await this.generateHostnameBasedId(r),o=r.customName||`AI Agent (${e})`;break;case"user-configured":n=await this.generateUserConfiguredId(r),o=r.customName||`AI Agent (${n})`;break;case"machine-fingerprint":n=await this.generateMachineFingerprintId(r),o=r.customName||`AI Agent (${e})`;break;case"hybrid":n=await this.generateHybridId(r),o=r.customName||`AI Agent (${this.extractReadablePart(n)})`;break;default:throw new Error(`Unknown identity strategy: ${r.strategy}`)}return{agentId:n,agentName:o,hostname:e,platform:t,userId:a,environment:i,createdAt:new Date().toISOString(),lastUsed:new Date().toISOString(),version:process.env.npm_package_version||"1.0.0"}}async generateHostnameBasedId(r){let e=Q.default.hostname(),t=[];r.prefix&&t.push(r.prefix);let a=e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").substring(0,20);if(t.push(a),r.includeUser){let i=Q.default.userInfo().username.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,10);t.push(i)}if(r.includeEnvironment){let i="production".substring(0,4);t.push(i)}return r.suffix&&t.push(r.suffix),t.join("-")}async generateUserConfiguredId(r){if(r.customName){let t=[r.customName.toLowerCase().replace(/[^a-z0-9-\s]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").substring(0,30)];if(r.includeEnvironment){let i="production".substring(0,4);t.push(i)}let a=ft.default.createHash("md5").update(Q.default.hostname()+Q.default.userInfo().username).digest("hex").substring(0,4);return t.push(a),t.join("-")}return this.generateInteractiveId(r)}async generateMachineFingerprintId(r){let e=this.getMachineFingerprint(),t=ft.default.createHash("sha256").update(e).digest("hex").substring(0,12),a=[];return r.prefix&&a.push(r.prefix),a.push("agent"),a.push(t),r.suffix&&a.push(r.suffix),a.join("-")}async generateHybridId(r){let e=Q.default.hostname(),t=Q.default.userInfo().username,a=e.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,8),i=ft.default.createHash("md5").update(`${e}-${t}-${Q.default.platform()}`).digest("hex").substring(0,6),n=[];if(r.prefix&&n.push(r.prefix),n.push(a),n.push(i),r.includeEnvironment){let o="production".substring(0,3);n.push(o)}return r.suffix&&n.push(r.suffix),n.join("-")}async generateInteractiveId(r){let t=`ai-agent-${Q.default.hostname().toLowerCase().substring(0,8)}`;return s.info("Using default agent ID (interactive mode not available)",{defaultId:t,service:"identity"}),t}getMachineFingerprint(){return[Q.default.hostname(),Q.default.platform(),Q.default.arch(),Q.default.userInfo().username,JSON.stringify(Object.keys(Q.default.networkInterfaces()).sort())].join("|")}extractReadablePart(r){let e=r.split("-");return e.length>1?e[1]:r}async loadExistingIdentity(){try{let r=await Fe.promises.readFile(this.identityFile,"utf8"),e=JSON.parse(r);return e.agentId&&e.agentName&&e.createdAt?e:(s.warn("Invalid identity file format, will regenerate",{service:"identity"}),null)}catch(r){return r.code!=="ENOENT"&&s.warn("Failed to load existing identity",{error:r instanceof Error?r.message:String(r),service:"identity"}),null}}async saveIdentity(r){try{await Fe.promises.mkdir(this.configDir,{recursive:!0}),await Fe.promises.writeFile(this.identityFile,JSON.stringify(r,null,2),"utf8"),s.info("Agent identity saved",{agentId:r.agentId,configDir:this.configDir,service:"identity"})}catch(e){throw s.error("Failed to save agent identity",{error:e instanceof Error?e.message:String(e),configDir:this.configDir,service:"identity"}),e}}getCurrentIdentity(){return this.currentIdentity||null}async updateIdentity(r){if(!this.currentIdentity)throw new Error("No current identity to update");let e={...this.currentIdentity,...r,lastUsed:new Date().toISOString()};return await this.saveIdentity(e),this.currentIdentity=e,s.info("Agent identity updated",{agentId:e.agentId,updates:Object.keys(r),service:"identity"}),e}async resetIdentity(){try{await Fe.promises.unlink(this.identityFile),this.currentIdentity=void 0,s.info("Agent identity reset",{service:"identity"})}catch(r){if(r.code!=="ENOENT")throw s.error("Failed to reset agent identity",{error:r instanceof Error?r.message:String(r),service:"identity"}),r}}getAvailableStrategies(){return[{strategy:"hostname",description:"Use machine hostname as base (most readable)",example:"macbook-pro-dev"},{strategy:"user-configured",description:"User provides custom name with uniqueness suffix",example:"my-ai-assistant-a4f2"},{strategy:"machine-fingerprint",description:"Generate from machine characteristics (most stable)",example:"agent-7f4e2a8b9c1d"},{strategy:"hybrid",description:"Combine readable hostname with unique suffix (balanced)",example:"macbook-7f4e2a-dev"}]}validateAgentId(r){let e=[];return r.length<3&&e.push("Agent ID must be at least 3 characters long"),r.length>50&&e.push("Agent ID must be no more than 50 characters long"),/^[a-z0-9-]+$/i.test(r)||e.push("Agent ID can only contain letters, numbers, and hyphens"),(r.startsWith("-")||r.endsWith("-"))&&e.push("Agent ID cannot start or end with a hyphen"),r.includes("--")&&e.push("Agent ID cannot contain consecutive hyphens"),{valid:e.length===0,errors:e}}getIdentityFilePath(){return this.identityFile}async identityExists(){try{return await Fe.promises.access(this.identityFile),!0}catch{return!1}}}});var ua=Hi((us,cn)=>{cn.exports={name:"@task-shepherd/agent",version:"1.0.11",description:"Simplified AI agent service for Task Shepherd project analysis",main:"dist/index.js",bin:{"task-shepherd-agent":"dist/cli/index.js"},files:["dist","mcp-agent","node_modules/@task-shepherd/shared","web/dist","README.md","LICENSE.md"],engines:{node:">=18.0.0"},scripts:{dev:"ts-node-dev --respawn --transpile-only src/index.ts",build:"node build.js","build:dev":"node build-dev.js","build:tsc":"tsc","build:prod":"npm run build && npm run build:web",start:"node dist/index.js","type-check":"tsc --noEmit",lint:"eslint src/**/*.ts --fix",kill:"(lsof -ti:8547,8548 | xargs kill -9 2>/dev/null) || pkill -f 'node.*agent|ts-node-dev.*agent' || echo 'AI agent service stopped'",test:"jest",prepublishOnly:"npm run build","test:workqueue":"jest --config jest.workqueue.config.js","test:workqueue:watch":"jest --config jest.workqueue.config.js --watch","test:workqueue:coverage":"jest --config jest.workqueue.config.js --coverage","dev:web":"cd web && npm run dev","build:web":"cd web && npm run build","dev:all":'concurrently "npm run dev" "npm run dev:web"',codegen:"graphql-codegen --config codegen.yml","agent:init":"ts-node src/cli/index.ts init","agent:status":"ts-node src/cli/index.ts status","reset:config":"node reset-org-config.js","agent:identity:show":"ts-node src/cli/index.ts identity show","agent:identity:reset":"ts-node src/cli/index.ts identity reset","agent:identity:strategies":"ts-node src/cli/index.ts identity strategies","agent:heartbeat:test":"ts-node src/cli/index.ts heartbeat test","agent:config:validate":"ts-node src/cli/index.ts config validate","agent:config:show":"ts-node src/cli/index.ts config show","agent:cli:help":"ts-node src/cli/index.ts --help"},dependencies:{"@anthropic-ai/sdk":"^0.56.0","@graphql-typed-document-node/core":"^3.2.0",chalk:"^4.1.2",commander:"^11.0.0",compression:"^1.7.4",cors:"^2.8.5",dotenv:"^16.3.1",express:"^4.18.2",glob:"^11.0.3",graphql:"^16.8.0","graphql-request":"^6.1.0","graphql-ws":"^6.0.5",helmet:"^7.0.0",joi:"^17.9.2",prompts:"^2.4.2",semver:"^7.5.4",sqlite3:"^5.1.6",uuid:"^11.1.0",winston:"^3.10.0",ws:"^8.14.2",zod:"^3.22.4"},devDependencies:{"@graphql-codegen/cli":"^5.0.0","@graphql-codegen/client-preset":"^4.1.0","@graphql-codegen/introspection":"^4.0.0","@graphql-codegen/typed-document-node":"^5.0.1","@graphql-codegen/typescript":"^4.0.1","@graphql-codegen/typescript-operations":"^4.0.1","@types/compression":"^1.7.2","@types/cors":"^2.8.13","@types/express":"^4.17.17","@types/glob":"^8.1.0","@types/jest":"^30.0.0","@types/nock":"^10.0.3","@types/node":"^20.4.5","@types/prompts":"^2.4.9","@types/semver":"^7.5.4","@types/uuid":"^9.0.8","@types/ws":"^8.5.8","@typescript-eslint/eslint-plugin":"^6.2.0","@typescript-eslint/parser":"^6.2.0",concurrently:"^8.2.0",esbuild:"^0.19.0",eslint:"^8.45.0","javascript-obfuscator":"^4.1.1",jest:"^29.6.1",nock:"^14.0.7","ts-jest":"^29.1.1","ts-node-dev":"^2.0.0",typescript:"^5.1.6"},keywords:["ai","project-analysis","claude","task-management","ai-agent","project-management","code-analysis"],author:"Task Shepherd Team",license:"SEE LICENSE IN LICENSE.md",repository:{type:"git",url:"https://github.com/taskshepherd/task-shepherd.git",directory:"packages/agent"},bugs:{url:"https://github.com/taskshepherd/task-shepherd/issues"},homepage:"https://taskshepherd.com",publishConfig:{access:"public"}}});function It(){return vr||(vr=new Ir),vr}var ln,re,Ir,vr,wr=M(()=>{"use strict";j();ln=ua(),re={version:ln.version||"1.0.0",buildTimestamp:process.env.BUILD_TIMESTAMP||new Date().toISOString(),commitHash:process.env.GIT_COMMIT_HASH||"dev",compatibility:{minBackendVersion:"1.0.0",maxBackendVersion:"3.0.0",supportedBackendMajors:[1,2]},features:{workspaceAutoDiscovery:!0,realTimeUpdates:!0,multiProjectAnalysis:!1,advancedReporting:!0},releaseChannel:process.env.RELEASE_CHANNEL||"stable",releaseNotes:"See CHANGELOG.md for detailed release notes",deprecationWarnings:[]},Ir=class{getVersionMetadata(){return{...re}}getVersion(){return re.version}getBuildInfo(){return{version:re.version,buildTimestamp:re.buildTimestamp,commitHash:re.commitHash,releaseChannel:re.releaseChannel}}getCompatibilityRequirements(){return{...re.compatibility}}getFeatureCapabilities(){return{...re.features}}logVersionInfo(){s.info("Agent version information",{version:re.version,buildTimestamp:re.buildTimestamp,commitHash:re.commitHash,releaseChannel:re.releaseChannel,compatibilityRequirements:re.compatibility,features:re.features})}},vr=null});var ga={};be(ga,{GraphQLHttpClient:()=>me,getGraphQLHttpClient:()=>Ne,initializeGraphQLHttpClient:()=>pn});function Ne(l){return s.debug("getGraphQLHttpClient called",{hasExistingClient:!!de,hasOptions:!!l,optionsProvided:l?JSON.stringify(l,null,2):"none"}),de||(s.info("Creating new HTTP client singleton via getGraphQLHttpClient"),de=new me(l)),s.debug("Returning HTTP client",{clientExists:!!de}),de}function pn(l){return s.info("initializeGraphQLHttpClient called",{providedOptions:JSON.stringify(l,null,2),hasExistingClient:!!de}),de&&(s.info("Destroying existing HTTP client"),de.destroy()),de=new me(l),s.info("New HTTP client singleton created",{clientExists:!!de}),de}var da,me,de,Ue=M(()=>{"use strict";da=require("events");j();ht();wr();me=class extends da.EventEmitter{constructor(e={}){super();this.healthCheckTimer=null;this.isHealthy=!1;this.circuitBreakerOpen=!1;this.failureCount=0;this.lastHealthCheck=0;let t=yt();s.info("GraphQL HTTP Client constructor called",{providedOptionsApiKey:e.apiKey?e.apiKey.substring(0,12)+"...":"none",configApiKey:t.taskShepherd.apiKey?t.taskShepherd.apiKey.substring(0,12)+"...":"none",configApiUrl:t.taskShepherd.apiUrl});let a=e.apiKey||t.taskShepherd.apiKey;a||s.error("CRITICAL: No API key available for GraphQL HTTP Client",{providedOptionsApiKey:e.apiKey?e.apiKey.substring(0,12)+"...":"none",configApiKey:t.taskShepherd.apiKey?t.taskShepherd.apiKey.substring(0,12)+"...":"none",configKeys:Object.keys(t.taskShepherd||{})});let i=t.taskShepherd.apiUrl,o={maxRetries:5,baseDelay:1e3,maxDelay:3e4,timeout:6e4,healthCheckInterval:3e4,enableCircuitBreaker:!0,baseUrl:e.baseUrl||i||"http://localhost:4002/api/graphql"};this.options={...o,...e,apiKey:e.apiKey!==void 0?e.apiKey:a},s.info("GraphQL HTTP Client initialized with options",{hasApiKey:!!this.options.apiKey,apiKeyLength:this.options.apiKey?.length||0,apiKeyPrefix:this.options.apiKey?this.options.apiKey.substring(0,12)+"...":"none",baseUrl:this.options.baseUrl,optionsKeys:Object.keys(this.options)}),this.startHealthChecking()}async query(e){if(this.circuitBreakerOpen)throw new Error("Circuit breaker is open - backend is unavailable");let t=null;for(let a=1;a<=this.options.maxRetries;a++)try{let i=await this.executeRequest(e,a);return this.failureCount=0,this.circuitBreakerOpen&&(this.circuitBreakerOpen=!1,s.info("Circuit breaker closed - backend is healthy again"),this.emit("circuitBreakerClosed")),i}catch(i){if(t=i instanceof Error?i:new Error(String(i)),s.warn(`GraphQL request attempt ${a}/${this.options.maxRetries} failed`,{error:t.message,operationName:e.operationName,willRetry:a<this.options.maxRetries}),a<this.options.maxRetries){let n=this.calculateRetryDelay(a);await this.sleep(n)}}throw this.failureCount++,this.options.enableCircuitBreaker&&this.failureCount>=5&&!this.circuitBreakerOpen&&(this.circuitBreakerOpen=!0,s.error("Circuit breaker opened - too many backend failures"),this.emit("circuitBreakerOpened"),setTimeout(()=>{this.circuitBreakerOpen=!1,this.failureCount=0,s.info("Circuit breaker half-open - testing backend"),this.emit("circuitBreakerHalfOpen")},6e4)),t||new Error("All GraphQL request attempts failed")}async mutate(e){return this.query(e)}async post(e){return this.query(e)}async registerWorkspace(e){let a=await this.mutate({query:`
4
4
  mutation RegisterWorkspace($input: WorkspaceRegistrationInput!) {
5
5
  registerWorkspace(input: $input) {
6
6
  id
@@ -18,7 +18,7 @@
18
18
  isActive
19
19
  }
20
20
  }
21
- `,variables:{input:e},operationName:"RegisterWorkspace"});if(!s.data?.registerWorkspace)throw new Error("Failed to register workspace");return s.data.registerWorkspace}async getAvailableWorkspaces(){let r=await this.query({query:`
21
+ `,variables:{input:e},operationName:"RegisterWorkspace"});if(!a.data?.registerWorkspace)throw new Error("Failed to register workspace");return a.data.registerWorkspace}async getAvailableWorkspaces(){let t=await this.query({query:`
22
22
  query AvailableWorkspaces {
23
23
  availableWorkspaces {
24
24
  id
@@ -37,7 +37,7 @@
37
37
  }
38
38
  }
39
39
  }
40
- `,operationName:"AvailableWorkspaces"});if(!r.data?.availableWorkspaces)throw new Error("Failed to fetch available workspaces");return r.data.availableWorkspaces}async exchangeApiKeyForJWT(e){c.debug("GraphQL HTTP Client exchangeApiKeyForJWT called",{providedApiKey:e?e.substring(0,12)+"...":"none",providedApiKeyLength:e?.length||0,clientOptionsApiKey:this.options.apiKey?this.options.apiKey.substring(0,12)+"...":"none",clientOptionsApiKeyLength:this.options.apiKey?.length||0});let s=await this.mutate({query:`
40
+ `,operationName:"AvailableWorkspaces"});if(!t.data?.availableWorkspaces)throw new Error("Failed to fetch available workspaces");return t.data.availableWorkspaces}async exchangeApiKeyForJWT(e){s.debug("GraphQL HTTP Client exchangeApiKeyForJWT called",{providedApiKey:e?e.substring(0,12)+"...":"none",providedApiKeyLength:e?.length||0,clientOptionsApiKey:this.options.apiKey?this.options.apiKey.substring(0,12)+"...":"none",clientOptionsApiKeyLength:this.options.apiKey?.length||0});let a=await this.mutate({query:`
41
41
  mutation ExchangeApiKeyForToken($apiKey: String!) {
42
42
  exchangeApiKeyForToken(apiKey: $apiKey) {
43
43
  token
@@ -52,103 +52,1071 @@
52
52
  }
53
53
  }
54
54
  }
55
- `,variables:{apiKey:e},operationName:"ExchangeApiKeyForToken"});if(!s.data?.exchangeApiKeyForToken)throw new Error("Failed to exchange API key for JWT token");return s.data.exchangeApiKeyForToken}async checkHealth(){try{let e=await this.query({query:`
55
+ `,variables:{apiKey:e},operationName:"ExchangeApiKeyForToken"});if(!a.data?.exchangeApiKeyForToken)throw new Error("Failed to exchange API key for JWT token");return a.data.exchangeApiKeyForToken}async checkHealth(){try{let e=await this.query({query:`
56
56
  query {
57
57
  me {
58
58
  id
59
59
  email
60
60
  }
61
61
  }
62
- `}),r=this.isHealthy;return this.isHealthy=!!e?.data?.me?.id,!r&&this.isHealthy?(c.info("Backend health recovered - authentication verified"),this.emit("healthRecovered")):r&&!this.isHealthy&&(c.warn("Backend health degraded - authentication failed"),this.emit("healthDegraded")),this.lastHealthCheck=Date.now(),this.isHealthy}catch(e){let r=this.isHealthy;return this.isHealthy=!1,r&&(c.warn("Backend health check failed",{error:e instanceof Error?e.message:String(e)}),this.emit("healthDegraded")),!1}}get healthy(){let e=Date.now()-this.lastHealthCheck>12e4;return this.isHealthy&&!e}destroy(){this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.removeAllListeners()}async executeRequest(e,r){let{query:s,variables:n,operationName:i}=e,l=kt().getBuildInfo(),u={"Content-Type":"application/json","X-Agent-Version":l.version,"X-Client-Type":"task-shepherd-agent","X-Agent-Build":l.buildTimestamp,"X-Agent-Commit":l.commitHash,"X-Agent-Channel":l.releaseChannel};c.debug("HTTP Client state before request",{operationName:i,attempt:r,hasApiKeyInOptions:!!this.options.apiKey,apiKeyLength:this.options.apiKey?.length||0,optionsKeys:Object.keys(this.options)}),this.options.apiKey?(u["X-API-Key"]=this.options.apiKey,c.info("Adding API key to request headers",{operationName:i,apiKeyPrefix:this.options.apiKey.substring(0,12)+"...",headerName:"X-API-Key"})):c.error("NO API KEY AVAILABLE for GraphQL request",{operationName:i,attempt:r,optionsApiKey:this.options.apiKey,optionsKeys:Object.keys(this.options),allOptions:JSON.stringify(this.options,null,2)}),c.debug("Executing GraphQL request",{operationName:i,attempt:r,hasAuth:!!this.options.apiKey,url:this.options.baseUrl});let m=await fetch(this.options.baseUrl,{method:"POST",headers:u,body:JSON.stringify({query:s,variables:n,operationName:i}),signal:AbortSignal.timeout(this.options.timeout)});if(!m.ok)throw new Error(`HTTP ${m.status}: ${m.statusText}`);let p=await m.json();if(p.errors&&p.errors.length>0){let f=p.errors.map(S=>S.message).join(", ");throw new Error(`GraphQL errors: ${f}`)}return p}calculateRetryDelay(e){let r=this.options.baseDelay*Math.pow(2,e-1),s=Math.random()*1e3;return Math.min(r+s,this.options.maxDelay)}sleep(e){return new Promise(r=>setTimeout(r,e))}startHealthChecking(){this.checkHealth().catch(()=>{}),this.healthCheckTimer=setInterval(()=>{this.checkHealth().catch(()=>{})},this.options.healthCheckInterval)}},ae=null});var Je,wt=A(()=>{"use strict";Je="1.0.0"});var Se,It=A(()=>{"use strict";wt();Se=class{validate(t){let e=[],r=[];return this.validateRequiredStructure(t,e),this.validateWorkspaceMetadata(t.workspace,e,r),this.validateServicesConfig(t.services,e,r),this.validateAIConfig(t.ai,e,r),this.validatePathsConfig(t.paths,e,r),this.validateDevelopmentConfig(t.development,e,r),this.validateSecurityConfig(t.security,e,r),t.git&&this.validateGitConfig(t.git,e,r),t.integrations&&this.validateIntegrationsConfig(t.integrations,e,r),{valid:e.length===0,errors:e,warnings:r}}validateRequiredStructure(t,e){let r=["workspace","services","ai","paths","development","security"];for(let s of r)t[s]||e.push({path:s,message:`Required field '${s}' is missing`,code:"MISSING_REQUIRED_FIELD",severity:"error"})}validateWorkspaceMetadata(t,e,r){t&&(t.id||e.push({path:"workspace.id",message:"Workspace ID is required",code:"MISSING_WORKSPACE_ID",severity:"error"}),t.name||e.push({path:"workspace.name",message:"Workspace name is required",code:"MISSING_WORKSPACE_NAME",severity:"error"}),t.version?t.version!==Je&&r.push({path:"workspace.version",message:`Workspace version ${t.version} may not be compatible with current version ${Je}`,code:"VERSION_MISMATCH",severity:"warning"}):e.push({path:"workspace.version",message:"Workspace version is required",code:"MISSING_VERSION",severity:"error"}),t.id&&!/^[a-zA-Z0-9_-]+$/.test(t.id)&&e.push({path:"workspace.id",message:"Workspace ID must contain only alphanumeric characters, hyphens, and underscores",code:"INVALID_WORKSPACE_ID",severity:"error"}),t.name&&(t.name.length<1||t.name.length>100)&&e.push({path:"workspace.name",message:"Workspace name must be between 1 and 100 characters",code:"INVALID_WORKSPACE_NAME_LENGTH",severity:"error"}))}validateServicesConfig(t,e,r){if(!t)return;let s=Object.keys(t);for(let n of s){let i=t[n];i&&typeof i=="object"&&this.validateServiceEndpoint(i,`services.${n}`,e,r)}s.length===0&&r.push({path:"services",message:"No services are configured",code:"NO_SERVICES_CONFIGURED",severity:"warning"})}validateServiceEndpoint(t,e,r,s){t.name||r.push({path:`${e}.name`,message:"Service name is required",code:"MISSING_SERVICE_NAME",severity:"error"});let n=e.split(".").pop()||"",o=["mcp","shared","cli","tasqhubmcp"].includes(n)||t.port===0;!t.url&&!o&&r.push({path:`${e}.url`,message:"Service URL is required",code:"MISSING_SERVICE_URL",severity:"error"});let u=["mcp","shared","cli","tasqhubmcp"].includes(n)||t.port===0;!t.port&&!u&&r.push({path:`${e}.port`,message:"Service port is required",code:"MISSING_SERVICE_PORT",severity:"error"}),t.protocol||r.push({path:`${e}.protocol`,message:"Service protocol is required",code:"MISSING_SERVICE_PROTOCOL",severity:"error"}),t.port&&(typeof t.port!="number"||t.port<1||t.port>65535)&&r.push({path:`${e}.port`,message:"Service port must be a number between 1 and 65535",code:"INVALID_SERVICE_PORT",severity:"error"});let m=["http","https","ws","wss","tcp","udp","postgresql","redis","mongodb"];t.protocol&&!m.includes(t.protocol)&&r.push({path:`${e}.protocol`,message:`Service protocol must be one of: ${m.join(", ")}`,code:"INVALID_SERVICE_PROTOCOL",severity:"error"}),t.environment&&!["development","staging","production"].includes(t.environment)&&r.push({path:`${e}.environment`,message:"Service environment must be one of: development, staging, production",code:"INVALID_SERVICE_ENVIRONMENT",severity:"error"})}validateAIConfig(t,e,r){t&&(t.provider?["claude","openai","custom"].includes(t.provider)||e.push({path:"ai.provider",message:"AI provider must be one of: claude, openai, custom",code:"INVALID_AI_PROVIDER",severity:"error"}):e.push({path:"ai.provider",message:"AI provider is required",code:"MISSING_AI_PROVIDER",severity:"error"}),t.models?this.validateAIModels(t.models,t.provider,e,r):e.push({path:"ai.models",message:"AI models configuration is required",code:"MISSING_AI_MODELS",severity:"error"}),t.capabilities?this.validateAICapabilities(t.capabilities,e,r):e.push({path:"ai.capabilities",message:"AI capabilities configuration is required",code:"MISSING_AI_CAPABILITIES",severity:"error"}))}validateAIModels(t,e,r,s){e==="claude"&&!t.claude&&r.push({path:"ai.models.claude",message:"Claude model configuration is required when provider is claude",code:"MISSING_CLAUDE_CONFIG",severity:"error"}),e==="openai"&&!t.openai&&r.push({path:"ai.models.openai",message:"OpenAI model configuration is required when provider is openai",code:"MISSING_OPENAI_CONFIG",severity:"error"}),t.claude&&(t.claude.apiKey||r.push({path:"ai.models.claude.apiKey",message:"Claude API key is required",code:"MISSING_CLAUDE_API_KEY",severity:"error"}),t.claude.defaultModel||r.push({path:"ai.models.claude.defaultModel",message:"Claude default model is required",code:"MISSING_CLAUDE_DEFAULT_MODEL",severity:"error"})),t.openai&&(t.openai.apiKey||r.push({path:"ai.models.openai.apiKey",message:"OpenAI API key is required",code:"MISSING_OPENAI_API_KEY",severity:"error"}),t.openai.defaultModel||r.push({path:"ai.models.openai.defaultModel",message:"OpenAI default model is required",code:"MISSING_OPENAI_DEFAULT_MODEL",severity:"error"}))}validateAICapabilities(t,e,r){t.maxConcurrentOperations===void 0?e.push({path:"ai.capabilities.maxConcurrentOperations",message:"Maximum concurrent operations is required",code:"MISSING_MAX_CONCURRENT_OPERATIONS",severity:"error"}):(typeof t.maxConcurrentOperations!="number"||t.maxConcurrentOperations<1||t.maxConcurrentOperations>100)&&e.push({path:"ai.capabilities.maxConcurrentOperations",message:"Maximum concurrent operations must be a number between 1 and 100",code:"INVALID_MAX_CONCURRENT_OPERATIONS",severity:"error"}),t.supportedAnalysisTypes?Array.isArray(t.supportedAnalysisTypes)||e.push({path:"ai.capabilities.supportedAnalysisTypes",message:"Supported analysis types must be an array",code:"INVALID_SUPPORTED_ANALYSIS_TYPES",severity:"error"}):e.push({path:"ai.capabilities.supportedAnalysisTypes",message:"Supported analysis types are required",code:"MISSING_SUPPORTED_ANALYSIS_TYPES",severity:"error"}),t.isolationLevel?["strict","moderate","relaxed"].includes(t.isolationLevel)||e.push({path:"ai.capabilities.isolationLevel",message:"Isolation level must be one of: strict, moderate, relaxed",code:"INVALID_ISOLATION_LEVEL",severity:"error"}):r.push({path:"ai.capabilities.isolationLevel",message:"Isolation level not specified, defaulting to moderate",code:"MISSING_ISOLATION_LEVEL",severity:"warning"})}validatePathsConfig(t,e,r){if(!t)return;t.root||e.push({path:"paths.root",message:"Root path is required",code:"MISSING_ROOT_PATH",severity:"error"});let s=["src","tests","docs","config","build","temp","logs","excluded"];for(let n of s)t[n]&&!Array.isArray(t[n])&&e.push({path:`paths.${n}`,message:`${n} must be an array of paths`,code:"INVALID_PATH_ARRAY",severity:"error"});(!t.src||t.src.length===0)&&r.push({path:"paths.src",message:"No source paths specified",code:"NO_SOURCE_PATHS",severity:"warning"})}validateDevelopmentConfig(t,e,r){t&&(t.packageManager?["npm","yarn","pnpm"].includes(t.packageManager)||e.push({path:"development.packageManager",message:"Package manager must be one of: npm, yarn, pnpm",code:"INVALID_PACKAGE_MANAGER",severity:"error"}):e.push({path:"development.packageManager",message:"Package manager is required",code:"MISSING_PACKAGE_MANAGER",severity:"error"}),t.nodeVersion&&!/^\d+\.\d+\.\d+$/.test(t.nodeVersion)&&r.push({path:"development.nodeVersion",message:"Node.js version should be in format x.y.z",code:"INVALID_NODE_VERSION_FORMAT",severity:"warning"}))}validateSecurityConfig(t,e,r){t&&(t.filePermissions?this.validateFilePermissions(t.filePermissions,e,r):e.push({path:"security.filePermissions",message:"File permissions configuration is required",code:"MISSING_FILE_PERMISSIONS",severity:"error"}),t.networkPermissions?this.validateNetworkPermissions(t.networkPermissions,e,r):e.push({path:"security.networkPermissions",message:"Network permissions configuration is required",code:"MISSING_NETWORK_PERMISSIONS",severity:"error"}))}validateFilePermissions(t,e,r){let s=["read","write","execute"];for(let n of s)typeof t[n]!="boolean"&&e.push({path:`security.filePermissions.${n}`,message:`${n} permission must be a boolean`,code:"INVALID_FILE_PERMISSION",severity:"error"});t.restricted&&!Array.isArray(t.restricted)&&e.push({path:"security.filePermissions.restricted",message:"Restricted paths must be an array",code:"INVALID_RESTRICTED_PATHS",severity:"error"}),t.write&&t.execute&&r.push({path:"security.filePermissions",message:"Both write and execute permissions are enabled, this may pose security risks",code:"SECURITY_RISK_WRITE_EXECUTE",severity:"warning"})}validateNetworkPermissions(t,e,r){let s=["http","https"];for(let i of s)typeof t[i]!="boolean"&&e.push({path:`security.networkPermissions.${i}`,message:`${i} permission must be a boolean`,code:"INVALID_NETWORK_PERMISSION",severity:"error"});let n=["allowedDomains","blockedDomains"];for(let i of n)t[i]&&!Array.isArray(t[i])&&e.push({path:`security.networkPermissions.${i}`,message:`${i} must be an array`,code:"INVALID_DOMAIN_ARRAY",severity:"error"});t.http&&!t.https&&r.push({path:"security.networkPermissions",message:"HTTP is enabled but HTTPS is not, consider enabling HTTPS for better security",code:"SECURITY_RISK_HTTP_ONLY",severity:"warning"})}validateGitConfig(t,e,r){t.repositoryUrl&&!this.isValidUrl(t.repositoryUrl)&&e.push({path:"git.repositoryUrl",message:"Repository URL must be a valid URL",code:"INVALID_REPOSITORY_URL",severity:"error"}),t.defaultBranch&&!/^[a-zA-Z0-9/_-]+$/.test(t.defaultBranch)&&e.push({path:"git.defaultBranch",message:"Default branch name contains invalid characters",code:"INVALID_BRANCH_NAME",severity:"error"}),t.remoteName&&!/^[a-zA-Z0-9_-]+$/.test(t.remoteName)&&e.push({path:"git.remoteName",message:"Remote name contains invalid characters",code:"INVALID_REMOTE_NAME",severity:"error"})}validateIntegrationsConfig(t,e,r){t.taskShepherd&&(t.taskShepherd.apiUrl?this.isValidUrl(t.taskShepherd.apiUrl)||e.push({path:"integrations.taskShepherd.apiUrl",message:"Task Shepherd API URL must be a valid URL",code:"INVALID_TASK_SHEPHERD_API_URL",severity:"error"}):e.push({path:"integrations.taskShepherd.apiUrl",message:"Task Shepherd API URL is required",code:"MISSING_TASK_SHEPHERD_API_URL",severity:"error"}),t.taskShepherd.apiKey||e.push({path:"integrations.taskShepherd.apiKey",message:"Task Shepherd API key is required",code:"MISSING_TASK_SHEPHERD_API_KEY",severity:"error"}))}isValidUrl(t){try{return new URL(t),!0}catch{return!1}}}});var pe={};Q(pe,{WorkspaceRegistryService:()=>Ie,getWorkspaceRegistry:()=>z});function z(){return Ye||(Ye=new Ie),Ye}var we,le,Ie,Ye,B=A(()=>{"use strict";we=require("fs"),le=h(require("path"));R();Ie=class{constructor(){this.registry=new Map;let t=le.join(process.env.HOME||process.env.USERPROFILE||"",".task-shepherd-agent");this.registryPath=le.join(t,"workspace-registry.json")}async initialize(){try{await this.ensureDataDirectory(),await this.loadRegistry(),c.info("Workspace registry initialized",{registryPath:this.registryPath,workspaceCount:this.registry.size})}catch(t){c.error("Failed to initialize workspace registry",{error:t instanceof Error?t.message:String(t)})}}async ensureDataDirectory(){let t=le.dirname(this.registryPath);try{await we.promises.mkdir(t,{recursive:!0})}catch(e){c.error("Failed to create data directory",{dataDir:t,error:e instanceof Error?e.message:String(e)})}}async loadRegistry(){try{let t=await we.promises.readFile(this.registryPath,"utf-8"),e=JSON.parse(t);this.registry.clear();for(let r of e)this.registry.set(r.workspace.workspaceId,r);c.info("Loaded workspace registry from disk",{workspaceCount:this.registry.size})}catch(t){t.code==="ENOENT"?c.info("No existing workspace registry found, starting fresh"):c.error("Failed to load workspace registry",{error:t instanceof Error?t.message:String(t)})}}async saveRegistry(){try{let t=Array.from(this.registry.values());await we.promises.writeFile(this.registryPath,JSON.stringify(t,null,2),"utf-8"),c.debug("Saved workspace registry to disk",{workspaceCount:t.length})}catch(t){c.error("Failed to save workspace registry",{error:t instanceof Error?t.message:String(t)})}}async addWorkspace(t){let e={workspace:t,discoveredAt:new Date().toISOString(),syncStatus:"pending"},r=this.registry.get(t.workspaceId);r&&(e.lastSyncedAt=r.lastSyncedAt,e.syncStatus=r.syncStatus,e.syncError=r.syncError),this.registry.set(t.workspaceId,e),await this.saveRegistry(),c.info("Added workspace to local registry",{workspaceId:t.workspaceId,name:t.name,syncStatus:e.syncStatus})}async addWorkspaces(t){for(let e of t)await this.addWorkspace(e)}getAllWorkspaces(){return Array.from(this.registry.values())}getWorkspacesBySyncStatus(t){return Array.from(this.registry.values()).filter(e=>e.syncStatus===t)}getWorkspace(t){return this.registry.get(t)}async removeWorkspace(t){this.registry.delete(t)&&(await this.saveRegistry(),c.info("Removed workspace from registry",{workspaceId:t}))}async markWorkspaceSynced(t){let e=this.registry.get(t);e&&(e.syncStatus="synced",e.lastSyncedAt=new Date().toISOString(),e.syncError=void 0,this.registry.set(t,e),await this.saveRegistry(),c.info("Marked workspace as synced",{workspaceId:t,lastSyncedAt:e.lastSyncedAt}))}async markWorkspaceSyncFailed(t,e){let r=this.registry.get(t);r&&(r.syncStatus="failed",r.syncError=e,this.registry.set(t,r),await this.saveRegistry(),c.warn("Marked workspace sync as failed",{workspaceId:t,error:e}))}getSyncStats(){let t=Array.from(this.registry.values());return{total:t.length,synced:t.filter(e=>e.syncStatus==="synced").length,pending:t.filter(e=>e.syncStatus==="pending").length,failed:t.filter(e=>e.syncStatus==="failed").length}}async clearRegistry(){this.registry.clear(),await this.saveRegistry(),c.info("Cleared workspace registry")}},Ye=null});var G,re,Ee,Et=A(()=>{"use strict";G=require("fs"),re=h(require("path"));It();R();B();Ee=class{constructor(){this.validator=new Se}async discoverWorkspaces(t){try{if(c.info("Starting workspace discovery",{rootPath:t}),!(await G.promises.stat(t)).isDirectory())throw new Error(`Path ${t} is not a directory`);let r=await this.detectTaskShepherdMonorepo(t),s;return r?s=await this.discoverTaskShepherdWorkspaces(t):s=await this.discoverGenericWorkspaces(t),await this.saveDiscoveredWorkspaces(s),s}catch(e){return c.error("Workspace discovery failed",{rootPath:t,error:e instanceof Error?e.message:e}),[{workspaceId:"error",name:"Discovery Error",path:t,pattern:"monorepo",services:[],config:{},errors:[e instanceof Error?e.message:"Unknown error occurred"]}]}}async detectTaskShepherdMonorepo(t){try{let e=re.join(t,"package.json"),r=await G.promises.readFile(e,"utf-8"),s=JSON.parse(r),n=s.name==="task-shepherd"||s.workspaces&&Array.isArray(s.workspaces)&&s.workspaces.includes("packages/*"),i=["packages/frontend","packages/backend","packages/agent"],o=await Promise.all(i.map(async l=>{try{let u=re.join(t,l);return(await G.promises.stat(u)).isDirectory()}catch{return!1}}));return n&&o.some(l=>l)}catch{return!1}}async discoverTaskShepherdWorkspaces(t){let e=[],r=[{path:"packages/frontend",name:"Frontend App",technology:"react",port:5173},{path:"packages/backend",name:"GraphQL Backend",technology:"nodejs",port:4002},{path:"packages/agent",name:"AI Agent Service",technology:"nodejs",port:8547},{path:"packages/mcp",name:"MCP Server",technology:"nodejs",port:3001},{path:"packages/shared",name:"Shared Types",technology:"other"}];for(let s of r){let n=re.join(t,s.path);try{if((await G.promises.stat(n)).isDirectory()){let o=re.join(n,"package.json");try{await G.promises.access(o),e.push({id:s.path.replace("packages/",""),name:s.name,path:n,relativePath:s.path,technology:s.technology,port:s.port})}catch{c.warn("Package directory found but no package.json",{path:n})}}}catch{c.debug("Package not found",{path:n})}}return[{workspaceId:"task-shepherd-monorepo",name:"Task Shepherd Monorepo",path:t,pattern:"monorepo",services:e,config:{},errors:[]}]}async discoverGenericWorkspaces(t){let e=[];try{let r=re.join(t,"package.json");try{let s=await G.promises.readFile(r,"utf-8"),n=JSON.parse(s);if(n.name){let i=[],o={...n.dependencies,...n.devDependencies};(o.react||o["@types/react"])&&i.push({id:"frontend",name:"React Frontend",path:t,technology:"react"}),(o.express||o.fastify||o.koa)&&i.push({id:"backend",name:"Node.js Backend",path:t,technology:"nodejs"}),o.next&&i.push({id:"nextjs",name:"Next.js App",path:t,technology:"other"}),(i.length>0||n.scripts)&&e.push({workspaceId:`generic-${n.name.replace(/[^a-zA-Z0-9]/g,"-")}`,name:n.name,path:t,pattern:"monorepo",services:i,config:{},errors:[]})}}catch(s){c.debug("No package.json found or invalid",{rootPath:t,error:s instanceof Error?s.message:s})}return e}catch(r){return c.warn("Generic workspace discovery failed",{rootPath:t,error:r instanceof Error?r.message:r}),[]}}async discoverWorkspacesFromPaths(t){let e=[];for(let r of t)try{c.info("Scanning directory for workspaces",{searchPath:r});let n=(await this.discoverWorkspaces(r)).filter(i=>i.errors.length===0);e.push(...n),c.info("Directory scan completed",{searchPath:r,foundWorkspaces:n.length,totalWorkspaces:e.length})}catch(s){c.warn("Failed to scan directory for workspaces",{searchPath:r,error:s instanceof Error?s.message:String(s)})}return e}async generateWorkspaceConfig(t){return c.info("Generating workspace configuration",{workspaceId:t.workspaceId}),{workspace:{id:t.workspaceId,name:t.name,pattern:t.pattern,rootPath:t.path},services:t.services.reduce((e,r)=>(e[r.id]={name:r.name,path:r.path,technology:r.technology,port:r.port,enabled:!0},e),{}),ai:{models:{claude:{provider:"anthropic",model:"claude-3-sonnet",enabled:!0}},defaultModel:"claude",capabilities:{codeGeneration:!0,codeReview:!0,projectAnalysis:!0}},development:{hotReload:!0,debugMode:!0,testRunner:"jest"},integrations:{github:{enabled:!1},slack:{enabled:!1}}}}async saveDiscoveredWorkspaces(t){let e=z();await e.initialize();for(let r of t){if(r.errors.length>0){c.warn("Skipping workspace due to errors",{workspaceId:r.workspaceId,errors:r.errors});continue}try{c.info("Saving workspace to local registry",{workspaceId:r.workspaceId,servicesCount:r.services.length,note:"Will be synced with backend when connected"}),await e.addWorkspace(r),c.info("Successfully saved workspace to local registry",{workspaceId:r.workspaceId,capabilities:r.services.map(s=>`${s.name} (${s.technology})`).join(", ")})}catch(s){c.error("Failed to save workspace to local registry",{workspaceId:r.workspaceId,error:s instanceof Error?s.message:String(s)})}}}async validateWorkspaceConfig(t){try{let e=this.validator.validate(t);return{isValid:e.valid,errors:e.errors?.map(r=>r.message)||[]}}catch(e){return{isValid:!1,errors:[e instanceof Error?e.message:"Validation failed"]}}}}});var H,x,Ce,Ct=A(()=>{"use strict";H=h(require("fs")),x=h(require("path"));R();Ce=class{async detect(t){try{if(c.info("Starting .NET workspace detection",{workspacePath:t}),!await this.hasDotNetIndicators(t))return null;let r=await this.detectSolutions(t),s=await this.detectStandaloneProjects(t,r),n=this.identifySharedProjects(r),i=H.existsSync(x.join(t,"global.json")),o=this.findNuGetConfig(t),l=await this.detectDockerFiles(t),u;return r.length>1?u="dotnet-multi-solution":r.length===1?u="dotnet-single-solution":u="dotnet-project-only",{pattern:u,solutions:r,standaloneProjects:s,sharedProjects:n,globalJsonExists:i,nugetConfig:o,dockerFiles:l}}catch(e){return c.error("Failed to detect .NET workspace",{error:e,workspacePath:t}),null}}async hasDotNetIndicators(t){let e=["**/*.sln","**/*.csproj","**/*.fsproj","**/*.vbproj","global.json","nuget.config","Directory.Build.props","Directory.Build.targets"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t})).length>0)return!0}return!1}async detectSolutions(t){let{glob:e}=await import("glob"),r=await e("**/*.sln",{cwd:t}),s=[];for(let n of r)try{let i=x.join(t,n),o=H.readFileSync(i,"utf8"),l=await this.parseSolutionProjects(i,o),u=this.parseSolutionConfigurations(o);s.push({name:x.basename(n,".sln"),file:n,path:x.dirname(i),projects:l,configurations:u})}catch(i){c.warn("Failed to parse solution file",{error:i,file:n})}return s}async parseSolutionProjects(t,e){let r=[],s=x.dirname(t),n=/Project\("[^"]+"\)\s*=\s*"([^"]+)",\s*"([^"]+)",\s*"[^"]+"/g,i;for(;(i=n.exec(e))!==null;){let o=i[1],l=i[2];if(l.endsWith(".sln"))continue;let u=x.resolve(s,l);if(H.existsSync(u))try{let m=await this.analyzeProject(u);m&&r.push({...m,name:o})}catch(m){c.warn("Failed to analyze project",{error:m,projectPath:u})}}return r}parseSolutionConfigurations(t){let e=[],r=/^\s*([^|]+)\|([^=]+)\s*=/gm,s;for(;(s=r.exec(t))!==null;){let n=`${s[1].trim()}|${s[2].trim()}`;e.includes(n)||e.push(n)}return e}async detectStandaloneProjects(t,e){let{glob:r}=await import("glob"),s=await r("**/*.csproj",{cwd:t}),n=new Set;e.forEach(o=>{o.projects.forEach(l=>{n.add(x.resolve(l.path,l.file))})});let i=[];for(let o of s){let l=x.resolve(t,o);if(!n.has(l))try{let u=await this.analyzeProject(l);u&&i.push(u)}catch(u){c.warn("Failed to analyze standalone project",{error:u,projectFile:o})}}return i}async analyzeProject(t){try{let e=H.readFileSync(t,"utf8"),r=x.dirname(t),s=x.basename(t,".csproj"),n=this.extractTargetFrameworks(e),i=this.extractPackageReferences(e),o=this.determineProjectType(e,i),l=this.isTestProject(e,i),u=await this.extractPort(r,o);return{name:s,file:x.basename(t),path:r,type:o,frameworks:n,port:u,packageReferences:i,isShared:!1,isTest:l}}catch(e){return c.error("Failed to analyze project file",{error:e,projectPath:t}),null}}extractTargetFrameworks(t){let e=[],r=t.match(/<TargetFramework>([^<]+)<\/TargetFramework>/);r&&e.push(r[1]);let s=t.match(/<TargetFrameworks>([^<]+)<\/TargetFrameworks>/);return s&&e.push(...s[1].split(";").map(n=>n.trim())),e}extractPackageReferences(t){let e=[],r=/<PackageReference\s+Include="([^"]+)"/g,s;for(;(s=r.exec(t))!==null;)e.push(s[1]);return e}determineProjectType(t,e){if(t.includes("Microsoft.NET.Sdk.Web"))return e.some(r=>r.includes("Blazor"))?"blazor":e.some(r=>r.includes("Mvc"))||t.includes("Microsoft.AspNetCore.Mvc")?"mvc":"aspnetcore";if(t.includes("Microsoft.NET.Sdk")){if(e.some(s=>["xunit","NUnit","MSTest"].some(n=>s.includes(n)))){if(e.some(s=>s.includes("xunit")))return"xunit";if(e.some(s=>s.includes("NUnit")))return"nunit";if(e.some(s=>s.includes("MSTest")))return"mstest"}let r=t.match(/<OutputType>([^<]+)<\/OutputType>/);return r&&r[1].toLowerCase()==="exe"?"console":"classlib"}return"unknown"}isTestProject(t,e){return e.some(r=>["xunit","nunit","mstest","Microsoft.NET.Test.Sdk"].some(s=>r.toLowerCase().includes(s.toLowerCase())))||t.toLowerCase().includes("test")}async extractPort(t,e){if(!["aspnetcore","mvc","webapi","blazor"].includes(e))return;let r=x.join(t,"Properties","launchSettings.json");if(H.existsSync(r))try{let n=JSON.parse(H.readFileSync(r,"utf8"));for(let i of Object.values(n.profiles||{})){let o=i;if(o.applicationUrl){let l=o.applicationUrl.match(/:(\d+)/);if(l)return parseInt(l[1])}}}catch(n){c.warn("Failed to parse launchSettings.json",{error:n,path:r})}return{aspnetcore:5e3,mvc:5e3,webapi:5001,blazor:5002}[e]}identifySharedProjects(t){if(t.length<2)return[];let e=new Map;t.forEach(s=>{s.projects.forEach(n=>{let i=x.resolve(n.path,n.file);e.has(i)?e.get(i).count++:e.set(i,{project:n,count:1})})});let r=[];for(let[,{project:s,count:n}]of e)n>1&&(s.isShared=!0,r.push(s));return r}findNuGetConfig(t){let e=["nuget.config","NuGet.config","NuGet.Config"];for(let r of e){let s=x.join(t,r);if(H.existsSync(s))return r}}async detectDockerFiles(t){let{glob:e}=await import("glob");return await e("**/Dockerfile*",{cwd:t})}}});var b,v,Ae,At=A(()=>{"use strict";b=h(require("fs")),v=h(require("path"));R();Ae=class{async detect(t){try{if(c.info("Starting Python workspace detection",{workspacePath:t}),!await this.hasPythonIndicators(t))return null;let r=await this.detectVirtualEnvironments(t),s=await this.detectPythonProjects(t),n=await this.detectGlobalPythonVersion(t),i=b.existsSync(v.join(t,"pyproject.toml"))&&b.readFileSync(v.join(t,"pyproject.toml"),"utf8").includes("[tool.poetry]"),o=b.existsSync(v.join(t,"Pipfile")),l=b.existsSync(v.join(t,"environment.yml"))||b.existsSync(v.join(t,"conda-env.yml")),u=await this.detectDockerFiles(t),m=await this.detectJupyterNotebooks(t),p;return s.length>1?p="python-monorepo":s.length===1&&s[0].apps.length>1?p="python-multi-app":p="python-single-project",{pattern:p,projects:s,virtualEnvironments:r,globalPythonVersion:n,hasPoetry:i,hasPipenv:o,hasCondaEnv:l,dockerFiles:u,jupyterNotebooks:m}}catch(e){return c.error("Failed to detect Python workspace",{error:e,workspacePath:t}),null}}async hasPythonIndicators(t){let e=["**/*.py","requirements.txt","requirements/**/*.txt","pyproject.toml","setup.py","setup.cfg","Pipfile","environment.yml","conda-env.yml","manage.py","app.py","main.py","**/__init__.py"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t,maxDepth:3})).length>0)return!0}return!1}async detectVirtualEnvironments(t){let e=["venv","env",".venv",".env","virtualenv"],r=[];for(let s of e){let n=v.join(t,s);if(b.existsSync(n)&&b.statSync(n).isDirectory()){let i=process.platform==="win32"?"Scripts/python.exe":"bin/python";b.existsSync(v.join(n,i))&&r.push(s)}}return r}async detectPythonProjects(t){let e=[];if(b.existsSync(v.join(t,"manage.py"))){let r=await this.analyzeDjangoProject(t);r&&e.push(r)}else{let r=await this.findPythonProjectDirectories(t);for(let s of r){let n=await this.analyzePythonProject(s);n&&e.push(n)}}return e}async findPythonProjectDirectories(t){let e=[t],{glob:r}=await import("glob"),s=await r("**/setup.py",{cwd:t,maxDepth:2}),n=await r("**/pyproject.toml",{cwd:t,maxDepth:2}),i=await r("**/app.py",{cwd:t,maxDepth:2}),o=await r("**/main.py",{cwd:t,maxDepth:2});return[...s,...n,...i,...o].forEach(l=>{let u=v.dirname(v.resolve(t,l));e.includes(u)||e.push(u)}),e}async analyzeDjangoProject(t){try{let e=v.basename(t),r=await this.detectDjangoApps(t),{dependencies:s,devDependencies:n}=await this.analyzeDependencies(t),i=b.existsSync(v.join(t,"manage.py"));return{name:e,path:t,type:"django-project",framework:"django",apps:r,dependencies:s,devDependencies:n,virtualEnv:await this.findVirtualEnv(t),hasDockerfile:b.existsSync(v.join(t,"Dockerfile")),hasRequirements:await this.hasRequirementsFiles(t),hasPyprojectToml:b.existsSync(v.join(t,"pyproject.toml")),hasSetupPy:b.existsSync(v.join(t,"setup.py")),hasManagePy:i,testFramework:await this.detectTestFramework(t,s)}}catch(e){return c.error("Failed to analyze Django project",{error:e,projectPath:t}),null}}async detectDjangoApps(t){let e=[];try{let{glob:r}=await import("glob"),s=await r("**/apps.py",{cwd:t,maxDepth:3});for(let n of s){let i=v.dirname(v.resolve(t,n)),o=v.basename(i);if(o===v.basename(t))continue;let l=await this.analyzeDjangoApp(i,o);l&&e.push(l)}if(e.length===0){let n=await r("**/models.py",{cwd:t,maxDepth:2}),i=await r("**/views.py",{cwd:t,maxDepth:2}),o=new Set;[...n,...i].forEach(l=>{let u=v.dirname(v.resolve(t,l));v.basename(u)!==v.basename(t)&&o.add(u)});for(let l of o){let u=v.basename(l),m=await this.analyzeDjangoApp(l,u);m&&e.push(m)}}}catch(r){c.warn("Failed to detect Django apps",{error:r,projectPath:t})}return e}async analyzeDjangoApp(t,e){try{let r=b.existsSync(v.join(t,"models.py"))?await this.extractDjangoModels(v.join(t,"models.py")):[],s=b.existsSync(v.join(t,"urls.py"))?[e]:[],n=await this.findManagementCommands(t),i=b.existsSync(v.join(t,"tests.py"))||b.existsSync(v.join(t,"tests"));return{name:e,path:t,type:"django",models:r,urls:s,managementCommands:n,hasTests:i,isPackage:b.existsSync(v.join(t,"__init__.py"))}}catch(r){return c.warn("Failed to analyze Django app",{error:r,appPath:t,appName:e}),null}}async analyzePythonProject(t){try{let e=v.basename(t),{dependencies:r,devDependencies:s}=await this.analyzeDependencies(t),n="unknown",i;r.some(l=>l.includes("flask"))?(n="flask-app",i="flask"):r.some(l=>l.includes("fastapi"))?(n="fastapi-app",i="fastapi"):(b.existsSync(v.join(t,"setup.py"))||b.existsSync(v.join(t,"pyproject.toml")))&&(n="package");let o=await this.detectPythonApps(t,n);return{name:e,path:t,type:n,framework:i,apps:o,dependencies:r,devDependencies:s,virtualEnv:await this.findVirtualEnv(t),hasDockerfile:b.existsSync(v.join(t,"Dockerfile")),hasRequirements:await this.hasRequirementsFiles(t),hasPyprojectToml:b.existsSync(v.join(t,"pyproject.toml")),hasSetupPy:b.existsSync(v.join(t,"setup.py")),hasManagePy:b.existsSync(v.join(t,"manage.py")),testFramework:await this.detectTestFramework(t,r)}}catch(e){return c.error("Failed to analyze Python project",{error:e,projectPath:t}),null}}async detectPythonApps(t,e){let r=[];if(e==="flask-app"||e==="fastapi-app"){let s=["app.py","main.py","server.py","api.py"];for(let n of s){let i=v.join(t,n);if(b.existsSync(i)){let o=await this.extractPortFromPythonFile(i);r.push({name:v.basename(n,".py"),path:t,type:e==="flask-app"?"flask":"fastapi",port:o,hasTests:await this.hasTestFiles(t),isPackage:b.existsSync(v.join(t,"__init__.py"))});break}}}return r}async analyzeDependencies(t){let e=[],r=[],s=v.join(t,"requirements.txt");if(b.existsSync(s)){let l=b.readFileSync(s,"utf8");e.push(...this.parseRequirements(l))}let n=v.join(t,"requirements-dev.txt");if(b.existsSync(n)){let l=b.readFileSync(n,"utf8");r.push(...this.parseRequirements(l))}let i=v.join(t,"pyproject.toml");if(b.existsSync(i)){let l=b.readFileSync(i,"utf8"),{deps:u,devDeps:m}=this.parsePyprojectToml(l);e.push(...u),r.push(...m)}let o=v.join(t,"Pipfile");if(b.existsSync(o)){let l=b.readFileSync(o,"utf8"),{deps:u,devDeps:m}=this.parsePipfile(l);e.push(...u),r.push(...m)}return{dependencies:e,devDependencies:r}}parseRequirements(t){return t.split(`
63
- `).map(e=>e.trim()).filter(e=>e&&!e.startsWith("#")&&!e.startsWith("-")).map(e=>e.split("==")[0].split(">=")[0].split("<=")[0].split("~=")[0].trim())}parsePyprojectToml(t){let e=[],r=[],s=t.match(/\[tool\.poetry\.dependencies\]([\s\S]*?)(\[|$)/);if(s){let o=s[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&e.push(...o.map(l=>l.split("=")[0].trim()))}let n=t.match(/\[tool\.poetry\.group\.dev\.dependencies\]([\s\S]*?)(\[|$)/);if(n){let o=n[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&r.push(...o.map(l=>l.split("=")[0].trim()))}return{deps:e,devDeps:r}}parsePipfile(t){let e=[],r=[],s=t.match(/\[packages\]([\s\S]*?)(\[|$)/);if(s){let o=s[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&e.push(...o.map(l=>l.split("=")[0].trim()))}let n=t.match(/\[dev-packages\]([\s\S]*?)(\[|$)/);if(n){let o=n[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&r.push(...o.map(l=>l.split("=")[0].trim()))}return{deps:e,devDeps:r}}async extractPortFromPythonFile(t){try{let e=b.readFileSync(t,"utf8"),r=[/\.run\([^)]*port\s*=\s*(\d+)/,/uvicorn\.run\([^)]*port\s*=\s*(\d+)/,/app\.run\([^)]*port\s*=\s*(\d+)/,/PORT\s*=\s*(\d+)/,/port\s*=\s*(\d+)/];for(let s of r){let n=e.match(s);if(n)return parseInt(n[1])}}catch(e){c.warn("Failed to extract port from Python file",{error:e,filePath:t})}}async extractDjangoModels(t){try{return(b.readFileSync(t,"utf8").match(/class\s+(\w+)\s*\([^)]*Model[^)]*\)/g)||[]).map(s=>{let n=s.match(/class\s+(\w+)/);return n?n[1]:""}).filter(s=>s)}catch{return[]}}async findManagementCommands(t){let e=v.join(t,"management","commands");if(!b.existsSync(e))return[];try{return b.readdirSync(e).filter(s=>s.endsWith(".py")&&s!=="__init__.py").map(s=>v.basename(s,".py"))}catch{return[]}}async findVirtualEnv(t){let e=["venv","env",".venv",".env"];for(let r of e){let s=v.join(t,r);if(b.existsSync(s))return r}}async hasRequirementsFiles(t){let e=["requirements.txt","requirements-dev.txt","requirements"];for(let s of e)if(b.existsSync(v.join(t,s)))return!0;let r=v.join(t,"requirements");return!!(b.existsSync(r)&&b.statSync(r).isDirectory())}async hasTestFiles(t){let{glob:e}=await import("glob");return(await e("**/test*.py",{cwd:t,maxDepth:2})).length>0}async detectTestFramework(t,e){if(e.some(n=>n.includes("pytest")))return"pytest";if(e.some(n=>n.includes("nose")))return"nose";if(e.some(n=>n.includes("tox")))return"tox";let{glob:r}=await import("glob"),s=await r("**/test*.py",{cwd:t,maxDepth:2});for(let n of s)try{let i=b.readFileSync(v.join(t,n),"utf8");if(i.includes("import unittest")||i.includes("from unittest"))return"unittest"}catch{}}async detectGlobalPythonVersion(t){let e=v.join(t,".python-version");if(b.existsSync(e))try{return b.readFileSync(e,"utf8").trim()}catch{}let r=v.join(t,"runtime.txt");if(b.existsSync(r))try{let n=b.readFileSync(r,"utf8").trim().match(/python-(\d+\.\d+(?:\.\d+)?)/);if(n)return n[1]}catch{}}async detectDockerFiles(t){let{glob:e}=await import("glob");return await e("**/Dockerfile*",{cwd:t,maxDepth:2})}async detectJupyterNotebooks(t){let{glob:e}=await import("glob");return await e("**/*.ipynb",{cwd:t,maxDepth:3})}}});var O,P,Te,Tt=A(()=>{"use strict";O=h(require("fs")),P=h(require("path"));R();Te=class{async detect(t){try{if(c.info("Starting Serverless Framework workspace detection",{workspacePath:t}),!await this.hasServerlessIndicators(t))return null;let r=await this.detectServerlessServices(t);if(r.length===0)return null;let s=await this.detectSharedResources(t),n=await this.detectGlobalPlugins(t),i=O.existsSync(P.join(t,"package.json")),o=O.existsSync(P.join(t,"lerna.json")),l=O.existsSync(P.join(t,"serverless.yml"))||O.existsSync(P.join(t,"serverless.yaml")),u=await this.detectFrameworkVersion(t),m=this.extractDeploymentBuckets(r),p=this.extractCustomDomains(r),f;return r.length>1?f=i||o?"serverless-monorepo":"serverless-multi-service":f="serverless-single-service",{pattern:f,services:r,sharedResources:s,globalPlugins:n,hasCommonPackageJson:i,hasLernaConfig:o,hasWorkspaceConfig:l,frameworkVersion:u,deploymentBuckets:m,customDomains:p}}catch(e){return c.error("Failed to detect Serverless workspace",{error:e,workspacePath:t}),null}}async hasServerlessIndicators(t){let e=["serverless.yml","serverless.yaml","serverless.json","**/serverless.yml","**/serverless.yaml","sls.yml","sls.yaml"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t,maxDepth:3})).length>0)return!0}return!1}async detectServerlessServices(t){let{glob:e}=await import("glob"),r=await e("**/serverless.{yml,yaml,json}",{cwd:t,maxDepth:3}),s=[];for(let n of r)try{let i=P.dirname(P.resolve(t,n)),o=await this.analyzeServerlessService(i,n);o&&s.push(o)}catch(i){c.warn("Failed to analyze Serverless service",{error:i,configFile:n})}return s}async analyzeServerlessService(t,e){try{let r=P.resolve(t,P.basename(e)),s;if(e.endsWith(".json"))s=JSON.parse(O.readFileSync(r,"utf8"));else{let ne=O.readFileSync(r,"utf8");s=await this.parseServerlessYaml(ne)}let n=s.service||P.basename(t),i=this.normalizeProvider(s.provider?.name||s.provider||"aws"),o=s.provider?.runtime||"nodejs18.x",l=s.provider?.region,u=s.provider?.stage,m=await this.parseFunctions(s.functions||{},t),p=await this.parseResources(s.resources||{}),f=await this.parseStages(s),S=s.plugins||[],U=s.custom||{},se=this.analyzeServiceCapabilities(s,m,p);return{name:n,path:t,provider:i,runtime:o,region:l,stage:u,functions:m,resources:p,stages:f,plugins:S,customVariables:U,...se}}catch(r){return c.error("Failed to analyze Serverless service",{error:r,servicePath:t,configFile:e}),null}}async parseServerlessYaml(t){let e=t.split(`
64
- `),r={},s="";for(let n of e){let i=n.trim();if(!i||i.startsWith("#"))continue;let o=n.length-n.trimStart().length;if(i.includes(":")){let[l,u]=i.split(":",2),m=l.trim(),p=u?.trim()||"";o===0?(s=m,r[m]=p||{}):s&&((!r[s]||typeof r[s]!="object")&&(r[s]={}),r[s][m]=p||{})}}return r}normalizeProvider(t){switch(t.toLowerCase()){case"aws":case"amazon":return"aws";case"azure":case"microsoft":return"azure";case"gcp":case"google":case"google-cloud":return"gcp";case"cloudflare":return"cloudflare";case"knative":return"knative";case"openwhisk":return"openwhisk";default:return"unknown"}}async parseFunctions(t,e){let r=[];for(let[s,n]of Object.entries(t))if(typeof n=="object"&&n!==null){let i=n,o={name:s,handler:i.handler||`${s}.handler`,runtime:i.runtime,events:this.parseEvents(i.events||[]),environment:i.environment,layers:i.layers,timeout:i.timeout,memorySize:i.memorySize,path:await this.findFunctionPath(e,s,i.handler)};r.push(o)}return r}parseEvents(t){let e=[];for(let r of t)if(typeof r=="object"){let s=Object.keys(r)[0];s&&e.push(s)}else typeof r=="string"&&e.push(r);return e}async parseResources(t){let e=[];if(t.Resources){for(let[r,s]of Object.entries(t.Resources))if(typeof s=="object"&&s!==null){let n=s;e.push({type:n.Type||"Unknown",name:r,properties:n.Properties||{}})}}return e}async parseStages(t){let e=[];if(t.provider?.stage&&e.push({name:t.provider.stage,region:t.provider.region,environment:t.provider.environment}),t.custom?.stages){for(let[r,s]of Object.entries(t.custom.stages))if(typeof s=="object"){let n=s;e.push({name:r,region:n.region,environment:n.environment,customDomain:n.customDomain})}}return e}analyzeServiceCapabilities(t,e,r){let s=r.length>0,n=r.some(p=>p.type.includes("StepFunctions"))||t.stepFunctions!==void 0,i=e.some(p=>p.events.includes("http")||p.events.includes("httpApi"))||r.some(p=>p.type.includes("ApiGateway")),o=e.some(p=>p.events.includes("eventBridge"))||r.some(p=>p.type.includes("Events")),l=r.some(p=>p.type.includes("DynamoDB"))||e.some(p=>p.environment&&Object.values(p.environment).some(f=>typeof f=="string"&&f.includes("dynamodb"))),u=e.some(p=>p.events.includes("s3"))||r.some(p=>p.type.includes("S3")),m=e.some(p=>p.layers&&p.layers.length>0);return{hasCustomResources:s,hasStepFunctions:n,hasApiGateway:i,hasEventBridge:o,hasDynamoDB:l,hasS3:u,hasLambdaLayers:m}}async findFunctionPath(t,e,r){let s=r.split(".");if(s.length<2)return;let n=s[0],i=[".js",".ts",".py",".cs",".java",".go"];for(let o of i){let l=P.join(t,n+o);if(O.existsSync(l))return P.relative(t,l)}}async detectSharedResources(t){let e=[],r=["shared/**/*.yml","shared/**/*.yaml","resources/**/*.yml","resources/**/*.yaml","common/**/*.yml","common/**/*.yaml"];for(let s of r){let{glob:n}=await import("glob"),i=await n(s,{cwd:t,maxDepth:3});e.push(...i)}return e}async detectGlobalPlugins(t){let e=[],r=P.join(t,"package.json");if(O.existsSync(r))try{let s=JSON.parse(O.readFileSync(r,"utf8")),n={...s.dependencies,...s.devDependencies};for(let i of Object.keys(n))(i.startsWith("serverless-")||i.includes("serverless"))&&e.push(i)}catch(s){c.warn("Failed to parse root package.json",{error:s})}return e}async detectFrameworkVersion(t){let e=P.join(t,"package.json");if(O.existsSync(e))try{let r=JSON.parse(O.readFileSync(e,"utf8")),s={...r.dependencies,...r.devDependencies};if(s.serverless)return s.serverless.replace(/[\^~]/,"")}catch(r){c.warn("Failed to detect Serverless Framework version",{error:r})}}extractDeploymentBuckets(t){let e=[];for(let r of t){r.customVariables.deploymentBucket&&e.push(r.customVariables.deploymentBucket);for(let s of r.resources)s.type.includes("S3")&&s.properties.BucketName&&e.push(s.properties.BucketName)}return[...new Set(e)]}extractCustomDomains(t){let e=[];for(let r of t){if(r.customVariables.customDomain){let s=r.customVariables.customDomain;typeof s=="object"&&s.domainName?e.push(s.domainName):typeof s=="string"&&e.push(s)}for(let s of r.stages)s.customDomain&&e.push(s.customDomain)}return[...new Set(e)]}}});var _,W,xe,xt=A(()=>{"use strict";_=h(require("fs")),W=h(require("path"));R();xe=class{async detect(t){try{if(c.info("Starting AWS SAM workspace detection",{workspacePath:t}),!await this.hasSamIndicators(t))return null;let r=await this.detectSamApplications(t);if(r.length===0)return null;let s=await this.detectSharedLayers(t),n=await this.detectSharedTemplates(t),i=await this.detectSamCliVersion(t),o=await this.detectAwsRegion(t),l=await this.detectDeploymentBucket(t),u=this.analyzeWorkspaceCapabilities(r),m;return r.some(f=>f.nestedApplications.length>0)?m="sam-nested-apps":r.length>1?m="sam-multi-app":m="sam-single-app",{pattern:m,applications:r,sharedLayers:s,sharedTemplates:n,samCliVersion:i,awsRegion:o,deploymentBucket:l,...u}}catch(e){return c.error("Failed to detect AWS SAM workspace",{error:e,workspacePath:t}),null}}async hasSamIndicators(t){let e=["template.yaml","template.yml","sam.yaml","sam.yml","**/template.yaml","**/template.yml","samconfig.toml",".aws-sam/**"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t,maxDepth:3})).length>0)return!0}return!1}async detectSamApplications(t){let{glob:e}=await import("glob"),r=await e("**/template.{yaml,yml}",{cwd:t,maxDepth:3}),s=[];for(let n of r)try{let i=W.dirname(W.resolve(t,n)),o=await this.analyzeSamApplication(i,n);o&&s.push(o)}catch(i){c.warn("Failed to analyze SAM application",{error:i,templateFile:n})}return s}async analyzeSamApplication(t,e){try{let r=W.resolve(t,W.basename(e)),s=_.readFileSync(r,"utf8"),n=await this.parseSamTemplate(s);if(!this.isSamTemplate(n))return null;let i=n.Parameters?.ApplicationName?.Default||W.basename(t),o=await this.parseSamFunctions(n.Resources||{},t),l=await this.parseSamApis(n.Resources||{},o),u=await this.parseSamTables(n.Resources||{}),m=await this.parseSamLayers(n.Resources||{},t),p=await this.findNestedApplications(n.Resources||{}),f=await this.hasLocalTesting(t),S=await this.hasIntegrationTests(t),U=await this.hasPipeline(t);return{name:i,path:t,templatePath:r,samVersion:n.AWSTemplateFormatVersion||"2010-09-09",transform:n.Transform||"AWS::Serverless-2016-10-31",description:n.Description,globals:n.Globals,parameters:n.Parameters,mappings:n.Mappings,conditions:n.Conditions,functions:o,apis:l,tables:u,layers:m,nestedApplications:p,outputs:n.Outputs,hasLocalTesting:f,hasIntegrationTests:S,hasPipeline:U}}catch(r){return c.error("Failed to analyze SAM application",{error:r,appPath:t,templateFile:e}),null}}async parseSamTemplate(t){let e=t.split(`
65
- `),r={},s="",n="",i=0;for(let o of e){let l=o.trim();if(!l||l.startsWith("#"))continue;let u=o.length-o.trimStart().length;if(l.includes(":")){let[m,p]=l.split(":",2),f=m.trim(),S=p?.trim()||"";u===0?(s=f,r[f]=S||{},i=0):u===2&&s?(n=f,(!r[s]||typeof r[s]!="object")&&(r[s]={}),r[s][f]=S||{},i=2):u>i&&s&&n&&((!r[s][n]||typeof r[s][n]!="object")&&(r[s][n]={}),r[s][n][f]=S||{})}}return r}isSamTemplate(t){return t.Transform==="AWS::Serverless-2016-10-31"||t.Resources&&Object.values(t.Resources).some(e=>e.Type&&e.Type.startsWith("AWS::Serverless::"))}async parseSamFunctions(t,e){let r=[];for(let[s,n]of Object.entries(t)){let i=n;if(i.Type==="AWS::Serverless::Function"){let o=i.Properties||{},l={name:s,handler:o.Handler||"index.handler",runtime:o.Runtime||"nodejs18.x",codeUri:o.CodeUri||".",events:await this.parseSamEvents(o.Events||{}),environment:o.Environment?.Variables,layers:o.Layers,timeout:o.Timeout,memorySize:o.MemorySize,reservedConcurrency:o.ReservedConcurrencyLimit,policies:o.Policies};r.push(l)}}return r}async parseSamEvents(t){let e=[];for(let[r,s]of Object.entries(t)){let n=s,i=n.Type||"Unknown";e.push({type:this.normalizeSamEventType(i),properties:n.Properties||{}})}return e}normalizeSamEventType(t){switch(t){case"Api":return"Api";case"HttpApi":return"HttpApi";case"S3":return"S3";case"DynamoDB":return"DynamoDB";case"SQS":return"SQS";case"SNS":return"SNS";case"EventBridge":case"EventBridgeRule":return"EventBridge";case"Schedule":return"Schedule";case"CloudWatchEvent":return"CloudWatchEvent";default:return"Unknown"}}async parseSamApis(t,e){let r=[];for(let[s,n]of Object.entries(t)){let i=n;if(i.Type==="AWS::Serverless::Api"||i.Type==="AWS::Serverless::HttpApi"){let o=i.Properties||{},l={name:s,type:i.Type==="AWS::Serverless::HttpApi"?"HttpApi":"Api",stageName:o.StageName,cors:o.Cors!==void 0,auth:o.Auth,domain:o.Domain?.DomainName,endpoints:[]};for(let u of e)for(let m of u.events)(m.type==="Api"||m.type==="HttpApi")&&(m.properties.RestApiId===s||!m.properties.RestApiId)&&l.endpoints.push({method:m.properties.Method||"ANY",path:m.properties.Path||"/",functionName:u.name});r.push(l)}}if(r.length===0){let s=[],n=[];for(let i of e)for(let o of i.events)o.type==="Api"?s.push({method:o.properties.Method||"ANY",path:o.properties.Path||"/",functionName:i.name}):o.type==="HttpApi"&&n.push({method:o.properties.Method||"ANY",path:o.properties.Path||"/",functionName:i.name});s.length>0&&r.push({name:"ImplicitApi",type:"Api",endpoints:s}),n.length>0&&r.push({name:"ImplicitHttpApi",type:"HttpApi",endpoints:n})}return r}async parseSamTables(t){let e=[];for(let[r,s]of Object.entries(t)){let n=s;if(n.Type==="AWS::Serverless::SimpleTable"||n.Type==="AWS::DynamoDB::Table"){let i=n.Properties||{};e.push({name:r,attributeDefinitions:i.AttributeDefinitions||[],keySchema:i.KeySchema||[],billingMode:i.BillingMode,streamSpecification:i.StreamSpecification})}}return e}async parseSamLayers(t,e){let r=[];for(let[s,n]of Object.entries(t)){let i=n;if(i.Type==="AWS::Serverless::LayerVersion"){let o=i.Properties||{};r.push({name:s,contentUri:o.ContentUri||"layers/",compatibleRuntimes:o.CompatibleRuntimes||[],description:o.Description})}}return r}async findNestedApplications(t){let e=[];for(let[r,s]of Object.entries(t))s.Type==="AWS::Serverless::Application"&&e.push(r);return e}async hasLocalTesting(t){let e=["tests/**","test/**","**/test_*.py","**/test_*.js","**/test_*.ts","**/spec_*.js","**/spec_*.ts","pytest.ini","jest.config.js","jest.config.ts"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t,maxDepth:2})).length>0)return!0}return!1}async hasIntegrationTests(t){let e=["integration/**","integration-tests/**","e2e/**","end-to-end/**","**/integration_*.py","**/integration_*.js","**/integration_*.ts","**/e2e_*.js","**/e2e_*.ts"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t,maxDepth:2})).length>0)return!0}return!1}async hasPipeline(t){let e=["pipeline.yaml","pipeline.yml","buildspec.yml","buildspec.yaml",".github/workflows/**",".gitlab-ci.yml","Jenkinsfile","azure-pipelines.yml","codepipeline/**"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t,maxDepth:2})).length>0)return!0}return!1}async detectSharedLayers(t){let e=[],r=W.join(t,"layers");if(_.existsSync(r)&&_.statSync(r).isDirectory()){let s=_.readdirSync(r).filter(n=>_.statSync(W.join(r,n)).isDirectory());for(let n of s)e.push({name:n,contentUri:`layers/${n}`,compatibleRuntimes:[],description:`Shared layer: ${n}`})}return e}async detectSharedTemplates(t){let{glob:e}=await import("glob"),r=["shared/**/*.{yaml,yml}","templates/**/*.{yaml,yml}","common/**/*.{yaml,yml}"],s=[];for(let n of r){let i=await e(n,{cwd:t,maxDepth:2});s.push(...i)}return s}async detectSamCliVersion(t){let e=W.join(t,"samconfig.toml");if(_.existsSync(e))try{let s=_.readFileSync(e,"utf8").match(/version\s*=\s*["']([^"']+)["']/);if(s)return s[1]}catch(r){c.warn("Failed to parse samconfig.toml",{error:r})}}async detectAwsRegion(t){let e=W.join(t,"samconfig.toml");if(_.existsSync(e))try{let s=_.readFileSync(e,"utf8").match(/region\s*=\s*["']([^"']+)["']/);if(s)return s[1]}catch(r){c.warn("Failed to parse region from samconfig.toml",{error:r})}}async detectDeploymentBucket(t){let e=W.join(t,"samconfig.toml");if(_.existsSync(e))try{let s=_.readFileSync(e,"utf8").match(/s3_bucket\s*=\s*["']([^"']+)["']/);if(s)return s[1]}catch(r){c.warn("Failed to parse deployment bucket from samconfig.toml",{error:r})}}analyzeWorkspaceCapabilities(t){let e=t.some(p=>p.layers.length>0),r=t.some(p=>p.hasPipeline),s=t.some(p=>p.hasLocalTesting),n=t.some(p=>p.apis.length>0),i=t.some(p=>p.tables.length>0),o=!1,l=!1,u=!1,m=!1;for(let p of t)for(let f of p.functions)for(let S of f.events)switch(S.type){case"S3":o=!0;break;case"EventBridge":l=!0;break;case"SQS":u=!0;break;case"SNS":m=!0;break}return{hasSharedResources:e,hasPipeline:r,hasLocalInvoke:s,hasApiGateway:n,hasDynamoDB:i,hasS3:o,hasEventBridge:l,hasSQS:u,hasSNS:m}}}});var w,I,Pe,Pt=A(()=>{"use strict";w=h(require("fs")),I=h(require("path"));R();Pe=class{async detect(t){try{if(c.info("Starting JavaScript/TypeScript workspace detection",{workspacePath:t}),!await this.hasJavaScriptIndicators(t))return null;let r=await this.detectPackageManager(t),s=await this.detectWorkspaceManager(t),n=await this.detectJavaScriptPackages(t,s);if(n.length===0)return null;let i=await this.detectNodeVersion(t),o=w.existsSync(I.join(t,"docker-compose.yml"))||w.existsSync(I.join(t,"docker-compose.yaml")),l=await this.hasCI(t),u=await this.hasHusky(t),m=await this.hasCommitizen(t),p=await this.hasRenovate(t),f=await this.hasSemanticRelease(t),S=await this.hasTurbo(t),U=await this.hasNx(t),se=await this.hasLerna(t),ne=await this.detectSharedConfigs(t),We=await this.detectGlobalDependencies(t),Y;return this.hasFullstackPattern(n)?Y="js-fullstack":s||n.length>1?Y=s?"js-monorepo":"js-multi-package":Y="js-single-package",{pattern:Y,packages:n,workspaceManager:s,nodeVersion:i,packageManager:r,hasDockerCompose:o,hasCI:l,hasHusky:u,hasCommitizen:m,hasRenovate:p,hasSemanticRelease:f,hasTurbo:S,hasNx:U,hasLerna:se,sharedConfigs:ne,globalDependencies:We}}catch(e){return c.error("Failed to detect JavaScript workspace",{error:e,workspacePath:t}),null}}async hasJavaScriptIndicators(t){let e=["package.json","**/*.js","**/*.ts","**/*.jsx","**/*.tsx","**/*.vue","node_modules/","yarn.lock","package-lock.json","pnpm-lock.yaml","bun.lockb"];for(let r of e){let{glob:s}=await import("glob");if((await s(r,{cwd:t,maxDepth:2})).length>0)return!0}return!1}async detectPackageManager(t){return w.existsSync(I.join(t,"bun.lockb"))?"bun":w.existsSync(I.join(t,"pnpm-lock.yaml"))?"pnpm":w.existsSync(I.join(t,"yarn.lock"))?"yarn":"npm"}async detectWorkspaceManager(t){if(w.existsSync(I.join(t,"nx.json")))return"nx";if(w.existsSync(I.join(t,"lerna.json")))return"lerna";if(w.existsSync(I.join(t,"rush.json")))return"rush";let e=I.join(t,"package.json");if(w.existsSync(e))try{if(JSON.parse(w.readFileSync(e,"utf8")).workspaces)switch(await this.detectPackageManager(t)){case"yarn":return"yarn-workspaces";case"npm":return"npm-workspaces";case"pnpm":return"pnpm-workspaces"}}catch(r){c.warn("Failed to parse root package.json",{error:r})}}async detectJavaScriptPackages(t,e){let r=[],{glob:s}=await import("glob"),n=await s("**/package.json",{cwd:t,maxDepth:3,ignore:["**/node_modules/**"]});for(let i of n)try{let o=I.dirname(I.resolve(t,i)),l=await this.analyzeJavaScriptPackage(o);l&&r.push(l)}catch(o){c.warn("Failed to analyze JavaScript package",{error:o,packageJsonFile:i})}return r}async analyzeJavaScriptPackage(t){try{let e=I.join(t,"package.json"),r=JSON.parse(w.readFileSync(e,"utf8")),s=Object.keys(r.dependencies||{}),n=Object.keys(r.devDependencies||{}),i=[...s,...n],o=this.detectFramework(i,t),l=this.detectBuildTool(i,t),u=await this.detectPackageManager(t),m=this.detectRuntime(o,i),p=await this.detectLanguage(t,i),f=this.detectPackageType(r,o,i),S=await this.extractPort(t,r.scripts||{}),U=this.detectTestFramework(i),se=await this.hasTestFiles(t)||U!==void 0,ne=this.hasLinting(i,t),We=p!=="javascript"||i.includes("typescript"),Y=w.existsSync(I.join(t,"Dockerfile")),nt=!!(r.workspaces||r.nx),Ut=this.extractWorkspacePackages(r);return{name:r.name||I.basename(t),path:t,type:f,framework:o,buildTool:l,packageManager:u,runtime:m,language:p,port:S,scripts:r.scripts||{},dependencies:s,devDependencies:n,hasTests:se,testFramework:U,hasLinting:ne,hasTypeChecking:We,hasDockerfile:Y,isWorkspaceRoot:nt,workspacePackages:Ut}}catch(e){return c.error("Failed to analyze JavaScript package",{error:e,packagePath:t}),null}}detectFramework(t,e){return t.includes("react")?t.includes("next")?"next":"react":t.some(r=>r.startsWith("@angular/"))||w.existsSync(I.join(e,"angular.json"))?"angular":t.includes("vue")?t.includes("nuxt")?"nuxt":"vue":t.includes("svelte")?"svelte":t.includes("@nestjs/core")?"nest":t.includes("fastify")?"fastify":t.includes("express")?"express":t.some(r=>["node","nodemon","@types/node"].includes(r))?"node":"none"}detectBuildTool(t,e){return t.includes("@angular/cli")||w.existsSync(I.join(e,"angular.json"))?"angular-cli":t.includes("turbo")?"turbo":t.includes("vite")?"vite":t.includes("webpack")?"webpack":t.includes("rollup")?"rollup":t.includes("parcel")?"parcel":t.includes("esbuild")?"esbuild":"none"}detectRuntime(t,e){return["react","angular","vue","svelte"].includes(t)?"browser":["next","nuxt"].includes(t)?"both":["express","fastify","nest","node"].includes(t)||e.some(r=>["express","fastify","@nestjs/core","http-server"].includes(r))?"node":e.some(r=>["react-dom","@angular/platform-browser","vue"].includes(r))?"browser":"node"}async detectLanguage(t,e){let r=e.includes("typescript")||w.existsSync(I.join(t,"tsconfig.json")),{glob:s}=await import("glob"),n=await s("**/*.{js,jsx}",{cwd:t,maxDepth:2,ignore:["**/node_modules/**"]}),i=await s("**/*.{ts,tsx}",{cwd:t,maxDepth:2,ignore:["**/node_modules/**"]});return i.length===0&&n.length>0?"javascript":n.length===0&&i.length>0?"typescript":n.length>0&&i.length>0?"mixed":r?"typescript":"javascript"}detectPackageType(t,e,r){return t.private===!1||t.publishConfig?"library":["react","angular","vue","svelte","next","nuxt"].includes(e)||["express","fastify","nest","node"].includes(e)?"app":t.name?.includes("config")||t.name?.includes("eslint")?"config":r.some(s=>["storybook","@storybook/react","@storybook/angular"].includes(s))?"component":t.bin||r.some(s=>["commander","yargs","inquirer"].includes(s))?"tool":"app"}async extractPort(t,e){for(let[s,n]of Object.entries(e))if(["start","dev","serve"].includes(s)){let i=n.match(/--port[=\s]+(\d+)|-p[=\s]+(\d+)|PORT[=\s]+(\d+)/);if(i)return parseInt(i[1]||i[2]||i[3])}let r=["vite.config.js","vite.config.ts","vue.config.js","angular.json",".env",".env.local"];for(let s of r){let n=I.join(t,s);if(w.existsSync(n))try{let i=w.readFileSync(n,"utf8");if(s==="angular.json"){let o=JSON.parse(i),u=Object.values(o.projects||{})[0]?.architect?.serve?.options?.port;if(u)return u}else{let o=i.match(/port[:\s=]+(\d+)/i);if(o)return parseInt(o[1])}}catch{}}}detectTestFramework(t){if(t.includes("jest"))return"jest";if(t.includes("vitest"))return"vitest";if(t.includes("mocha"))return"mocha";if(t.includes("cypress"))return"cypress";if(t.includes("playwright")||t.includes("@playwright/test"))return"playwright";if(t.includes("jasmine"))return"jasmine";if(t.includes("karma"))return"karma"}async hasTestFiles(t){let{glob:e}=await import("glob"),r=["**/*.test.{js,ts,jsx,tsx}","**/*.spec.{js,ts,jsx,tsx}","**/test/**/*.{js,ts,jsx,tsx}","**/tests/**/*.{js,ts,jsx,tsx}","**/__tests__/**/*.{js,ts,jsx,tsx}"];for(let s of r)if((await e(s,{cwd:t,maxDepth:3,ignore:["**/node_modules/**"]})).length>0)return!0;return!1}hasLinting(t,e){return t.some(r=>r.includes("eslint"))||w.existsSync(I.join(e,".eslintrc.js"))||w.existsSync(I.join(e,".eslintrc.json"))||w.existsSync(I.join(e,"eslint.config.js"))}extractWorkspacePackages(t){if(t.workspaces){if(Array.isArray(t.workspaces))return t.workspaces;if(t.workspaces.packages)return t.workspaces.packages}}hasFullstackPattern(t){let e=["react","angular","vue","svelte"],r=["express","fastify","nest","node"],s=t.some(i=>e.includes(i.framework)),n=t.some(i=>r.includes(i.framework));return s&&n}async detectNodeVersion(t){let e=I.join(t,".nvmrc");if(w.existsSync(e))try{return w.readFileSync(e,"utf8").trim()}catch{}let r=I.join(t,"package.json");if(w.existsSync(r))try{let s=JSON.parse(w.readFileSync(r,"utf8"));if(s.engines?.node)return s.engines.node}catch{}}async hasCI(t){let e=[".github/workflows",".gitlab-ci.yml","azure-pipelines.yml","Jenkinsfile",".circleci/config.yml",".travis.yml"];for(let r of e)if(w.existsSync(I.join(t,r)))return!0;return!1}async hasHusky(t){return w.existsSync(I.join(t,".husky"))||await this.packageHasDependency(t,"husky")}async hasCommitizen(t){return await this.packageHasDependency(t,"commitizen")||await this.packageHasDependency(t,"cz-conventional-changelog")}async hasRenovate(t){return w.existsSync(I.join(t,"renovate.json"))||w.existsSync(I.join(t,".renovaterc"))}async hasSemanticRelease(t){return await this.packageHasDependency(t,"semantic-release")}async hasTurbo(t){return w.existsSync(I.join(t,"turbo.json"))||await this.packageHasDependency(t,"turbo")}async hasNx(t){return w.existsSync(I.join(t,"nx.json"))}async hasLerna(t){return w.existsSync(I.join(t,"lerna.json"))}async packageHasDependency(t,e){let r=I.join(t,"package.json");if(!w.existsSync(r))return!1;try{let s=JSON.parse(w.readFileSync(r,"utf8")),n={...s.dependencies,...s.devDependencies};return e in n}catch{return!1}}async detectSharedConfigs(t){let e=[".eslintrc.js",".eslintrc.json","eslint.config.js","prettier.config.js",".prettierrc","jest.config.js","vitest.config.js","tsconfig.json","tsconfig.base.json","babel.config.js",".babelrc","webpack.config.js","vite.config.js","tailwind.config.js",".editorconfig",".gitignore"],r=[];for(let s of e)w.existsSync(I.join(t,s))&&r.push(s);return r}async detectGlobalDependencies(t){let e=I.join(t,"package.json");if(!w.existsSync(e))return[];try{let r=JSON.parse(w.readFileSync(e,"utf8"));return Object.keys({...r.dependencies,...r.devDependencies})}catch{return[]}}}});var Rt={};Q(Rt,{WorkspaceRegistrationWizard:()=>Qe});var M,k,D,C,Qe,Dt=A(()=>{"use strict";M=h(require("prompts")),k=h(require("chalk")),D=h(require("fs")),C=h(require("path"));Et();R();Ct();At();Tt();xt();Pt();Qe=class{constructor(){this.configService=new Ee,this.dotNetDetector=new Ce,this.pythonDetector=new Ae,this.serverlessDetector=new Te,this.awsSamDetector=new xe,this.jsDetector=new Pe}async run(t){try{console.log(k.default.blue.bold(`
66
- \u{1F680} Task Shepherd Workspace Registration`)),console.log(k.default.gray("\u2550".repeat(50))),console.log(k.default.gray(`Registering workspace at: ${t}`)),console.log();let e=C.join(t,"task-shepherd-workspace.json"),r=D.existsSync(e);if(r){console.log(k.default.yellow("\u26A0\uFE0F Existing workspace configuration found"));let i=await(0,M.default)({type:"select",name:"action",message:"What would you like to do?",choices:[{title:"Register workspace with existing configuration",value:"register"},{title:"Edit configuration and register",value:"edit"},{title:"Cancel",value:"cancel"}],initial:0});if(i.action==="cancel"){console.log(k.default.yellow("Registration cancelled"));return}if(i.action==="register"){await this.registerExistingConfig(t,e);return}}console.log(k.default.blue("\u{1F50D} Analyzing workspace..."));let s=await this.analyzeWorkspace(t);if(r)try{let i=D.readFileSync(e,"utf8"),o=JSON.parse(i);s=this.mergeWithExistingConfig(s,o.workspace)}catch(i){c.warn("Could not load existing config for editing",{error:i})}let n=await this.collectWorkspaceInfo(s);await this.saveWorkspaceConfig(t,n),this.displaySummary(t,n)}catch(e){throw c.error("Workspace registration failed",{error:e,workspacePath:t}),e}}async registerExistingConfig(t,e){try{let r=D.readFileSync(e,"utf8"),s=JSON.parse(r);console.log(k.default.blue(`
67
- \u{1F4CB} Existing Configuration`)),console.log(k.default.gray("\u2550".repeat(30)));let n=s.workspace;if(console.log(k.default.cyan("Workspace:")),console.log(` Name: ${k.default.white(n.name)}`),n.description&&console.log(` Description: ${k.default.white(n.description)}`),console.log(` Pattern: ${k.default.white(n.pattern)}`),n.services&&n.services.length>0&&(console.log(k.default.cyan(`
68
- Services:`)),n.services.forEach(o=>{console.log(` \u2022 ${k.default.white(o.name)} (${o.technology})`)})),!(await(0,M.default)({type:"confirm",name:"proceed",message:"Register this workspace with the backend?",initial:!0})).proceed){console.log(k.default.yellow("Registration cancelled"));return}console.log(k.default.green(`
69
- \u2705 Workspace registered successfully with existing configuration`)),console.log(k.default.gray("Run `task-shepherd-agent workspace sync` to sync with backend"))}catch(r){throw c.error("Failed to load existing configuration",{error:r,configPath:e}),new Error(`Failed to load existing configuration: ${r instanceof Error?r.message:r}`)}}mergeWithExistingConfig(t,e){return{name:e.name||t.name,description:e.description||t.description,pattern:e.pattern||t.pattern,detectedTechnologies:t.detectedTechnologies,services:e.services||t.services,capabilities:e.capabilities||t.capabilities,tags:e.tags||t.tags}}async analyzeWorkspace(t){let e={};try{console.log(k.default.gray(" Detecting workspace technologies..."));let[r,s,n,i,o]=await Promise.all([this.dotNetDetector.detect(t).catch(()=>null),this.pythonDetector.detect(t).catch(()=>null),this.serverlessDetector.detect(t).catch(()=>null),this.awsSamDetector.detect(t).catch(()=>null),this.jsDetector.detect(t).catch(()=>null)]),l=[],u=[],m="multi-repo";if(r&&(console.log(k.default.gray(` \u2713 Detected .NET workspace (${r.pattern})`)),u.push("dotnet","csharp"),r.solutions.forEach(p=>{l.push({name:p.name,technology:"dotnet-solution",framework:"dotnet",path:C.relative(t,p.path)||"."})}),[...r.standaloneProjects,...r.sharedProjects].forEach(p=>{l.push({name:p.name,technology:p.type,framework:"dotnet",port:p.port,path:C.relative(t,p.path)||"."})}),r.solutions.length>1&&(m="monorepo")),s&&(console.log(k.default.gray(` \u2713 Detected Python workspace (${s.pattern})`)),u.push("python"),s.projects.forEach(p=>{u.push(p.framework||"python"),p.apps.forEach(f=>{l.push({name:f.name,technology:f.type,framework:p.framework,runtime:"python",port:f.port,path:C.relative(t,f.path)||"."})})}),s.pattern==="python-monorepo"&&(m="monorepo")),n&&(console.log(k.default.gray(` \u2713 Detected Serverless workspace (${n.pattern})`)),u.push("serverless"),n.services.forEach(p=>{l.push({name:p.name,technology:"serverless",framework:"serverless-framework",runtime:p.runtime,path:C.relative(t,p.path)||"."})}),n.pattern==="serverless-monorepo"&&(m="monorepo")),i&&(console.log(k.default.gray(` \u2713 Detected AWS SAM workspace (${i.pattern})`)),u.push("aws-sam","serverless"),i.applications.forEach(p=>{l.push({name:p.name,technology:"aws-sam",framework:"aws-sam",runtime:"serverless",path:C.relative(t,p.path)||"."})}),i.pattern==="sam-multi-app"&&(m="monorepo")),o&&(console.log(k.default.gray(` \u2713 Detected JavaScript/TypeScript workspace (${o.pattern})`)),u.push("javascript","typescript","nodejs"),o.packages.forEach(p=>{p.framework!=="none"&&u.push(p.framework),l.push({name:p.name,technology:p.type,framework:p.framework,runtime:p.runtime,port:p.port,path:C.relative(t,p.path)||"."})}),o.pattern==="js-monorepo"&&(m="monorepo")),l.length===0){console.log(k.default.gray(" Using generic workspace detection..."));let p=await this.configService.discoverWorkspaces(t);if(p.length>0){let f=p[0];e.name=f.name,e.pattern=f.pattern,e.services=f.services.map(S=>({name:S.name,technology:S.technology,port:S.port,path:C.relative(t,S.path)||"."}))}}else e.name=C.basename(t),e.pattern=m,e.detectedTechnologies=[...new Set(u)],e.services=l;e.capabilities=await this.detectCapabilities(t,e.detectedTechnologies),e.tags=await this.suggestTags(t,e),e.detectedTechnologies&&e.detectedTechnologies.length>0&&console.log(k.default.gray(` Technologies: ${e.detectedTechnologies.join(", ")}`))}catch(r){c.warn("Failed to analyze workspace, will use defaults",{error:r,workspacePath:t}),e.name=C.basename(t),e.pattern="multi-repo",e.services=[],e.capabilities=[],e.tags=[]}return e}async collectWorkspaceInfo(t){console.log(k.default.blue(`
70
- \u{1F4CB} Workspace Configuration`)),console.log(k.default.gray(`Press Enter to accept suggested values
71
- `)),t.detectedTechnologies&&t.detectedTechnologies.length>0&&(console.log(k.default.cyan("Detected Technologies:")),console.log(` ${t.detectedTechnologies.map(i=>k.default.white(i)).join(", ")}`),console.log());let e=await(0,M.default)([{type:"text",name:"name",message:"Workspace name:",initial:t.name||C.basename(process.cwd()),validate:i=>i.trim().length>0?!0:"Name is required"},{type:"text",name:"description",message:"Description (optional):",initial:this.generateDescription(t)},{type:"select",name:"pattern",message:"Workspace pattern:",choices:[{title:"Monorepo - Single repository with multiple services",value:"monorepo"},{title:"Multi-repo - Multiple related repositories",value:"multi-repo"},{title:"Hybrid - Mix of monorepo and multi-repo patterns",value:"hybrid"}],initial:t.pattern==="monorepo"?0:t.pattern==="hybrid"?2:1}]);if(!e.name)throw new Error("Workspace registration cancelled");let r=await this.collectServicesInfo(t.services||[]);if((await(0,M.default)({type:"confirm",name:"manual",message:"Add services manually (if auto-detection missed anything)?",initial:!1})).manual){let i=await this.collectManualServices();r.push(...i)}let n=await(0,M.default)([{type:"list",name:"capabilities",message:"Capabilities (comma-separated):",initial:(t.capabilities||[]).join(", "),separator:","},{type:"list",name:"tags",message:"Tags (comma-separated):",initial:(t.tags||[]).join(", "),separator:","}]);return{name:e.name,description:e.description||void 0,pattern:e.pattern,detectedTechnologies:t.detectedTechnologies,services:r,capabilities:n.capabilities?.filter(i=>i.trim())||[],tags:n.tags?.filter(i=>i.trim())||[]}}async collectServicesInfo(t){console.log(k.default.blue(`
72
- \u2699\uFE0F Services Configuration`));let e=[];if(t.length===0)return console.log(k.default.gray(" No services were automatically detected")),e;console.log(k.default.gray(` Found ${t.length} potential service(s)
73
- `));for(let r of t){let s=this.formatServiceDescription(r);if((await(0,M.default)({type:"confirm",name:"include",message:`Include detected service: ${s}?`,initial:!0})).include){let i=await(0,M.default)([{type:"text",name:"name",message:"Service name:",initial:r.name,validate:o=>o.trim().length>0?!0:"Name is required"},{type:"text",name:"technology",message:"Technology/Framework:",initial:r.technology},{type:"number",name:"port",message:"Port (optional):",initial:r.port,min:1,max:65535},{type:"text",name:"path",message:"Relative path:",initial:r.path||"."}]);i.name&&e.push({name:i.name,technology:i.technology||"unknown",framework:r.framework,runtime:r.runtime,port:i.port||void 0,path:i.path||"."})}}return e}async detectCapabilities(t,e){let r=[];try{e&&((e.includes("dotnet")||e.includes("csharp"))&&r.push("dotnet-development","enterprise-development"),e.includes("python")&&r.push("python-development"),e.includes("django")&&r.push("web-development","orm-development"),(e.includes("flask")||e.includes("fastapi"))&&r.push("api-development","microservices"),(e.includes("serverless")||e.includes("aws-sam"))&&r.push("serverless-development","cloud-native"),e.includes("react")&&r.push("frontend-development","spa-development"),e.includes("angular")&&r.push("frontend-development","enterprise-frontend"),e.includes("nodejs")&&r.push("backend-development","javascript-development"),e.includes("typescript")&&r.push("type-safe-development"));let s=C.join(t,"package.json");if(D.existsSync(s)){r.push("nodejs-development");let n=JSON.parse(D.readFileSync(s,"utf8")),i={...n.dependencies,...n.devDependencies};i.react&&r.push("react-development"),i.typescript&&r.push("typescript-development"),i.graphql&&r.push("graphql-api"),i.express&&r.push("rest-api"),(i.jest||i.vitest)&&r.push("automated-testing"),i.docker&&r.push("containerization")}(D.existsSync(C.join(t,"requirements.txt"))||D.existsSync(C.join(t,"pyproject.toml")))&&r.push("python-development"),D.existsSync(C.join(t,"global.json"))&&r.push("dotnet-development"),D.existsSync(C.join(t,"Dockerfile"))&&r.push("containerization"),D.existsSync(C.join(t,".github"))&&r.push("ci-cd"),D.existsSync(C.join(t,"docker-compose.yml"))&&r.push("multi-service-orchestration"),D.existsSync(C.join(t,"serverless.yml"))&&r.push("serverless-development"),D.existsSync(C.join(t,"template.yaml"))&&r.push("aws-sam-development")}catch(s){c.warn("Failed to detect capabilities",{error:s,workspacePath:t})}return[...new Set(r)]}async suggestTags(t,e){let r=[];e.pattern&&r.push(e.pattern),e.services?.forEach(n=>{n.technology&&!r.includes(n.technology)&&r.push(n.technology)});let s=e.name?.toLowerCase()||"";return s.includes("api")&&r.push("api"),s.includes("web")&&r.push("web"),s.includes("mobile")&&r.push("mobile"),s.includes("admin")&&r.push("admin"),s.includes("dashboard")&&r.push("dashboard"),r}async saveWorkspaceConfig(t,e){let r=C.join(t,"task-shepherd-workspace.json"),s={version:"1.0",workspace:{name:e.name,description:e.description,pattern:e.pattern,services:e.services.map(n=>({name:n.name,technology:n.technology,port:n.port,path:n.path})),capabilities:e.capabilities,tags:e.tags},metadata:{createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),configVersion:"1.0"}};try{await D.promises.writeFile(r,JSON.stringify(s,null,2)+`
74
- `,"utf8"),console.log(k.default.green(`
75
- \u2705 Workspace configuration saved to ${k.default.bold("task-shepherd-workspace.json")}`))}catch(n){throw c.error("Failed to save workspace configuration",{error:n,configPath:r}),new Error(`Failed to save configuration: ${n instanceof Error?n.message:n}`)}}displaySummary(t,e){console.log(k.default.blue.bold(`
76
- \u{1F4CB} Registration Summary`)),console.log(k.default.gray("\u2550".repeat(40))),console.log(k.default.cyan("Workspace:")),console.log(` Name: ${k.default.white(e.name)}`),e.description&&console.log(` Description: ${k.default.white(e.description)}`),console.log(` Pattern: ${k.default.white(e.pattern)}`),e.services.length>0&&(console.log(k.default.cyan(`
77
- Services:`)),e.services.forEach(r=>{let s=r.framework?`${r.technology}/${r.framework}`:r.technology;console.log(` \u2022 ${k.default.white(r.name)} (${s})`),r.runtime&&r.runtime!==r.framework&&console.log(` Runtime: ${r.runtime}`),r.port&&console.log(` Port: ${r.port}`),r.path&&r.path!=="."&&console.log(` Path: ${r.path}`)})),e.capabilities&&e.capabilities.length>0&&(console.log(k.default.cyan(`
78
- Capabilities:`)),console.log(` ${e.capabilities.map(r=>k.default.white(r)).join(", ")}`)),e.tags&&e.tags.length>0&&(console.log(k.default.cyan(`
79
- Tags:`)),console.log(` ${e.tags.map(r=>k.default.white(r)).join(", ")}`)),console.log(k.default.cyan(`
80
- Next Steps:`)),console.log(` \u2022 Configuration saved to ${k.default.bold("task-shepherd-workspace.json")}`),console.log(" \u2022 Commit this file to version control"),console.log(` \u2022 Run ${k.default.bold("task-shepherd-agent workspace sync")} to sync with backend`),console.log()}generateDescription(t){if(!t.detectedTechnologies||t.detectedTechnologies.length===0)return"";let e=t.detectedTechnologies,r=[];return(e.includes("react")||e.includes("angular")||e.includes("vue"))&&r.push("frontend application"),e.includes("nodejs")&&(e.includes("express")||e.includes("fastify"))&&r.push("backend API"),e.includes("dotnet")&&r.push(".NET application"),e.includes("python")&&(e.includes("django")?r.push("Django web application"):e.includes("flask")||e.includes("fastapi")?r.push("Python API"):r.push("Python application")),(e.includes("serverless")||e.includes("aws-sam"))&&r.push("serverless application"),r.length===0?`Application built with ${e.slice(0,3).join(", ")}`:r.join(" and ")}formatServiceDescription(t){let e=`${k.default.cyan(t.name)}`;return t.framework&&t.framework!=="none"?e+=` (${t.framework})`:e+=` (${t.technology})`,t.port&&(e+=` on port ${t.port}`),t.path&&t.path!=="."&&(e+=` at ${t.path}`),e}async collectManualServices(){console.log(k.default.blue(`
81
- \u2795 Manual Service Entry`));let t=[],e=!0;for(;e;){let r=await(0,M.default)([{type:"text",name:"name",message:"Service name:",validate:n=>n.trim().length>0?!0:"Name is required"},{type:"select",name:"technology",message:"Technology/Framework:",choices:[{title:"Node.js/Express",value:"nodejs-express"},{title:"React",value:"react"},{title:"Angular",value:"angular"},{title:"Vue.js",value:"vue"},{title:".NET Core API",value:"dotnet-webapi"},{title:".NET Core MVC",value:"dotnet-mvc"},{title:"Python/Django",value:"python-django"},{title:"Python/Flask",value:"python-flask"},{title:"Python/FastAPI",value:"python-fastapi"},{title:"AWS Lambda",value:"aws-lambda"},{title:"Serverless Function",value:"serverless-function"},{title:"Database",value:"database"},{title:"Other",value:"other"}]},{type:"text",name:"framework",message:"Framework (if different from technology):",initial:""},{type:"number",name:"port",message:"Port (optional):",min:1,max:65535},{type:"text",name:"path",message:"Relative path:",initial:"."}]);r.name&&t.push({name:r.name,technology:r.technology,framework:r.framework||void 0,port:r.port||void 0,path:r.path||"."}),e=(await(0,M.default)({type:"confirm",name:"continue",message:"Add another service?",initial:!1})).continue}return t}}});var Ze={};Q(Ze,{WorkspaceSyncService:()=>Re,getWorkspaceSyncService:()=>hr});function hr(){return Xe||(Xe=new Re),Xe}var _t,Re,Xe,et=A(()=>{"use strict";R();B();ke();_t=require("events"),Re=class extends _t.EventEmitter{constructor(e=3e4){super();this.syncIntervalMs=e;this.syncInProgress=!1;this.syncTimer=null;this.isConnected=!1}startPeriodicSync(){this.syncTimer||(c.info("Starting periodic workspace sync",{intervalMs:this.syncIntervalMs}),this.syncWorkspaces(),this.syncTimer=setInterval(()=>{this.syncWorkspaces()},this.syncIntervalMs))}stopPeriodicSync(){this.syncTimer&&(clearInterval(this.syncTimer),this.syncTimer=null,c.info("Stopped periodic workspace sync"))}setConnectionStatus(e,r=!0){this.isConnected=e,e&&r?(c.info("Backend connection established, triggering workspace sync"),this.syncWorkspaces()):e?c.info("Backend connection enabled"):c.warn("Backend connection lost, workspace sync will pause")}async forceSyncAllWorkspaces(){if(this.syncInProgress){c.debug("Workspace sync already in progress, skipping");return}if(!this.isConnected){c.debug("Backend not connected, skipping workspace sync");return}this.syncInProgress=!0,this.emit("syncStarted");try{let e=z(),r=e.getAllWorkspaces();if(r.length===0){c.debug("No workspaces to sync"),this.emit("syncCompleted",{synced:0,failed:0}),this.syncInProgress=!1;return}c.info("Force syncing ALL workspaces",{totalCount:r.length});let s=te(),n=0,i=0;for(let o of r)try{c.debug("Force syncing workspace",{workspaceId:o.workspace.workspaceId,name:o.workspace.name,currentStatus:o.syncStatus}),await s.registerWorkspace({workspaceId:o.workspace.workspaceId,name:o.workspace.name,path:o.workspace.path,pattern:o.workspace.pattern,description:`${o.workspace.pattern} workspace with ${o.workspace.services.length} services`,services:o.workspace.services.map(l=>({serviceId:l.id,name:l.name,path:l.relativePath||l.path,technology:l.technology,port:l.port}))}),await e.markWorkspaceSynced(o.workspace.workspaceId),n++,this.emit("workspaceSynced",o.workspace)}catch(l){c.error("Failed to force sync workspace",{workspaceId:o.workspace.workspaceId,error:l instanceof Error?l.message:String(l)}),await e.markWorkspaceSyncFailed(o.workspace.workspaceId,l instanceof Error?l.message:"Unknown error"),i++,this.emit("workspaceSyncFailed",o.workspace,l)}c.info("Force workspace sync completed",{total:r.length,synced:n,failed:i}),this.emit("syncCompleted",{synced:n,failed:i})}catch(e){c.error("Force workspace sync failed:",e),this.emit("syncFailed",e)}finally{this.syncInProgress=!1}}async syncWorkspaces(){if(this.syncInProgress){c.debug("Workspace sync already in progress, skipping");return}if(!this.isConnected){c.debug("Backend not connected, skipping workspace sync");return}this.syncInProgress=!0,this.emit("syncStarted");try{let e=z(),r=e.getWorkspacesBySyncStatus("pending"),s=e.getWorkspacesBySyncStatus("failed"),n=[...r,...s];if(n.length===0){c.debug("No workspaces to sync"),this.emit("syncCompleted",{synced:0,failed:0}),this.syncInProgress=!1;return}c.info("Starting workspace sync",{pendingCount:r.length,failedRetryCount:s.length});let i=te(),o=0,l=0;for(let u of n)try{c.debug("Syncing workspace",{workspaceId:u.workspace.workspaceId,name:u.workspace.name}),await i.registerWorkspace({workspaceId:u.workspace.workspaceId,name:u.workspace.name,path:u.workspace.path,pattern:u.workspace.pattern,description:`${u.workspace.pattern} workspace with ${u.workspace.services.length} services`,services:u.workspace.services.map(m=>({serviceId:m.id,name:m.name,path:m.relativePath||m.path,technology:m.technology,port:m.port}))}),await e.markWorkspaceSynced(u.workspace.workspaceId),o++,this.emit("workspaceSynced",u.workspace)}catch(m){c.error("Failed to sync workspace",{workspaceId:u.workspace.workspaceId,error:m instanceof Error?m.message:String(m)}),await e.markWorkspaceSyncFailed(u.workspace.workspaceId,m instanceof Error?m.message:"Unknown error"),l++,this.emit("workspaceSyncFailed",u.workspace,m)}c.info("Workspace sync completed",{synced:o,failed:l}),this.emit("syncCompleted",{synced:o,failed:l})}catch(e){c.error("Workspace sync failed",{error:e instanceof Error?e.message:String(e)}),this.emit("syncError",e)}finally{this.syncInProgress=!1}}async syncWorkspace(e){let r=z(),s=r.getWorkspace(e);if(!s)throw new Error(`Workspace not found: ${e}`);try{await te().registerWorkspace({workspaceId:s.workspace.workspaceId,name:s.workspace.name,path:s.workspace.path,pattern:s.workspace.pattern,description:`${s.workspace.pattern} workspace with ${s.workspace.services.length} services`,services:s.workspace.services.map(i=>({serviceId:i.id,name:i.name,technology:i.technology,port:i.port}))}),await r.markWorkspaceSynced(s.workspace.workspaceId),this.emit("workspaceSynced",s.workspace)}catch(n){throw await r.markWorkspaceSyncFailed(s.workspace.workspaceId,n instanceof Error?n.message:"Unknown error"),n}}getSyncStatus(){let e=z();return{isConnected:this.isConnected,syncInProgress:this.syncInProgress,stats:e.getSyncStats()}}},Xe=null});var tt=A(()=>{"use strict"});function De(){if(!Nt)throw new Error("WorkItemErrorTracker not initialized. Call initializeWorkItemErrorTracker first.");return Nt}var Nt,jt=A(()=>{"use strict";R();tt();Nt=null});var _e={};Q(_e,{createDebugWorkItemCommand:()=>yr});function yr(){let a=new Wt.Command("debug");return a.description("Debug work items and analyze error patterns").option("-i, --work-item-id <id>","Debug specific work item by ID").option("-t, --work-type <type>","Analyze error patterns for work type").option("-v, --verbose","Show detailed information").option("--timeline","Show execution timeline").option("--suggestions","Show fix suggestions").option("--export <format>","Export debug data (json|csv)").action(async t=>{try{t.workItemId?await vr(t.workItemId,t):t.workType?await kr(t.workType,t):await br(t)}catch(e){console.error(E.default.red("\u274C Debug command failed:"),e instanceof Error?e.message:e),process.exit(1)}}),a}async function vr(a,t){console.log(E.default.blue(`\u{1F50D} Debugging work item: ${a}
82
- `));try{let e=De(),r=e.getErrorHistory(a),s=e.getLogHistory(a);if(r.length===0&&s.length===0){console.log(E.default.yellow("\u26A0\uFE0F No debug data found for this work item")),console.log(E.default.gray("This could mean:")),console.log(E.default.gray(" \u2022 Work item hasn't been processed yet")),console.log(E.default.gray(" \u2022 Work item ID is incorrect")),console.log(E.default.gray(" \u2022 Error tracking wasn't enabled when processed"));return}if(s.length>0){let n=s[0];console.log(E.default.green("\u{1F4CB} Work Item Information:")),console.log(` Work Type: ${n.workType}`),console.log(` Status: ${Ot(n.status)} ${n.status}`),console.log(` Worker ID: ${n.metadata.workerId}`),n.metadata.projectId&&console.log(` Project ID: ${n.metadata.projectId}`),console.log()}t.timeline&&s.length>0&&Sr(s),r.length>0?wr(r,t.verbose||!1):console.log(E.default.green("\u2705 No errors found for this work item")),t.suggestions&&r.length>0&&Ir(r),t.export&&await Er(a,{errors:r,logs:s},t.export)}catch(e){console.error(E.default.red("\u274C Failed to debug work item:"),e instanceof Error?e.message:e)}}async function kr(a,t){console.log(E.default.blue(`\u{1F4CA} Analyzing error patterns for work type: ${a}
83
- `));try{let r=De().getFailurePattern(a);if(!r||r.frequency===0){console.log(E.default.yellow("\u26A0\uFE0F No error data found for this work type"));return}console.log(E.default.green("\u{1F4C8} Error Pattern Analysis:")),console.log(` Most Common Error: ${r.errorType}`),console.log(` Frequency: ${r.frequency} occurrences`),console.log(` Average Retry Count: ${r.averageRetryCount.toFixed(1)}`),console.log(` Success Rate After Retry: ${r.successRateAfterRetry.toFixed(1)}%`),console.log(),Object.keys(r.commonContext).length>0&&(console.log(E.default.cyan("\u{1F50D} Common Context Patterns:")),Object.entries(r.commonContext).forEach(([s,n])=>{console.log(` ${s}: ${n}`)}),console.log()),r.suggestedFixes.length>0&&(console.log(E.default.yellow("\u{1F4A1} Suggested Fixes:")),r.suggestedFixes.forEach((s,n)=>{console.log(` ${n+1}. ${s}`)}),console.log()),t.export&&await Cr(a,r,t.export)}catch(e){console.error(E.default.red("\u274C Failed to analyze work type:"),e instanceof Error?e.message:e)}}async function br(a){console.log(E.default.blue(`\u{1F3E5} Work Item Health Overview
84
- `));try{let e=await De().getHealthStatus();console.log(E.default.green("\u{1F4CA} Current Status:")),console.log(` Active Work Items: ${e.activeWorkItems}`),console.log(` Failed (24h): ${e.failedInLast24Hours}`),console.log(` Success Rate: ${e.successRate.toFixed(1)}%`),console.log(` Avg Processing Time: ${e.averageProcessingTime}ms`),console.log(),e.topErrors.length>0&&(console.log(E.default.red("\u{1F6A8} Top Errors (24h):")),e.topErrors.slice(0,5).forEach((r,s)=>{let n=Lt(r.lastOccurrence);console.log(` ${s+1}. ${r.type} (${r.count}x) - ${n}`)}),console.log()),console.log(E.default.cyan("\u{1F4BB} System Resources:")),console.log(` Memory Usage: ${e.systemResources.memoryUsage}MB`),console.log(` CPU Usage: ${e.systemResources.cpuUsage}%`),console.log(` Disk Space: ${e.systemResources.diskSpace}MB`),console.log(),console.log(E.default.magenta("\u{1F310} External Services:")),Object.entries(e.externalServices).forEach(([r,s])=>{console.log(` ${r}: ${s==="healthy"?"\u2705":s==="degraded"?"\u26A0\uFE0F":"\u274C"} ${s}`)}),console.log(),a.export&&await Ar(e,a.export)}catch(t){console.error(E.default.red("\u274C Failed to get health overview:"),t instanceof Error?t.message:t)}}function Sr(a){console.log(E.default.cyan("\u23F1\uFE0F Execution Timeline:"));let t=a.sort((e,r)=>e.timestamp.getTime()-r.timestamp.getTime());t.forEach((e,r)=>{let s=e.timestamp.toLocaleTimeString(),n=e.duration?` (${Math.round(e.duration/1e3)}s)`:"",i=e.progress?.percentage?` - ${e.progress.percentage}%`:"";console.log(` ${s} ${Ot(e.status)} ${e.stage}${i}${n}`),e.errorData&&r<t.length-1&&console.log(E.default.red(` \u274C ${e.errorData.message}`))}),console.log()}function wr(a,t){console.log(E.default.red(`\u{1F6A8} Errors Found (${a.length}):`)),a.slice(0,t?a.length:5).forEach((e,r)=>{let s=Lt(e.context.timestamp);console.log(`
85
- ${r+1}. ${e.errorType} (${e.metadata.severity})`),console.log(` Message: ${e.message}`),console.log(` Stage: ${e.stage}`),console.log(` Occurred: ${s}`),console.log(` Retryable: ${e.metadata.retryable?"\u2705":"\u274C"}`),t&&e.stack&&console.log(E.default.gray(` Stack: ${e.stack.split(`
86
- `)[0]}`)),e.metadata.tags.length>0&&console.log(` Tags: ${e.metadata.tags.join(", ")}`)}),!t&&a.length>5&&console.log(E.default.gray(`
87
- ... and ${a.length-5} more errors (use --verbose to see all)`)),console.log()}function Ir(a){let t=a[0];if(!t)return;console.log(E.default.yellow("\u{1F4A1} Suggested Fixes:")),Tr(t.errorType,t.metadata.category).forEach((r,s)=>{console.log(` ${s+1}. ${r}`)}),console.log()}async function Er(a,t,e){let r=new Date().toISOString().replace(/[:.]/g,"-"),s=`work-item-debug-${a}-${r}.${e}`;try{let n=await import("fs/promises");if(e==="json")await n.writeFile(s,JSON.stringify(t,null,2));else if(e==="csv"){let i=t.errors.map(l=>`"${l.id}","${l.errorType}","${l.stage}","${l.message}","${l.context.timestamp}"`).join(`
88
- `);await n.writeFile(s,`ID,Error Type,Stage,Message,Timestamp
89
- `+i)}console.log(E.default.green(`\u2705 Debug data exported to: ${s}`))}catch(n){console.error(E.default.red("\u274C Failed to export debug data:"),n instanceof Error?n.message:n)}}async function Cr(a,t,e){let r=new Date().toISOString().replace(/[:.]/g,"-"),s=`work-type-analysis-${a}-${r}.${e}`;try{let n=await import("fs/promises");e==="json"&&await n.writeFile(s,JSON.stringify(t,null,2)),console.log(E.default.green(`\u2705 Pattern data exported to: ${s}`))}catch(n){console.error(E.default.red("\u274C Failed to export pattern data:"),n instanceof Error?n.message:n)}}async function Ar(a,t){let r=`health-overview-${new Date().toISOString().replace(/[:.]/g,"-")}.${t}`;try{let s=await import("fs/promises");t==="json"&&await s.writeFile(r,JSON.stringify(a,null,2)),console.log(E.default.green(`\u2705 Health data exported to: ${r}`))}catch(s){console.error(E.default.red("\u274C Failed to export health data:"),s instanceof Error?s.message:s)}}function Ot(a){switch(a){case"ASSIGNED":return"\u{1F4CB}";case"PROCESSING":return"\u2699\uFE0F";case"COMPLETED":return"\u2705";case"FAILED":return"\u274C";case"RETRYING":return"\u{1F504}";default:return"\u2753"}}function Lt(a){let e=new Date().getTime()-a.getTime(),r=Math.floor(e/(1e3*60)),s=Math.floor(r/60),n=Math.floor(s/24);return r<1?"just now":r<60?`${r}m ago`:s<24?`${s}h ago`:`${n}d ago`}function Tr(a,t){let e=[];switch(a){case"network_error":e.push("Check network connectivity"),e.push("Verify API endpoint URLs"),e.push("Increase request timeout");break;case"authentication_error":e.push("Refresh authentication token"),e.push("Verify API key is valid"),e.push("Check user permissions");break;case"claude_api_error":e.push("Check Claude API key"),e.push("Verify Claude CLI installation"),e.push("Check token usage limits");break;case"missing_project":e.push("Verify project ID exists in database"),e.push("Check project access permissions"),e.push("Refresh project data cache");break;case"timeout_error":e.push("Increase operation timeout"),e.push("Break down large operations"),e.push("Check system resource usage");break;default:e.push("Check logs for detailed error information"),e.push("Verify system configuration"),e.push("Contact system administrator")}return e}var Wt,E,Ne=A(()=>{"use strict";Wt=require("commander"),E=h(require("chalk"));jt();tt()});var xr={};Q(xr,{program:()=>F});module.exports=ot(xr);var Ft=require("commander"),d=h(require("chalk"));var ht=h(require("readline")),y=h(require("chalk"));var Z=require("fs"),ze=h(require("path")),T=h(require("os")),fe=h(require("crypto"));R();var N=class{constructor(t){this.configDir=t||ze.default.join(T.default.homedir(),".task-shepherd-agent"),this.identityFile=ze.default.join(this.configDir,"agent-identity.json")}async initializeIdentity(t){let e=await this.loadExistingIdentity();if(e&&t.persistent!==!1)return e.lastUsed=new Date().toISOString(),await this.saveIdentity(e),c.info("Using existing agent identity",{agentId:e.agentId,agentName:e.agentName,service:"identity"}),this.currentIdentity=e,e;let r=await this.generateNewIdentity(t);return t.persistent!==!1&&await this.saveIdentity(r),this.currentIdentity=r,c.info("Generated new agent identity",{agentId:r.agentId,agentName:r.agentName,strategy:t.strategy,service:"identity"}),r}async generateNewIdentity(t){let e=T.default.hostname(),r=T.default.platform(),s=T.default.userInfo().username,n="production",i,o;switch(t.strategy){case"hostname":i=await this.generateHostnameBasedId(t),o=t.customName||`AI Agent (${e})`;break;case"user-configured":i=await this.generateUserConfiguredId(t),o=t.customName||`AI Agent (${i})`;break;case"machine-fingerprint":i=await this.generateMachineFingerprintId(t),o=t.customName||`AI Agent (${e})`;break;case"hybrid":i=await this.generateHybridId(t),o=t.customName||`AI Agent (${this.extractReadablePart(i)})`;break;default:throw new Error(`Unknown identity strategy: ${t.strategy}`)}return{agentId:i,agentName:o,hostname:e,platform:r,userId:s,environment:n,createdAt:new Date().toISOString(),lastUsed:new Date().toISOString(),version:process.env.npm_package_version||"1.0.0"}}async generateHostnameBasedId(t){let e=T.default.hostname(),r=[];t.prefix&&r.push(t.prefix);let s=e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").substring(0,20);if(r.push(s),t.includeUser){let n=T.default.userInfo().username.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,10);r.push(n)}if(t.includeEnvironment){let n="production".substring(0,4);r.push(n)}return t.suffix&&r.push(t.suffix),r.join("-")}async generateUserConfiguredId(t){if(t.customName){let r=[t.customName.toLowerCase().replace(/[^a-z0-9-\s]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").substring(0,30)];if(t.includeEnvironment){let n="production".substring(0,4);r.push(n)}let s=fe.default.createHash("md5").update(T.default.hostname()+T.default.userInfo().username).digest("hex").substring(0,4);return r.push(s),r.join("-")}return this.generateInteractiveId(t)}async generateMachineFingerprintId(t){let e=this.getMachineFingerprint(),r=fe.default.createHash("sha256").update(e).digest("hex").substring(0,12),s=[];return t.prefix&&s.push(t.prefix),s.push("agent"),s.push(r),t.suffix&&s.push(t.suffix),s.join("-")}async generateHybridId(t){let e=T.default.hostname(),r=T.default.userInfo().username,s=e.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,8),n=fe.default.createHash("md5").update(`${e}-${r}-${T.default.platform()}`).digest("hex").substring(0,6),i=[];if(t.prefix&&i.push(t.prefix),i.push(s),i.push(n),t.includeEnvironment){let o="production".substring(0,3);i.push(o)}return t.suffix&&i.push(t.suffix),i.join("-")}async generateInteractiveId(t){let r=`ai-agent-${T.default.hostname().toLowerCase().substring(0,8)}`;return c.info("Using default agent ID (interactive mode not available)",{defaultId:r,service:"identity"}),r}getMachineFingerprint(){return[T.default.hostname(),T.default.platform(),T.default.arch(),T.default.userInfo().username,JSON.stringify(Object.keys(T.default.networkInterfaces()).sort())].join("|")}extractReadablePart(t){let e=t.split("-");return e.length>1?e[1]:t}async loadExistingIdentity(){try{let t=await Z.promises.readFile(this.identityFile,"utf8"),e=JSON.parse(t);return e.agentId&&e.agentName&&e.createdAt?e:(c.warn("Invalid identity file format, will regenerate",{service:"identity"}),null)}catch(t){return t.code!=="ENOENT"&&c.warn("Failed to load existing identity",{error:t instanceof Error?t.message:String(t),service:"identity"}),null}}async saveIdentity(t){try{await Z.promises.mkdir(this.configDir,{recursive:!0}),await Z.promises.writeFile(this.identityFile,JSON.stringify(t,null,2),"utf8"),c.info("Agent identity saved",{agentId:t.agentId,configDir:this.configDir,service:"identity"})}catch(e){throw c.error("Failed to save agent identity",{error:e instanceof Error?e.message:String(e),configDir:this.configDir,service:"identity"}),e}}getCurrentIdentity(){return this.currentIdentity||null}async updateIdentity(t){if(!this.currentIdentity)throw new Error("No current identity to update");let e={...this.currentIdentity,...t,lastUsed:new Date().toISOString()};return await this.saveIdentity(e),this.currentIdentity=e,c.info("Agent identity updated",{agentId:e.agentId,updates:Object.keys(t),service:"identity"}),e}async resetIdentity(){try{await Z.promises.unlink(this.identityFile),this.currentIdentity=void 0,c.info("Agent identity reset",{service:"identity"})}catch(t){if(t.code!=="ENOENT")throw c.error("Failed to reset agent identity",{error:t instanceof Error?t.message:String(t),service:"identity"}),t}}getAvailableStrategies(){return[{strategy:"hostname",description:"Use machine hostname as base (most readable)",example:"macbook-pro-dev"},{strategy:"user-configured",description:"User provides custom name with uniqueness suffix",example:"my-ai-assistant-a4f2"},{strategy:"machine-fingerprint",description:"Generate from machine characteristics (most stable)",example:"agent-7f4e2a8b9c1d"},{strategy:"hybrid",description:"Combine readable hostname with unique suffix (balanced)",example:"macbook-7f4e2a-dev"}]}validateAgentId(t){let e=[];return t.length<3&&e.push("Agent ID must be at least 3 characters long"),t.length>50&&e.push("Agent ID must be no more than 50 characters long"),/^[a-z0-9-]+$/i.test(t)||e.push("Agent ID can only contain letters, numbers, and hyphens"),(t.startsWith("-")||t.endsWith("-"))&&e.push("Agent ID cannot start or end with a hyphen"),t.includes("--")&&e.push("Agent ID cannot contain consecutive hyphens"),{valid:e.length===0,errors:e}}getIdentityFilePath(){return this.identityFile}async identityExists(){try{return await Z.promises.access(this.identityFile),!0}catch{return!1}}};var oe=class{constructor(){this.rl=ht.default.createInterface({input:process.stdin,output:process.stdout}),this.identityService=new N}async run(){try{if(console.log(y.default.blue.bold(`
90
- \u{1F916} Task Shepherd AI Agent Setup Wizard`)),console.log(y.default.gray(`Let's configure your AI agent for optimal performance
91
- `)),!await this.checkExistingConfiguration())return;let e=await this.gatherConfiguration(),r=await this.identityService.initializeIdentity(e.identity);await this.saveConfiguration(e,r.agentId),this.showSummary(r,e),console.log(y.default.green.bold(`
92
- \u2705 Agent setup complete!`)),console.log(y.default.gray(`You can now start your agent with: npm run dev
93
- `))}catch(t){console.error(y.default.red(`
94
- \u274C Setup failed:`),t instanceof Error?t.message:t),process.exit(1)}finally{this.rl.close()}}async checkExistingConfiguration(){if(await this.identityService.identityExists()){let e=await this.ask(y.default.yellow("\u26A0\uFE0F An agent identity already exists. Do you want to reconfigure? (y/N): "));if(e.toLowerCase()!=="y"&&e.toLowerCase()!=="yes")return console.log(y.default.gray("Setup cancelled. Existing configuration preserved.")),!1;await this.identityService.resetIdentity()}return!0}async gatherConfiguration(){let t={identity:{strategy:"hostname",persistent:!0},backend:{apiUrl:"http://localhost:4002/graphql"},capabilities:[],features:{enableHeartbeat:!0,enableMetrics:!0,enableWebUI:!0},advanced:{heartbeatInterval:3e4,logLevel:"info",webPort:8548}};return await this.configureIdentity(t),await this.configureBackend(t),await this.configureCapabilities(t),await this.configureFeatures(t),await this.askBoolean("Configure advanced settings? (heartbeat interval, logging, etc.)",!1)&&await this.configureAdvanced(t),t}async configureIdentity(t){console.log(y.default.blue.bold(`
95
- \u{1F4DD} Step 1: Agent Identity`)),console.log(y.default.gray(`Choose how your agent will be identified in the system
96
- `));let e=this.identityService.getAvailableStrategies();console.log("Available identity strategies:"),e.forEach((i,o)=>{console.log(y.default.cyan(`${o+1}. ${i.strategy}`)+y.default.gray(` - ${i.description}`)),console.log(y.default.gray(` Example: ${i.example}
97
- `))});let r=await this.askChoice("Select identity strategy",e.map(i=>i.strategy),"hostname");if(t.identity.strategy=r,r==="user-configured"){let i=await this.ask("Enter a custom name for your agent: ");i.trim()&&(t.identity.customName=i.trim())}let s=await this.askBoolean("Include environment in agent ID? (dev, prod, etc.)",!0);if(t.identity.includeEnvironment=s,r==="hostname"||r==="hybrid"){let i=await this.askBoolean("Include username in agent ID?",!1);t.identity.includeUser=i}if(await this.askBoolean("Add prefix to agent ID?",!1)){let i=await this.ask("Enter prefix: ");i.trim()&&(t.identity.prefix=i.trim().toLowerCase().replace(/[^a-z0-9]/g,""))}console.log(y.default.green("\u2713 Identity configuration complete"))}async configureBackend(t){console.log(y.default.blue.bold(`
98
- \u{1F517} Step 2: Backend Connection`)),console.log(y.default.gray(`Configure connection to Task Shepherd backend
99
- `));let e="http://localhost:4002/graphql",r=await this.ask(`Backend GraphQL URL (${e}): `);if(t.backend.apiUrl=r.trim()||e,console.log(y.default.yellow(`
100
- \u{1F511} API Key Setup`)),console.log(y.default.gray("You need an API key to authenticate with the backend.")),console.log(y.default.gray("You can generate one in the Task Shepherd admin panel.")),await this.askBoolean("Do you have an API key?",!1)){let n=await this.askPassword("Enter API key: ");n.trim()&&(t.backend.apiKey=n.trim())}else console.log(y.default.yellow("\u26A0\uFE0F You can add an API key later in the configuration file."));console.log(y.default.green("\u2713 Backend configuration complete"))}async configureCapabilities(t){console.log(y.default.blue.bold(`
101
- \u26A1 Step 3: Agent Capabilities`)),console.log(y.default.gray(`Select what your agent can do
102
- `));let e=[{key:"project_review",name:"Project Review",description:"Analyze and review project requirements"},{key:"code_review",name:"Code Review",description:"Review code for quality and best practices"},{key:"development_planning",name:"Development Planning",description:"Create development plans and estimates"},{key:"story_implementation",name:"Story Implementation",description:"Implement user stories and features"},{key:"documentation",name:"Documentation",description:"Generate and maintain documentation"},{key:"testing",name:"Testing",description:"Create and execute tests"}];console.log("Available capabilities:"),e.forEach((s,n)=>{console.log(y.default.cyan(`${n+1}. ${s.name}`)+y.default.gray(` - ${s.description}`))}),console.log(y.default.gray(`
103
- Enter capability numbers separated by commas (e.g., 1,2,3):`));let r=await this.ask("Select capabilities: ");if(r.trim()){let s=r.split(",").map(n=>parseInt(n.trim())-1).filter(n=>n>=0&&n<e.length);t.capabilities=s.map(n=>e[n].key)}t.capabilities.length===0&&(console.log(y.default.yellow("\u26A0\uFE0F No capabilities selected. Adding default project_review capability.")),t.capabilities=["project_review"]),console.log(y.default.green(`\u2713 Selected capabilities: ${t.capabilities.join(", ")}`))}async configureFeatures(t){console.log(y.default.blue.bold(`
104
- \u{1F6E0}\uFE0F Step 4: Features`)),console.log(y.default.gray(`Enable/disable agent features
105
- `)),t.features.enableHeartbeat=await this.askBoolean("Enable heartbeat monitoring?",!0),t.features.enableMetrics=await this.askBoolean("Enable performance metrics collection?",!0),t.features.enableWebUI=await this.askBoolean("Enable web dashboard?",!0),console.log(y.default.green("\u2713 Features configured"))}async configureAdvanced(t){if(console.log(y.default.blue.bold(`
106
- \u{1F527} Step 5: Advanced Settings`)),console.log(y.default.gray(`Fine-tune agent behavior
107
- `)),t.features.enableHeartbeat){let r=await this.askNumber("Heartbeat interval (seconds)",30);t.advanced.heartbeatInterval=r*1e3}let e=await this.askChoice("Log level",["error","warn","info","debug"],"info");if(t.advanced.logLevel=e,t.features.enableWebUI){let r=await this.askNumber("Web dashboard port",8548);t.advanced.webPort=r}console.log(y.default.green("\u2713 Advanced settings configured"))}async saveConfiguration(t,e){console.log(y.default.blue.bold(`
108
- \u{1F4BE} Saving Configuration...`));let r=this.generateEnvContent(t,e),s=".env";require("fs").writeFileSync(s,r),console.log(y.default.green(`\u2713 Configuration saved to ${s}`))}generateEnvContent(t,e){let r=["# AI Worker Service Configuration",`AGENT_ID=${e}`,`AGENT_NAME=${t.identity.customName||"AI Agent"}`,"PORT=8547","NODE_ENV=production","","# Task Shepherd API Configuration",`TASK_SHEPHERD_API_URL=${t.backend.apiUrl}`];return t.backend.apiKey?r.push(`TASK_SHEPHERD_API_KEY=${t.backend.apiKey}`):r.push("# TASK_SHEPHERD_API_KEY=your-api-key-here"),r.push("","# Agent Features",`ENABLE_HEARTBEAT=${t.features.enableHeartbeat}`,`ENABLE_METRICS=${t.features.enableMetrics}`,`ENABLE_WEB_UI=${t.features.enableWebUI}`,"","# Agent Capabilities",`AGENT_CAPABILITIES=${t.capabilities.join(",")}`,"","# Advanced Settings",`HEARTBEAT_INTERVAL=${t.advanced.heartbeatInterval}`,`LOG_LEVEL=${t.advanced.logLevel}`,`WEB_PORT=${t.advanced.webPort}`,"","# Redis Configuration","REDIS_URL=redis://localhost:6379","","# Claude CLI Configuration (Primary Method)","CLAUDE_COMMAND_PATH=/Users/$USER/.claude/local/claude","","# Claude API Configuration (Optional - Enables Enhanced Features)","# ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}","# ANTHROPIC_BASE_URL=https://api.anthropic.com","# CLAUDE_MODEL=claude-3-5-sonnet-20241022","# CLAUDE_MAX_RETRIES=3","# CLAUDE_TIMEOUT_MS=60000","","# Service Configuration","MAX_CONCURRENT_JOBS=3","TOKEN_RATE_LIMIT=10000",""),r.join(`
109
- `)}showSummary(t,e){console.log(y.default.blue.bold(`
110
- \u{1F4CB} Configuration Summary`)),console.log(y.default.gray("\u2550".repeat(50))),console.log(y.default.cyan("Agent Identity:")),console.log(` ID: ${y.default.white(t.agentId)}`),console.log(` Name: ${y.default.white(t.agentName)}`),console.log(` Strategy: ${y.default.white(e.identity.strategy)}`),console.log(y.default.cyan(`
111
- Backend Connection:`)),console.log(` URL: ${y.default.white(e.backend.apiUrl)}`),console.log(` API Key: ${e.backend.apiKey?y.default.green("\u2713 Configured"):y.default.yellow("\u26A0\uFE0F Not set")}`),console.log(y.default.cyan(`
112
- Capabilities:`)),e.capabilities.forEach(r=>{console.log(` \u2022 ${y.default.white(r)}`)}),console.log(y.default.cyan(`
113
- Features:`)),console.log(` Heartbeat: ${e.features.enableHeartbeat?y.default.green("\u2713"):y.default.red("\u2717")}`),console.log(` Metrics: ${e.features.enableMetrics?y.default.green("\u2713"):y.default.red("\u2717")}`),console.log(` Web UI: ${e.features.enableWebUI?y.default.green("\u2713"):y.default.red("\u2717")}`),e.features.enableWebUI&&(console.log(y.default.cyan(`
114
- Web Dashboard:`)),console.log(` URL: ${y.default.white(`http://localhost:${e.advanced.webPort}`)}`))}ask(t){return new Promise(e=>{this.rl.question(t,e)})}async askPassword(t){return this.ask(t)}async askBoolean(t,e=!1){let r=e?"Y/n":"y/N",s=await this.ask(`${t} (${r}): `);return s.trim()?s.toLowerCase().startsWith("y"):e}async askNumber(t,e){let r=await this.ask(`${t} (${e}): `);if(!r.trim())return e;let s=parseInt(r);return isNaN(s)?e:s}async askChoice(t,e,r){let s=e.map((u,m)=>`${m+1}. ${u}`).join(", "),n=r?` (default: ${r})`:"",i=await this.ask(`${t} [${s}]${n}: `);if(!i.trim()&&r)return r;let o=parseInt(i)-1;if(o>=0&&o<e.length)return e[o];let l=e.find(u=>u.toLowerCase()===i.toLowerCase());return l||r||e[0]}};require.main===module&&new oe().run().catch(t=>{console.error(y.default.red("Wizard failed:"),t),process.exit(1)});var yt=require("events");var ft=require("events");R();var ee=h(require("os")),K=h(require("process")),ye=class extends ft.EventEmitter{constructor(e,r,s,n={}){super();this.responseTimes=[];this.maxResponseTimeHistory=50;this.metricsProviders=new Map;this.workerId=e,this.tokenTracker=r,this.httpClient=s,this.options={interval:3e4,timeout:1e4,retryAttempts:3,retryDelay:5e3,enableMetrics:!0,preferWebSocket:!0,fallbackToHttp:!0,...n},this.metrics=this.getInitialMetrics(),this.status={isRunning:!1,consecutiveFailures:0,totalSent:0,totalSuccessful:0,totalFailed:0,averageResponseTime:0,currentStatus:"offline"},this.setupDefaultMetricsProviders()}start(){if(this.intervalId){c.warn("Heartbeat service is already running",{workerId:this.workerId,service:"heartbeat"});return}c.info("Starting heartbeat service",{workerId:this.workerId,interval:this.options.interval,service:"heartbeat"}),this.status.isRunning=!0,this.status.currentStatus="healthy",this.sendHeartbeat(),this.intervalId=setInterval(()=>{this.sendHeartbeat()},this.options.interval),this.emit("started",{workerId:this.workerId})}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0),this.status.isRunning=!1,this.status.currentStatus="offline",c.info("Heartbeat service stopped",{workerId:this.workerId,service:"heartbeat"}),this.emit("stopped",{workerId:this.workerId})}async sendHeartbeat(){let e=Date.now();try{await this.collectMetrics();let r={workerId:this.workerId,timestamp:new Date().toISOString(),isHealthy:this.isAgentHealthy(),metrics:this.options.enableMetrics?this.metrics:void 0,status:this.determineAgentStatus(),version:K.default.env.npm_package_version||"1.0.0",localWorkState:await this.collectLocalWorkState()},s=await this.sendHeartbeatMessage(r),n=Date.now()-e;return this.updateResponseTimeHistory(n),s?(this.handleHeartbeatSuccess(),this.emit("heartbeat_sent",{workerId:this.workerId,responseTime:n,metrics:this.metrics})):(this.handleHeartbeatFailure(),this.emit("heartbeat_failed",{workerId:this.workerId,consecutiveFailures:this.status.consecutiveFailures})),s}catch(r){let s=Date.now()-e;return this.updateResponseTimeHistory(s),this.handleHeartbeatFailure(),c.error("Heartbeat error",{workerId:this.workerId,error:r instanceof Error?r.message:String(r),responseTime:s,service:"heartbeat"}),this.emit("heartbeat_error",{workerId:this.workerId,error:r,consecutiveFailures:this.status.consecutiveFailures}),!1}}async sendHeartbeatMessage(e){if(this.httpClient)return this.sendHttpHeartbeat(e);throw new Error("No available heartbeat transport (WebSocket failed and HTTP not configured)")}async sendHttpHeartbeat(e){c.debug("Sending heartbeat via HTTP GraphQL",{workerId:this.workerId,service:"heartbeat"});let r=0;for(;r<this.options.retryAttempts;)try{let s=`
62
+ `}),t=this.isHealthy;return this.isHealthy=!!e?.data?.me?.id,!t&&this.isHealthy?(s.info("Backend health recovered - authentication verified"),this.emit("healthRecovered")):t&&!this.isHealthy&&(s.warn("Backend health degraded - authentication failed"),this.emit("healthDegraded")),this.lastHealthCheck=Date.now(),this.isHealthy}catch(e){let t=this.isHealthy;return this.isHealthy=!1,t&&(s.warn("Backend health check failed",{error:e instanceof Error?e.message:String(e)}),this.emit("healthDegraded")),!1}}get healthy(){let e=Date.now()-this.lastHealthCheck>12e4;return this.isHealthy&&!e}destroy(){this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.removeAllListeners()}async executeRequest(e,t){let{query:a,variables:i,operationName:n}=e,c=It().getBuildInfo(),d={"Content-Type":"application/json","X-Agent-Version":c.version,"X-Client-Type":"task-shepherd-agent","X-Agent-Build":c.buildTimestamp,"X-Agent-Commit":c.commitHash,"X-Agent-Channel":c.releaseChannel};s.debug("HTTP Client state before request",{operationName:n,attempt:t,hasApiKeyInOptions:!!this.options.apiKey,apiKeyLength:this.options.apiKey?.length||0,optionsKeys:Object.keys(this.options)}),this.options.apiKey?(d["X-API-Key"]=this.options.apiKey,s.info("Adding API key to request headers",{operationName:n,apiKeyPrefix:this.options.apiKey.substring(0,12)+"...",headerName:"X-API-Key"})):s.error("NO API KEY AVAILABLE for GraphQL request",{operationName:n,attempt:t,optionsApiKey:this.options.apiKey,optionsKeys:Object.keys(this.options),allOptions:JSON.stringify(this.options,null,2)}),s.debug("Executing GraphQL request",{operationName:n,attempt:t,hasAuth:!!this.options.apiKey,url:this.options.baseUrl});let p=await fetch(this.options.baseUrl,{method:"POST",headers:d,body:JSON.stringify({query:a,variables:i,operationName:n}),signal:AbortSignal.timeout(this.options.timeout)});if(!p.ok)throw new Error(`HTTP ${p.status}: ${p.statusText}`);let u=await p.json();if(u.errors&&u.errors.length>0){let h=u.errors.map(f=>f.message).join(", ");throw new Error(`GraphQL errors: ${h}`)}return u}calculateRetryDelay(e){let t=this.options.baseDelay*Math.pow(2,e-1),a=Math.random()*1e3;return Math.min(t+a,this.options.maxDelay)}sleep(e){return new Promise(t=>setTimeout(t,e))}startHealthChecking(){this.checkHealth().catch(()=>{}),this.healthCheckTimer=setInterval(()=>{this.checkHealth().catch(()=>{})},this.options.healthCheckInterval)}},de=null});var ze,br=M(()=>{"use strict";j();Ue();ze=class{constructor(){this.usageHistory=[];this.COST_PER_1K_INPUT_TOKENS=.003;this.COST_PER_1K_OUTPUT_TOKENS=.015;this.MAX_HISTORY_SIZE=1e4}async trackUsage(r){r.cost||(r.cost=this.calculateCost(r.inputTokens,r.outputTokens)),this.usageHistory.push(r),this.usageHistory.length>this.MAX_HISTORY_SIZE&&(this.usageHistory=this.usageHistory.slice(-this.MAX_HISTORY_SIZE)),s.info("Token usage tracked",{sessionId:r.sessionId,inputTokens:r.inputTokens,outputTokens:r.outputTokens,totalTokens:r.totalTokens,cost:r.cost,analysisType:r.analysisType});try{await this.persistUsage(r)}catch(e){s.error("Failed to persist usage to backend",{sessionId:r.sessionId,error:e instanceof Error?e.message:String(e)})}}getUsageStats(r){let e=this.usageHistory;r&&(e=this.usageHistory.filter(h=>h.timestamp>=r.start&&h.timestamp<=r.end));let t=e.length,a=e.reduce((h,f)=>h+f.inputTokens,0),i=e.reduce((h,f)=>h+f.outputTokens,0),n=e.reduce((h,f)=>h+f.totalTokens,0),o=e.reduce((h,f)=>h+f.cost,0),c=t>0?a/t:0,d=t>0?i/t:0,p=t>0?o/t:0,u=e.reduce((h,f)=>(h[f.analysisType]||(h[f.analysisType]={sessions:0,inputTokens:0,outputTokens:0,totalTokens:0,cost:0}),h[f.analysisType].sessions++,h[f.analysisType].inputTokens+=f.inputTokens,h[f.analysisType].outputTokens+=f.outputTokens,h[f.analysisType].totalTokens+=f.totalTokens,h[f.analysisType].cost+=f.cost,h),{});return{summary:{totalSessions:t,totalInputTokens:a,totalOutputTokens:i,totalTokens:n,totalCost:o,avgInputTokens:c,avgOutputTokens:d,avgCost:p},byAnalysisType:u,recentUsage:e.slice(-10)}}getUsageHistory(r=100){return this.usageHistory.slice(-r)}getTotalTokens(){return this.usageHistory.reduce((r,e)=>r+e.totalTokens,0)}getApiCallCount(){return this.usageHistory.length}getEstimatedCost(){return this.usageHistory.reduce((r,e)=>r+e.cost,0)}getDailyUsage(){let r=new Date,e=new Date(r.getFullYear(),r.getMonth(),r.getDate()),t=this.usageHistory.filter(o=>o.timestamp>=e),a=t.reduce((o,c)=>o+c.totalTokens,0),i=t.reduce((o,c)=>o+c.cost,0),n=t.length;return{totalTokens:a,totalCost:i,operationCount:n}}getCurrentRateLimit(){let r=new Date,e=new Date(r.getTime()-60*60*1e3),a=this.usageHistory.filter(n=>n.timestamp>=e).reduce((n,o)=>n+o.totalTokens,0),i=new Date(Math.ceil(r.getTime()/(60*60*1e3))*(60*60*1e3));return{used:a,limit:1e4,resetTime:i}}calculateCost(r,e){let t=r/1e3*this.COST_PER_1K_INPUT_TOKENS,a=e/1e3*this.COST_PER_1K_OUTPUT_TOKENS;return Number((t+a).toFixed(6))}async persistUsage(r){try{let e=Ne(),t=`
63
+ mutation CreateClaudeUsageSession($input: CreateClaudeUsageSessionInput!) {
64
+ createClaudeUsageSession(input: $input) {
65
+ id
66
+ sessionId
67
+ type
68
+ isError
69
+ totalCostUsd
70
+ createdAt
71
+ }
72
+ }
73
+ `,a=this.mapAnalysisTypeToSessionType(r.analysisType),i=this.mapAnalysisTypeToSessionSubtype(r.analysisType),n={sessionId:r.sessionId,type:a,subtype:i,organizationId:process.env.TASK_SHEPHERD_ORGANIZATION_ID||"default-org",isError:!1,durationMs:0,durationApiMs:0,numTurns:1,totalCostUsd:r.cost,usage:{inputTokens:r.inputTokens,outputTokens:r.outputTokens,cacheCreationInputTokens:0,cacheReadInputTokens:0,totalTokens:r.totalTokens},startedAt:r.timestamp,completedAt:r.timestamp},o=await e.mutate({query:t,variables:{input:n},operationName:"CreateClaudeUsageSession"});if(!o.data?.createClaudeUsageSession)throw new Error("Failed to create usage session in backend");s.debug("Usage session persisted to backend",{sessionId:r.sessionId,backendId:o.data.createClaudeUsageSession.id})}catch(e){throw s.warn("Failed to persist usage to backend",{sessionId:r.sessionId,error:e instanceof Error?e.message:String(e)}),e}}mapAnalysisTypeToSessionType(r){switch(r.toLowerCase()){case"project_review":return"PROJECT_REVIEW";case"development_plan":return"DEVELOPMENT_PLAN";case"story_implementation":return"STORY_IMPLEMENTATION";case"task_implementation":return"TASK_IMPLEMENTATION";case"code_review":return"CODE_REVIEW";default:return"OTHER"}}mapAnalysisTypeToSessionSubtype(r){switch(r.toLowerCase()){case"project_review":return"ANALYSIS";case"development_plan":return"PLANNING";case"story_implementation":case"task_implementation":return"IMPLEMENTATION";case"code_review":return"REVIEW";default:return"OTHER"}}}});function ha(){console.log("DEBUG: Environment API Key:",process.env.TASK_SHEPHERD_API_KEY),console.log("DEBUG: Environment CAPABILITIES:",process.env.CAPABILITIES),console.log("DEBUG: Environment AGENT_CAPABILITIES:",process.env.AGENT_CAPABILITIES),console.log("DEBUG: Using capabilities:",process.env.CAPABILITIES?"from environment":"dynamic from handlers"),console.log("DEBUG: Dynamic capabilities would be:",ma().join(",")),console.log("DEBUG: All TASK_SHEPHERD env vars:",Object.keys(process.env).filter(e=>e.startsWith("TASK_SHEPHERD")));let l={apiKey:process.env.TASK_SHEPHERD_API_KEY||"",apiUrl:process.env.TASK_SHEPHERD_API_URL||"",wsUrl:process.env.TASK_SHEPHERD_WS_URL||"",httpPort:parseInt(process.env.PORT||"8547"),tcpPort:parseInt(process.env.TCP_PORT||"8549"),webPort:parseInt(process.env.WEB_PORT||"8548"),workerId:process.env.WORKER_ID||gn(),capabilities:(()=>{let e=process.env.CAPABILITIES||process.env.AGENT_CAPABILITIES,t=e?Sa(e):ma();return console.log("DEBUG: Final capabilities assigned:",t),t})(),websocketEnabled:process.env.WEBSOCKET_ENABLED==="true",heartbeatInterval:parseInt(process.env.HEARTBEAT_INTERVAL||"30000"),connectionTimeout:parseInt(process.env.CONNECTION_TIMEOUT||"10000"),retryAttempts:parseInt(process.env.RETRY_ATTEMPTS||"3"),retryDelay:parseInt(process.env.RETRY_DELAY||"2000"),environment:"production"},r=un();if(r){let e={...l},t=dn();Object.assign(l,r),Object.assign(l,t),l.apiUrl||(l.apiUrl=e.apiUrl),l.wsUrl||(l.wsUrl=e.wsUrl),l.httpPort||(l.httpPort=e.httpPort),(!l.capabilities||l.capabilities.length===0)&&(l.capabilities=e.capabilities)}return mn(l),l}function un(){let l;if(process.env.AGENT_CONFIG_PATH?(l=bt.resolve(process.env.AGENT_CONFIG_PATH),console.log("DEBUG: Using custom config path from AGENT_CONFIG_PATH:",l)):(l=bt.join(process.cwd(),"config","config.json"),console.log("DEBUG: Using default config path:",l)),!wt.existsSync(l))return console.log("DEBUG: Config file not found at:",l),null;try{let r=wt.readFileSync(l,"utf-8"),e=JSON.parse(r);return console.log("DEBUG: Loaded config from file:",l),{apiUrl:e.taskShepherd?.apiUrl,wsUrl:e.taskShepherd?.wsUrl,httpPort:e.server?.port,capabilities:e.worker?.enabledCapabilities,heartbeatInterval:e.worker?.healthCheckInterval,connectionTimeout:e.taskShepherd?.timeout,retryAttempts:e.taskShepherd?.retries,retryDelay:e.taskShepherd?.retryDelay}}catch(r){return console.warn("Failed to load config file:",r),null}}function dn(){let l={};return process.env.TASK_SHEPHERD_API_URL&&(l.apiUrl=process.env.TASK_SHEPHERD_API_URL),process.env.TASK_SHEPHERD_WS_URL&&(l.wsUrl=process.env.TASK_SHEPHERD_WS_URL),process.env.PORT&&(l.httpPort=parseInt(process.env.PORT)),process.env.TCP_PORT&&(l.tcpPort=parseInt(process.env.TCP_PORT)),process.env.WEB_PORT&&(l.webPort=parseInt(process.env.WEB_PORT)),process.env.WORKER_ID&&(l.workerId=process.env.WORKER_ID),(process.env.CAPABILITIES||process.env.AGENT_CAPABILITIES)&&(l.capabilities=Sa(process.env.CAPABILITIES||process.env.AGENT_CAPABILITIES||"")),process.env.WEBSOCKET_ENABLED&&(l.websocketEnabled=process.env.WEBSOCKET_ENABLED==="true"),process.env.HEARTBEAT_INTERVAL&&(l.heartbeatInterval=parseInt(process.env.HEARTBEAT_INTERVAL)),process.env.CONNECTION_TIMEOUT&&(l.connectionTimeout=parseInt(process.env.CONNECTION_TIMEOUT)),process.env.RETRY_ATTEMPTS&&(l.retryAttempts=parseInt(process.env.RETRY_ATTEMPTS)),process.env.RETRY_DELAY&&(l.retryDelay=parseInt(process.env.RETRY_DELAY)),l.environment="production",l}function ma(){return["project_review","implementation_plan","story_implementation","code_review","review_application","task_completion"]}function Sa(l){return l.split(",").map(r=>r.trim()).filter(r=>r.length>0)}function gn(){return`${ya.hostname()}-production`}function mn(l){let r=[];if(console.log("DEBUG: Final config API key:",l.apiKey?l.apiKey.substring(0,8)+"...":"MISSING"),console.log("DEBUG: Final config apiUrl:",l.apiUrl),l.apiKey||console.log("DEBUG: No global API key configured - using multi-organization mode"),l.apiUrl||console.log("DEBUG: No global API URL configured - using multi-organization mode"),!l.wsUrl&&l.websocketEnabled&&r.push("TASK_SHEPHERD_WS_URL is required when WebSocket is enabled"),Ar(l.httpPort)||r.push(`Invalid HTTP port: ${l.httpPort}`),Ar(l.tcpPort)||r.push(`Invalid TCP port: ${l.tcpPort}`),Ar(l.webPort)||r.push(`Invalid Web port: ${l.webPort}`),(!l.capabilities||l.capabilities.length===0)&&r.push("At least one capability is required"),l.heartbeatInterval<1e3&&r.push("Heartbeat interval must be at least 1000ms"),l.connectionTimeout<1e3&&r.push("Connection timeout must be at least 1000ms"),(l.retryAttempts<0||l.retryAttempts>10)&&r.push("Retry attempts must be between 0 and 10"),l.retryDelay<100&&r.push("Retry delay must be at least 100ms"),yn(l.apiUrl)||r.push(`Invalid API URL: ${l.apiUrl}`),l.websocketEnabled&&!hn(l.wsUrl)&&r.push(`Invalid WebSocket URL: ${l.wsUrl}`),r.length>0)throw new Error(`Configuration validation failed:
74
+ ${r.join(`
75
+ `)}`)}function Ar(l){return Number.isInteger(l)&&l>0&&l<65536}function yn(l){try{let r=new URL(l);return r.protocol==="http:"||r.protocol==="https:"}catch{return!1}}function hn(l){try{let r=new URL(l);return r.protocol==="ws:"||r.protocol==="wss:"}catch{return!1}}var wt,bt,ya,fa=M(()=>{"use strict";wt=A(require("fs")),bt=A(require("path")),ya=A(require("os"))});var ka,va,He,Er=M(()=>{"use strict";ka=A(require("http")),va=A(require("https"));j();He=class{constructor(r,e,t=3e4,a=3,i=1e3){this.apiKey=r;this.baseUrl=e;this.timeout=t;this.maxRetries=a;this.retryDelay=i;this.closed=!1;e.startsWith("https:")?this.agent=new va.Agent({keepAlive:!0,maxSockets:10,timeout:t,keepAliveMsecs:3e4}):this.agent=new ka.Agent({keepAlive:!0,maxSockets:10,timeout:t,keepAliveMsecs:3e4})}async authenticate(){if(this.closed)throw new Error("HttpClient is closed");s.info("Authenticating with Main API using API key authentication",{apiUrl:this.baseUrl,hasApiKey:!!this.apiKey});let r=await this.post({query:`
76
+ mutation ExchangeApiKeyForToken($apiKey: String!) {
77
+ exchangeApiKeyForToken(apiKey: $apiKey) {
78
+ token
79
+ expiresIn
80
+ refreshToken
81
+ user {
82
+ id
83
+ email
84
+ }
85
+ }
86
+ }
87
+ `,variables:{apiKey:this.apiKey},operationName:"ExchangeApiKeyForToken"});if(!r.data?.exchangeApiKeyForToken?.token)throw new Error("Authentication failed: Invalid API key or response format");this.token=r.data.exchangeApiKeyForToken.token,this.authenticatedUser=r.data.exchangeApiKeyForToken.user,s.info("Successfully authenticated with Main API",{hasToken:!!this.token,userId:this.authenticatedUser.id,userEmail:this.authenticatedUser.email,expiresIn:r.data.exchangeApiKeyForToken.expiresIn,authMethod:"api_key_to_jwt"})}async executeGraphQLMutation(r,e){return this.post({query:r,variables:e})}async post(r){if(this.closed)throw new Error("HttpClient is closed");let e=null;for(let t=1;t<=this.maxRetries;t++)try{return await this.executeRequest(r,t)}catch(a){e=a instanceof Error?a:new Error(String(a)),s.warn(`HTTP request attempt ${t}/${this.maxRetries} failed`,{error:e.message,operationName:r.operationName,willRetry:t<this.maxRetries}),t<this.maxRetries&&await this.sleep(this.retryDelay*t)}throw e||new Error("All HTTP request attempts failed")}async executeRequest(r,e){let t={"Content-Type":"application/json","User-Agent":"TaskShepherd-Agent/1.0","X-Client-Type":"agent"};this.token?t.Authorization=`Bearer ${this.token}`:this.apiKey&&(t["X-API-Key"]=this.apiKey);let a=JSON.stringify({query:r.query,variables:r.variables,operationName:r.operationName});s.debug("Executing HTTP request",{operationName:r.operationName,attempt:e,hasAuth:!!(this.token||this.apiKey),url:this.baseUrl});try{let i=await this.fetch(this.baseUrl,{method:"POST",headers:t,body:a,timeout:this.timeout});if(!i.ok)throw new Error(`HTTP ${i.status}: ${i.statusText}`);let n=await i.json();if(n.errors&&n.errors.length>0){let o=n.errors.map(c=>c.message).join(", ");throw new Error(`GraphQL errors: ${o}`)}return n}catch(i){throw i instanceof Error?i:new Error(`Request failed: ${String(i)}`)}}async fetch(r,e){return typeof fetch<"u"?fetch(r,{...e}):require("node-fetch")(r,{...e,agent:this.agent})}sleep(r){return new Promise(e=>setTimeout(e,r))}getToken(){return this.token}getAuthenticatedUser(){return this.authenticatedUser}isAuthenticated(){return!!this.token}getApiKey(){return this.apiKey}getBaseUrl(){return this.baseUrl}isClosed(){return this.closed}async close(){if(!this.closed){this.closed=!0,s.debug("Closing HTTP client");try{this.agent.destroy(),s.debug("HTTP agent destroyed")}catch(r){s.warn("Error destroying HTTP agent:",r)}this.token=void 0}}async registerWorker(r,e){let t=await this.post({query:`
88
+ mutation RegisterAIWorker($input: RegisterAIWorkerInput!) {
89
+ registerAIWorker(input: $input) {
90
+ id
91
+ success
92
+ message
93
+ }
94
+ }
95
+ `,variables:{input:{workerId:r,capabilities:e,scope:"USER",maxConcurrentTasks:3}},operationName:"RegisterAIWorker"});if(!t.data?.registerAIWorker?.success)throw new Error(`Worker registration failed: ${t.data?.registerAIWorker?.message||"Unknown error"}`);return t.data.registerAIWorker}async sendHeartbeat(r){await this.post({query:`
96
+ mutation Heartbeat($workerId: String!) {
97
+ heartbeat(workerId: $workerId) {
98
+ success
99
+ timestamp
100
+ }
101
+ }
102
+ `,variables:{workerId:r},operationName:"Heartbeat"})}async healthCheck(){try{let r=this.baseUrl.replace("/graphql","/health");return(await this.fetch(r,{method:"GET",timeout:5e3})).ok}catch{return!1}}}});var At,Ia=M(()=>{"use strict";j();At=class{constructor(r){this.httpClient=r;this.config=null;this.lastFetch=null;this.CACHE_DURATION_MS=60*60*1e3}async getConfiguration(){if(this.config&&this.lastFetch&&Date.now()-this.lastFetch.getTime()<this.CACHE_DURATION_MS)return this.config;try{s.info("Fetching work type configuration from backend");let e=await this.httpClient.post({query:`
103
+ query GetWorkTypeConfiguration {
104
+ aiWorkTypeConfiguration
105
+ }
106
+ `});if(!e.data?.aiWorkTypeConfiguration)throw new Error("No work type configuration returned from backend");return this.config=e.data.aiWorkTypeConfiguration,this.lastFetch=new Date,s.info("Work type configuration fetched successfully",{workTypes:this.config.workTypes.length,workerTypes:this.config.workerTypes.length}),this.config}catch(r){return s.error("Failed to fetch work type configuration",{error:r instanceof Error?r.message:String(r)}),this.getDefaultConfiguration()}}async getWorkTypesForWorker(r){return(await this.getConfiguration()).workerTypeToWorkTypes[r]||[]}async getWorkerTypeForWork(r){return(await this.getConfiguration()).workTypeToWorkerType[r]||null}async normalizeWorkType(r){let e=await this.getConfiguration();return e.workTypes.includes(r)?r:e.legacyWorkTypeMappings[r]||r}async normalizeWorkerType(r){let e=await this.getConfiguration();return e.workerTypes.includes(r)?r:e.legacyWorkerTypeMappings[r]||r}async getAllWorkTypes(){return(await this.getConfiguration()).workTypes}async getAllWorkerTypes(){return(await this.getConfiguration()).workerTypes}clearCache(){this.config=null,this.lastFetch=null,s.info("Work type configuration cache cleared")}getDefaultConfiguration(){return{workTypes:["project_review","implementation_plan","story_implementation","task_completion","code_review","review_application"],workerTypes:["project-reviewer","development-planner","story-developer","code-reviewer","review-application-agent"],workTypeToWorkerType:{project_review:"project-reviewer",implementation_plan:"development-planner",story_implementation:"story-developer",task_completion:"story-developer",code_review:"code-reviewer",review_application:"review-application-agent"},workerTypeToWorkTypes:{"project-reviewer":["project_review"],"development-planner":["implementation_plan"],"story-developer":["story_implementation","task_completion"],"code-reviewer":["code_review"],"review-application-agent":["review_application"]},legacyWorkTypeMappings:{"project-review":"project_review","implementation-plan":"implementation_plan",development_planning:"implementation_plan","development-planning":"implementation_plan","story-implementation":"story_implementation","task-completion":"task_completion","code-review":"code_review","review-application":"review_application"},legacyWorkerTypeMappings:{project_reviewer:"project-reviewer",development_planner:"development-planner",story_developer:"story-developer",code_reviewer:"code-reviewer",review_application_agent:"review-application-agent"}}}}});var wa,ba,Aa,Ea,Ta,Ca,Pa,Ra,Da,Ma,Na,xa,Wa,Tr=M(()=>{"use strict";wa={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"query",name:{kind:"Name",value:"Me"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"me"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"email"}}]}}]}}]},ba={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"mutation",name:{kind:"Name",value:"ExchangeApiKeyForToken"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"apiKey"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"exchangeApiKeyForToken"},arguments:[{kind:"Argument",name:{kind:"Name",value:"apiKey"},value:{kind:"Variable",name:{kind:"Name",value:"apiKey"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"token"}},{kind:"Field",name:{kind:"Name",value:"refreshToken"}},{kind:"Field",name:{kind:"Name",value:"expiresIn"}},{kind:"Field",name:{kind:"Name",value:"tokenType"}},{kind:"Field",name:{kind:"Name",value:"user"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"email"}},{kind:"Field",name:{kind:"Name",value:"role"}},{kind:"Field",name:{kind:"Name",value:"status"}}]}}]}}]}}]},Aa={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"mutation",name:{kind:"Name",value:"UpdateProjectReview"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"id"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}},{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"input"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"UpdateProjectReviewInput"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"updateProjectReview"},arguments:[{kind:"Argument",name:{kind:"Name",value:"id"},value:{kind:"Variable",name:{kind:"Name",value:"id"}}},{kind:"Argument",name:{kind:"Name",value:"input"},value:{kind:"Variable",name:{kind:"Name",value:"input"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"overallScore"}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"updatedAt"}},{kind:"Field",name:{kind:"Name",value:"completedAt"}},{kind:"Field",name:{kind:"Name",value:"isCompleted"}}]}}]}}]},Ea={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"mutation",name:{kind:"Name",value:"CompleteAIReview"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"input"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"CompleteAIReviewInput"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"completeAIReview"},arguments:[{kind:"Argument",name:{kind:"Name",value:"input"},value:{kind:"Variable",name:{kind:"Name",value:"input"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"overallScore"}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"updatedAt"}},{kind:"Field",name:{kind:"Name",value:"completedAt"}},{kind:"Field",name:{kind:"Name",value:"isCompleted"}}]}}]}}]},Ta={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"query",name:{kind:"Name",value:"GetProjectForReview"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"id"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"project"},arguments:[{kind:"Argument",name:{kind:"Name",value:"id"},value:{kind:"Variable",name:{kind:"Name",value:"id"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"name"}},{kind:"Field",name:{kind:"Name",value:"description"}},{kind:"Field",name:{kind:"Name",value:"repositoryUrl"}},{kind:"Field",name:{kind:"Name",value:"documentationUrl"}},{kind:"Field",name:{kind:"Name",value:"stage"}},{kind:"Field",name:{kind:"Name",value:"workspaces"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"workspaceId"}},{kind:"Field",name:{kind:"Name",value:"name"}},{kind:"Field",name:{kind:"Name",value:"path"}},{kind:"Field",name:{kind:"Name",value:"pattern"}}]}},{kind:"Field",name:{kind:"Name",value:"affectedServices"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"serviceId"}},{kind:"Field",name:{kind:"Name",value:"name"}},{kind:"Field",name:{kind:"Name",value:"technology"}}]}},{kind:"Field",name:{kind:"Name",value:"workspaceConfig"}},{kind:"Field",name:{kind:"Name",value:"stories"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"title"}},{kind:"Field",name:{kind:"Name",value:"description"}},{kind:"Field",name:{kind:"Name",value:"acceptanceCriteria"}},{kind:"Field",name:{kind:"Name",value:"status"}}]}}]}}]}}]},Ca={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"query",name:{kind:"Name",value:"GetPreviousReview"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"id"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"projectReview"},arguments:[{kind:"Argument",name:{kind:"Name",value:"id"},value:{kind:"Variable",name:{kind:"Name",value:"id"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"overallScore"}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"project"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"name"}},{kind:"Field",name:{kind:"Name",value:"description"}},{kind:"Field",name:{kind:"Name",value:"repositoryUrl"}},{kind:"Field",name:{kind:"Name",value:"stage"}},{kind:"Field",name:{kind:"Name",value:"workspaces"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"workspaceId"}},{kind:"Field",name:{kind:"Name",value:"name"}},{kind:"Field",name:{kind:"Name",value:"path"}},{kind:"Field",name:{kind:"Name",value:"pattern"}}]}},{kind:"Field",name:{kind:"Name",value:"workspaceConfig"}}]}},{kind:"Field",name:{kind:"Name",value:"reviewData"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"analysis"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"strengths"}},{kind:"Field",name:{kind:"Name",value:"weaknesses"}},{kind:"Field",name:{kind:"Name",value:"risks"}},{kind:"Field",name:{kind:"Name",value:"opportunities"}}]}},{kind:"Field",name:{kind:"Name",value:"scores"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"completeness"}},{kind:"Field",name:{kind:"Name",value:"clarity"}},{kind:"Field",name:{kind:"Name",value:"feasibility"}},{kind:"Field",name:{kind:"Name",value:"overall"}}]}},{kind:"Field",name:{kind:"Name",value:"suggestedProductRequirements"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"explicitRequirements"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"requirement"}},{kind:"Field",name:{kind:"Name",value:"source_text"}},{kind:"Field",name:{kind:"Name",value:"confidence"}}]}},{kind:"Field",name:{kind:"Name",value:"inferredFunctionalRequirements"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"requirement"}},{kind:"Field",name:{kind:"Name",value:"rationale"}},{kind:"Field",name:{kind:"Name",value:"domain_pattern"}},{kind:"Field",name:{kind:"Name",value:"priority"}}]}},{kind:"Field",name:{kind:"Name",value:"suggestedNonFunctionalRequirements"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"category"}},{kind:"Field",name:{kind:"Name",value:"requirement"}},{kind:"Field",name:{kind:"Name",value:"industry_standard"}},{kind:"Field",name:{kind:"Name",value:"customization_needed"}}]}},{kind:"Field",name:{kind:"Name",value:"requirementsClarificationQuestions"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"category"}},{kind:"Field",name:{kind:"Name",value:"question"}},{kind:"Field",name:{kind:"Name",value:"impact_if_unclear"}},{kind:"Field",name:{kind:"Name",value:"suggested_default"}}]}}]}}]}},{kind:"Field",name:{kind:"Name",value:"suggestions"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"requirements"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"type"}},{kind:"Field",name:{kind:"Name",value:"current"}},{kind:"Field",name:{kind:"Name",value:"suggested"}},{kind:"Field",name:{kind:"Name",value:"rationale"}},{kind:"Field",name:{kind:"Name",value:"priority"}}]}},{kind:"Field",name:{kind:"Name",value:"architecture"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"component"}},{kind:"Field",name:{kind:"Name",value:"suggestion"}},{kind:"Field",name:{kind:"Name",value:"impact"}}]}},{kind:"Field",name:{kind:"Name",value:"risks"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"risk"}},{kind:"Field",name:{kind:"Name",value:"mitigation"}},{kind:"Field",name:{kind:"Name",value:"severity"}}]}}]}},{kind:"Field",name:{kind:"Name",value:"createdAt"}},{kind:"Field",name:{kind:"Name",value:"updatedAt"}}]}}]}}]},Pa={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"query",name:{kind:"Name",value:"GetReviewForProjectId"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"id"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"projectReview"},arguments:[{kind:"Argument",name:{kind:"Name",value:"id"},value:{kind:"Variable",name:{kind:"Name",value:"id"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"project"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"name"}}]}}]}}]}}]},Ra={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"query",name:{kind:"Name",value:"PollForWork"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"workerId"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}},{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"capabilities"}},type:{kind:"NonNullType",type:{kind:"ListType",type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}}}},{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"maxWork"}},type:{kind:"NamedType",name:{kind:"Name",value:"Int"}},defaultValue:{kind:"IntValue",value:"3"}},{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"autoClaimWork"}},type:{kind:"NamedType",name:{kind:"Name",value:"Boolean"}},defaultValue:{kind:"BooleanValue",value:!0}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"pollForWork"},arguments:[{kind:"Argument",name:{kind:"Name",value:"workerId"},value:{kind:"Variable",name:{kind:"Name",value:"workerId"}}},{kind:"Argument",name:{kind:"Name",value:"capabilities"},value:{kind:"Variable",name:{kind:"Name",value:"capabilities"}}},{kind:"Argument",name:{kind:"Name",value:"maxWork"},value:{kind:"Variable",name:{kind:"Name",value:"maxWork"}}},{kind:"Argument",name:{kind:"Name",value:"autoClaimWork"},value:{kind:"Variable",name:{kind:"Name",value:"autoClaimWork"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"availableWork"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"workType"}},{kind:"Field",name:{kind:"Name",value:"priority"}},{kind:"Field",name:{kind:"Name",value:"createdAt"}},{kind:"Field",name:{kind:"Name",value:"metadata"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"workType"}},{kind:"Field",name:{kind:"Name",value:"aiWorkerId"}},{kind:"Field",name:{kind:"Name",value:"attemptCount"}},{kind:"Field",name:{kind:"Name",value:"maxRetryAttempts"}},{kind:"Field",name:{kind:"Name",value:"projectId"}},{kind:"Field",name:{kind:"Name",value:"reviewId"}},{kind:"Field",name:{kind:"Name",value:"progress"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"percentage"}},{kind:"Field",name:{kind:"Name",value:"currentStep"}},{kind:"Field",name:{kind:"Name",value:"totalSteps"}},{kind:"Field",name:{kind:"Name",value:"completedSteps"}}]}},{kind:"Field",name:{kind:"Name",value:"lastError"}},{kind:"Field",name:{kind:"Name",value:"reconciledAt"}},{kind:"Field",name:{kind:"Name",value:"reconciledFrom"}}]}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"currentStep"}},{kind:"Field",name:{kind:"Name",value:"progressPercentage"}},{kind:"Field",name:{kind:"Name",value:"project"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"name"}}]}},{kind:"Field",name:{kind:"Name",value:"story"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"title"}}]}}]}},{kind:"Field",name:{kind:"Name",value:"myClaimedWork"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"workType"}},{kind:"Field",name:{kind:"Name",value:"priority"}},{kind:"Field",name:{kind:"Name",value:"createdAt"}},{kind:"Field",name:{kind:"Name",value:"claimedAt"}},{kind:"Field",name:{kind:"Name",value:"lastHeartbeat"}},{kind:"Field",name:{kind:"Name",value:"assignedWorker"}},{kind:"Field",name:{kind:"Name",value:"metadata"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"workType"}},{kind:"Field",name:{kind:"Name",value:"aiWorkerId"}},{kind:"Field",name:{kind:"Name",value:"attemptCount"}},{kind:"Field",name:{kind:"Name",value:"maxRetryAttempts"}},{kind:"Field",name:{kind:"Name",value:"projectId"}},{kind:"Field",name:{kind:"Name",value:"reviewId"}},{kind:"Field",name:{kind:"Name",value:"progress"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"percentage"}},{kind:"Field",name:{kind:"Name",value:"currentStep"}},{kind:"Field",name:{kind:"Name",value:"totalSteps"}},{kind:"Field",name:{kind:"Name",value:"completedSteps"}}]}},{kind:"Field",name:{kind:"Name",value:"lastError"}},{kind:"Field",name:{kind:"Name",value:"reconciledAt"}},{kind:"Field",name:{kind:"Name",value:"reconciledFrom"}}]}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"currentStep"}},{kind:"Field",name:{kind:"Name",value:"progressPercentage"}},{kind:"Field",name:{kind:"Name",value:"project"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"name"}}]}},{kind:"Field",name:{kind:"Name",value:"story"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"title"}}]}}]}},{kind:"Field",name:{kind:"Name",value:"claimedWork"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"workType"}},{kind:"Field",name:{kind:"Name",value:"priority"}},{kind:"Field",name:{kind:"Name",value:"createdAt"}},{kind:"Field",name:{kind:"Name",value:"claimedAt"}},{kind:"Field",name:{kind:"Name",value:"lastHeartbeat"}},{kind:"Field",name:{kind:"Name",value:"assignedWorker"}},{kind:"Field",name:{kind:"Name",value:"metadata"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"workType"}},{kind:"Field",name:{kind:"Name",value:"aiWorkerId"}},{kind:"Field",name:{kind:"Name",value:"attemptCount"}},{kind:"Field",name:{kind:"Name",value:"maxRetryAttempts"}},{kind:"Field",name:{kind:"Name",value:"projectId"}},{kind:"Field",name:{kind:"Name",value:"reviewId"}},{kind:"Field",name:{kind:"Name",value:"progress"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"percentage"}},{kind:"Field",name:{kind:"Name",value:"currentStep"}},{kind:"Field",name:{kind:"Name",value:"totalSteps"}},{kind:"Field",name:{kind:"Name",value:"completedSteps"}}]}},{kind:"Field",name:{kind:"Name",value:"lastError"}},{kind:"Field",name:{kind:"Name",value:"reconciledAt"}},{kind:"Field",name:{kind:"Name",value:"reconciledFrom"}}]}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"currentStep"}},{kind:"Field",name:{kind:"Name",value:"progressPercentage"}},{kind:"Field",name:{kind:"Name",value:"project"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"name"}}]}},{kind:"Field",name:{kind:"Name",value:"story"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"title"}}]}}]}},{kind:"Field",name:{kind:"Name",value:"nextPollInterval"}},{kind:"Field",name:{kind:"Name",value:"hasMoreWork"}},{kind:"Field",name:{kind:"Name",value:"workerStatus"}},{kind:"Field",name:{kind:"Name",value:"queueStats"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"totalQueued"}},{kind:"Field",name:{kind:"Name",value:"totalInProgress"}},{kind:"Field",name:{kind:"Name",value:"estimatedWaitTime"}}]}}]}}]}}]},Da={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"mutation",name:{kind:"Name",value:"UpdateAIWork"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"input"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"UpdateAIWorkInput"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"updateAIWork"},arguments:[{kind:"Argument",name:{kind:"Name",value:"input"},value:{kind:"Variable",name:{kind:"Name",value:"input"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"startedAt"}},{kind:"Field",name:{kind:"Name",value:"metadata"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"aiWorkerId"}},{kind:"Field",name:{kind:"Name",value:"progress"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"currentStep"}},{kind:"Field",name:{kind:"Name",value:"percentage"}}]}}]}}]}}]}}]},Ma={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"mutation",name:{kind:"Name",value:"CompleteAIWork"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"id"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}},{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"summary"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}},{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"artifacts"}},type:{kind:"ListType",type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"String"}}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"completeAIWork"},arguments:[{kind:"Argument",name:{kind:"Name",value:"id"},value:{kind:"Variable",name:{kind:"Name",value:"id"}}},{kind:"Argument",name:{kind:"Name",value:"summary"},value:{kind:"Variable",name:{kind:"Name",value:"summary"}}},{kind:"Argument",name:{kind:"Name",value:"artifacts"},value:{kind:"Variable",name:{kind:"Name",value:"artifacts"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"completedAt"}}]}}]}}]},Na={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"query",name:{kind:"Name",value:"GetMyAIWorkers"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"me"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"aiWorkers"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"workerId"}},{kind:"Field",name:{kind:"Name",value:"status"}},{kind:"Field",name:{kind:"Name",value:"capabilities"}},{kind:"Field",name:{kind:"Name",value:"metadata"}},{kind:"Field",name:{kind:"Name",value:"createdAt"}},{kind:"Field",name:{kind:"Name",value:"lastHeartbeat"}}]}}]}}]}}]},xa={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"mutation",name:{kind:"Name",value:"RegisterWorker"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"input"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"AIWorkerRegistrationInput"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"registerAIWorker"},arguments:[{kind:"Argument",name:{kind:"Name",value:"input"},value:{kind:"Variable",name:{kind:"Name",value:"input"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"success"}},{kind:"Field",name:{kind:"Name",value:"message"}},{kind:"Field",name:{kind:"Name",value:"worker"},selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"id"}},{kind:"Field",name:{kind:"Name",value:"workerId"}},{kind:"Field",name:{kind:"Name",value:"status"}}]}}]}}]}}]},Wa={kind:"Document",definitions:[{kind:"OperationDefinition",operation:"mutation",name:{kind:"Name",value:"UpdateWorkerHeartbeat"},variableDefinitions:[{kind:"VariableDefinition",variable:{kind:"Variable",name:{kind:"Name",value:"input"}},type:{kind:"NonNullType",type:{kind:"NamedType",name:{kind:"Name",value:"AIWorkerHealthCheckInput"}}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"updateAIWorkerHeartbeat"},arguments:[{kind:"Argument",name:{kind:"Name",value:"input"},value:{kind:"Variable",name:{kind:"Name",value:"input"}}}],selectionSet:{kind:"SelectionSet",selections:[{kind:"Field",name:{kind:"Name",value:"success"}},{kind:"Field",name:{kind:"Name",value:"message"}}]}}]}}]}});var Oa,ye,Et=M(()=>{"use strict";Oa=require("graphql-request");j();Tr();ye=class{constructor(r){let e={"Content-Type":"application/json"};r.apiKey&&(e["X-API-Key"]=r.apiKey),this.client=new Oa.GraphQLClient(r.apiUrl,{headers:e})}async me(){try{s.debug("Executing Me query");let r=await this.client.request(wa);return s.debug("Me query successful",{userId:r.me?.id}),r}catch(r){throw s.error("Me query failed",{error:r instanceof Error?r.message:String(r)}),r}}async exchangeApiKeyForToken(r){try{s.debug("Executing ExchangeApiKeyForToken mutation");let e=await this.client.request(ba,r);return s.debug("ExchangeApiKeyForToken successful"),e}catch(e){throw s.error("ExchangeApiKeyForToken failed",{error:e instanceof Error?e.message:String(e)}),e}}async getMyAIWorkers(){try{s.debug("Executing GetMyAIWorkers query");let r=await this.client.request(Na);return s.debug("GetMyAIWorkers successful",{workerCount:r.me?.aiWorkers?.length||0}),r}catch(r){throw s.error("GetMyAIWorkers failed",{error:r instanceof Error?r.message:String(r)}),r}}async registerWorker(r){try{s.info("REGISTRATION DEBUG: TypedGraphQLClient sending mutation",{workerId:r.input.workerId,capabilities:r.input.capabilities,capabilityCount:r.input.capabilities?.length,fullInput:JSON.stringify(r.input)});let e=await this.client.request(xa,r);return s.info("REGISTRATION DEBUG: GraphQL response",{result:e.registerAIWorker,success:e.registerAIWorker}),e}catch(e){throw s.error("RegisterWorker failed",{workerId:r.input.workerId,error:e instanceof Error?e.message:String(e)}),e}}async updateWorkerHeartbeat(r){try{s.debug("Executing UpdateWorkerHeartbeat mutation",{workerId:r.input.workerId});let e=await this.client.request(Wa,r);return s.debug("UpdateWorkerHeartbeat successful"),e}catch(e){throw s.error("UpdateWorkerHeartbeat failed",{workerId:r.input.workerId,error:e instanceof Error?e.message:String(e)}),e}}setApiKey(r){this.client.setHeaders({...this.client.requestConfig.headers,"X-API-Key":r})}setToken(r){this.client.setHeaders({...this.client.requestConfig.headers,Authorization:`Bearer ${r}`})}async pollForWork(r){try{s.debug("Executing PollForWork query",{workerId:r.workerId});let e=await this.client.request(Ra,r);return s.debug("PollForWork successful",{workerId:r.workerId,claimedWork:e.pollForWork.claimedWork.length,availableWork:e.pollForWork.availableWork.length,nextPollInterval:e.pollForWork.nextPollInterval}),e}catch(e){throw s.error("PollForWork failed",{workerId:r.workerId,error:e instanceof Error?e.message:String(e)}),e}}async updateProjectReview(r){try{s.debug("Executing UpdateProjectReview mutation",{reviewId:r.id});let e=await this.client.request(Aa,r);return s.debug("UpdateProjectReview successful",{reviewId:e.updateProjectReview.id,overallScore:e.updateProjectReview.overallScore}),e}catch(e){throw s.error("UpdateProjectReview failed",{reviewId:r.id,error:e instanceof Error?e.message:String(e)}),e}}async completeAIReview(r){try{s.debug("Executing CompleteAIReview mutation",{reviewId:r.input.reviewId});let e=await this.client.request(Ea,r);return s.debug("CompleteAIReview successful",{reviewId:e.completeAIReview.id,overallScore:e.completeAIReview.overallScore}),e}catch(e){throw s.error("CompleteAIReview failed",{reviewId:r.input.reviewId,error:e instanceof Error?e.message:String(e)}),e}}async getProjectForReview(r){try{s.debug("Executing GetProjectForReview query",{projectId:r.id});let e=await this.client.request(Ta,r);return s.debug("GetProjectForReview successful",{projectId:e.project?.id,projectName:e.project?.name}),e}catch(e){throw s.error("GetProjectForReview failed",{projectId:r.id,error:e instanceof Error?e.message:String(e)}),e}}async getPreviousReview(r){try{s.debug("Executing GetPreviousReview query",{reviewId:r.id});let e=await this.client.request(Ca,r);return s.debug("GetPreviousReview successful",{reviewId:e.projectReview?.id}),e}catch(e){throw s.error("GetPreviousReview failed",{reviewId:r.id,error:e instanceof Error?e.message:String(e)}),e}}async getReviewForProjectId(r){try{s.debug("Executing GetReviewForProjectId query",{reviewId:r.id});let e=await this.client.request(Pa,r);return s.debug("GetReviewForProjectId successful",{reviewId:e.projectReview?.id,projectId:e.projectReview?.project?.id}),e}catch(e){throw s.error("GetReviewForProjectId failed",{reviewId:r.id,error:e instanceof Error?e.message:String(e)}),e}}async updateAiWork(r){try{s.debug("Executing UpdateAiWork mutation",{workId:r.input.workId,status:r.input.status});let e=await this.client.request(Da,r);return s.debug("UpdateAiWork successful",{workId:e.updateAIWork?.id,status:e.updateAIWork?.status}),e}catch(e){throw s.error("UpdateAiWork failed",{workId:r.input.workId,error:e instanceof Error?e.message:String(e)}),e}}async completeAiWork(r){try{s.debug("Executing CompleteAiWork mutation",{workId:r.id});let e=await this.client.request(Ma,r);return s.debug("CompleteAiWork successful",{workId:e.completeAIWork?.id,status:e.completeAIWork?.status}),e}catch(e){throw s.error("CompleteAiWork failed",{workId:r.id,error:e instanceof Error?e.message:String(e)}),e}}clearAuth(){this.client.setHeaders({"Content-Type":"application/json"})}async request(r,e){try{s.debug("Executing custom GraphQL request");let t=await this.client.request(r,e);return s.debug("Custom GraphQL request successful"),t}catch(t){throw s.error("Custom GraphQL request failed",{error:t instanceof Error?t.message:String(t)}),t}}}});var Tt=M(()=>{"use strict"});function $e(){if(!Pt)throw new Error("WorkItemErrorTracker not initialized. Call initializeWorkItemErrorTracker first.");return Pt}function Fa(l,r,e){return Pt=new Cr(l,r,e),Pt}var ja,tt,Ct,Cr,Pt,Rt=M(()=>{"use strict";ja=require("events"),tt=A(require("fs/promises")),Ct=A(require("path"));j();Tt();Cr=class extends ja.EventEmitter{constructor(e,t,a){super();this.httpClient=e;this._workerId=t;this.errorHistory=new Map;this.logHistory=new Map;this.errorPatterns=new Map;this.maxHistoryPerItem=50;this.logDirectory=a||Ct.join(process.cwd(),"logs","work-items"),this.ensureLogDirectory()}async logError(e,t){try{this.addToErrorHistory(e),s.error("Work item error logged",{workItemId:e.workItemId,workerId:this._workerId,errorType:e.errorType,stage:e.stage,message:e.message,retryable:e.metadata.retryable,severity:e.metadata.severity}),await this.persistErrorLog(e),await this.sendErrorToBackend(e,t),this.emit("errorLogged",e),this.updateErrorPatterns(e),this.checkAlertConditions(e)}catch(a){s.error("Failed to track work item error",{originalError:e,trackingError:a instanceof Error?a.message:String(a)})}}async logWorkItemEvent(e,t){try{this.addToLogHistory(e);let a=e.status==="FAILED"?"error":e.status==="COMPLETED"?"info":"debug";s[a]("Work item event",{workItemId:e.workItemId,status:e.status,stage:e.stage,duration:e.duration,retryCount:e.metadata.retryCount}),await this.persistWorkItemLog(e),await this.sendLogToBackend(e,t),this.emit("workItemLogged",e)}catch(a){s.error("Failed to track work item log",{originalLog:e,trackingError:a instanceof Error?a.message:String(a)})}}getErrorHistory(e){return this.errorHistory.get(e)||[]}getLogHistory(e){return this.logHistory.get(e)||[]}getFailurePattern(e){return this.errorPatterns.get(e)}async getHealthStatus(){let e=new Date,t=new Date(e.getTime()-24*60*60*1e3),a=Array.from(this.errorHistory.values()).flat().filter(b=>b.context.timestamp>=t),i=Array.from(this.logHistory.values()).flat().filter(b=>b.timestamp>=t),n=i.filter(b=>b.status==="COMPLETED"),o=i.filter(b=>b.status==="FAILED"),c=n.length+o.length,d=c>0?n.length/c*100:100,p=n.length>0?n.reduce((b,w)=>b+(w.duration||0),0)/n.length:0,u=new Map,h=new Map;a.forEach(b=>{u.set(b.errorType,(u.get(b.errorType)||0)+1);let w=h.get(b.errorType);(!w||b.context.timestamp>w)&&h.set(b.errorType,b.context.timestamp)});let f=Array.from(u.entries()).map(([b,w])=>({type:b,count:w,lastOccurrence:h.get(b)})).sort((b,w)=>w.count-b.count).slice(0,10);return{activeWorkItems:this.getActiveWorkItemCount(),failedInLast24Hours:o.length,successRate:Math.round(d*100)/100,averageProcessingTime:Math.round(p),topErrors:f,systemResources:await this.getSystemResourceUsage(),externalServices:await this.checkExternalServices()}}analyzeErrorPatterns(e){let t=Array.from(this.errorHistory.values()).flat().filter(f=>f.workType===e);if(t.length===0)return{workType:e,errorType:"internal_error",frequency:0,averageRetryCount:0,successRateAfterRetry:0,commonContext:{},suggestedFixes:[]};let a=new Map;t.forEach(f=>{a.set(f.errorType,(a.get(f.errorType)||0)+1)});let i=Array.from(a.entries()).sort((f,b)=>b[1]-f[1])[0][0],n=t.filter(f=>f.errorType===i),o=n.length,c=n.reduce((f,b)=>f+b.context.attempt,0)/o,p=n.filter(f=>f.resolved).length/o*100,u=this.extractCommonContext(n),h=this.generateSuggestedFixes(i,u);return{workType:e,errorType:i,frequency:o,averageRetryCount:c,successRateAfterRetry:p,commonContext:u,suggestedFixes:h}}async markErrorResolved(e,t,a,i){let o=(this.errorHistory.get(e)||[]).find(c=>c.id===t);o&&(o.resolved=!0,o.resolution={...a,timestamp:new Date},await this.sendErrorToBackend(o,i),this.emit("errorResolved",o))}addToErrorHistory(e){this.errorHistory.has(e.workItemId)||this.errorHistory.set(e.workItemId,[]);let t=this.errorHistory.get(e.workItemId);t.unshift(e),t.length>this.maxHistoryPerItem&&t.splice(this.maxHistoryPerItem)}addToLogHistory(e){this.logHistory.has(e.workItemId)||this.logHistory.set(e.workItemId,[]);let t=this.logHistory.get(e.workItemId);t.unshift(e),t.length>this.maxHistoryPerItem&&t.splice(this.maxHistoryPerItem)}async ensureLogDirectory(){try{await tt.mkdir(this.logDirectory,{recursive:!0})}catch(e){s.error("Failed to create log directory",{directory:this.logDirectory,error:e instanceof Error?e.message:String(e)})}}async persistErrorLog(e){try{let t=`error-${e.workItemId}-${Date.now()}.json`,a=Ct.join(this.logDirectory,t);await tt.writeFile(a,JSON.stringify(e,null,2))}catch(t){s.error("Failed to persist error log",{error:e.id,writeError:t instanceof Error?t.message:String(t)})}}async persistWorkItemLog(e){try{let t=`log-${e.workItemId}-${Date.now()}.json`,a=Ct.join(this.logDirectory,t);await tt.writeFile(a,JSON.stringify(e,null,2))}catch(t){s.error("Failed to persist work item log",{workItemId:e.workItemId,writeError:t instanceof Error?t.message:String(t)})}}async sendErrorToBackend(e,t){try{let a=`
107
+ mutation LogWorkItemError($input: WorkItemErrorInput!) {
108
+ logWorkItemError(input: $input) {
109
+ id
110
+ logged
111
+ }
112
+ }
113
+ `,i={input:{workItemId:e.workItemId,assignmentId:e.assignmentId,workType:e.workType,errorType:e.errorType.toUpperCase(),message:e.message,stack:e.stack,stage:e.stage,workerId:e.context.workerId,severity:(e.metadata?.severity||"medium").toUpperCase(),category:(e.metadata?.category||"system").toUpperCase(),retryable:e.metadata?.retryable??!0,tags:e.metadata?.tags||[],contextJson:JSON.stringify(e.context),resolved:e.resolved||!1,resolutionJson:e.resolution?JSON.stringify(e.resolution):void 0}};await(t||this.httpClient).post({query:a,variables:i,operationName:"LogWorkItemError"})}catch(a){s.warn("Failed to send error to backend",{errorId:e.id,sendError:a instanceof Error?a.message:String(a)})}}async sendLogToBackend(e,t){try{let a=`
114
+ mutation LogWorkItemEvent($input: WorkItemLogInput!) {
115
+ logWorkItemEvent(input: $input) {
116
+ id
117
+ logged
118
+ }
119
+ }
120
+ `,i={input:{workItemId:e.workItemId,assignmentId:e.assignmentId,workType:e.workType,status:e.status,stage:e.stage,timestamp:e.timestamp,duration:e.duration,progress:e.progress,metadata:e.metadata}};await(t||this.httpClient).post({query:a,variables:i,operationName:"LogWorkItemEvent"})}catch(a){s.warn("Failed to send log to backend",{workItemId:e.workItemId,sendError:a instanceof Error?a.message:String(a)})}}updateErrorPatterns(e){let t=this.analyzeErrorPatterns(e.workType);this.errorPatterns.set(e.workType,t)}checkAlertConditions(e){e.metadata.severity==="critical"&&this.emit("criticalError",e);let t=this.getErrorHistory(e.workItemId).filter(a=>a.errorType===e.errorType).slice(0,5);t.length>=3&&this.emit("recurringError",{error:e,pattern:t})}getActiveWorkItemCount(){return Array.from(this.logHistory.values()).flat().filter(e=>e.status==="PROCESSING").length}async getSystemResourceUsage(){let e=process.memoryUsage();return{memoryUsage:Math.round(e.heapUsed/1024/1024),cpuUsage:0,diskSpace:0}}async checkExternalServices(){return{claudeApiStatus:"healthy",backendApiStatus:this.httpClient.isAuthenticated()?"healthy":"down",databaseStatus:"healthy"}}extractCommonContext(e){let t=e.map(i=>i.context),a={};if(t.length>0){let i=t[0];Object.keys(i).forEach(n=>{let o=t.map(c=>c[n]).filter(c=>c!==void 0);o.length===t.length&&o.every(c=>c===o[0])&&(a[n]=o[0])})}return a}generateSuggestedFixes(e,t){let a=[];switch(e){case"network_error":a.push("Check network connectivity"),a.push("Verify API endpoint URLs"),a.push("Increase request timeout");break;case"authentication_error":a.push("Refresh authentication token"),a.push("Verify API key is valid"),a.push("Check user permissions");break;case"claude_api_error":a.push("Check Claude API key"),a.push("Verify Claude CLI installation"),a.push("Check token usage limits");break;case"missing_project":a.push("Verify project ID exists in database"),a.push("Check project access permissions"),a.push("Refresh project data cache");break;case"timeout_error":a.push("Increase operation timeout"),a.push("Break down large operations"),a.push("Check system resource usage");break;default:a.push("Check logs for detailed error information"),a.push("Verify system configuration"),a.push("Contact system administrator")}return a}},Pt=null});var La,xe,Pr=M(()=>{"use strict";j();La=require("events"),xe=class l extends La.EventEmitter{constructor(){super();this.isPaused=!1}static getInstance(){return l.instance||(l.instance=new l),l.instance}pauseForUsageLimit(e,t){this.isPaused&&s.warn("Agent already paused, updating resume time",{currentResumeTime:this.resumeTimestamp,newResumeTime:e}),this.isPaused=!0,this.resumeTimestamp=e;let a=new Date(e*1e3);this.resumeTimeout&&clearTimeout(this.resumeTimeout);let i=e*1e3-Date.now();s.warn("\u{1F6AB} Agent paused due to Claude usage limits",{reason:t,resumeTimestamp:this.resumeTimestamp,resumeDate:a.toISOString(),timeUntilResumeMs:i,timeUntilResumeMinutes:Math.ceil(i/(1e3*60))}),this.emit("agent_paused",{reason:t,resumeTimestamp:this.resumeTimestamp,resumeDate:a,timeUntilResumeMs:i}),i>0?(this.resumeTimeout=setTimeout(()=>{this.resume("Usage limit reset time reached")},i),s.info(`\u23F0 Agent will automatically resume at ${a.toISOString()}`)):this.resume("Usage limit already expired")}resume(e="Manual resume"){if(!this.isPaused){s.debug("Agent resume requested but not paused");return}this.resumeTimeout&&(clearTimeout(this.resumeTimeout),this.resumeTimeout=void 0),this.isPaused=!1,this.resumeTimestamp=void 0,s.info("\u2705 Agent resumed",{reason:e}),this.emit("agent_resumed",{reason:e})}isPausedState(){return this.isPaused}getResumeInfo(){if(!this.isPaused||!this.resumeTimestamp)return null;let e=this.resumeTimestamp*1e3-Date.now();return{resumeTimestamp:this.resumeTimestamp,resumeDate:new Date(this.resumeTimestamp*1e3),timeUntilResumeMs:e}}forceResume(){this.resume("Force resume requested")}}});var qe,Rr,Dt,Ua=M(()=>{"use strict";qe=A(require("fs")),Rr=A(require("path")),Dt=class l{constructor(){let r=Rr.join(process.cwd(),"logs");qe.existsSync(r)||qe.mkdirSync(r,{recursive:!0});let e=new Date().toISOString().split("T")[0];this.logFilePath=Rr.join(r,`claude-interactions-${e}.log`)}static getInstance(){return l.instance||(l.instance=new l),l.instance}formatLogEntry(r){let e="=".repeat(80),t=r.timestamp,a=`Session: ${r.sessionId}${r.workItemId?` | WorkItem: ${r.workItemId}`:""}${r.assignmentId?` | Assignment: ${r.assignmentId}`:""}`,i=`
121
+ ${e}
122
+ [${t}] ${r.phase.toUpperCase()}
123
+ ${a}
124
+ ${e}
125
+ `;return r.prompt&&(i+=`
126
+ \u{1F916} PROMPT:
127
+ ${r.prompt}
128
+ `),r.response&&(i+=`
129
+ \u{1F4AC} RESPONSE:
130
+ ${r.response}
131
+ `),r.error&&(i+=`
132
+ \u274C ERROR:
133
+ ${r.error}
134
+ `),r.metadata&&(i+=`
135
+ \u{1F4CA} METADATA:
136
+ ${JSON.stringify(r.metadata,null,2)}
137
+ `),i+=`${e}
138
+ `,i}writeToLog(r){try{let e=this.formatLogEntry(r);qe.appendFileSync(this.logFilePath,e,"utf8")}catch(e){console.error("Failed to write to Claude log file:",e)}}logPrompt(r,e,t={}){this.writeToLog({timestamp:new Date().toISOString(),sessionId:r,workItemId:t.workItemId,assignmentId:t.assignmentId,phase:"prompt",prompt:e,metadata:{workspaceTargeting:t.workspaceTargeting}})}logResponse(r,e,t={}){this.writeToLog({timestamp:new Date().toISOString(),sessionId:r,workItemId:t.workItemId,assignmentId:t.assignmentId,phase:"response",response:e,metadata:{executionTime:t.executionTime,tokenCount:t.tokenCount}})}logError(r,e,t={}){this.writeToLog({timestamp:new Date().toISOString(),sessionId:r,workItemId:t.workItemId,assignmentId:t.assignmentId,phase:"error",error:e,prompt:t.prompt})}getLogFilePath(){return this.logFilePath}}});var za,Dr,Mr,Be,ae,Ge=M(()=>{"use strict";za=require("child_process"),Dr=A(require("fs")),Mr=A(require("path"));Ua();mr();Be=class extends Error{constructor(r,e){super(r),this.name="ClaudeUsageLimitError",this.resetTimestamp=e,this.resetDate=new Date(e*1e3)}},ae=class{constructor(r){this.claudeCommand=r}parseUsageLimitError(r){try{let e=JSON.parse(r);if(e.result&&typeof e.result=="string"){let t=e.result.match(/Claude AI usage limit reached\|(\d+)/);if(t){let a=parseInt(t[1],10);return new Be(`Claude AI usage limit reached. Resets at ${new Date(a*1e3).toISOString()}`,a)}}}catch{let e=r.match(/Claude AI usage limit reached\|(\d+)/);if(e){let t=parseInt(e[1],10);return new Be(`Claude AI usage limit reached. Resets at ${new Date(t*1e3).toISOString()}`,t)}}return null}async executeCommand(r,e,t,a=18e5,i,n){return new Promise((o,c)=>{(async()=>{let p,u,h=Date.now(),f=i||`claude-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,b=Dt.getInstance();b.logPrompt(f,r,{workspaceTargeting:t});try{let w=this.buildClaudeArgs(t,!0,r),B=gr(this.claudeCommand);console.log("Executing Claude CLI:",B,w.join(" ")),console.log("MCP config:",w.find(K=>K.includes("mcpServers"))),console.log(`Session ${f}: Claude process starting at ${new Date().toISOString()}`),p=setTimeout(()=>{if(u){console.log(`Claude execution timeout after ${a}ms, killing process`);let K=`Claude execution timed out after ${a}ms`;b.logError(f,K,{prompt:r}),u.kill("SIGTERM"),c(new Error(K))}},a),u=(0,za.spawn)(B,w,{cwd:e,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_WORKSPACE_PATH:e,CLAUDE_WORKSPACE_NAME:t?.workspaceName||"default"}});let T="",$="";u.stdout.on("data",K=>{let X=K.toString();T+=X,console.log(`Session ${f}: ${X}`)}),u.stderr.on("data",K=>{let X=K.toString();$+=X,console.error(`Session ${f}: [STDERR] ${X}`)}),u.on("close",K=>{p&&clearTimeout(p);let X=Date.now()-h;try{u&&!u.killed&&(console.log(`Session ${f}: Ensuring Claude process ${u.pid} is terminated`),u.kill("SIGTERM"),setTimeout(()=>{u&&!u.killed&&(console.log(`Session ${f}: Force killing Claude process ${u.pid}`),u.kill("SIGKILL"))},5e3))}catch(ue){console.error(`Session ${f}: Error killing Claude process:`,ue)}if(K===0)b.logResponse(f,T,{executionTime:X,tokenCount:this.estimateTokenCount(T)}),o(T);else{let ue=this.parseUsageLimitError(T)||this.parseUsageLimitError($);if(ue){b.logError(f,ue.message,{prompt:r}),c(ue);return}let sr=`Claude CLI failed - Exit code: ${K}, Stderr: ${$}, Stdout: ${T}`;b.logError(f,sr,{prompt:r}),c(new Error(sr))}}),u.on("error",K=>{p&&clearTimeout(p);let X=`Failed to spawn Claude Code CLI: ${K.message}`;b.logError(f,X,{prompt:r}),c(new Error(X))})}catch(w){p&&clearTimeout(p);let B=`Claude execution error: ${w instanceof Error?w.message:String(w)}`;b.logError(f,B,{prompt:r}),c(w)}})()})}buildClaudeArgs(r,e=!1,t){let a=[];if(a.push("--verbose"),a.push("--output-format","stream-json"),t?a.push("--print",t):a.push("--print"),a.push("--permission-mode","acceptEdits"),e){let i,n=null,o=Mr.resolve(process.cwd(),"packages/mcp-agent/dist/index.js");if(Dr.existsSync(o))n=o;else{let c=Mr.resolve(__dirname,"../../mcp-agent/dist/index.js");if(Dr.existsSync(c))n=c;else throw new Error(`MCP agent not found. Expected locations:
139
+ - Monorepo: ${o}
140
+ - Bundled: ${c}`)}i={mcpServers:{"task-shepherd-agent-mcp":{command:"node",args:[n],env:{AGENT_TCP_PORT:"8549"}}}},a.push("--mcp-config"),a.push(JSON.stringify(i))}return r&&r.workspacePath&&a.push("--add-dir",r.workspacePath),a}estimateTokenCount(r){return Math.ceil(r.length/4)}}});var Ha,$a,ie,We=M(()=>{"use strict";Ha=require("events"),$a=require("uuid");j();Et();Er();Tr();Rt();Pr();Ge();Tt();ie=class extends Ha.EventEmitter{constructor(e){super();this.workType=e;this.retryCount=0}async handle(e){s.info("\u{1F525} BASE_WORK_HANDLER: Starting work assignment handling",{assignmentId:e.assignmentId,workItemId:e.workItemId,workType:this.workType,workItemType:e.workItemType,workerId:e.workerId,priority:e.priority,hasWorkData:!!e.workData,workDataKeys:e.workData?Object.keys(e.workData):[]}),this.currentAssignment=e,this.startTime=new Date,this.retryCount=0,e.organizationApiUrl&&e.organizationApiKey?(s.info("\u{1F525} BASE_WORK_HANDLER: Creating org-specific GraphQL and HTTP clients",{assignmentId:e.assignmentId,orgId:e.organizationId,orgApiUrl:e.organizationApiUrl}),this.orgGraphQLClient=new ye({apiUrl:e.organizationApiUrl,apiKey:e.organizationApiKey}),this.orgHttpClient=new He(e.organizationApiKey,e.organizationApiUrl),s.info("\u{1F525} BASE_WORK_HANDLER: Organization clients created",{assignmentId:e.assignmentId,orgId:e.organizationId,hasGraphQLClient:!!this.orgGraphQLClient,hasHttpClient:!!this.orgHttpClient})):s.error("\u{1F525} BASE_WORK_HANDLER: CRITICAL - No organization API details in assignment!",{assignmentId:e.assignmentId,hasOrgUrl:!!e.organizationApiUrl,hasOrgKey:!!e.organizationApiKey,orgUrl:e.organizationApiUrl||"MISSING",orgId:e.organizationId||"MISSING",workDataKeys:e.workData?Object.keys(e.workData):[],workDataOrgId:e.workData?.organizationId,workDataOrgUrl:e.workData?.organizationApiUrl}),s.info("\u{1F525} BASE_WORK_HANDLER: Assignment initialized",{assignmentId:e.assignmentId}),s.info("\u{1F525} BASE_WORK_HANDLER: Starting validation",{assignmentId:e.assignmentId});let t=await this.validateWorkAssignment(e);if(s.info("\u{1F525} BASE_WORK_HANDLER: Validation completed",{assignmentId:e.assignmentId,validationValid:t.valid,errorsCount:t.errors.length,warningsCount:t.warnings.length,validationErrors:t.errors.map(a=>a.message),validationWarnings:t.warnings.map(a=>a.message)}),!t.valid){s.error("\u{1F525} BASE_WORK_HANDLER: Validation failed, handling validation errors",{assignmentId:e.assignmentId,errors:t.errors}),await this.handleValidationErrors(e,t);return}s.info("\u{1F525} BASE_WORK_HANDLER: Validation passed, starting work processing",{assignmentId:e.assignmentId,workItemId:e.workItemId,workType:this.workType,validationPassed:t.warnings.length===0?"clean":"with_warnings"}),this.emit("workStarted",{assignment:e,workType:this.workType});try{await this.markWorkInProgress(e.assignmentId),await this.updateProgress(e.assignmentId,{stage:"Starting",progressPercentage:0,currentStep:"Initializing",message:`${this.workType}: Initializing work`,updatedAt:new Date}),s.info("\u{1F525} BASE_WORK_HANDLER: About to call executeWorkWithErrorHandling()",{assignmentId:e.assignmentId,workType:this.workType}),await this.executeWorkWithErrorHandling(e),s.info("\u{1F525} BASE_WORK_HANDLER: executeWorkWithErrorHandling() completed successfully",{assignmentId:e.assignmentId,workType:this.workType}),await this.updateProgress(e.assignmentId,{stage:"Completed",progressPercentage:100,currentStep:"Finished",message:`${this.workType}: Work completed successfully`,updatedAt:new Date}),await this.markWorkComplete(e.assignmentId);let a=Date.now()-this.startTime.getTime();this.emit("workCompleted",{assignmentId:e.assignmentId,workType:this.workType,result:"Work completed successfully",duration:a}),s.info(`${this.workType} completed successfully with enhanced tracking`,{assignmentId:e.assignmentId,workItemId:e.workItemId,duration:a,retryCount:this.retryCount})}catch(a){throw await this.handleWorkError(e,a,"execution"),a}finally{this.currentAssignment=void 0,this.startTime=void 0,this.retryCount=0}}async updateProgress(e,t){let a={assignmentId:e,...t};s.debug(`Progress update: ${t.stage}`,{assignmentId:e,progress:t.progressPercentage,step:t.currentStep}),this.emit("workProgress",a);try{await this.sendProgressUpdate(e,t)}catch(i){s.warn("Failed to send progress update to backend",{assignmentId:e,error:i instanceof Error?i.message:String(i)})}}async markWorkComplete(e){try{let t={id:e,summary:`Work completed successfully by AI agent at ${new Date().toISOString()}`,artifacts:[]};s.info("Marking work as complete in backend",{assignmentId:e,variables:t});let a=this.getOrganizationGraphQLClient();if(!a)throw new Error("Organization GraphQL client not available");let i=await a.completeAiWork(t);s.info("Work successfully marked as complete in backend",{assignmentId:e,status:i.completeAIWork?.status,completedAt:i.completeAIWork?.completedAt})}catch(t){throw s.error("Failed to mark work as complete:",{assignmentId:e,error:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0}),t}}async markWorkInProgress(e){try{let t={input:{workId:e,status:"IN_PROGRESS",metadataJson:JSON.stringify({progress:{currentStep:"Processing",percentage:5},startedAt:new Date().toISOString()})}};s.info("Marking work as in progress in backend",{assignmentId:e,variables:t});let a=this.getOrganizationGraphQLClient();if(!a)throw new Error("Organization GraphQL client not available");let i=await a.updateAiWork(t);s.info("Work successfully marked as in progress in backend",{assignmentId:e,status:i.updateAIWork?.status,startedAt:i.updateAIWork?.startedAt})}catch(t){throw s.error("Failed to mark work as in progress:",{assignmentId:e,error:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0}),t}}async markWorkFailed(e,t){try{let a={input:{workId:e,status:"FAILED",metadataJson:JSON.stringify({failedAt:new Date().toISOString(),failureReason:t,reason:t,workType:this.workType})}};s.info("Marking work as failed in backend",{assignmentId:e,reason:t});let i=this.getOrganizationGraphQLClient();if(!i)throw s.error("CRITICAL: Cannot mark work as failed - no GraphQL client available!",{assignmentId:e,reason:t,hasOrgClient:!!this.orgGraphQLClient,assignmentDetails:{orgId:this.currentAssignment?.organizationId,hasOrgUrl:!!this.currentAssignment?.organizationApiUrl,hasOrgKey:!!this.currentAssignment?.organizationApiKey}}),new Error("Organization GraphQL client not available - cannot mark work as failed");let n=await i.updateAiWork(a);s.info("Work successfully marked as failed in backend",{assignmentId:e,status:n.updateAIWork?.status,failureReason:t})}catch(a){s.error("CRITICAL: Failed to mark work as failed in backend!",{assignmentId:e,reason:t,error:a instanceof Error?a.message:String(a),stack:a instanceof Error?a.stack:void 0})}}async sendProgressUpdate(e,t){try{let a={input:{workId:e,metadataJson:JSON.stringify({progress:{currentStep:t.currentStep,percentage:t.progressPercentage,stage:t.stage,updatedAt:t.updatedAt.toISOString(),estimatedCompletion:t.estimatedCompletion?.toISOString()},metadata:t.metadata})}},i=this.getOrganizationGraphQLClient();if(!i){s.debug("Organization GraphQL client not available for progress update");return}await i.updateAiWork(a)}catch(a){s.debug("Failed to send progress update to backend",{assignmentId:e,error:a instanceof Error?a.message:String(a)})}}async logErrorToBackend(e,t,a){try{let i=this.mapToGraphQLErrorType(t,a),n=this.mapToGraphQLSeverity(t),o=this.mapToGraphQLCategory(t),c=this.isRetryable(t,this.categorizeError(t,a)),d={input:{workItemId:e,assignmentId:e,workType:this.workType,workerId:this.currentAssignment?.workerId||"unknown",errorType:i,message:t.message,stack:t.stack,stage:a,category:o,severity:n,retryable:c,tags:this.generateErrorTags(t,this.categorizeError(t,a),a),contextJson:JSON.stringify({errorName:t.name,workerId:this.currentAssignment?.workerId,retryCount:this.retryCount,timestamp:new Date().toISOString()}),resolved:!1}};if(s.debug("Logging error to backend",{assignmentId:e,stage:a}),!this.getOrganizationGraphQLClient()){s.warn("Organization GraphQL client not available for error logging",{assignmentId:e});return}s.debug("Error would be logged to backend (method not available)",{assignmentId:e,stage:a,errorType:d.input.errorType})}catch(i){s.warn("Failed to log error to backend",{assignmentId:e,originalError:t.message,logError:i instanceof Error?i.message:String(i)})}}async simulateWork(e,t){for(let a of t)await new Promise(i=>setTimeout(i,1e3)),await this.updateProgress(e.assignmentId,{stage:a.name,progressPercentage:a.progress,currentStep:a.name,message:`${this.workType}: ${a.name}`,updatedAt:new Date})}async executeWorkWithErrorHandling(e){s.info("\u{1F525} BASE_WORK_HANDLER: executeWorkWithErrorHandling starting",{assignmentId:e.assignmentId,workType:this.workType});try{s.info("\u{1F525} BASE_WORK_HANDLER: About to call executeWork() (subclass implementation)",{assignmentId:e.assignmentId,workType:this.workType}),await this.executeWork(e),s.info("\u{1F525} BASE_WORK_HANDLER: executeWork() completed successfully",{assignmentId:e.assignmentId,workType:this.workType})}catch(t){s.error("\u{1F525} BASE_WORK_HANDLER: executeWork() threw an error",{assignmentId:e.assignmentId,workType:this.workType,error:t instanceof Error?t.message:String(t),errorName:t instanceof Error?t.name:"Unknown",stack:t instanceof Error?t.stack:void 0});let a=this.enhanceError(t,e,"executeWork");throw await this.logWorkItemError(a,e,"executeWork"),s.error("\u{1F525} BASE_WORK_HANDLER: Re-throwing enhanced error",{assignmentId:e.assignmentId,enhancedErrorMessage:a.message}),a}}async validateWorkAssignment(e){let t=[],a=[];try{e.assignmentId||t.push({field:"assignmentId",message:"Assignment ID is required",code:"MISSING_ASSIGNMENT_ID",severity:"error"}),e.workItemId||t.push({field:"workItemId",message:"Work item ID is required",code:"MISSING_WORK_ITEM_ID",severity:"error"}),e.workItemType||t.push({field:"workItemType",message:"Work item type is required",code:"MISSING_WORK_TYPE",severity:"error"}),e.workItemType&&!this.isWorkTypeSupported(e.workItemType)&&t.push({field:"workItemType",message:`Work type ${e.workItemType} not supported by ${this.workType} handler`,code:"WORK_TYPE_MISMATCH",severity:"error"}),e.deadline&&e.deadline<new Date&&a.push({field:"deadline",message:"Assignment deadline has already passed",code:"DEADLINE_PASSED",impact:"medium"});let i=await this.customValidation(e);t.push(...i.errors),a.push(...i.warnings)}catch(i){t.push({field:"validation",message:"Validation process failed: "+(i instanceof Error?i.message:String(i)),code:"VALIDATION_ERROR",severity:"error"})}return{valid:t.length===0,errors:t,warnings:a}}async customValidation(e){return{errors:[],warnings:[]}}isWorkTypeSupported(e){return!0}async handleValidationErrors(e,t){let a=`Validation failed: ${t.errors.map(n=>n.message).join(", ")}`,i=new Error(a);throw i.name="ValidationError",await this.handleWorkError(e,i,"validation"),i}async handleUsageLimitError(e,t,a){try{let i=`Agent paused: Claude AI usage limit reached. Will resume at ${t.resetDate.toISOString()}`;s.warn("Claude usage limit reached - pausing agent",{assignmentId:e.assignmentId,workItemId:e.workItemId,resetTimestamp:t.resetTimestamp,resetDate:t.resetDate.toISOString(),stage:a}),await this.updateProgress(e.assignmentId,{stage:"Paused - Usage Limit",progressPercentage:0,currentStep:"Agent Paused",message:i,updatedAt:new Date}),await this.releaseWorkItemForUsageLimit(e.assignmentId,i),xe.getInstance().pauseForUsageLimit(t.resetTimestamp,t.message);let o=this.startTime?Date.now()-this.startTime.getTime():0;s.info("Work paused for usage limit",{assignmentId:e.assignmentId,reason:"usage_limit",resetTimestamp:t.resetTimestamp,resetDate:t.resetDate.toISOString(),duration:o,retryCount:this.retryCount}),this.emit("workPausedForUsageLimit",{assignmentId:e.assignmentId,workType:this.workType,resetTimestamp:t.resetTimestamp,resetDate:t.resetDate})}catch(i){s.error("Failed to handle usage limit error",{assignmentId:e.assignmentId,originalError:t.message,handlingError:i instanceof Error?i.message:String(i)}),await this.markWorkFailed(e.assignmentId,`Usage limit error handling failed: ${t.message}`)}}async releaseWorkItemForUsageLimit(e,t){try{let a={input:{workId:e,status:"PENDING",metadataJson:JSON.stringify({pausedForUsageLimit:!0,pausedAt:new Date().toISOString(),pauseReason:t,reason:t})}},i=this.getOrganizationGraphQLClient();if(!i)throw new Error("Organization GraphQL client not available");await i.updateAiWork(a),s.info("Work item released back to queue due to usage limit",{assignmentId:e,reason:t})}catch(a){throw s.error("Failed to release work item for usage limit",{assignmentId:e,error:a instanceof Error?a.message:String(a)}),a}}async handleWorkError(e,t,a){s.error("\u{1F525} HANDLE_WORK_ERROR: Starting error handling",{assignmentId:e.assignmentId,workType:this.workType,error:t.message,stage:a,hasOrgClient:!!this.orgGraphQLClient,orgDetails:{orgId:e.organizationId,hasOrgUrl:!!e.organizationApiUrl,hasOrgKey:!!e.organizationApiKey}});try{if(t instanceof Be){s.info("\u{1F525} HANDLE_WORK_ERROR: Handling usage limit error"),await this.handleUsageLimitError(e,t,a);return}s.info("\u{1F525} HANDLE_WORK_ERROR: Enhancing error");let i=this.enhanceError(t,e,a);s.info("\u{1F525} HANDLE_WORK_ERROR: Logging work item error"),await this.logWorkItemError(i,e,a),s.info("\u{1F525} HANDLE_WORK_ERROR: Updating progress to failed"),await this.updateProgress(e.assignmentId,{stage:"Failed",progressPercentage:0,currentStep:"Error",message:`${this.workType}: ${t.message}`,updatedAt:new Date}),s.info("\u{1F525} HANDLE_WORK_ERROR: Marking work as failed in backend"),await this.markWorkFailed(e.assignmentId,t.message),s.info("\u{1F525} HANDLE_WORK_ERROR: Logging local failure");let n=this.startTime?Date.now()-this.startTime.getTime():0;s.error("Work item failed",{assignmentId:e.assignmentId,error:i,duration:n,retryCount:this.retryCount}),s.info("\u{1F525} HANDLE_WORK_ERROR: Emitting workFailed event"),this.emit("workFailed",{assignment:e,workType:this.workType,error:i,stage:a}),s.error(`\u{1F525} HANDLE_WORK_ERROR: ${this.workType} failed with enhanced error tracking:`,{assignmentId:e.assignmentId,workItemId:e.workItemId,errorType:i.errorType,stage:a,retryable:i.metadata.retryable,severity:i.metadata.severity}),s.info("\u{1F525} HANDLE_WORK_ERROR: Error handling completed successfully")}catch(i){s.error("\u{1F525} HANDLE_WORK_ERROR: CRITICAL - Failed to handle work error!",{assignmentId:e.assignmentId,originalError:t?.message||String(t),handlingError:i instanceof Error?i.message:String(i),handlingErrorStack:i instanceof Error?i.stack:void 0})}}enhanceError(e,t,a){let i=this.categorizeError(e,a),n=this.determineSeverity(e,i),o=this.isRetryable(e,i);return{id:(0,$a.v4)(),workItemId:t.workItemId,assignmentId:t.assignmentId,workType:this.workType,errorType:i,message:e.message,stack:e.stack,stage:a,context:{projectId:t.workData?.projectId,workerId:t.workerId,attempt:this.retryCount+1,timestamp:new Date,systemState:{memoryUsage:process.memoryUsage(),uptime:process.uptime()},requestData:t.workData},metadata:{retryable:o,severity:n,category:this.determineCategory(i),tags:this.generateErrorTags(e,i,a)},resolved:!1}}categorizeError(e,t){let a=(e?.message||"").toLowerCase(),i=(e?.name||"").toLowerCase();if(a.includes("econnrefused")||a.includes("enotfound")||a.includes("timeout")||a.includes("network"))return"network_error";if(a.includes("unauthorized")||a.includes("authentication")||a.includes("access denied")||i.includes("auth"))return"authentication_error";if(a.includes("claude")||a.includes("anthropic")||a.includes("token limit")||a.includes("api key"))return"claude_api_error";if(i==="validationerror"||a.includes("validation")||a.includes("required")||a.includes("invalid"))return"validation_failed";if(a.includes("project not found")||a.includes("missing project"))return"missing_project";if(a.includes("timeout")||a.includes("timed out"))return"timeout_error";switch(t){case"validation":return"validation_failed";case"analysis":return"analysis_failed";case"generation":return"plan_generation_failed";case"save":return"save_failed";default:return"internal_error"}}determineSeverity(e,t){switch(t){case"authentication_error":case"handler_not_found":case"work_type_mismatch":return"critical";case"missing_project":case"validation_failed":case"claude_api_error":return"high";case"network_error":case"timeout_error":case"analysis_failed":return"medium";default:return"low"}}isRetryable(e,t){switch(t){case"network_error":case"timeout_error":case"connection_error":return!0;case"authentication_error":case"validation_failed":case"missing_project":case"work_type_mismatch":return!1;case"claude_api_error":return e.message.includes("rate limit")||e.message.includes("timeout");default:return!1}}determineCategory(e){switch(e){case"network_error":case"timeout_error":case"connection_error":return"transient";case"authentication_error":case"claude_api_error":case"work_type_mismatch":return"configuration";case"validation_failed":case"missing_project":return"permanent";default:return"system"}}generateErrorTags(e,t,a){let i=[this.workType,a,t];return e.message.includes("timeout")&&i.push("timeout"),e.message.includes("network")&&i.push("network"),e.message.includes("authentication")&&i.push("auth"),e.message.includes("claude")&&i.push("claude"),e.message.includes("api")&&i.push("api"),i}async logWorkItemError(e,t,a){try{await $e().logError(e,this.orgHttpClient)}catch(i){s.warn("Failed to log work item error",{originalError:e.message,logError:i instanceof Error?i.message:String(i)})}}getOrganizationGraphQLClient(){return this.orgGraphQLClient}mapToGraphQLErrorType(e,t){return"INTERNAL_ERROR"}mapToGraphQLSeverity(e){switch(this.determineSeverity(e,this.categorizeError(e,"execution"))){case"critical":return"CRITICAL";case"high":return"HIGH";case"medium":return"MEDIUM";case"low":return"LOW";default:return"MEDIUM"}}mapToGraphQLCategory(e){switch(this.determineCategory(this.categorizeError(e,"execution"))){case"transient":return"TRANSIENT";case"permanent":return"PERMANENT";case"configuration":return"CONFIGURATION";case"system":return"SYSTEM";default:return"SYSTEM"}}}});var Mt,qa=M(()=>{"use strict";We();j();Ge();Mt=class extends ie{constructor(e){super("project-review");this.tcpService=e}async executeWork(e){s.info("\u{1F525} PROJECT_REVIEW_HANDLER: Starting project review execution",{assignmentId:e.assignmentId,workItemId:e.workItemId,workItemType:e.workItemType,organizationId:e.organizationId,organizationApiUrl:e.organizationApiUrl,hasWorkData:!!e.workData,workDataKeys:e.workData?Object.keys(e.workData):[],fullWorkData:JSON.stringify(e.workData,null,2)});try{await this.updateProgress(e.assignmentId,{stage:"Fetching Project Data",progressPercentage:10,currentStep:"Loading project information",message:"Retrieving project details from backend",updatedAt:new Date});let t;if(e.workData?.projectId)t=e.workData.projectId;else if(e.workData?.project?.id)t=e.workData.project.id;else if(e.workData?.reviewId){s.warn("Project ID not directly available, will fetch from review",{assignmentId:e.assignmentId,reviewId:e.workData.reviewId,workItemId:e.workItemId});try{t=(await this.fetchReviewForProjectId(e.workData.reviewId)).project?.id}catch(u){s.error("Failed to fetch project ID from review",{assignmentId:e.assignmentId,reviewId:e.workData.reviewId,error:u instanceof Error?u.message:String(u)})}}if(!t){let u=`Cannot determine project ID from work assignment. WorkData: ${JSON.stringify(e.workData,null,2)}`;throw s.error(u,{assignmentId:e.assignmentId,workItemId:e.workItemId,workDataKeys:e.workData?Object.keys(e.workData):[]}),new Error(u)}s.info("About to fetch project data",{assignmentId:e.assignmentId,workItemId:e.workItemId,extractedProjectId:t,workData:e.workData,hasWorkData:!!e.workData,isValidProjectId:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)});let a=await this.fetchProjectData(t);await this.updateProgress(e.assignmentId,{stage:"Setting Up Analysis",progressPercentage:20,currentStep:"Preparing MCP server",message:"Setting up AI analysis infrastructure",updatedAt:new Date}),this.setupTCPListener(),s.info("Starting Claude analysis",{assignmentId:e.assignmentId,currentProgress:e.workData?.metadata?.progress?.percentage||0,attemptCount:e.workData?.metadata?.attemptCount||0}),await this.updateProgress(e.assignmentId,{stage:"AI Analysis",progressPercentage:40,currentStep:"Running Claude analysis",message:"Claude is analyzing the project structure and requirements",updatedAt:new Date});let i=this.generateAIReview(a,e),n=parseInt(process.env.PROJECT_REVIEW_TIMEOUT_MS||"1800000"),o=new Promise((u,h)=>setTimeout(()=>h(new Error(`Analysis timeout after ${n/6e4} minutes`)),n)),c=Date.now(),d=setInterval(async()=>{try{let u=Math.floor((Date.now()-c)/6e4);await this.updateProgress(e.assignmentId,{stage:"AI Analysis",progressPercentage:40,currentStep:"Claude analysis in progress",message:`Claude is analyzing the project (${u} minute${u!==1?"s":""} elapsed)`,updatedAt:new Date}),s.debug("Sent heartbeat update during Claude analysis",{assignmentId:e.assignmentId,elapsedMinutes:u})}catch(u){s.warn("Failed to send heartbeat update during Claude analysis",{assignmentId:e.assignmentId,error:u instanceof Error?u.message:String(u)})}},12e4);try{await Promise.race([i,o])}finally{clearInterval(d)}if(!this.analysisResult)throw new Error("No analysis result received from Claude");await this.updateProgress(e.assignmentId,{stage:"Saving Results",progressPercentage:80,currentStep:"Storing analysis",message:"Saving review results to database",updatedAt:new Date});let p=e.workData?.reviewId||e.workData?.metadata?.reviewId;if(s.info("\u{1F50D} DEBUG: Checking for reviewId in work data",{assignmentId:e.assignmentId,projectId:t,hasWorkData:!!e.workData,workDataKeys:e.workData?Object.keys(e.workData):[],reviewIdDirect:e.workData?.reviewId,reviewIdNested:e.workData?.metadata?.reviewId,workDataSample:e.workData?JSON.stringify(e.workData).substring(0,500):"null"}),!p&&t){s.warn("ReviewId not found in work data, attempting to find from project",{assignmentId:e.assignmentId,projectId:t,organizationId:e.organizationId});try{p=await this.findMostRecentProjectReviewId(t),p&&s.info("Found reviewId from project reviews",{assignmentId:e.assignmentId,projectId:t,reviewId:p})}catch(u){s.error("Failed to find reviewId from project",{assignmentId:e.assignmentId,projectId:t,error:u instanceof Error?u.message:String(u)})}}if(!p)throw new Error("No reviewId found in work assignment data and unable to find from project");await this.saveReviewResults(a.id,this.analysisResult,p),await this.updateProgress(e.assignmentId,{stage:"Review Complete",progressPercentage:100,currentStep:"Finished",message:"Project review completed successfully",updatedAt:new Date}),s.info("Project review execution completed",{assignmentId:e.assignmentId,projectId:a.id,overallScore:this.analysisResult?.scores?.overall?.score})}catch(t){throw s.error("Project review failed",{assignmentId:e.assignmentId,error:t instanceof Error?t.message:String(t)}),t}finally{this.cleanupTCPListener()}}async fetchProjectData(e){s.debug("Fetching project data",{projectId:e});let t=this.getOrganizationGraphQLClient();if(!t)throw new Error("Organization GraphQL client not available");let a=await t.getProjectForReview({id:e});if(!a.project)throw new Error(`Project not found: ${e}`);return a.project}async fetchPreviousReview(e){s.debug("Fetching previous review for reprompt context",{reviewId:e});let t=this.getOrganizationGraphQLClient();if(!t)throw new Error("Organization GraphQL client not available");let a=await t.getPreviousReview({id:e});if(!a.projectReview)throw new Error(`Previous review not found: ${e}`);return a.projectReview}async fetchReviewForProjectId(e){s.debug("Fetching review to extract project ID",{reviewId:e});let t=this.getOrganizationGraphQLClient();if(!t)throw new Error("Organization GraphQL client not available");let a=await t.getReviewForProjectId({id:e});if(!a.projectReview)throw new Error(`Review not found for project ID extraction: ${e}`);return a.projectReview}setupTCPListener(){this.tcpListener=e=>{e.type==="analysis_complete"&&(s.info("Received analysis from MCP",{projectId:e.projectId,overallScore:e.data?.scores?.overall?.score,dataKeys:Object.keys(e.data||{}),fullData:JSON.stringify(e.data,null,2).substring(0,500)}),this.analysisResult=e.data)},this.tcpService.on("analysis_complete",this.tcpListener),s.debug("TCP listener set up for analysis results")}cleanupTCPListener(){this.tcpListener&&(this.tcpService.off("analysis_complete",this.tcpListener),this.tcpListener=void 0,s.debug("TCP listener cleaned up"))}async generateAIReview(e,t){let a=new ae("claude"),i=t.workData?.isReprompt||!1,n=t.workData?.repromptContext||"",o=t.workData?.focusAreas||[],c=t.workData?.previousReviewId,d="";if(i&&c)try{let u=await this.fetchPreviousReview(c),h=u.reviewData||null;d=`
141
+
142
+ PREVIOUS REVIEW CONTEXT:
143
+ This is a reprompt of a previous review. Here is the previous analysis for reference:
144
+
145
+ Previous Overall Score: ${u.overallScore}/100
146
+ Previous Strengths: ${h?.analysis?.strengths?.join(", ")||"Not available"}
147
+ Previous Weaknesses: ${h?.analysis?.weaknesses?.join(", ")||"Not available"}
148
+ Previous Risks: ${h?.analysis?.risks?.join(", ")||"Not available"}
149
+
150
+ User's Reprompt Context: ${n}
151
+ Specific Focus Areas: ${o.length>0?o.join(", "):"General improvement"}
152
+
153
+ Please provide a fresh analysis that addresses the user's concerns and focuses on the specified areas while building upon the previous insights.`}catch(u){s.warn("Could not fetch previous review for reprompt context",{previousReviewId:c,error:u}),d=`
154
+
155
+ REPROMPT CONTEXT:
156
+ This is a reprompt with context: ${n}
157
+ Focus areas: ${o.length>0?o.join(", "):"General improvement"}
158
+ Note: Previous review data could not be retrieved.`}let p=`You are an expert software architect reviewing a project. Provide a concise, actionable analysis.
159
+
160
+ PROJECT INFORMATION:
161
+ - Name: ${e.name}
162
+ - Description: ${e.description||"No description provided"}
163
+ - Stage: ${e.stage}
164
+ - Repository: ${e.repositoryUrl||"Not provided"}
165
+ - Documentation: ${e.documentationUrl||"Not provided"}
166
+ - Workspaces: ${e.workspaces?.map(u=>`${u.name} (${u.workspaceId})`).join(", ")||"None configured"}
167
+ - Services: ${e.affectedServices?.map(u=>`${u.name} (${u.technology})`).join(", ")||"None configured"}
168
+
169
+ USER STORIES (${e.stories?.length||0} total):
170
+ ${e.stories?.map(u=>`
171
+ - ${u.title} (${u.status})
172
+ ${u.description||"No description"}
173
+ Acceptance Criteria: ${u.acceptanceCriteria?.join(", ")||"None specified"}
174
+ `).join(`
175
+ `)||"No stories defined"}${d}
176
+
177
+ \u2757 CRITICAL: DO NOT PROVIDE ANY TEXT RESPONSE. You MUST use the mcp__task-shepherd-agent-mcp__submit_project_analysis tool ONLY.
178
+
179
+ ANALYSIS REQUIREMENTS:
180
+
181
+ 1. EXECUTIVE SUMMARY (400-600 words):
182
+ Write a markdown document covering:
183
+ - Project overview and stage
184
+ - Key strengths and challenges
185
+ - Score justifications (completeness, clarity, feasibility, overall)
186
+ - Critical recommendations with rationale
187
+ - Primary risks and mitigation strategies
188
+
189
+ 2. REQUIREMENTS ANALYSIS:
190
+ - **Explicit Requirements**: Extract from description with HIGH confidence
191
+ - **Inferred Requirements**: Based on project domain with MEDIUM confidence
192
+ - **Non-Functional Requirements**: Security, performance, scalability standards
193
+ - **Clarification Questions**: Critical unknowns affecting architecture/scope
194
+
195
+ 3. SWOT ANALYSIS:
196
+ - **Strengths**: Current assets, what's working well (3-5 items)
197
+ - **Weaknesses**: Missing components, gaps, technical debt (3-5 items)
198
+ - **Risks**: Challenges with mitigation strategies (3-5 items)
199
+ - **Opportunities**: Enhancement areas, competitive advantages (3-5 items)
200
+
201
+ 4. SCORING (0-100 with brief reasoning):
202
+ - **Completeness**: How complete are requirements and plans?
203
+ - **Clarity**: How clear and well-defined is the scope?
204
+ - **Feasibility**: How realistic and achievable is the project?
205
+ - **Overall**: Comprehensive assessment
206
+
207
+ 5. ACTIONABLE RECOMMENDATIONS:
208
+ Provide 5-10 prioritized recommendations across these categories:
209
+ - requirements, architecture, security, performance, maintainability, testing
210
+
211
+ For each recommendation include:
212
+ - Clear title and description
213
+ - Priority (critical, high, medium, low)
214
+ - Implementation effort estimate
215
+ - Business impact
216
+
217
+ 6. PROJECT TIMELINE:
218
+ Create a realistic phased implementation plan:
219
+
220
+ **Phase 1: Requirements & Architecture** (2-3 weeks)
221
+ - Key deliverables and dependencies
222
+
223
+ **Phase 2: Core Foundation** (4-6 weeks)
224
+ - Database, authentication, basic API/UI
225
+
226
+ **Phase 3: Feature Development** (6-10 weeks)
227
+ - Primary business logic and workflows
228
+
229
+ **Phase 4: Performance & Quality** (3-5 weeks)
230
+ - Testing, optimization, security
231
+
232
+ **Phase 5: Launch & Refinement** (2-3 weeks)
233
+ - Deployment and stabilization
234
+
235
+ For each phase specify: duration, deliverables, dependencies, key risks
236
+
237
+ \u26A0\uFE0F MANDATORY: Use mcp__task-shepherd-agent-mcp__submit_project_analysis tool with:
238
+ - project_id: "${e.id}"
239
+ - analysis_type: "project_review"
240
+ - Include ALL required fields: executive_summary, analysis, scores, recommendations, timeline, suggested_product_requirements, metadata
241
+
242
+ \u2757 DO NOT WRITE ANY TEXT RESPONSE - ONLY USE THE TOOL`;s.info("Executing Claude with MCP for project review",{projectId:e.id,promptLength:p.length});try{let u=this.getWorkspacePath(e);s.debug("Using workspace path for Claude execution",{workspacePath:u,projectId:e.id,workspaceCount:e.workspaces?.length||0,isReprompt:i,repromptContext:n?n.substring(0,100)+"...":"None"});let h=await a.executeCommand(p,u);s.debug("Claude execution completed",{resultLength:h.length,resultPreview:h.substring(0,200),isReprompt:i}),await new Promise(f=>setTimeout(f,2e3))}catch(u){throw s.error("Claude execution failed",{error:u instanceof Error?u.message:String(u),isReprompt:i,repromptContext:n?"Has context":"No context"}),u}}getWorkspacePath(e){if(e.workspaceConfig?.workspace?.paths?.root)return s.debug("Using workspace config root path",{rootPath:e.workspaceConfig.workspace.paths.root}),e.workspaceConfig.workspace.paths.root;if(e.workspaces&&e.workspaces.length>0){let a=e.workspaces[0];if(a.path)return s.debug("Using first workspace path",{workspaceId:a.workspaceId,workspaceName:a.name,path:a.path}),a.path}if(e.name==="Mobile App Development"||e.repositoryUrl?.includes("task-shepherd")){let a="/Users/scotto/Documents/javascript/task-shepherd";return s.warn("Using hardcoded Task Shepherd workspace for testing",{projectId:e.id,projectName:e.name,workspacePath:a}),a}let t=`Project ${e.id} (${e.name}) has no workspace configuration. Cannot determine workspace for Claude execution.`;throw s.error("Missing workspace configuration",{projectId:e.id,projectName:e.name,hasWorkspaceConfig:!!e.workspaceConfig,hasWorkspaces:!!e.workspaces?.length,workspaceCount:e.workspaces?.length||0,workspaceConfig:e.workspaceConfig}),new Error(t)}async saveReviewResults(e,t,a){let i={reviewId:a,reviewDataJson:JSON.stringify({executiveSummary:t.executive_summary||"",analysis:{strengths:t.analysis.strengths.map(c=>c.title),weaknesses:t.analysis.weaknesses.map(c=>c.title),risks:t.analysis.risks.map(c=>c.title),opportunities:t.analysis.opportunities.map(c=>c.title)},scores:{completeness:{score:t.scores.completeness.score,reasoning:t.scores.completeness.reasoning},clarity:{score:t.scores.clarity.score,reasoning:t.scores.clarity.reasoning},feasibility:{score:t.scores.feasibility.score,reasoning:t.scores.feasibility.reasoning},overall:{score:t.scores.overall.score,reasoning:t.scores.overall.reasoning}},timeline:t.timeline||null,suggestedProductRequirements:{explicitRequirements:t.suggested_product_requirements?.explicit_requirements||[],inferredFunctionalRequirements:t.suggested_product_requirements?.inferred_functional_requirements||[],suggestedNonFunctionalRequirements:t.suggested_product_requirements?.suggested_non_functional_requirements||[],requirementsClarificationQuestions:t.suggested_product_requirements?.requirements_clarification_questions||[]},featureGapAnalysis:{missingCoreFeatures:(t.recommendations||[]).filter(c=>c.category==="feature_gap"||c.title?.toLowerCase().includes("missing feature")).map(c=>({feature:c.title,priority:c.priority||"medium",rationale:c.description,suggestedApproach:c.implementation_guide||c.description,estimatedEffort:c.estimated_effort||"TBD"})),missingNonFunctionalRequirements:(t.suggested_product_requirements?.suggested_non_functional_requirements||[]).map(c=>({requirement:c.requirement,category:c.category||"general",impact:`Industry standard: ${c.industry_standard?"Yes":"No"}. Customization needed: ${c.customization_needed?"Yes":"No"}`,recommendation:c.requirement}))},metadata:{analysisDuration:t.metadata.analysis_duration_seconds*1e3,modelUsed:t.metadata.claude_model,confidence:t.metadata.confidence_level}}),suggestionsJson:JSON.stringify({requirements:t.recommendations.filter(c=>c.category==="requirements").map(c=>({id:c.id,type:"add",suggested:c.title,rationale:c.description,priority:c.priority})),architecture:t.recommendations.filter(c=>c.category==="architecture").map(c=>({component:c.title,suggestion:c.description,impact:c.business_impact||"Medium impact"})),risks:t.analysis.risks.map(c=>({risk:c.title,mitigation:c.mitigation_strategy||c.description,severity:c.impact}))}),overallScore:t.scores.overall.score},n=this.getOrganizationGraphQLClient();if(!n)throw new Error("Organization GraphQL client not available");let o=await n.completeAIReview({input:i});s.info("Project review completed successfully",{reviewId:o.completeAIReview.id,projectId:e,overallScore:o.completeAIReview.overallScore})}async findMostRecentProjectReviewId(e){let t=`
243
+ query GetProjectReviews($projectId: String!) {
244
+ projectReviews(projectId: $projectId, limit: 1) {
245
+ id
246
+ createdAt
247
+ status
248
+ }
249
+ }
250
+ `;try{let a=this.getOrganizationGraphQLClient();if(!a)throw new Error("Organization GraphQL client not available");let n=(await a.request(t,{projectId:e})).projectReviews;return n&&n.length>0?n.sort((c,d)=>new Date(d.createdAt).getTime()-new Date(c.createdAt).getTime())[0].id:null}catch(a){return s.error("Failed to query project reviews",{projectId:e,error:a instanceof Error?a.message:String(a)}),null}}}});var Nt,Ba=M(()=>{"use strict";We();j();Nt=class extends ie{constructor(){super("code-review")}async executeWork(r){s.info("Starting code review execution",{assignmentId:r.assignmentId,workItemId:r.workItemId});let e=[{name:"Fetching Code Changes",progress:15},{name:"Analyzing Code Quality",progress:35},{name:"Checking Security Issues",progress:55},{name:"Evaluating Performance",progress:75},{name:"Generating Feedback",progress:90},{name:"Finalizing Review",progress:100}];await this.simulateWork(r,e),s.info("Code review execution completed",{assignmentId:r.assignmentId})}}});var xt,Wt,Ga=M(()=>{"use strict";xt=require("@task-shepherd/shared");j();Ge();We();console.log("DevelopmentPlanningHandler: AIWorkType imported:",xt.AIWorkType);Wt=class extends ie{constructor(e){super("development-planning");this.tcpService=e}isWorkTypeSupported(e){try{let t=xt.AIWorkType||{};s.info("Checking work type support",{workType:e,AIWorkType_available:!!xt.AIWorkType,enumKeys:Object.keys(t),IMPLEMENTATION_PLAN_value:t.IMPLEMENTATION_PLAN||"undefined",PROJECT_REVIEW_value:t.PROJECT_REVIEW||"undefined",service:"agent"});let a=e.toLowerCase().replace(/-/g,"_"),i=a==="implementation_plan"||a==="development_planning"||a==="development_planner"||a==="project_review";return s.info("Work type support result",{workType:e,normalizedWorkType:a,isSupported:i,service:"agent"}),i}catch(t){s.error("Error in isWorkTypeSupported",{workType:e,error:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0,service:"agent"});let a=e.toLowerCase().replace(/-/g,"_");return a==="implementation_plan"||a==="development_planning"||a==="development_planner"||a==="project_review"}}async executeWork(e){let t=this.isRepromptRequest(e);s.info("Starting development planning execution",{assignmentId:e.assignmentId,workItemId:e.workItemId,workData:e.workData,isReprompt:t,originalPlanId:e.workData?.metadata?.originalPlanId||null});let a;try{a=await this.extractProjectId(e)}catch(i){throw s.error("Failed to extract project ID from work assignment",{assignmentId:e.assignmentId,workItemId:e.workItemId,error:i instanceof Error?i.message:String(i),workData:e.workData}),await this.updateProgress(e.assignmentId,{stage:"Failed",progressPercentage:0,currentStep:"Error extracting project ID",message:`Failed to extract project ID: ${i instanceof Error?i.message:String(i)}`,updatedAt:new Date}),i}t?await this.executeRepromptWork(e,a):await this.executeRegularPlanningWork(e,a)}async executeRegularPlanningWork(e,t){try{await this.updateProgress(e.assignmentId,{stage:"Fetching Project Data",progressPercentage:10,currentStep:"Loading project information",message:"Retrieving project details from backend",updatedAt:new Date});let a=await this.fetchProjectData(t);await this.updateProgress(e.assignmentId,{stage:"Setting Up Analysis",progressPercentage:20,currentStep:"Preparing MCP server",message:"Setting up AI analysis infrastructure",updatedAt:new Date}),this.setupTCPListener(),await this.updateProgress(e.assignmentId,{stage:"AI Analysis",progressPercentage:30,currentStep:"Performing comprehensive project analysis",message:"Claude is analyzing the project comprehensively (requirements, architecture, planning, estimates)",updatedAt:new Date});let i=this.performComprehensiveAnalysis(a,e.assignmentId),n=new Promise((d,p)=>setTimeout(()=>p(new Error("Analysis timeout after 30 minutes")),18e5));await Promise.race([i,n]);let o=await this.waitForAnalysisResult(17e5);await this.updateProgress(e.assignmentId,{stage:"Generating Development Plan",progressPercentage:80,currentStep:"Creating structured development plan",message:"Converting AI analysis into structured development plan",updatedAt:new Date});let c=await this.transformAnalysisToDevelopmentPlan(o,a);await this.updateProgress(e.assignmentId,{stage:"Saving Plan",progressPercentage:95,currentStep:"Saving development plan to backend",message:"Storing implementation plan in the database",updatedAt:new Date}),await this.savePlan(t,c),s.info("Development planning execution completed successfully (MCP-based)",{assignmentId:e.assignmentId,projectId:t,planPhasesCount:c.planData.phases.length,estimatedDays:c.estimates.totalDays,analysisType:o.analysis_type,overallScore:o.scores?.overall?.score})}catch(a){s.error("Development planning execution failed",{assignmentId:e.assignmentId,projectId:t||"unknown",error:a instanceof Error?a.message:String(a),stack:a instanceof Error?a.stack:void 0});let i=this.buildErrorContext(e,t||"unknown",a);throw await this.updateProgress(e.assignmentId,{stage:"Failed",progressPercentage:0,currentStep:"Error in development planning",message:`Development planning failed: ${i.userFriendlyMessage}`,updatedAt:new Date}),new Error(i.detailedMessage)}finally{this.cleanupTCPListener()}}async executeRepromptWork(e,t){let a=e.workData?.metadata,i=a?.originalPlanId,n=a?.repromptType,o=a?.changeRequest;try{await this.updateProgress(e.assignmentId,{stage:"Loading Original Plan",progressPercentage:10,currentStep:"Loading existing development plan",message:`Loading original plan ${i} for reprompting`,updatedAt:new Date});let c=await this.fetchExistingPlan(i);await this.updateProgress(e.assignmentId,{stage:"Fetching Project Data",progressPercentage:20,currentStep:"Loading current project information",message:"Retrieving updated project details from backend",updatedAt:new Date});let d=await this.fetchProjectData(t);await this.updateProgress(e.assignmentId,{stage:"Analyzing Reprompt Request",progressPercentage:35,currentStep:"Analyzing requested changes",message:`Processing ${n} reprompt request`,updatedAt:new Date});let p=await this.analyzeRepromptChanges(c,d,n,o,e.assignmentId);await this.updateProgress(e.assignmentId,{stage:"Updating Plan Sections",progressPercentage:60,currentStep:"Applying requested changes",message:"Claude is updating the development plan based on your requests",updatedAt:new Date});let u=await this.generateUpdatedPlan(c,d,p,n,o,e.assignmentId);await this.updateProgress(e.assignmentId,{stage:"Saving Updated Plan",progressPercentage:90,currentStep:"Saving new plan version",message:"Storing updated implementation plan as new version",updatedAt:new Date}),await this.saveRepromptedPlan(t,u,i,a),s.info("Development plan reprompt execution completed successfully",{assignmentId:e.assignmentId,projectId:t,originalPlanId:i,repromptType:n,newVersion:u.version||"unknown"})}catch(c){s.error("Development plan reprompt execution failed",{assignmentId:e.assignmentId,projectId:t||"unknown",originalPlanId:i,error:c instanceof Error?c.message:String(c),stack:c instanceof Error?c.stack:void 0});let d=this.buildErrorContext(e,t||"unknown",c);throw await this.updateProgress(e.assignmentId,{stage:"Failed",progressPercentage:0,currentStep:"Error in development plan reprompt",message:`Development plan reprompt failed: ${d.userFriendlyMessage}`,updatedAt:new Date}),new Error(d.detailedMessage)}}async extractProjectId(e){let t;if(e.workData?.projectId)t=e.workData.projectId;else if(e.workData?.project?.id)t=e.workData.project.id;else if(e.workData?.metadata?.projectId)t=e.workData.metadata.projectId;else if(this.isRepromptRequest(e)&&e.workData?.originalPlanId){s.info("Reprompt request detected, fetching project ID from original plan",{assignmentId:e.assignmentId,originalPlanId:e.workData.originalPlanId});try{t=(await this.fetchExistingPlan(e.workData.originalPlanId)).project.id,s.info("Successfully fetched project ID from original plan",{assignmentId:e.assignmentId,originalPlanId:e.workData.originalPlanId,projectId:t})}catch(a){throw s.error("Failed to fetch project ID from original plan",{assignmentId:e.assignmentId,originalPlanId:e.workData.originalPlanId,error:a instanceof Error?a.message:String(a)}),new Error("projectId is not defined - could not fetch from original plan")}}else if(e.workItemType==="implementation_plan"&&e.workItemId){s.info("Project ID not found in workData, fetching from backend work item",{assignmentId:e.assignmentId,workItemId:e.workItemId});try{t=await this.fetchProjectIdFromWorkItem(e.workItemId),s.info("Successfully fetched project ID from backend",{assignmentId:e.assignmentId,workItemId:e.workItemId,projectId:t})}catch(a){throw s.error("Failed to fetch project ID from backend work item",{assignmentId:e.assignmentId,workItemId:e.workItemId,error:a instanceof Error?a.message:String(a)}),new Error("projectId is not defined - could not fetch from backend")}}if(!t){let a=`Cannot determine project ID from work assignment. WorkData: ${JSON.stringify(e.workData,null,2)}`;throw s.error(a,{assignmentId:e.assignmentId,workItemId:e.workItemId,workDataKeys:e.workData?Object.keys(e.workData):[],workItemType:e.workItemType}),new Error("projectId is not defined")}return t}async fetchProjectIdFromWorkItem(e){let t=`
251
+ query GetWorkItem($search: AIWorkQueueSearchInput) {
252
+ aiWorkQueue(search: $search) {
253
+ id
254
+ project {
255
+ id
256
+ }
257
+ }
258
+ }
259
+ `,a=this.getOrganizationGraphQLClient();if(!a)throw new Error("Organization GraphQL client not available");let n=await a.request(t,{search:{ids:[e]}});if(!n.aiWorkQueue||n.aiWorkQueue.length===0)throw new Error(`Work item not found: ${e}`);let o=n.aiWorkQueue[0];if(!o.project?.id)throw new Error(`Work item ${e} has no associated project`);return o.project.id}async fetchProjectData(e){let t=`
260
+ query GetProject($id: String!) {
261
+ project(id: $id) {
262
+ id
263
+ name
264
+ description
265
+ repositoryUrl
266
+ documentationUrl
267
+ stage
268
+ stories {
269
+ id
270
+ title
271
+ description
272
+ acceptanceCriteria
273
+ status
274
+ }
275
+ workspaces {
276
+ id
277
+ workspaceId
278
+ name
279
+ path
280
+ pattern
281
+ }
282
+ affectedServices {
283
+ id
284
+ serviceId
285
+ name
286
+ technology
287
+ }
288
+ }
289
+ }
290
+ `,a={id:e};try{let i=this.getOrganizationGraphQLClient();if(!i)throw new Error("Organization GraphQL client not available");let n=await i.request(t,a);if(!n.project)throw new Error(`Project not found: ${e}`);return n.project}catch(i){throw s.error("Failed to fetch project data",{projectId:e,error:i instanceof Error?i.message:String(i)}),i}}async performComprehensiveAnalysis(e,t){let a=new ae("claude"),i=`
291
+ You are an expert software architect and project manager performing a comprehensive implementation plan analysis.
292
+
293
+ IMPORTANT: Use the submit_implementation_plan MCP tool to submit your complete implementation plan analysis results. Do NOT output JSON directly to stdout.
294
+
295
+ Project Information:
296
+ - Project ID: ${e.id}
297
+ - Name: ${e.name}
298
+ - Description: ${e.description||"No description provided"}
299
+ - Stage: ${e.stage}
300
+ - Repository: ${e.repositoryUrl||"Not provided"}
301
+ - Documentation: ${e.documentationUrl||"Not provided"}
302
+
303
+ Existing Stories (${e.stories?.length||0}):
304
+ ${e.stories?.map(n=>`
305
+ - ${n.title} (ID: ${n.id})
306
+ Status: ${n.status}
307
+ Description: ${n.description||"No description"}
308
+ Acceptance Criteria: ${n.acceptanceCriteria?.join(", ")||"None specified"}
309
+ `).join(`
310
+ `)||"No stories defined yet"}
311
+
312
+ Available Workspaces (${e.workspaces?.length||0}):
313
+ ${e.workspaces?.map(n=>`
314
+ - ${n.name} (${n.workspaceId})
315
+ Path: ${n.path}
316
+ Pattern: ${n.pattern}
317
+ `).join(`
318
+ `)||"No workspaces configured"}
319
+
320
+ Available Services (${e.affectedServices?.length||0}):
321
+ ${e.affectedServices?.map(n=>`
322
+ - ${n.name} (${n.technology})
323
+ Service ID: ${n.serviceId}
324
+ `).join(`
325
+ `)||"No services identified"}
326
+
327
+ Return a JSON object with the following structure:
328
+
329
+ {
330
+ "project_id": "${e.id}",
331
+ "analysis_type": "implementation_plan",
332
+ "executive_summary": "High-level summary of project state and implementation recommendations",
333
+ "analysis": {
334
+ "strengths": [
335
+ {
336
+ "title": "Strength title",
337
+ "description": "Detailed description",
338
+ "impact": "high|medium|low",
339
+ "evidence": ["supporting evidence"]
340
+ }
341
+ ],
342
+ "weaknesses": [
343
+ {
344
+ "title": "Weakness title",
345
+ "description": "Detailed description",
346
+ "severity": "high|medium|low",
347
+ "affected_areas": ["area1", "area2"],
348
+ "improvement_effort": "minimal|moderate|significant"
349
+ }
350
+ ],
351
+ "risks": [
352
+ {
353
+ "title": "Risk title",
354
+ "description": "Risk description",
355
+ "probability": "high|medium|low",
356
+ "impact": "high|medium|low",
357
+ "mitigation_strategy": "How to mitigate"
358
+ }
359
+ ],
360
+ "opportunities": [
361
+ {
362
+ "title": "Opportunity title",
363
+ "description": "Opportunity description",
364
+ "potential_value": "high|medium|low",
365
+ "implementation_complexity": "simple|moderate|complex"
366
+ }
367
+ ]
368
+ },
369
+ "scores": {
370
+ "completeness": { "score": 0-100, "reasoning": "Explanation" },
371
+ "clarity": { "score": 0-100, "reasoning": "Explanation" },
372
+ "feasibility": { "score": 0-100, "reasoning": "Explanation" },
373
+ "overall": { "score": 0-100, "reasoning": "Explanation" }
374
+ },
375
+ "recommendations": [
376
+ {
377
+ "id": "rec1",
378
+ "category": "requirements|architecture|security|performance|maintainability|testing",
379
+ "title": "Recommendation title",
380
+ "description": "Detailed description",
381
+ "priority": "low|medium|high|critical",
382
+ "technical_complexity": "simple|moderate|complex",
383
+ "business_impact": "Impact description",
384
+ "implementation_guide": "How to implement",
385
+ "estimated_effort": "Time estimate"
386
+ }
387
+ ],
388
+ "timeline": {
389
+ "total_duration_weeks": 12,
390
+ "phases": [
391
+ {
392
+ "id": "phase1",
393
+ "name": "Phase name",
394
+ "description": "Phase description",
395
+ "duration_weeks": 4,
396
+ "start_week": 1,
397
+ "dependencies": ["previous_phase_id"],
398
+ "deliverables": ["deliverable1", "deliverable2"],
399
+ "key_milestones": ["milestone1"],
400
+ "resources_required": ["skill1", "skill2"],
401
+ "risks": ["potential_risk"]
402
+ }
403
+ ]
404
+ },
405
+
406
+ CRITICAL INSTRUCTION: Each story must appear in EXACTLY ONE phase. Never assign the same story to multiple phases. Each phase should have distinct stories assigned to it. Distribute stories across phases without duplication.
407
+ "suggested_product_requirements": {
408
+ "explicit_requirements": [
409
+ {
410
+ "requirement": "Clear requirement text",
411
+ "source_text": "Source text from stories",
412
+ "confidence": "high|medium|low"
413
+ }
414
+ ],
415
+ "inferred_functional_requirements": [
416
+ {
417
+ "requirement": "Inferred requirement",
418
+ "rationale": "Why this is needed",
419
+ "domain_pattern": "Common pattern",
420
+ "priority": "critical|high|medium|low"
421
+ }
422
+ ],
423
+ "suggested_non_functional_requirements": [
424
+ {
425
+ "category": "performance|security|scalability|maintainability|usability",
426
+ "requirement": "NFR description",
427
+ "industry_standard": true|false,
428
+ "customization_needed": true|false
429
+ }
430
+ ],
431
+ "requirements_clarification_questions": [
432
+ {
433
+ "category": "Category",
434
+ "question": "What needs clarification?",
435
+ "impact_if_unclear": "Impact of not clarifying",
436
+ "suggested_default": "Default assumption"
437
+ }
438
+ ]
439
+ },
440
+ "metadata": {
441
+ "analysis_duration_seconds": 30,
442
+ "confidence_level": 0.85,
443
+ "analysis_timestamp": "ISO timestamp",
444
+ "claude_model": "sonnet-4",
445
+ "reviewer_notes": "Optional notes"
446
+ }
447
+ }
448
+
449
+ Analyze the codebase thoroughly, understand existing architecture, and provide a comprehensive implementation plan. Return only valid JSON.
450
+ `;try{s.info("Starting comprehensive project and source code analysis",{projectId:e.id,storiesCount:e.stories?.length||0,servicesCount:e.affectedServices?.length||0});let n=this.getWorkspacePathForAnalysis(e),o=t?`development-plan-${t}`:`development-plan-${Date.now()}`;s.info("Starting comprehensive development plan analysis with Claude",{projectId:e.id,workspacePath:n,storiesCount:e.stories?.length||0,servicesCount:e.affectedServices?.length||0,sessionId:o}),await a.executeCommand(i,n,{workspaceId:e.workspaces?.[0]?.workspaceId||"default",workspaceName:e.name,workspacePath:n,targetServices:e.affectedServices?.map(c=>c.name)||[],analysisScope:"workspace-wide"},18e5,o),await new Promise(c=>setTimeout(c,2e3)),s.info("Claude execution completed - results should arrive via TCP",{projectId:e.id,sessionId:o})}catch(n){return s.error("Requirements and source code analysis failed",{projectId:e.id,error:n instanceof Error?n.message:String(n)}),{sourceCodeAnalysis:{architecturePattern:"Unable to analyze - using fallback assessment",technologyStack:this.inferTechnologyStack(e),codeQuality:{strengths:["Project structure exists"],weaknesses:["Unable to analyze code quality"],testCoverage:"Unknown - requires code analysis",documentation:"Unknown - requires code analysis"},technicalDebt:[{area:"Code analysis",severity:"medium",description:"Unable to perform automated code analysis",impact:"May miss technical debt items"}],performanceAnalysis:{bottlenecks:["Unknown - requires profiling"],scalabilityIssues:["Unknown - requires analysis"],recommendations:["Perform manual code review","Add performance monitoring"]}},functionalRequirements:e.stories?.map(o=>({requirement:o.title,priority:"high",source:o.id,complexity:"medium"}))||[{requirement:"Implement core project functionality",priority:"high",source:"inferred",complexity:"medium"}],technicalRequirements:[{requirement:"Scalable architecture",category:"scalability",currentState:"Unknown - requires analysis",gapAnalysis:"Need to assess current architecture"},{requirement:"Security implementation",category:"security",currentState:"Unknown - requires security audit",gapAnalysis:"Need security assessment"}],integrationRequirements:e.affectedServices?.map(o=>({integration:o.name,type:"service",currentStatus:"exists",complexity:"medium"}))||[{integration:"Database integration",type:"database",currentStatus:"unknown",complexity:"medium"}],qualityRequirements:[{requirement:"Test coverage",category:"testing",currentLevel:"Unknown - requires analysis",targetLevel:"Comprehensive test suite"},{requirement:"Documentation",category:"documentation",currentLevel:"Unknown - requires analysis",targetLevel:"Complete technical documentation"}],currentState:{completedWork:e.stories?.filter(o=>o.status==="COMPLETE").map(o=>o.title)||[],inProgressWork:e.stories?.filter(o=>o.status==="IMPLEMENTATION").map(o=>o.title)||[],technicalDebt:["Code analysis required","Documentation updates needed"],gaps:["Missing automated code analysis","Performance monitoring needed"]},implementationScope:{coreFunctionality:e.stories?.map(o=>o.title)||["Core business logic"],supportingFeatures:["Admin interfaces","Monitoring and logging"],priorityAreas:["Core functionality","User experience"],riskAreas:["Integration complexity","Performance requirements"]},developmentRecommendations:{immediateActions:["Set up automated code analysis","Review current architecture"],architecturalChanges:["Assess current patterns","Plan improvements"],toolingUpdates:["Code quality tools","Testing frameworks"],processImprovements:["Code review process","Documentation standards"]}}}}async savePlan(e,t){let a=`
451
+ mutation CreateDevelopmentPlan($input: CreateDevelopmentPlanInput!) {
452
+ createDevelopmentPlan(input: $input) {
453
+ id
454
+ project {
455
+ id
456
+ }
457
+ createdAt
458
+ updatedAt
459
+ }
460
+ }
461
+ `,i={projectId:e,planDataJson:JSON.stringify(t.planData),estimatesJson:JSON.stringify(t.estimates),dependenciesJson:JSON.stringify(t.dependencies)};try{let n=this.getOrganizationGraphQLClient();if(!n)throw new Error("Organization GraphQL client not available");let o=await n.request(a,{input:i});if(!o.createDevelopmentPlan)throw new Error("Failed to save development plan");s.info("Development plan saved successfully",{planId:o.createDevelopmentPlan.id,projectId:e,phasesCount:t.planData.phases.length,totalHours:t.estimates.totalHours})}catch(n){throw s.error("Failed to save development plan",{projectId:e,error:n instanceof Error?n.message:String(n)}),n}}getWorkspacePathForAnalysis(e){if(e.workspaceConfig?.workspace?.paths?.root)return e.workspaceConfig.workspace.paths.root;if(e.workspaces&&e.workspaces.length>0){let a=e.workspaces[0];if(a.path)return a.path}if(e.name==="Implementation Plan Feature"||e.repositoryUrl?.includes("task-shepherd"))return"/Users/scotto/Documents/javascript/task-shepherd";let t=process.cwd();return t.includes("/packages/agent")?t.replace(/\/packages\/agent.*$/,""):t}inferTechnologyStack(e){let t=[];return e.affectedServices?.forEach(a=>{t.includes(a.technology)||t.push(a.technology)}),t.length===0&&t.push("JavaScript","Node.js","React","TypeScript"),t}selectPrimaryWorkspace(e,t){if(t.workspaceStrategy?.primaryWorkspace){let a=t.workspaceStrategy.primaryWorkspace,i=e.workspaces?.find(n=>n.workspaceId===a||n.name===a);if(i)return i.workspaceId}if(e.workspaces&&e.workspaces.length>0){let a=e.workspaces.find(i=>i.pattern==="monorepo");return a&&e.affectedServices&&e.affectedServices.length>1?a.workspaceId:e.workspaces[0].workspaceId}return"main"}enrichWorkspaceCoordination(e,t){let a=[];if(!e.workspaces||e.workspaces.length===0)return a;let i=t.workspaceStrategy?.coordination||[];return e.workspaces.forEach(n=>{let o=i.find(d=>d.workspaceId===n.workspaceId||d.workspaceId===n.name);o||(o={workspaceId:n.workspaceId,role:this.determineWorkspaceRole(n,e),services:[],integrationPoints:[],developmentFocus:""}),o.workspaceId=n.workspaceId,o.workspaceName=n.name,o.workspacePath=n.path,o.workspacePattern=n.pattern;let c=this.mapServicesToWorkspace(n,e);o.services=c.map(d=>d.name),o.serviceDetails=c.map(d=>({name:d.name,technology:d.technology,serviceId:d.serviceId})),o.integrationPoints=this.identifyIntegrationPoints(n,c),o.developmentFocus=this.determineDevelopmentFocus(n,c),a.push(o)}),a}planDeploymentSequence(e,t){if(!e.workspaces||e.workspaces.length===0)return[];if(t.workspaceStrategy?.deploymentSequence)return t.workspaceStrategy.deploymentSequence;let a=[];return e.workspaces.filter(c=>this.hasInfrastructureServices(c,e)).forEach(c=>a.push(c.workspaceId)),e.workspaces.filter(c=>this.hasBackendServices(c,e)&&!a.includes(c.workspaceId)).forEach(c=>a.push(c.workspaceId)),e.workspaces.filter(c=>this.hasFrontendServices(c,e)&&!a.includes(c.workspaceId)).forEach(c=>a.push(c.workspaceId)),e.workspaces.forEach(c=>{a.includes(c.workspaceId)||a.push(c.workspaceId)}),a}mapWorkspaceDependencies(e,t){let a={};return e.workspaces&&e.workspaces.forEach(i=>{let n=[];this.mapServicesToWorkspace(i,e).forEach(c=>{switch(c.technology.toLowerCase()){case"react":case"frontend":case"nextjs":let d=e.workspaces?.filter(u=>this.hasBackendServices(u,e)&&u.workspaceId!==i.workspaceId)||[];n.push(...d.map(u=>u.workspaceId));break;case"nodejs":case"backend":case"api":let p=e.workspaces?.filter(u=>this.hasInfrastructureServices(u,e)&&u.workspaceId!==i.workspaceId)||[];n.push(...p.map(u=>u.workspaceId));break}}),a[i.workspaceId]=[...new Set(n)]}),a}determineWorkspaceRole(e,t){let a=this.mapServicesToWorkspace(e,t);return e.pattern==="monorepo"||a.length>=2?"primary":this.hasInfrastructureServices(e,t)?"dependency":"secondary"}mapServicesToWorkspace(e,t){return t.affectedServices?t.affectedServices||[]:[]}identifyIntegrationPoints(e,t){let a=[];return t.forEach(i=>{switch(i.technology.toLowerCase()){case"react":case"frontend":a.push("API endpoint integration"),a.push("Authentication integration"),a.push("State management coordination");break;case"nodejs":case"backend":a.push("Database integration"),a.push("External API integration"),a.push("Authentication service");break;case"database":case"postgresql":case"mongodb":a.push("Schema coordination"),a.push("Migration management");break}}),[...new Set(a)]}determineDevelopmentFocus(e,t){let a=t.map(i=>i.technology.toLowerCase());return a.includes("react")||a.includes("frontend")?"Frontend user interface and user experience development":a.includes("nodejs")||a.includes("backend")?"Backend API and business logic development":a.includes("database")||a.includes("postgresql")?"Data modeling and persistence layer development":"General application development and integration"}hasInfrastructureServices(e,t){return this.mapServicesToWorkspace(e,t).some(i=>["database","redis","nginx","docker","infrastructure"].includes(i.technology.toLowerCase()))}hasBackendServices(e,t){return this.mapServicesToWorkspace(e,t).some(i=>["nodejs","backend","api","server"].includes(i.technology.toLowerCase()))}hasFrontendServices(e,t){return this.mapServicesToWorkspace(e,t).some(i=>["react","frontend","nextjs","vue","angular"].includes(i.technology.toLowerCase()))}buildErrorContext(e,t,a){let i=a instanceof Error?a.message:String(a),n="unknown",o="An unexpected error occurred during implementation planning",c=[];i.includes("Project not found")?(n="project_not_found",o="The specified project could not be found",c=["Verify the project ID is correct","Check if the project has been deleted","Ensure you have permissions to access this project"]):i.includes("workspace")?(n="workspace_configuration",o="There was an issue with the project workspace configuration",c=["Check if workspace paths are accessible","Verify workspace configuration is valid","Ensure Claude CLI has access to the workspace"]):i.includes("Claude")||i.includes("timeout")?(n="claude_execution",o="AI analysis service encountered an issue",c=["Retry the operation after a few minutes","Check if Claude CLI is properly configured","Verify network connectivity to AI services"]):i.includes("JSON")||i.includes("parse")?(n="response_parsing",o="Failed to process AI analysis results",c=["Retry the operation to get a properly formatted response","Check if the AI service is functioning correctly","Verify the project data is not corrupted"]):i.includes("GraphQL")||i.includes("mutation")?(n="backend_communication",o="Failed to save implementation plan to the database",c=["Check backend service availability","Verify database connectivity","Retry the operation after ensuring services are running"]):(i.includes("permission")||i.includes("access"))&&(n="permissions",o="Insufficient permissions to complete the operation",c=["Verify you have the required permissions","Check if the API key is valid and has necessary scopes","Contact an administrator for access"]);let d=`Development planning failed (${n}): ${i}. Recovery actions: ${c.join("; ")}`;return{userFriendlyMessage:o,detailedMessage:d,errorType:n,recoveryActions:c}}isRepromptRequest(e){let t=e.workData?.metadata;return!!(t?.originalPlanId&&t?.repromptType&&t?.changeRequest)}async fetchExistingPlan(e){s.info("Fetching existing development plan",{planId:e});let t=`
462
+ query GetDevelopmentPlan($id: String!) {
463
+ developmentPlan(id: $id) {
464
+ id
465
+ version
466
+ status
467
+ planData
468
+ estimates
469
+ dependencies
470
+ generatedBy
471
+ project {
472
+ id
473
+ name
474
+ }
475
+ }
476
+ }
477
+ `;try{let a=this.getOrganizationGraphQLClient();if(!a)throw new Error("Organization GraphQL client not available");let i=await a.request(t,{id:e});if(!i.developmentPlan)throw new Error(`Development plan ${e} not found`);return i.developmentPlan}catch(a){throw s.error("Failed to fetch existing development plan",{planId:e,error:a instanceof Error?a.message:String(a)}),new Error(`Failed to load original development plan: ${a instanceof Error?a.message:String(a)}`)}}async analyzeRepromptChanges(e,t,a,i,n){s.info("Analyzing reprompt changes with Claude",{repromptType:a,originalPlanVersion:e.version||1});let o=`You are analyzing a development plan reprompt request.
478
+
479
+ ORIGINAL DEVELOPMENT PLAN:
480
+ ${JSON.stringify(e,null,2)}
481
+
482
+ PROJECT CONTEXT:
483
+ ${JSON.stringify(t,null,2)}
484
+
485
+ REPROMPT TYPE: ${a}
486
+ CHANGE REQUEST: ${i}
487
+
488
+ Please analyze what changes are needed and provide:
489
+ 1. Summary of requested changes
490
+ 2. Affected plan sections (overview, phases, architecture, estimates, etc.)
491
+ 3. Specific modifications to implement
492
+ 4. Risk assessment of changes
493
+ 5. Impact on timeline and resources
494
+
495
+ Respond in JSON format with clear analysis of what needs to be updated.`,c=new ae("claude"),d=n?`reprompt-analysis-${n}`:`reprompt-analysis-${Date.now()}`,p=await c.executeCommand(o,"",void 0,6e5,d);try{return JSON.parse(p)}catch(u){return s.warn("Failed to parse changes analysis as JSON, using text response",{parseError:u}),{summary:p,affectedSections:["all"],modifications:[i],risks:["Unknown - analysis parsing failed"],impact:"To be determined"}}}async generateUpdatedPlan(e,t,a,i,n,o){s.info("Generating updated development plan with Claude",{repromptType:i,originalVersion:e.version||1});let c=`You are updating a development plan based on a reprompt request.
496
+
497
+ ORIGINAL PLAN:
498
+ ${JSON.stringify(e,null,2)}
499
+
500
+ PROJECT DATA:
501
+ ${JSON.stringify(t,null,2)}
502
+
503
+ CHANGES ANALYSIS:
504
+ ${JSON.stringify(a,null,2)}
505
+
506
+ REPROMPT TYPE: ${i}
507
+ CHANGE REQUEST: ${n}
508
+
509
+ Please generate a completely updated development plan that incorporates the requested changes while preserving the context and structure of the original plan.
510
+
511
+ The updated plan should:
512
+ 1. Maintain the same JSON structure as the original
513
+ 2. Increment the version number from ${e.version||1} to ${(e.version||1)+1}
514
+ 3. Apply all requested changes from the reprompt
515
+ 4. Update estimates, timelines, and dependencies accordingly
516
+ 5. Preserve any unchanged sections from the original plan
517
+ 6. Ensure all required fields are complete and accurate
518
+
519
+ Generate a comprehensive development plan in JSON format that addresses the change request: "${n}"
520
+
521
+ Focus on providing complete, detailed sections for:
522
+ - planData (overview, phases, architecture, timeline, resources, workspaceStrategy)
523
+ - estimates (totalHours, totalDays, stories, confidenceInterval)
524
+ - dependencies (storyGraph, externalDependencies)
525
+
526
+ Make sure all phases have complete descriptions, estimated durations, and story assignments.`,d=new ae("claude"),p=o?`reprompt-generation-${o}`:`reprompt-generation-${Date.now()}`,u=await d.executeCommand(c,"",void 0,6e5,p);try{let h=JSON.parse(u);return h.version=(e.version||1)+1,h}catch(h){throw s.error("Failed to parse updated development plan",{parseError:h}),new Error("Failed to generate valid updated development plan from Claude response")}}async saveRepromptedPlan(e,t,a,i){s.info("Saving reprompted development plan",{projectId:e,originalPlanId:a,newVersion:t.version||"unknown"});let n=`
527
+ mutation CreateDevelopmentPlanVersion($input: CreateDevelopmentPlanVersionInput!) {
528
+ createDevelopmentPlanVersion(input: $input) {
529
+ id
530
+ version
531
+ status
532
+ }
533
+ }
534
+ `,o={parentPlanId:a,planDataJson:JSON.stringify(t.planData),estimatesJson:JSON.stringify(t.estimates),dependenciesJson:JSON.stringify(t.dependencies),repromptContext:JSON.stringify({repromptType:i.repromptType,changeRequest:i.changeRequest,preserveContext:i.preserveContext}),versionNotes:`Reprompted for ${i.repromptType}: ${i.changeRequest}`};try{let c=this.getOrganizationGraphQLClient();if(!c)throw new Error("Organization GraphQL client not available");let d=await c.request(n,{input:o});if(!d.createDevelopmentPlanVersion)throw new Error("Failed to create development plan version");return s.info("Development plan version created successfully",{newPlanId:d.createDevelopmentPlanVersion.id,version:d.createDevelopmentPlanVersion.version,originalPlanId:a}),d.createDevelopmentPlanVersion}catch(c){throw s.error("Failed to save reprompted development plan",{projectId:e,originalPlanId:a,error:c instanceof Error?c.message:String(c)}),new Error(`Failed to save updated development plan: ${c instanceof Error?c.message:String(c)}`)}}async transformAnalysisToDevelopmentPlan(e,t){s.info("Transforming MCP analysis to development plan format",{projectId:t.id,analysisType:e.analysis_type,hasTimeline:!!e.timeline,phasesCount:e.timeline?.phases?.length||0});let a=e.timeline?.phases?.map(p=>({name:p.name,description:p.description,storyIds:this.mapPhaseToStoryIds(p,t),estimatedDuration:p.duration_weeks,parallelizationFactor:.8}))||[],i=e.timeline?.total_duration_weeks||a.reduce((p,u)=>p+u.estimatedDuration,0),n=new Date,o=new Date(n.getTime()+i*7*24*60*60*1e3),c=a.map((p,u)=>({name:`${p.name} Complete`,date:new Date(n.getTime()+(u+1)*p.estimatedDuration*7*24*60*60*1e3).toISOString(),deliverables:p.deliverables||[`${p.name} deliverables`]})),d={planData:{overview:e.executive_summary||`Implementation plan for ${t.name}`,phases:a,architecture:{components:e.analysis?.strengths?.map(p=>p.title)||[],technologies:this.extractTechnologies(e,t),integrations:this.extractIntegrations(e,t)},timeline:{startDate:n.toISOString(),endDate:o.toISOString(),milestones:c},resources:{requiredSkills:this.extractRequiredSkills(e,t),estimatedTeamSize:this.estimateTeamSize(e,t),aiWorkloadPercentage:30},workspaceStrategy:{primaryWorkspace:this.selectPrimaryWorkspace(t,e),workspaceCoordination:this.buildWorkspaceCoordination(t,e),crossWorkspaceDeployment:{sequence:this.planDeploymentSequence(t,e),dependencies:this.mapWorkspaceDependencies(t,e)}}},estimates:{totalHours:this.estimateTotalHours(e,t),totalDays:Math.ceil(this.estimateTotalHours(e,t)/8),stories:this.buildStoryEstimates(e,t),confidenceInterval:{best:Math.ceil(i*.8),likely:i,worst:Math.ceil(i*1.3)}},dependencies:{storyGraph:this.buildStoryGraph(e,t),externalDependencies:this.extractExternalDependencies(e,t)}};return s.info("MCP analysis transformed to development plan",{projectId:t.id,phasesCount:d.planData.phases.length,totalHours:d.estimates.totalHours,totalDays:d.estimates.totalDays,confidenceScore:e.scores?.overall?.score}),d}mapPhaseToStoryIds(e,t){let a=[],i=t.stories||[];if(e.deliverables?.forEach(n=>{let o=i.find(c=>c.title.toLowerCase().includes(n.toLowerCase())||n.toLowerCase().includes(c.title.toLowerCase()));o&&a.push(o.id)}),a.length===0&&i.length>0){let n=Math.ceil(i.length/3),c=(parseInt(e.id)||0)*n,d=Math.min(c+n,i.length);for(let p=c;p<d;p++)a.push(i[p].id)}return a}extractTechnologies(e,t){let a=[];return t.affectedServices?.forEach(i=>{a.includes(i.technology)||a.push(i.technology)}),e.recommendations?.forEach(i=>{i.category==="architecture"&&i.technical_complexity&&["React","Node.js","TypeScript","PostgreSQL","GraphQL","Docker"].forEach(o=>{i.description.includes(o)&&!a.includes(o)&&a.push(o)})}),a.length===0&&a.push("JavaScript","Node.js","React","TypeScript"),a}extractIntegrations(e,t){let a=[];return t.affectedServices?.forEach(i=>{a.push(`${i.name} integration`)}),e.analysis?.opportunities?.forEach(i=>{i.title.toLowerCase().includes("integration")&&a.push(i.title)}),a.length===0&&a.push("Database integration","Authentication integration","API integration"),a}extractRequiredSkills(e,t){let a=[];return e.recommendations?.forEach(i=>{(i.category==="requirements"||i.category==="architecture")&&((i.description.includes("frontend")||i.description.includes("React"))&&a.push("Frontend Development"),(i.description.includes("backend")||i.description.includes("API"))&&a.push("Backend Development"),(i.description.includes("database")||i.description.includes("PostgreSQL"))&&a.push("Database Design"))}),a.length===0&&a.push("Full-stack Development","TypeScript","React","Node.js"),a}estimateTeamSize(e,t){let a=t.stories?.length||1,i=e.scores?.overall?.score||70;return a>10&&i<70?3:a>5?2:1}estimateTotalHours(e,t){let a=t.stories?.length||1,i=e.scores?.feasibility?.score?(100-e.scores.feasibility.score)/50+1:1.5;return Math.ceil(a*40*i)}buildStoryEstimates(e,t){let a=t.stories||[],i=40;return a.map(n=>({storyId:n.id,title:n.title,hours:i,confidence:.75,complexity:"medium",dependencies:[]}))}buildStoryGraph(e,t){let a={};return t.stories?.forEach(i=>{a[i.id]={dependsOn:[],blocks:[],criticalPath:!1}}),a}extractExternalDependencies(e,t){let a=[];return e.analysis?.risks?.forEach(i=>{(i.title.toLowerCase().includes("dependency")||i.title.toLowerCase().includes("external")||i.title.toLowerCase().includes("integration"))&&a.push({name:i.title,type:"external",status:"unknown"})}),a}buildWorkspaceCoordination(e,t){return this.enrichWorkspaceCoordination(e,{workspaceStrategy:{}})}setupTCPListener(){this.tcpListener=e=>{e.type==="implementation_plan_complete"&&(s.info("\u{1F3AF} Received implementation plan from MCP",{projectId:e.projectId,analysisType:e.analysisType,hasData:!!e.data,dataKeys:Object.keys(e.data||{}),overallScore:e.data?.scores?.overall?.score}),this.analysisResult=e.data)},this.tcpService.on("implementation_plan_complete",this.tcpListener),s.debug("\u2705 TCP listener set up for implementation plan results")}cleanupTCPListener(){this.tcpListener&&(this.tcpService.off("implementation_plan_complete",this.tcpListener),this.tcpListener=void 0,s.debug("\u{1F9F9} TCP listener cleaned up"))}async waitForAnalysisResult(e=17e5){let t=Date.now(),a=500,i=0;return new Promise((n,o)=>{let c=()=>{if(i++,i%60===0){let d=Math.floor((Date.now()-t)/1e3),p=Math.floor((e-(Date.now()-t))/1e3);s.info(`\u23F3 Still waiting for implementation plan analysis... ${d}s elapsed, ${p}s remaining`,{elapsedTime:Date.now()-t,checksPerformed:i,hasAnalysisResult:!!this.analysisResult,timeoutMs:e})}if(this.analysisResult){s.info("\u2705 Implementation plan analysis result retrieved",{hasResult:!!this.analysisResult,resultKeys:this.analysisResult?Object.keys(this.analysisResult):[],resultType:this.analysisResult?.analysis_type,waitTime:Date.now()-t});let d=this.analysisResult;this.analysisResult=void 0,n(d);return}if(Date.now()-t>e){let d=`Implementation plan analysis timeout after ${e}ms`;s.error("\u274C "+d,{elapsedTime:Date.now()-t,hasAnalysisResult:!!this.analysisResult}),o(new Error(d));return}setTimeout(c,a)};c()})}}});var Ot,Va=M(()=>{"use strict";We();j();Ot=class extends ie{constructor(){super("story-implementation")}async executeWork(r){s.info("Starting story implementation execution",{assignmentId:r.assignmentId,workItemId:r.workItemId});let e=[{name:"Analyzing Story Requirements",progress:10},{name:"Setting up Development Environment",progress:20},{name:"Implementing Core Functionality",progress:50},{name:"Writing Tests",progress:70},{name:"Code Review and Refinement",progress:85},{name:"Documentation and Cleanup",progress:95},{name:"Finalizing Implementation",progress:100}];await this.simulateWork(r,e),s.info("Story implementation execution completed",{assignmentId:r.assignmentId})}}});var _t,Ka=M(()=>{"use strict";We();j();Ge();_t=class extends ie{constructor(r){super("review-application")}async executeWork(r){s.debug("Full work assignment structure received",{assignmentId:r.assignmentId,workData:r.workData,organizationId:r.organizationId});let e=r.workData?.reviewId||r.workData?.metadata?.reviewId||r.workData?.reviewId;if(!e&&r.workData?.projectId){s.warn("ReviewId not found in work data, attempting to find from project",{assignmentId:r.assignmentId,projectId:r.workData.projectId,organizationId:r.organizationId});try{e=await this.findMostRecentProjectReviewId(r.workData.projectId),e&&s.info("Found reviewId from project reviews",{assignmentId:r.assignmentId,projectId:r.workData.projectId,reviewId:e})}catch(o){s.error("Failed to find reviewId from project",{assignmentId:r.assignmentId,projectId:r.workData.projectId,error:o instanceof Error?o.message:String(o)})}}if(!e){let o=new Error("Missing reviewId in work assignment data and unable to find from project");throw s.error("Review application work failed: Missing reviewId",{assignmentId:r.assignmentId,organizationId:r.organizationId,workData:r.workData,workItemId:r.workItemId}),o}let t=r.workData?.applicationDetails||{},a=r.workData?.applicationPrompt||t.applicationPrompt,i=r.workData?.focusAreas||t.focusAreas,n=r.workData?.customInstructions||t.customInstructions;s.info("Starting review application work",{assignmentId:r.assignmentId,organizationId:r.organizationId,reviewId:e,focusAreas:i||"all",hasCustomInstructions:!!n});try{if(await this.updateProgress(r.assignmentId,{stage:"Fetching Review Data",progressPercentage:10,currentStep:"Loading review and project information",message:"Retrieving review data and project context",updatedAt:new Date}),this.reviewData=await this.fetchReviewData(e),!this.reviewData.project)throw new Error(`Review ${e} does not have an associated project`);s.debug("Review data fetched successfully",{reviewId:e,projectId:this.reviewData.project.id,projectName:this.reviewData.project.name,suggestionsCount:{requirements:this.reviewData.suggestions.requirements?.length||0,architecture:this.reviewData.suggestions.architecture?.length||0,risks:this.reviewData.suggestions.risks?.length||0},scores:this.reviewData.reviewData.scores}),await this.updateProgress(r.assignmentId,{stage:"Planning Implementation",progressPercentage:25,currentStep:"Analyzing review suggestions and creating implementation plan",message:"Generating implementation plan from review suggestions",updatedAt:new Date}),this.implementationPlan=await this.generateImplementationPlan(this.reviewData,a,i),s.debug("Implementation plan generated",{reviewId:e,prioritizedSuggestionsCount:this.implementationPlan?.prioritizedSuggestions?.length||0,estimatedDuration:this.implementationPlan?.estimatedDuration||0,validationSteps:this.implementationPlan?.validationSteps?.length||0}),await this.updateProgress(r.assignmentId,{stage:"Applying Changes",progressPercentage:50,currentStep:"Executing Claude CLI to apply review suggestions",message:"Applying review suggestions using Claude CLI",updatedAt:new Date});let o=await this.executeClaudeApplication(this.implementationPlan,this.reviewData,n);s.info("Claude application completed",{reviewId:e,summary:o.summary.substring(0,200),filesModifiedCount:o.filesModified.length}),await this.updateProgress(r.assignmentId,{stage:"Validating Changes",progressPercentage:80,currentStep:"Validating applied changes and running tests",message:"Validating applied changes and checking consistency",updatedAt:new Date});let c=await this.validateAppliedChanges(o,this.reviewData);s.info("Validation completed",{reviewId:e,validationPassed:c.passed,errorCount:c.errors.length,warningCount:c.warnings.length,errors:c.errors,warnings:c.warnings}),await this.updateProgress(r.assignmentId,{stage:"Finalizing",progressPercentage:95,currentStep:"Saving application results",message:"Finalizing review application and saving results",updatedAt:new Date}),this.applicationResult={filesModified:o.filesModified,validationResults:c,applicationSummary:o.summary,implementationPlan:this.implementationPlan},await this.saveApplicationResults(e,this.applicationResult),s.info("Review application completed successfully",{assignmentId:r.assignmentId,reviewId:e,filesModified:this.applicationResult.filesModified.length,validationPassed:c.passed})}catch(o){let c=o instanceof Error?o.message:String(o),d=o instanceof Error?o.stack:void 0;throw s.error("Review application failed",{assignmentId:r.assignmentId,reviewId:e,error:c,stack:d}),o}}async fetchReviewData(r){let e=this.getOrganizationGraphQLClient();if(!e)throw new Error("Organization GraphQL client not available");let t=await e.getPreviousReview({id:r});if(!t.projectReview)throw new Error(`Review not found: ${r}`);return t.projectReview}async generateImplementationPlan(r,e,t){let a=new ae("claude"),i=this.getWorkspacePath(r.project),n=t&&t.length>0?`Focus specifically on these areas: ${t.join(", ")}`:"Consider all suggestions equally",o=`You are an expert software architect. Based on this project review, create a detailed implementation plan.
535
+
536
+ Project: ${r.project.name}
537
+ Description: ${r.project.description||"No description"}
538
+
539
+ Review Analysis:
540
+ Strengths: ${r.reviewData.analysis.strengths.join(", ")}
541
+ Weaknesses: ${r.reviewData.analysis.weaknesses.join(", ")}
542
+ Risks: ${r.reviewData.analysis.risks.join(", ")}
543
+ Opportunities: ${r.reviewData.analysis.opportunities.join(", ")}
544
+
545
+ Suggestions to implement:
546
+ Requirements: ${JSON.stringify(r.suggestions.requirements,null,2)}
547
+ Architecture: ${JSON.stringify(r.suggestions.architecture,null,2)}
548
+ Risks: ${JSON.stringify(r.suggestions.risks,null,2)}
549
+
550
+ ${n}
551
+
552
+ ${e?`Additional context: ${e}`:""}
553
+
554
+ Create a prioritized implementation plan with specific file changes, dependencies, and estimated effort. Return ONLY a JSON object with this structure:
555
+ {
556
+ "prioritizedSuggestions": [
557
+ {
558
+ "id": "unique-id",
559
+ "type": "requirement|architecture|risk",
560
+ "description": "what to implement",
561
+ "priority": 1-3,
562
+ "estimatedEffort": "low|medium|high",
563
+ "dependencies": ["other-suggestion-ids"],
564
+ "implementation": {
565
+ "files": ["list of files to modify"],
566
+ "actions": [
567
+ {
568
+ "type": "create|modify|delete",
569
+ "path": "file path",
570
+ "description": "what change to make"
571
+ }
572
+ ]
573
+ }
574
+ }
575
+ ],
576
+ "validationSteps": ["validation commands to run"],
577
+ "estimatedDuration": "total minutes"
578
+ }`;s.debug("Generating implementation plan with Claude",{reviewId:r.id,projectName:r.project.name,workspacePath:i,focusAreas:t||"all",hasApplicationPrompt:!!e});try{let c=await a.executeCommand(o,i),d=JSON.parse(c.trim());return s.debug("Implementation plan generated successfully",{reviewId:r.id,suggestionsCount:d.prioritizedSuggestions?.length||0,estimatedDuration:d.estimatedDuration}),d}catch(c){return s.error("Failed to generate implementation plan with Claude",{reviewId:r.id,error:c instanceof Error?c.message:String(c),willUseFallback:!0}),this.generateBasicPlan(r,t)}}async executeClaudeApplication(r,e,t){s.info("Incorporating review suggestions into project requirements",{reviewId:e.id,projectId:e.project.id,suggestionsCount:r?.prioritizedSuggestions?.length||0});let a=await this.incorporateReviewIntoRequirements(e,r,t);return{filesModified:[],summary:a.applicationSummary}}async incorporateReviewIntoRequirements(r,e,t){let a=new ae("claude"),i=`You are an expert product manager and technical architect. Your job is to incorporate AI review insights directly into project requirements and specifications to improve project clarity and completeness.
579
+
580
+ Project: ${r.project.name}
581
+ Current Description: ${r.project.description||"No description provided"}
582
+
583
+ Review Analysis:
584
+ - Strengths: ${r.reviewData.analysis.strengths.join(", ")}
585
+ - Weaknesses: ${r.reviewData.analysis.weaknesses.join(", ")}
586
+ - Risks: ${r.reviewData.analysis.risks.join(", ")}
587
+ - Opportunities: ${r.reviewData.analysis.opportunities.join(", ")}
588
+
589
+ Review Suggestions to Incorporate:
590
+ ${JSON.stringify(r.suggestions,null,2)}
591
+
592
+ Implementation Plan:
593
+ ${JSON.stringify(e,null,2)}
594
+
595
+ ${t?`Additional Context: ${t}`:""}
596
+
597
+ Your task is to improve the project by incorporating these review insights INTO the project requirements themselves, not as separate tasks but as integral improvements. Respond with a JSON object:
598
+
599
+ {
600
+ "enhancedDescription": "Rewritten project description that incorporates the insights and addresses weaknesses",
601
+ "clarifiedRequirements": [
602
+ "Clear, actionable requirements that incorporate the review suggestions",
603
+ "Requirements should be specific, measurable, and implementable",
604
+ "Address the identified weaknesses and opportunities",
605
+ "Each requirement should be standalone and complete"
606
+ ],
607
+ "improvedArchitecture": "Architectural guidance that addresses the review recommendations",
608
+ "riskMitigations": [
609
+ "Specific risk mitigation strategies that should be built into the project",
610
+ "These become part of the requirements, not separate tasks"
611
+ ],
612
+ "nextSteps": [
613
+ "Immediate actionable steps based on the incorporated improvements",
614
+ "Focus on the highest priority items from the review"
615
+ ],
616
+ "applicationSummary": "Summary of how the review insights were incorporated to improve the project requirements and specifications"
617
+ }
618
+
619
+ Important: Don't create TODO items or questions. Instead, incorporate the insights as refined, detailed requirements and specifications that make the project better defined and more complete.`;try{let n=await a.executeCommand(i,process.cwd()),o=JSON.parse(n?.trim()||"{}"),c={enhancedDescription:o?.enhancedDescription||r.project.description||"Project description",clarifiedRequirements:o?.clarifiedRequirements||[],improvedArchitecture:o?.improvedArchitecture||"",riskMitigations:o?.riskMitigations||[],nextSteps:o?.nextSteps||[],applicationSummary:o?.applicationSummary||"Review insights incorporated"};return await this.updateProjectRequirements(r.project.id,c,r.suggestions),c}catch(n){throw s.error("Failed to incorporate review into requirements:",n),new Error(`Requirements incorporation failed: ${n instanceof Error?n.message:String(n)}`)}}async updateProjectRequirements(r,e,t){try{let a=`
620
+ mutation UpdateProject($id: String!, $input: UpdateProjectInput!) {
621
+ updateProject(id: $id, input: $input) {
622
+ id
623
+ name
624
+ description
625
+ }
626
+ }
627
+ `,i=this.getOrganizationGraphQLClient();if(!i)throw new Error("Organization GraphQL client not available");await i.request(a,{id:r,input:{description:e.enhancedDescription}});let n=await this.completeReviewApplication({projectId:r,applicationSummary:e.applicationSummary,projectImprovements:{enhancedDescription:e.enhancedDescription,clarifiedRequirements:e.clarifiedRequirements,improvedArchitecture:e.improvedArchitecture,nextSteps:e.nextSteps,riskMitigations:e.riskMitigations},validationResults:{passed:!0,errors:[],warnings:[]}});s.info("Successfully applied review improvements to project",{projectId:r,requirementsAdded:e.clarifiedRequirements.length,applicationResult:n})}catch(a){throw s.error("Failed to update project requirements:",{projectId:r,error:a instanceof Error?a.message:String(a)}),a}}async completeReviewApplication(r){try{let e={reviewId:this.reviewData?.id||"unknown",applicationSummary:r.applicationSummary,projectImprovements:r.projectImprovements,validationResults:r.validationResults};return s.info("Review application completed with structured improvements",{reviewApplicationData:e}),e}catch(e){throw s.error("Failed to complete review application:",e),e}}async validateAppliedChanges(r,e){let t=new ae("claude"),a=this.getWorkspacePath(e.project),i=`You are a senior code reviewer. Validate the changes that were just applied to this project.
628
+
629
+ Project: ${e.project.name}
630
+ Files Modified: ${r.filesModified.join(", ")}
631
+ Implementation Summary: ${r.summary}
632
+
633
+ Validation Tasks:
634
+ 1. Check that all modified files compile/parse correctly
635
+ 2. Verify that changes are consistent with project architecture
636
+ 3. Look for potential runtime errors or logical issues
637
+ 4. Check that imports and dependencies are correct
638
+ 5. Verify that the changes align with the original review suggestions
639
+ 6. Run type checking if TypeScript project
640
+ 7. Check for code style consistency
641
+
642
+ Provide validation results in this JSON format:
643
+ {
644
+ "passed": true/false,
645
+ "errors": ["list of critical issues that must be fixed"],
646
+ "warnings": ["list of minor issues or improvements"],
647
+ "recommendations": ["additional suggestions for improvement"]
648
+ }
649
+
650
+ Be thorough but practical. Focus on issues that would prevent the code from working correctly.`;try{let n=await t.executeCommand(i,a),o=JSON.parse(n.trim());return{passed:o.passed,errors:o.errors||[],warnings:o.warnings||[]}}catch(n){return s.error("Failed to validate changes with Claude:",n),{passed:!0,errors:[],warnings:[`${r.filesModified.length} files were modified`,"Automated validation failed - manual review recommended"]}}}async saveApplicationResults(r,e){let t=`
651
+ mutation CompleteReviewApplication($reviewId: String!, $result: JSONObject!, $workQueueId: String) {
652
+ completeReviewApplication(reviewId: $reviewId, result: $result, workQueueId: $workQueueId)
653
+ }
654
+ `,a={reviewId:r,result:{applicationSummary:e.applicationSummary,validationResults:e.validationResults,projectImprovements:{enhancedDescription:e.implementationPlan?"Project enhanced with AI review insights":"Project requirements improved",clarifiedRequirements:e.implementationPlan?.prioritizedSuggestions?.map(i=>i.description)||[],improvedArchitecture:"Architecture recommendations incorporated from review",nextSteps:e.implementationPlan?.validationSteps||[],riskMitigations:[]}},workQueueId:null};try{let i=this.getOrganizationGraphQLClient();if(!i)throw new Error("Organization GraphQL client not available");await i.request(t,a),s.info("Review application completed successfully",{reviewId:r,requirementsIncorporated:a.result.projectImprovements.clarifiedRequirements.length})}catch(i){throw s.error("Failed to complete review application:",{reviewId:r,error:i instanceof Error?i.message:String(i)}),new Error(`Failed to complete review application: ${i}`)}}getWorkspacePath(r){if(r.workspaceConfig?.workspace?.paths?.root)return r.workspaceConfig.workspace.paths.root;if(r.workspaces&&r.workspaces.length>0){let t=r.workspaces[0];if(t.path)return t.path}if(r.name==="Mobile App Development"||r.repositoryUrl?.includes("task-shepherd")){let t="/Users/scotto/Documents/javascript/task-shepherd";return s.warn("Using hardcoded Task Shepherd workspace for testing",{projectName:r.name,workspacePath:t}),t}let e=`Project ${r.name} has no workspace configuration. Cannot determine workspace for Claude execution.`;throw s.error("Missing workspace configuration",{projectName:r.name,hasWorkspaceConfig:!!r.workspaceConfig,hasWorkspaces:!!r.workspaces?.length,workspaceCount:r.workspaces?.length||0,workspaceConfig:r.workspaceConfig}),new Error(e)}async findMostRecentProjectReviewId(r){let e=`
655
+ query GetProjectReviews($search: ProjectReviewSearchInput) {
656
+ projectReviews(search: $search) {
657
+ id
658
+ createdAt
659
+ status
660
+ }
661
+ }
662
+ `;try{let t=this.getOrganizationGraphQLClient();if(!t)return s.error("Organization GraphQL client not available"),null;let i=(await t.request(e,{search:{projectId:r}}))?.projectReviews;if(i&&i.length>0){let n=i.sort((o,c)=>new Date(c.createdAt).getTime()-new Date(o.createdAt).getTime());return s.info("Found project reviews, using most recent",{projectId:r,reviewCount:i.length,mostRecentReviewId:n[0].id,mostRecentCreatedAt:n[0].createdAt}),n[0].id}return s.warn("No project reviews found for project",{projectId:r}),null}catch(t){return s.error("Failed to query project reviews",{projectId:r,error:t instanceof Error?t.message:String(t)}),null}}generateBasicPlan(r,e){let t=[],a=1;for(let i of r.suggestions.requirements||[])(!e||e.includes("requirements"))&&t.push({id:`req-${a++}`,type:"requirement",description:i.suggested,priority:i.priority==="high"?3:i.priority==="medium"?2:1,estimatedEffort:i.priority==="high"?"high":"medium",dependencies:[],implementation:{files:["requirements.md","docs/specifications.md"],actions:[{type:"modify",path:"requirements.md",description:`Update requirements: ${i.suggested}`}]}});for(let i of r.suggestions.architecture||[])(!e||e.includes("architecture"))&&t.push({id:`arch-${a++}`,type:"architecture",description:i.suggestion,priority:2,estimatedEffort:"high",dependencies:[],implementation:{files:[`src/${i.component.toLowerCase()}.ts`],actions:[{type:"modify",path:`src/${i.component.toLowerCase()}.ts`,description:`Apply architecture change: ${i.suggestion}`}]}});return t.sort((i,n)=>n.priority-i.priority),{prioritizedSuggestions:t,validationSteps:["Run type checking","Execute test suite","Validate build process","Check code formatting"],estimatedDuration:t.length*5}}}});var jt,Qa=M(()=>{"use strict";We();j();Ge();jt=class extends ie{constructor(e){super("story-task-generator");this.tcpService=e}async executeWork(e){s.info("Starting story and task generation",{assignmentId:e.assignmentId,workItemId:e.workItemId,workData:e.workData,workItemType:e.workItemType});try{await this.updateProgress(e.assignmentId,{stage:"Analyzing Project",progressPercentage:10,currentStep:"Loading project and development plan data",message:"Retrieving project information and development plan",updatedAt:new Date});let t=e.workData?.projectId,a=e.workData?.developmentPlanId;if(!t)throw new Error("Project ID not found in work assignment data");if(!a)throw new Error("Development Plan ID not found in work assignment data");let i=await this.fetchProjectData(t),n=await this.fetchDevelopmentPlan(a);await this.updateProgress(e.assignmentId,{stage:"Analyzing Codebase",progressPercentage:30,currentStep:"Understanding existing code structure",message:"Analyzing codebase for relevant context",updatedAt:new Date}),await this.updateProgress(e.assignmentId,{stage:"Generating Stories",progressPercentage:50,currentStep:"Creating stories from development plan",message:"AI is generating detailed stories with tasks",updatedAt:new Date}),this.setupTCPListener();let o=this.generateStoriesAndTasks(i,n,e),c=parseInt(process.env.STORY_TASK_GENERATION_TIMEOUT_MS||"1800000"),d=new Promise((p,u)=>setTimeout(()=>u(new Error(`Story generation timeout after ${c/6e4} minutes`)),c));if(await Promise.race([o,d]),!this.generationResults)throw new Error("No story generation results received from Claude");await this.updateProgress(e.assignmentId,{stage:"Creating Stories",progressPercentage:80,currentStep:"Saving stories to database",message:"Creating stories and tasks in Task Shepherd",updatedAt:new Date}),await this.createStoriesAndTasks(i.id,this.generationResults),await this.updateProgress(e.assignmentId,{stage:"Generation Complete",progressPercentage:100,currentStep:"Finished",message:"Stories and tasks generated successfully",updatedAt:new Date}),s.info("Story and task generation completed",{assignmentId:e.assignmentId,projectId:i.id,storiesGenerated:this.generationResults?.stories?.length||0,tasksGenerated:this.generationResults?.tasks?.length||0})}catch(t){throw s.error("Story and task generation failed",{assignmentId:e.assignmentId,error:t instanceof Error?t.message:String(t)}),t}finally{this.cleanupTCPListener()}}async fetchProjectData(e){s.debug("Fetching project data",{projectId:e});let t=`
663
+ query GetProjectForStoryGeneration($id: String!) {
664
+ project(id: $id) {
665
+ id
666
+ name
667
+ description
668
+ repositoryUrl
669
+ documentationUrl
670
+ stage
671
+ workspaces {
672
+ id
673
+ workspaceId
674
+ name
675
+ path
676
+ pattern
677
+ }
678
+ affectedServices {
679
+ id
680
+ serviceId
681
+ name
682
+ technology
683
+ }
684
+ workspaceConfig
685
+ stories {
686
+ id
687
+ title
688
+ description
689
+ acceptanceCriteria
690
+ status
691
+ }
692
+ }
693
+ }
694
+ `,a=this.getOrganizationGraphQLClient();if(!a)throw new Error("Organization GraphQL client not available");let i=await a.request(t,{id:e});if(!i.data?.project)throw new Error(`Project not found: ${e}`);return i.data.project}async fetchDevelopmentPlan(e){s.debug("Fetching development plan",{planId:e});let t=`
695
+ query GetDevelopmentPlan($id: String!) {
696
+ developmentPlan(id: $id) {
697
+ id
698
+ project {
699
+ id
700
+ name
701
+ }
702
+ planData
703
+ createdAt
704
+ updatedAt
705
+ }
706
+ }
707
+ `,a=this.getOrganizationGraphQLClient();if(!a)throw new Error("Organization GraphQL client not available");let i=await a.request(t,{id:e});if(!i.data?.developmentPlan)throw new Error(`Development plan not found: ${e}`);return i.data.developmentPlan}setupTCPListener(){this.tcpListener=e=>{e.type==="story_generation_complete"&&(s.info("Received story generation results from MCP",{projectId:e.projectId,storiesCount:e.data?.stories?.length||0,tasksCount:e.data?.tasks?.length||0,dataKeys:Object.keys(e.data||{})}),this.generationResults=e.data)},this.tcpService.on("story_generation_complete",this.tcpListener),s.debug("TCP listener set up for story generation results")}cleanupTCPListener(){this.tcpListener&&(this.tcpService.off("story_generation_complete",this.tcpListener),this.tcpListener=void 0,s.debug("TCP listener cleaned up"))}async generateStoriesAndTasks(e,t,a){let i=new ae("claude"),n=`You are an expert product manager and software architect specializing in breaking down development plans into implementable user stories and tasks.
708
+
709
+ CRITICAL INSTRUCTIONS:
710
+ \u2757 You MUST use the mcp__task-shepherd__create_story and mcp__task-shepherd__create_task tools to create stories and tasks directly in the system.
711
+ \u2757 DO NOT provide text responses with story descriptions. ONLY use the tools to create the actual stories and tasks.
712
+ \u2757 Each story MUST be followed immediately by its associated tasks using the task creation tools.
713
+
714
+ PROJECT INFORMATION:
715
+ - Project ID: ${e.id}
716
+ - Name: ${e.name}
717
+ - Description: ${e.description||"No description provided"}
718
+ - Stage: ${e.stage}
719
+ - Repository: ${e.repositoryUrl||"Not provided"}
720
+ - Workspaces: ${e.workspaces?.map(o=>`${o.name} (${o.workspaceId})`).join(", ")||"None configured"}
721
+ - Services: ${e.affectedServices?.map(o=>`${o.name} (${o.technology})`).join(", ")||"None configured"}
722
+
723
+ EXISTING STORIES (${e.stories?.length||0} total):
724
+ ${e.stories?.map(o=>`- ${o.title} (${o.status})`).join(`
725
+ `)||"No existing stories"}
726
+
727
+ DEVELOPMENT PLAN DATA:
728
+ ${JSON.stringify(t.planData,null,2)}
729
+
730
+ STORY GENERATION REQUIREMENTS:
731
+
732
+ 1. STORY SIZING:
733
+ - Target 1-2 days of development effort per story
734
+ - Maximum 3 days for any single story
735
+ - Break down larger features into multiple stories
736
+ - Ensure each story is independently deliverable
737
+
738
+ 2. STORY CONTENT REQUIREMENTS:
739
+ Each story must include:
740
+ - Clear title that describes the user value
741
+ - Detailed description with technical context
742
+ - Specific acceptance criteria (3-5 criteria per story)
743
+ - Appropriate priority level (LOW, MEDIUM, HIGH, CRITICAL)
744
+ - Relevant tags from the required set
745
+
746
+ 3. REQUIRED TAGS (use these exactly):
747
+ - "migration" - for database or system migrations
748
+ - "refactor" - for significant code restructuring
749
+ - "infrastructure" - for deployment, CI/CD, or system setup
750
+ - "feature" - for new user-facing functionality
751
+ - "api" - for backend API development
752
+ - "ui" - for frontend user interface work
753
+ - "testing" - for test implementation
754
+ - "documentation" - for documentation work
755
+ - "security" - for security-related changes
756
+ - "performance" - for performance optimizations
757
+
758
+ 4. TASK GENERATION REQUIREMENTS:
759
+ For each story, create 3-8 specific tasks that:
760
+ - Break down the story into implementable units
761
+ - Each task should be 2-8 hours of work
762
+ - Include technical implementation details
763
+ - Specify which files/components need changes
764
+ - Have clear acceptance criteria
765
+ - Use appropriate technical areas (see list below)
766
+
767
+ 5. TECHNICAL AREAS for tasks (use these exactly):
768
+ - "frontend" - React components, UI implementation
769
+ - "backend" - Node.js API, GraphQL resolvers
770
+ - "database" - Database schema, migrations, queries
771
+ - "testing" - Unit tests, integration tests, E2E tests
772
+ - "devops" - CI/CD, deployment, infrastructure
773
+ - "documentation" - Technical docs, API docs, README updates
774
+ - "security" - Authentication, authorization, vulnerability fixes
775
+ - "performance" - Optimization, caching, monitoring
776
+
777
+ 6. STORY ORDERING AND DEPENDENCIES:
778
+ - Create stories in logical implementation order
779
+ - Use story dependencies to enforce proper sequencing
780
+ - Infrastructure and migration stories should come first
781
+ - Feature stories should build on foundational work
782
+ - Testing and documentation can be parallel to feature work
783
+
784
+ 7. IMPLEMENTATION WORKFLOW:
785
+ For each story you create:
786
+ a) Use mcp__task-shepherd__create_story with full details
787
+ b) Immediately create associated tasks using mcp__task-shepherd__create_task
788
+ c) Ensure story ID is captured and used for task story references
789
+ d) Create dependencies between stories as needed
790
+
791
+ EXAMPLE WORKFLOW:
792
+ 1. Create foundational/infrastructure stories first
793
+ 2. Create core feature stories with proper dependencies
794
+ 3. Create testing and documentation stories
795
+ 4. Ensure no gaps in requirements coverage
796
+
797
+ STORY TEMPLATE (for reference - use the tools, not text):
798
+ - Title: "As a [user type], I want [goal] so that [benefit]"
799
+ - Description: Technical approach, implementation details, context
800
+ - Acceptance Criteria: Specific, testable conditions
801
+ - Priority: Based on business impact and dependencies
802
+ - Tags: Relevant tags from the required set
803
+
804
+ TASK TEMPLATE (for reference - use the tools, not text):
805
+ - Title: Specific implementation task
806
+ - Description: Technical details, file changes needed
807
+ - Areas: Relevant technical areas
808
+ - Priority: Based on story priority and implementation order
809
+
810
+ START IMPLEMENTATION:
811
+ Begin by analyzing the development plan and creating stories in logical order. Use ONLY the MCP tools to create actual stories and tasks - no text descriptions.
812
+
813
+ Focus Areas Based on Development Plan:
814
+ ${t.planData?.recommendations?.map(o=>`- ${o.title}: ${o.description}`).join(`
815
+ `)||"No specific recommendations"}
816
+
817
+ Required Timeline: ${t.planData?.timeline?.total_duration_weeks||"Not specified"} weeks total`;s.info("Executing Claude for story and task generation",{projectId:e.id,promptLength:n.length,developmentPlanId:t.id});try{let o=this.getWorkspacePath(e);s.debug("Using workspace path for Claude execution",{workspacePath:o,projectId:e.id,workspaceCount:e.workspaces?.length||0});let c=await i.executeCommand(n,o);s.debug("Claude execution completed for story generation",{resultLength:c.length,resultPreview:c.substring(0,200)}),await new Promise(d=>setTimeout(d,3e3))}catch(o){throw s.error("Claude execution failed for story generation",{error:o instanceof Error?o.message:String(o)}),o}}getWorkspacePath(e){if(e.workspaceConfig?.workspace?.paths?.root)return s.debug("Using workspace config root path",{rootPath:e.workspaceConfig.workspace.paths.root}),e.workspaceConfig.workspace.paths.root;if(e.workspaces&&e.workspaces.length>0){let a=e.workspaces[0];if(a.path)return s.debug("Using first workspace path",{workspaceId:a.workspaceId,workspaceName:a.name,path:a.path}),a.path}if(e.name?.includes("Task Shepherd")||e.repositoryUrl?.includes("task-shepherd")){let a="/Users/scotto/Documents/javascript/task-shepherd";return s.warn("Using hardcoded Task Shepherd workspace for testing",{projectId:e.id,projectName:e.name,workspacePath:a}),a}let t=`Project ${e.id} (${e.name}) has no workspace configuration. Cannot determine workspace for Claude execution.`;throw s.error("Missing workspace configuration",{projectId:e.id,projectName:e.name,hasWorkspaceConfig:!!e.workspaceConfig,hasWorkspaces:!!e.workspaces?.length,workspaceCount:e.workspaces?.length||0,workspaceConfig:e.workspaceConfig}),new Error(t)}async createStoriesAndTasks(e,t){s.info("Creating stories and tasks from generation results",{projectId:e,storiesCount:t?.stories?.length||0,tasksCount:t?.tasks?.length||0}),t?.stories&&s.info("Stories created via MCP",{count:t.stories.length,titles:t.stories.map(a=>a.title).slice(0,5)}),t?.tasks&&s.info("Tasks created via MCP",{count:t.tasks.length,taskTitles:t.tasks.map(a=>a.title).slice(0,10)})}}});var Ve,Nr=M(()=>{"use strict";qa();Ba();Ga();Va();Ka();Qa();Ve=class{constructor(r){this.tcpService=r;this.workTypeMappings=new Map;this.initializeWorkTypeMappings()}createHandler(r){let e=this.workTypeMappings.get(r);if(e)return e()}getSupportedWorkTypes(){return Array.from(this.workTypeMappings.keys())}getSupportedCapabilities(){return["project_review","implementation_plan","story_implementation","code_review","review_application","task_completion"]}initializeWorkTypeMappings(){let r=["project-review","project_review","project-reviewer","PROJECT_REVIEW","project-analysis","project_analysis"],e=()=>new Mt(this.tcpService);r.forEach(f=>{this.workTypeMappings.set(f,e)});let t=["development-plan","development_plan","development-planner","IMPLEMENTATION_PLAN","implementation-plan","implementation_plan","project-planning","project_planning"],a=()=>new Wt(this.tcpService);t.forEach(f=>{this.workTypeMappings.set(f,a)});let i=["story-implementation","story_implementation","story-developer","STORY_IMPLEMENTATION","feature-development","feature_development"],n=()=>new Ot;i.forEach(f=>{this.workTypeMappings.set(f,n)});let o=["code-review","code_review","code-reviewer","CODE_REVIEW","pr-review","pr_review"],c=()=>new Nt;o.forEach(f=>{this.workTypeMappings.set(f,c)});let d=["review-application","review_application","review-application-agent","REVIEW_APPLICATION","apply-review","apply_review"],p=()=>new _t(this.tcpService);d.forEach(f=>{this.workTypeMappings.set(f,p)});let u=["story-task-generator","story_task_generator","task-generator","TASK_GENERATION","generate-tasks","generate_tasks","task_completion","task-completion","TASK_COMPLETION"],h=()=>new jt(this.tcpService);u.forEach(f=>{this.workTypeMappings.set(f,h)})}}});var Ke,xr=M(()=>{"use strict";j();Ia();Nr();Ke=class{constructor(r,e){this.handlerFactory=new Ve(e),this.initializationPromise=this.tryEnhanceWithBackendConfig(r)}async handle(r){let e=r.workItemType;s.info("\u{1F525} WORK_HANDLER_REGISTRY: Starting work assignment handling",{workType:e,assignmentId:r.assignmentId,workerId:r.workerId,supportedWorkTypes:this.handlerFactory.getSupportedWorkTypes(),totalSupportedTypes:this.handlerFactory.getSupportedWorkTypes().length});let t=this.handlerFactory.createHandler(e);if(!t){let a=this.handlerFactory.getSupportedWorkTypes().sort(),i=new Error(`No handler found for work type: ${e}. Supported: ${a.slice(0,5).join(", ")}${a.length>5?"...":""}`);throw s.error("\u274C No handler found for work type",{workType:e,assignmentId:r.assignmentId,supportedTypes:a,workData:r.workData}),i}s.info("\u{1F525} WORK_HANDLER_REGISTRY: Fresh handler instance created, about to call handler.handle()",{workType:e,assignmentId:r.assignmentId,handlerClass:t.constructor.name,hasWorkData:!!r.workData,workDataKeys:r.workData?Object.keys(r.workData):[]});try{s.info("\u{1F525} WORK_HANDLER_REGISTRY: Calling handler.handle(assignment)",{assignmentId:r.assignmentId,handlerClass:t.constructor.name}),await t.handle(r),s.info("\u{1F525} WORK_HANDLER_REGISTRY: handler.handle(assignment) completed without throwing",{assignmentId:r.assignmentId,handlerClass:t.constructor.name}),s.info("\u2705 Work assignment completed successfully",{workType:e,assignmentId:r.assignmentId,handlerClass:t.constructor.name})}catch(a){throw s.error("\u274C Work assignment failed",{workType:e,assignmentId:r.assignmentId,handlerClass:t.constructor.name,error:a instanceof Error?a.message:String(a)}),a}finally{s.debug("Handler instance cleanup (automatic via garbage collection)",{assignmentId:r.assignmentId,handlerClass:t.constructor.name})}}async waitForInitialization(){await this.initializationPromise}getHandler(r){return this.handlerFactory.createHandler(r)}getRegisteredWorkTypes(){return this.handlerFactory.getSupportedWorkTypes()}getStats(){let r=this.handlerFactory.getSupportedWorkTypes();return{totalHandlers:r.length,workTypes:r.sort()}}async tryEnhanceWithBackendConfig(r){try{s.info("\u{1F4E1} Attempting to enhance handler registry with backend configuration...");let a=(await new At(r).getConfiguration()).workTypes;a&&a.length>0?s.info("\u2705 Backend work type configuration loaded successfully",{workTypesCount:a.length,workTypes:a.slice(0,10)}):s.info("\u26A0\uFE0F No backend work type configuration found, using factory defaults")}catch(e){s.warn("\u26A0\uFE0F Failed to load backend work type configuration, using factory defaults",{error:e instanceof Error?e.message:String(e)})}}}});function rt(){return Wr||(Wr=new _r),Wr}var Qe,Or,_r,Wr,jr=M(()=>{"use strict";Qe=A(require("fs")),Or=A(require("path"));j();_r=class{constructor(){this.completedItems=[];this.maxItems=25;this.dataDir=Or.default.join(process.env.HOME||process.env.USERPROFILE||"",".task-shepherd-agent"),this.filePath=Or.default.join(this.dataDir,"completed-work.json"),this.ensureDataDir(),this.loadFromDisk()}ensureDataDir(){try{Qe.default.existsSync(this.dataDir)||(Qe.default.mkdirSync(this.dataDir,{recursive:!0}),s.info("Created completed work data directory",{dataDir:this.dataDir}))}catch(r){s.error("Failed to create completed work data directory",{dataDir:this.dataDir,error:r instanceof Error?r.message:String(r)})}}loadFromDisk(){try{if(Qe.default.existsSync(this.filePath)){let r=Qe.default.readFileSync(this.filePath,"utf8"),e=JSON.parse(r);this.completedItems=e.slice(-this.maxItems),s.info("Loaded completed work items from disk",{itemsLoaded:this.completedItems.length,filePath:this.filePath})}else s.info("No existing completed work file found, starting fresh",{filePath:this.filePath})}catch(r){s.error("Failed to load completed work items from disk",{filePath:this.filePath,error:r instanceof Error?r.message:String(r)}),this.completedItems=[]}}saveToDisk(){try{let r=JSON.stringify(this.completedItems,null,2);Qe.default.writeFileSync(this.filePath,r,"utf8"),s.debug("Saved completed work items to disk",{itemsSaved:this.completedItems.length,filePath:this.filePath})}catch(r){s.error("Failed to save completed work items to disk",{filePath:this.filePath,error:r instanceof Error?r.message:String(r)})}}addCompletedItem(r){try{let e=this.completedItems.findIndex(t=>t.id===r.id);e!==-1?(this.completedItems[e]=r,s.debug("Updated existing completed work item",{workItemId:r.id,type:r.type})):(this.completedItems.push(r),s.debug("Added new completed work item",{workItemId:r.id,type:r.type})),this.completedItems.length>this.maxItems&&(this.completedItems=this.completedItems.slice(-this.maxItems)),this.saveToDisk(),s.info("Added completed work item",{workItemId:r.id,type:r.type,title:r.title,totalItems:this.completedItems.length})}catch(e){s.error("Failed to add completed work item",{workItemId:r.id,error:e instanceof Error?e.message:String(e)})}}getCompletedItems(r=10,e=0){return{items:[...this.completedItems].sort((i,n)=>new Date(n.completedAt).getTime()-new Date(i.completedAt).getTime()).slice(e,e+r),total:this.completedItems.length,limit:r,offset:e,hasMore:e+r<this.completedItems.length}}getStats(){let r=new Date,e=new Date(r.getFullYear(),r.getMonth(),r.getDate()),t=new Date(e.getTime()-7*24*60*60*1e3),a=this.completedItems.filter(u=>new Date(u.completedAt)>=e).length,i=this.completedItems.filter(u=>new Date(u.completedAt)>=t).length,n=this.completedItems.filter(u=>u.actualDuration),o=n.length>0?n.reduce((u,h)=>u+(h.actualDuration||0),0)/n.length:0,c=this.completedItems.filter(u=>u.status==="completed").length,d=this.completedItems.length>0?c/this.completedItems.length:0,p=this.completedItems.reduce((u,h)=>(u[h.type]=(u[h.type]||0)+1,u),{});return{totalCompleted:this.completedItems.length,completedToday:a,completedThisWeek:i,averageCompletionTime:o,successRate:d,byType:p}}clearAll(){this.completedItems=[],this.saveToDisk(),s.info("Cleared all completed work items")}},Wr=null});var ve,Ja=M(()=>{"use strict";ve={EXCHANGE_API_KEY_FOR_TOKEN:`
818
+ mutation ExchangeApiKeyForToken($apiKey: String!) {
819
+ exchangeApiKeyForToken(apiKey: $apiKey) {
820
+ token
821
+ expiresIn
822
+ refreshToken
823
+ user {
824
+ id
825
+ email
826
+ }
827
+ }
828
+ }
829
+ `,REFRESH_TOKEN:`
830
+ mutation RefreshToken($refreshToken: String!) {
831
+ refreshToken(refreshToken: $refreshToken) {
832
+ token
833
+ expiresIn
834
+ refreshToken
835
+ }
836
+ }
837
+ `,REGISTER_AGENT:`
838
+ mutation RegisterAIWorker($input: AIWorkerRegistrationInput!) {
839
+ registerAIWorker(input: $input) {
840
+ success
841
+ message
842
+ worker {
843
+ id
844
+ workerId
845
+ workerName
846
+ status
847
+ capabilities
848
+ scope
849
+ scopeId
850
+ createdAt
851
+ updatedAt
852
+ }
853
+ }
854
+ }
855
+ `,UPDATE_AGENT:`
856
+ mutation UpdateAIWorker($input: UpdateAIWorkerInput!) {
857
+ updateAIWorker(input: $input) {
858
+ success
859
+ message
860
+ worker {
861
+ id
862
+ status
863
+ capabilities
864
+ updatedAt
865
+ }
866
+ }
867
+ }
868
+ `,GET_AGENT_STATUS:`
869
+ query GetAIWorker($workerId: String!) {
870
+ aiWorker(workerId: $workerId) {
871
+ id
872
+ workerId
873
+ workerName
874
+ status
875
+ capabilities
876
+ scope
877
+ lastHeartbeatAt
878
+ createdAt
879
+ updatedAt
880
+ }
881
+ }
882
+ `,GET_CLAIMED_WORK:`
883
+ query GetAgentClaimedWork($workerId: String!) {
884
+ aiWorkQueue(search: {
885
+ aiWorkerId: $workerId,
886
+ status: CLAIMED
887
+ }) {
888
+ id
889
+ status
890
+ aiWorkerId
891
+ priority
892
+ startedAt
893
+ createdAt
894
+ deadline
895
+ metadataJson
896
+ workType
897
+ project {
898
+ id
899
+ name
900
+ description
901
+ }
902
+ story {
903
+ id
904
+ title
905
+ description
906
+ }
907
+ task {
908
+ id
909
+ title
910
+ description
911
+ }
912
+ }
913
+ }
914
+ `,UPDATE_WORK_STATUS:`
915
+ mutation UpdateAIWork($input: UpdateAIWorkInput!) {
916
+ updateAIWork(input: $input) {
917
+ id
918
+ status
919
+ updatedAt
920
+ }
921
+ }
922
+ `,COMPLETE_WORK:`
923
+ mutation UpdateAIWork($input: UpdateAIWorkInput!) {
924
+ updateAIWork(input: $input) {
925
+ id
926
+ status
927
+ completedAt
928
+ results
929
+ }
930
+ }
931
+ `,SEND_HEARTBEAT:`
932
+ mutation UpdateAIWorkerHeartbeat($input: AIWorkerHealthCheckInput!) {
933
+ updateAIWorkerHeartbeat(input: $input) {
934
+ success
935
+ message
936
+ reconciliationNeeded
937
+ discrepancies {
938
+ workItemId
939
+ serverStatus
940
+ clientStatus
941
+ recommendedAction
942
+ }
943
+ }
944
+ }
945
+ `,GET_AGENT_STATS:`
946
+ query GetAgentStatistics($workerId: String!) {
947
+ aiWorker(workerId: $workerId) {
948
+ id
949
+ workerId
950
+ status
951
+ capabilities
952
+ stats {
953
+ totalAssigned
954
+ totalCompleted
955
+ totalFailed
956
+ averageCompletionTime
957
+ successRate
958
+ lastActivityAt
959
+ }
960
+ recentWork {
961
+ id
962
+ status
963
+ startedAt
964
+ completedAt
965
+ project {
966
+ id
967
+ name
968
+ }
969
+ story {
970
+ id
971
+ title
972
+ }
973
+ }
974
+ }
975
+ }
976
+ `,WORK_ASSIGNMENT_SUBSCRIPTION:`
977
+ subscription AIWorkAssigned($workerId: String!) {
978
+ aiWorkAssigned(workerId: $workerId) {
979
+ assignmentId
980
+ workerId
981
+ workItemType
982
+ workItemId
983
+ priority
984
+ assignedAt
985
+ deadline
986
+ workData
987
+ project {
988
+ id
989
+ name
990
+ }
991
+ story {
992
+ id
993
+ title
994
+ }
995
+ task {
996
+ id
997
+ title
998
+ }
999
+ }
1000
+ }
1001
+ `}});var Ft,Ya=M(()=>{"use strict";j();Ja();Ft=class{constructor(r){this.httpClient=r}async registerAgent(r){s.info("Registering agent with Main API",{workerId:r.workerId,capabilities:r.capabilities,scope:r.scope});let e={input:{workerId:r.workerId,workerName:r.workerName,capabilities:r.capabilities,scope:r.scope,scopeId:this.httpClient.getAuthenticatedUser()?.id,maxConcurrentTasks:r.maxConcurrentTasks,metadata:{...r.metadata,registeredVia:"main_api_integration",authMethod:"api_key_to_jwt",registrationTimestamp:new Date().toISOString()},accessibleWorkspaces:[],accessibleServices:["task-shepherd-main-api"]}},a=(await this.httpClient.post({query:ve.REGISTER_AGENT,variables:e,operationName:"RegisterAIWorker"})).data.registerAIWorker;if(!a.success)throw new Error(`Agent registration failed: ${a.message}`);return s.info("\u2705 Agent registered successfully with Main API",{workerId:r.workerId,workerData:a.worker}),a.worker}async sendHeartbeat(r){let e={input:{workerId:r.workerId,isHealthy:r.isHealthy,cpuUsage:r.cpuUsage,memoryUsage:r.memoryUsage,responseTime:r.responseTime||0,errorRate:r.errorRate||0,localWorkState:r.localWorkState,timestamp:new Date().toISOString(),agentMetadata:{platform:process.platform,nodeVersion:process.version,uptime:process.uptime()}}},a=(await this.httpClient.post({query:ve.SEND_HEARTBEAT,variables:e,operationName:"UpdateAIWorkerHeartbeat"})).data.updateAIWorkerHeartbeat;if(!a.success){s.warn("Heartbeat failed",{workerId:r.workerId,message:a.message});return}a.reconciliationNeeded&&a.discrepancies?.length>0&&s.info("Work state discrepancies detected, reconciliation needed",{workerId:r.workerId,discrepancies:a.discrepancies}),s.debug("Heartbeat sent successfully",{workerId:r.workerId,reconciliationNeeded:a.reconciliationNeeded})}async getClaimedWork(r){let t=(await this.httpClient.post({query:ve.GET_CLAIMED_WORK,variables:{workerId:r},operationName:"GetAgentClaimedWork"})).data?.aiWorkQueue||[];return s.debug("Retrieved claimed work from Main API",{workerId:r,itemCount:t.length}),t.map(a=>{let i={};if(a.metadataJson)try{i=typeof a.metadataJson=="string"?JSON.parse(a.metadataJson):a.metadataJson}catch(n){s.warn("Failed to parse work item metadata",{workItemId:a.id,metadataJson:a.metadataJson,error:n instanceof Error?n.message:String(n)})}return{id:a.id,type:a.workType||i?.workType||"unknown",projectId:a.project?.id,storyId:a.story?.id,taskId:a.task?.id,priority:a.priority,status:a.status.toLowerCase(),assignedAt:a.startedAt,deadline:a.deadline,metadata:i,project:a.project,story:a.story,task:a.task}})}async updateWorkItem(r,e,t){let a={input:{workId:r,status:e.toUpperCase(),metadata:t?{...t,updatedVia:"main_api_integration",lastUpdateTimestamp:new Date().toISOString()}:void 0,updatedAt:new Date().toISOString()}};await this.httpClient.post({query:ve.UPDATE_WORK_STATUS,variables:a,operationName:"UpdateAIWork"}),s.debug("Work item status updated in Main API",{workId:r,status:e,hasMetadata:!!t})}async completeWorkItem(r,e,t){let a={input:{workId:r,status:"COMPLETED",results:e,metadata:{...t,completedVia:"main_api_integration",completionTimestamp:new Date().toISOString()},completedAt:new Date().toISOString()}};await this.httpClient.post({query:ve.COMPLETE_WORK,variables:a,operationName:"UpdateAIWork"}),s.info("Work item completed in Main API",{workId:r,hasResults:!!e})}async failWorkItem(r,e,t){let a={input:{workId:r,status:"FAILED",failureReason:e,metadata:{...t,failedVia:"main_api_integration",failureTimestamp:new Date().toISOString(),error:e},completedAt:new Date().toISOString()}};await this.httpClient.post({query:ve.UPDATE_WORK_STATUS,variables:a,operationName:"UpdateAIWork"}),s.error("Work item failed in Main API",{workId:r,error:e})}async getAgentStats(r){return(await this.httpClient.post({query:ve.GET_AGENT_STATS,variables:{workerId:r},operationName:"GetAgentStatistics"})).data?.aiWorker}getWorkAssignmentSubscription(r){return{id:"ai-work-assigned",query:ve.WORK_ASSIGNMENT_SUBSCRIPTION,variables:{workerId:r},handler:void 0}}}});var Xa,Lt,Za=M(()=>{"use strict";Xa=require("events");j();Er();xr();jr();Rt();Pr();Ya();Lt=class extends Xa.EventEmitter{constructor(e,t,a){super();this.config=e;this.resourceManager=t;this.tcpService=a;this.registered=!1;this.connected=!1;this.closed=!1;this.setupAgentPauseHandling(),this.httpClient=new He(e.apiKey,e.apiUrl,e.connectionTimeout,e.retryAttempts,e.retryDelay),this.mainApiIntegration=new Ft(this.httpClient),t.register("agent-http-client",this.httpClient),Fa(this.httpClient,e.workerId),this.workHandlerRegistry=new Ke(this.httpClient,this.tcpService),s.info("AgentService initialized with Main API integration",{workerId:e.workerId,capabilities:e.capabilities,registeredWorkTypes:this.workHandlerRegistry.getRegisteredWorkTypes(),apiIntegration:"main_api",errorTrackingEnabled:!0})}getHttpClient(){return this.httpClient}getTcpService(){return this.tcpService}async connect(){if(this.closed)throw new Error("AgentService is closed");if(this.connected){s.warn("AgentService already connected");return}s.info("\u{1F680} Starting simplified agent startup...");let e=Date.now();try{await this.authenticateAndRegister(),this.startHeartbeat();let t=[];t.push(this.backgroundProcessClaimedWork()),Promise.allSettled(t).then(i=>{i.forEach(n=>{n.status==="rejected"?s.warn("\u274C Background task ClaimedWork failed:",n.reason):s.info("\u2705 Background task ClaimedWork completed successfully")})}),setTimeout(async()=>{try{s.info("\u{1F504} Performing scheduled claimed work check..."),await this.processClaimedWorkImmediate()}catch(i){s.warn("\u26A0\uFE0F Scheduled claimed work check failed",{error:i instanceof Error?i.message:String(i)})}},2e3),this.connected=!0,this.emit("connected");let a=Date.now()-e;s.info("\u2705 Agent startup completed",{workerId:this.config.workerId,capabilities:this.config.capabilities,startupDuration:`${a}ms`,authenticated:this.httpClient.isAuthenticated()})}catch(t){let a=Date.now()-e;throw s.error("\u274C Agent startup failed",{error:t instanceof Error?t.message:String(t),duration:`${a}ms`}),await this.cleanup(),t}}async authenticateAndRegister(){s.info("\u{1F510} Authenticating with backend..."),await this.httpClient.authenticate(),s.info("\u{1F4DD} Registering worker with retry logic..."),await this.registerWorkerWithRetry(),s.info("\u2705 Authentication and registration completed")}async backgroundProcessClaimedWork(){try{s.info("\u{1F50D} Processing existing claimed work..."),await this.processClaimedWorkImmediate(),s.info("\u2705 Claimed work processing completed")}catch(e){s.warn("\u26A0\uFE0F Claimed work processing failed (will retry later)",{error:e instanceof Error?e.message:String(e)}),setTimeout(()=>this.backgroundProcessClaimedWork(),3e4)}}async registerWorkerWithRetry(){s.info("Starting agent registration with Main API",{workerId:this.config.workerId,capabilities:this.config.capabilities,maxRetries:3});for(let a=1;a<=3;a++)try{await this.registerWorker();return}catch(i){if(s.warn(`Main API worker registration attempt ${a}/3 failed`,{error:i instanceof Error?i.message:String(i),workerId:this.config.workerId}),a===3)throw new Error(`Main API worker registration failed after 3 attempts: ${i instanceof Error?i.message:String(i)}`);await new Promise(n=>setTimeout(n,1e3*a))}}async registerWorker(){try{let e=this.normalizeCapabilities(this.config.capabilities),t={workerId:this.config.workerId,workerName:`Task Shepherd AI Agent (${this.config.workerId})`,capabilities:e,scope:"AGENT",maxConcurrentTasks:3,metadata:{platform:process.platform,nodeVersion:process.version,agentVersion:"1.0.0",startedAt:new Date().toISOString(),authMethod:"api_key",clientType:"agent",apiIntegration:"main_api",capabilityMappings:this.config.capabilities}},a=await this.mainApiIntegration.registerAgent(t);this.registered=!0,this.emit("workerRegistered",{workerId:this.config.workerId,capabilities:this.config.capabilities,registeredAt:new Date,workerData:a,apiIntegration:"main_api"})}catch(e){throw s.error("\u274C Agent registration with Main API failed:",e),e}}normalizeCapabilities(e){let t={"project-reviewer":"PROJECT_REVIEW","project-review":"PROJECT_REVIEW",project_review:"PROJECT_REVIEW","code-review":"CODE_REVIEW",code_review:"CODE_REVIEW","development-planning":"DEVELOPMENT_PLANNING",implementation_plan:"IMPLEMENTATION_PLAN","story-implementation":"STORY_IMPLEMENTATION",story_implementation:"STORY_IMPLEMENTATION","review-application":"REVIEW_APPLICATION",review_application:"REVIEW_APPLICATION",testing:"TESTING",documentation:"DOCUMENTATION"};return e.map(a=>{let i=t[a];return i||(s.warn(`Unknown capability '${a}', using uppercase conversion`,{capability:a}),a.toUpperCase().replace(/-/g,"_"))})}async processClaimedWorkImmediate(){s.info("\u{1F50D} Starting immediate claimed work processing via Main API...",{workerId:this.config.workerId});try{let e=await this.mainApiIntegration.getClaimedWork(this.config.workerId);if(s.info("\u{1F4CB} Claimed work retrieved from Main API",{workerId:this.config.workerId,foundItems:e.length,items:e.map(o=>({id:o.id,type:o.type,status:o.status,projectName:o.project?.name||o.story?.title||"Unknown"}))}),e.length===0){s.info("\u2705 No claimed work found for processing");return}s.info(`\u{1F680} Processing ${e.length} claimed work items immediately`);let t=e.slice(0,3).map(async o=>{try{let c=this.convertMainApiWorkToAssignment(o);s.info("\u26A1 Processing claimed work item",{assignmentId:c.assignmentId,workItemType:c.workItemType,workItemId:c.workItemId,projectName:o.project?.name||o.story?.title}),await this.handleWorkAssignment(c),s.info(`\u2705 Successfully completed claimed work: ${c.assignmentId}`)}catch(c){s.error("\u274C Failed to process claimed work item",{workId:o.id,error:c instanceof Error?c.message:String(c),stack:c instanceof Error?c.stack:void 0})}}),a=await Promise.allSettled(t),i=a.filter(o=>o.status==="fulfilled").length,n=a.filter(o=>o.status==="rejected").length;s.info("\u2705 Claimed work processing batch completed",{total:e.length,successful:i,failed:n})}catch(e){throw s.error("\u274C Failed to process claimed work immediately",{workerId:this.config.workerId,error:e instanceof Error?e.message:String(e),stack:e instanceof Error?e.stack:void 0}),e}}async reportWorkFailureToBackend(e,t,a){try{let i=`
1002
+ mutation UpdateAIWork($input: UpdateAIWorkInput!) {
1003
+ updateAIWork(input: $input) {
1004
+ id
1005
+ status
1006
+ metadata
1007
+ }
1008
+ }
1009
+ `,o={...e.workData||{},failureReason:t,failedAt:new Date().toISOString(),failedBy:e.workerId||this.config.workerId,assignmentId:e.assignmentId,workItemType:e.workItemType,error:t,errorStack:a,lastAttempt:{assignmentId:e.assignmentId,timestamp:new Date().toISOString(),error:t,workerId:e.workerId||this.config.workerId}};await this.httpClient.post({query:i,variables:{input:{workId:e.assignmentId,status:"FAILED",metadataJson:JSON.stringify(o)}},operationName:"UpdateAIWork"}),s.info("Successfully reported work failure to backend",{assignmentId:e.assignmentId,workItemType:e.workItemType,errorMessage:t.substring(0,200)})}catch(i){s.error("Failed to report error to backend",{assignmentId:e.assignmentId,originalError:t,reportError:i instanceof Error?i.message:String(i)})}}convertMainApiWorkToAssignment(e){let t=e.projectId||e.storyId||e.taskId;if(!t)throw new Error(`Work item ${e.id} has no valid project, story, or task ID`);let a={...e.metadata,projectId:e.projectId,project:e.project,storyId:e.storyId,story:e.story,taskId:e.taskId,task:e.task};return{assignmentId:e.id,workerId:this.config.workerId,workItemType:e.type||"project-review",workItemId:t,priority:e.priority||1,assignedAt:e.assignedAt,deadline:e.deadline,workData:a}}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(async()=>{try{await this.sendHeartbeat()}catch(e){s.error("Heartbeat failed:",e),this.emit("heartbeatFailed",e)}},this.config.heartbeatInterval),this.resourceManager.register("agent-heartbeat",{close:async()=>{this.stopHeartbeat()}}),s.debug("Heartbeat timer started",{interval:this.config.heartbeatInterval})}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0,s.debug("Heartbeat timer stopped"))}async sendHeartbeat(){try{let e=rt(),t=[];try{let i=e.getCompletedItems(5,0);if(i&&i.items)for(let n of i.items){let o=new Date(n.completedAt).getTime(),c=Date.now()-30*60*1e3;o>c&&t.push({workItemId:n.id,status:n.status==="completed"?"completed":"failed",startedAt:n.startedAt||new Date().toISOString(),completedAt:n.completedAt||new Date().toISOString(),lastUpdate:new Date().toISOString()})}}catch(i){s.warn("Failed to collect local work state for heartbeat",{error:i instanceof Error?i.message:String(i)})}let a={workerId:this.config.workerId,isHealthy:!0,cpuUsage:0,memoryUsage:Math.round(process.memoryUsage().heapUsed/1024/1024),responseTime:0,errorRate:0,localWorkState:t.length>0?t:void 0};await this.mainApiIntegration.sendHeartbeat(a),this.emit("heartbeatSent",{workerId:this.config.workerId,timestamp:new Date,localWorkStateItems:t.length})}catch(e){throw s.error("Failed to send heartbeat to Main API:",e),e}}async handleWorkAssignment(e){let t=xe.getInstance();if(t.isPausedState()){let n=t.getResumeInfo();if(!n){s.error("Agent is paused but no resume info available");return}s.warn("\u{1F6AB} Cannot process work assignment - agent is paused",{assignmentId:e.assignmentId,resumeTimestamp:n.resumeTimestamp,resumeDate:n.resumeDate?.toISOString(),timeUntilResumeMs:n.timeUntilResumeMs}),n.resumeTimestamp&&n.resumeDate&&n.timeUntilResumeMs!==void 0&&await this.releaseWorkItemDueToPause(e,{resumeTimestamp:n.resumeTimestamp,resumeDate:n.resumeDate,timeUntilResumeMs:n.timeUntilResumeMs});return}let a=Date.now();s.info("\u{1F680} Starting work assignment processing",{assignmentId:e.assignmentId,workItemType:e.workItemType,workItemId:e.workItemId,priority:e.priority,assignedAt:e.assignedAt,deadline:e.deadline,hasWorkData:!!e.workData,workDataKeys:e.workData?Object.keys(e.workData):[]});let i=null;try{this.emit("workAssigned",e);let n={assignmentId:e.assignmentId,workerId:e.workerId||this.config.workerId,workItemType:e.workItemType,workItemId:e.workItemId,priority:e.priority||1,assignedAt:e.assignedAt?new Date(e.assignedAt):new Date,deadline:e.deadline?new Date(e.deadline):void 0,workData:e.workData};s.info("\u{1F527} Routing work to handler registry",{assignmentId:n.assignmentId,workItemType:n.workItemType,registeredHandlers:this.workHandlerRegistry.getRegisteredWorkTypes()}),await this.workHandlerRegistry.handle(n);let o=Date.now(),c=o-a;s.info("\u2705 Work assignment completed successfully",{assignmentId:e.assignmentId,workItemType:e.workItemType,duration:c}),i={id:e.assignmentId,type:this.mapWorkTypeToCompletedType(e.workItemType),status:"completed",priority:e.priority||1,projectId:e.workItemId,projectName:e.workData?.projectName||"Unknown Project",title:e.workData?.title||`${e.workItemType} work`,description:e.workData?.description,assignedTo:e.workerId||this.config.workerId,actualDuration:c,createdAt:e.assignedAt||new Date().toISOString(),startedAt:new Date(a).toISOString(),completedAt:new Date(o).toISOString(),metadata:e.workData}}catch(n){let o=Date.now(),c=o-a,d=n instanceof Error?n.message:String(n),p=n instanceof Error?n.stack:void 0;s.error("Failed to handle work assignment:",{assignmentId:e.assignmentId,workItemType:e.workItemType,error:d,stack:p,duration:c}),await this.reportWorkFailureToBackend(e,d,p),i={id:e.assignmentId,type:this.mapWorkTypeToCompletedType(e.workItemType),status:"failed",priority:e.priority||1,projectId:e.workItemId,projectName:e.workData?.projectName||"Unknown Project",title:e.workData?.title||`${e.workItemType} work`,description:e.workData?.description,assignedTo:e.workerId||this.config.workerId,actualDuration:c,createdAt:e.assignedAt||new Date().toISOString(),startedAt:new Date(a).toISOString(),completedAt:new Date(o).toISOString(),metadata:{...e.workData,error:n instanceof Error?n.message:String(n)}},this.emit("workAssignmentFailed",{assignment:e,error:n})}finally{if(i)try{rt().addCompletedItem(i),s.info("\u{1F4CB} Added work item to completed work tracking",{workItemId:i.id,status:i.status,type:i.type})}catch(n){s.error("Failed to add completed work item to tracking service",{workItemId:i.id,error:n instanceof Error?n.message:String(n)})}}}mapWorkTypeToCompletedType(e){switch(e){case"project-review":case"project_review":case"project-reviewer":return"project_review";case"code-review":case"code_review":case"code-reviewer":return"code_review";case"development-planning":case"development_planning":case"development-planner":case"implementation_plan":return"development_planning";case"story-implementation":case"story_implementation":case"story-developer":return"story_implementation";case"review-application":case"review-application-agent":return"project_review";default:return s.warn("Unknown work type, defaulting to project_review",{workType:e}),"project_review"}}isConnected(){return this.connected&&!this.closed}isRegistered(){return this.registered}isClosed(){return this.closed}getStatus(){return{connected:this.connected,registered:this.registered,closed:this.closed,workerId:this.config.workerId,capabilities:this.config.capabilities,authenticated:this.httpClient.isAuthenticated(),uptime:this.connected?Date.now()-this.connectedAt:0,workHandlers:this.workHandlerRegistry.getStats()}}async cleanup(){this.stopHeartbeat(),this.connected=!1,this.registered=!1}async close(){if(!this.closed){this.closed=!0,s.info("Closing AgentService...");try{this.stopHeartbeat(),this.connected=!1,this.registered=!1,this.emit("closing"),s.info("\u2713 AgentService closed successfully"),this.emit("closed")}catch(e){throw s.error("Error during AgentService close:",e),e}}}setupAgentPauseHandling(){let e=xe.getInstance();e.on("agent_paused",t=>{s.warn("\u{1F6AB} Agent paused due to usage limits",t),this.emit("agentPaused",t)}),e.on("agent_resumed",t=>{s.info("\u2705 Agent resumed after usage limit reset",t),this.emit("agentResumed",t)})}async releaseWorkItemDueToPause(e,t){try{let a=`
1010
+ mutation UpdateAIWork($input: UpdateAIWorkInput!) {
1011
+ updateAIWork(input: $input) {
1012
+ id
1013
+ status
1014
+ }
1015
+ }
1016
+ `,i=`Agent paused for Claude usage limits. Will resume at ${t.resumeDate.toISOString()}`,n={input:{workId:e.assignmentId,status:"PENDING",failureReason:i,completedAt:null,metadata:{pausedForUsageLimit:!0,pausedAt:new Date().toISOString(),resumeTimestamp:t.resumeTimestamp,resumeDate:t.resumeDate.toISOString()}}};await this.httpClient.executeGraphQLMutation(a,n),s.info("Work item released back to queue due to agent pause",{assignmentId:e.assignmentId,resumeTimestamp:t.resumeTimestamp})}catch(a){s.error("Failed to release work item due to agent pause",{assignmentId:e.assignmentId,error:a instanceof Error?a.message:String(a)})}}}});var Ut,ei=M(()=>{"use strict";j();Ut=class{constructor(){this.resources=new Map;this.isClosing=!1}register(r,e){if(this.isClosing){s.warn(`Cannot register resource '${r}' during shutdown`);return}this.resources.has(r)&&s.warn(`Resource '${r}' already registered, replacing`),this.resources.set(r,e),s.debug(`Resource registered: ${r}`)}unregister(r){this.resources.delete(r)&&s.debug(`Resource unregistered: ${r}`)}async closeAll(){if(this.isClosing){s.warn("CloseAll already in progress");return}this.isClosing=!0;let r=this.resources.size;if(r===0){s.info("No resources to close");return}s.info(`Closing ${r} resources...`);let e=Array.from(this.resources.entries()).reverse(),t=[];for(let[n,o]of e)try{await Promise.race([o.close(),new Promise((c,d)=>setTimeout(()=>d(new Error("Resource close timeout")),5e3))]),t.push({name:n,success:!0}),s.info(`\u2713 Closed: ${n}`)}catch(c){let d=c instanceof Error?c:new Error(String(c));t.push({name:n,success:!1,error:d}),s.error(`\u2717 Failed to close ${n}:`,d.message)}this.resources.clear();let a=t.filter(n=>n.success).length,i=t.filter(n=>!n.success).length;i===0?s.info(`\u2713 All ${a} resources closed successfully`):s.warn(`\u26A0 ${a} resources closed, ${i} failed`)}getRegisteredResources(){return Array.from(this.resources.keys())}getResourceCount(){return this.resources.size}hasResource(r){return this.resources.has(r)}isShuttingDown(){return this.isClosing}}});var Fr,ti,zt,ri=M(()=>{"use strict";Fr=A(require("net"));j();ti=require("events"),zt=class extends ti.EventEmitter{constructor(e=8549){super();this.server=null;this.connections=new Set;this.port=e}async start(){return new Promise((e,t)=>{this.server=Fr.createServer(a=>{this.handleConnection(a)}),this.server.on("listening",()=>{let a=this.server.address(),i=typeof a=="object"&&a?a.port:this.port;s.info(`TCP IPC server started on port ${i}`),e()}),this.server.on("error",a=>{a.code==="EADDRINUSE"?(s.warn(`Port ${this.port} is in use, attempting to kill existing process`),this.killProcessOnPort(this.port).then(()=>{setTimeout(()=>{s.info(`Retrying TCP IPC server start on port ${this.port}`),this.retryStart(e,t)},1e3)}).catch(()=>{this.port=this.port+1,s.info(`Trying alternative port ${this.port}`),this.retryStart(e,t)})):(s.error("TCP IPC server error:",a),t(a))}),this.server.listen({port:this.port,host:"localhost",exclusive:!1})})}retryStart(e,t){this.server&&(this.server.removeAllListeners(),this.server.close()),this.server=Fr.createServer(a=>{this.handleConnection(a)}),this.server.on("listening",()=>{let a=this.server.address(),i=typeof a=="object"&&a?a.port:this.port;s.info(`TCP IPC server started on port ${i} (retry)`),e()}),this.server.on("error",a=>{s.error("TCP IPC server retry failed:",a),t(a)}),this.server.listen({port:this.port,host:"localhost",exclusive:!1})}async killProcessOnPort(e){return new Promise((t,a)=>{let{exec:i}=require("child_process");i(`lsof -ti :${e}`,(n,o)=>{if(n||!o.trim()){a(new Error(`No process found on port ${e}`));return}let c=o.trim();s.info(`Found process ${c} using port ${e}, attempting to kill`),i(`kill -9 ${c}`,d=>{d?a(d):(s.info(`Successfully killed process ${c}`),t())})})})}async stop(){return new Promise(e=>{if(this.server){this.connections.forEach(a=>{a.destroy()}),this.connections.clear();let t=setTimeout(()=>{s.warn("TCP IPC server close timeout, forcing shutdown"),this.server=null,e()},5e3);this.server.close(()=>{clearTimeout(t),s.info("TCP IPC server stopped gracefully"),this.server=null,e()}),this.server.unref()}else e()})}handleConnection(e){this.connections.add(e),e.setKeepAlive(!0,3e4),e.setTimeout(6e4),e.setNoDelay(!0),s.debug("New TCP IPC connection established");let t="";e.on("data",a=>{t+=a.toString();let i=t.split(`
1017
+ `);t=i.pop()||"";for(let n of i)if(n.trim())try{let o=JSON.parse(n);this.handleMessage(o)}catch(o){s.error("Failed to parse IPC message:",{error:o instanceof Error?o.message:"Unknown error",message:n})}}),e.on("timeout",()=>{s.debug("TCP IPC socket timeout, closing connection"),e.destroy()}),e.on("error",a=>{s.error("TCP IPC socket error:",a),this.connections.delete(e)}),e.on("close",a=>{this.connections.delete(e),s.debug("TCP IPC connection closed",{hadError:a})})}handleMessage(e){s.debug("Received IPC message:",{type:e.type,projectId:e.projectId}),this.emit("message",e),this.emit(e.type,e)}isRunning(){return this.server!==null&&this.server.listening}getPort(){return this.port}getConnectionCount(){return this.connections.size}}});var ge,$t,Ht,ai=M(()=>{"use strict";ge=A(require("fs")),$t=A(require("path"));j();Ht=class{constructor(r=process.cwd()){this.mcpTools=["mcp__task-shepherd-agent-mcp__submit_project_analysis","mcp__task-shepherd-agent-mcp__get_analysis_result","mcp__task-shepherd-agent-mcp__submit_implementation_plan","mcp__task-shepherd-agent-mcp__submit_task_implementation","mcp__task-shepherd-agent-mcp__submit_story_progress"];this.settingsPath=$t.join(r,".claude","settings.local.json")}async ensureMCPToolsAllowed(){try{let r=$t.dirname(this.settingsPath);ge.existsSync(r)||(ge.mkdirSync(r,{recursive:!0}),s.info("Created .claude directory",{path:r}));let e={};if(ge.existsSync(this.settingsPath))try{let a=ge.readFileSync(this.settingsPath,"utf8");e=JSON.parse(a)}catch(a){s.warn("Failed to parse existing settings, creating new file",{path:this.settingsPath,error:a instanceof Error?a.message:String(a)})}e.$schema||(e.$schema="https://json.schemastore.org/claude-code-settings.json"),e.permissions||(e.permissions={}),e.permissions.allow||(e.permissions.allow=[]);let t=0;for(let a of this.mcpTools)e.permissions.allow.includes(a)||(e.permissions.allow.push(a),t++);t>0?(ge.writeFileSync(this.settingsPath,JSON.stringify(e,null,2)),s.info("Updated Claude settings with MCP tools",{path:this.settingsPath,toolsAdded:t,totalTools:e.permissions.allow.length})):s.debug("Claude settings already up to date",{path:this.settingsPath,totalTools:e.permissions.allow.length})}catch(r){throw s.error("Failed to update Claude settings",{path:this.settingsPath,error:r instanceof Error?r.message:String(r)}),r}}getCurrentAllowedTools(){try{if(!ge.existsSync(this.settingsPath))return[];let r=ge.readFileSync(this.settingsPath,"utf8");return JSON.parse(r).permissions?.allow||[]}catch(r){return s.warn("Failed to read Claude settings",{path:this.settingsPath,error:r instanceof Error?r.message:String(r)}),[]}}async addTools(r){this.mcpTools.push(...r),await this.ensureMCPToolsAllowed()}}});var it={};be(it,{WorkspaceRegistryService:()=>Bt,getWorkspaceRegistry:()=>he});function he(){return Lr||(Lr=new Bt),Lr}var qt,at,Bt,Lr,Ce=M(()=>{"use strict";qt=require("fs"),at=A(require("path"));j();Bt=class{constructor(){this.registry=new Map;let r=at.join(process.env.HOME||process.env.USERPROFILE||"",".task-shepherd-agent");this.registryPath=at.join(r,"workspace-registry.json")}async initialize(){try{await this.ensureDataDirectory(),await this.loadRegistry(),s.info("Workspace registry initialized",{registryPath:this.registryPath,workspaceCount:this.registry.size})}catch(r){s.error("Failed to initialize workspace registry",{error:r instanceof Error?r.message:String(r)})}}async ensureDataDirectory(){let r=at.dirname(this.registryPath);try{await qt.promises.mkdir(r,{recursive:!0})}catch(e){s.error("Failed to create data directory",{dataDir:r,error:e instanceof Error?e.message:String(e)})}}async loadRegistry(){try{let r=await qt.promises.readFile(this.registryPath,"utf-8"),e=JSON.parse(r);this.registry.clear();for(let t of e)this.registry.set(t.workspace.workspaceId,t);s.info("Loaded workspace registry from disk",{workspaceCount:this.registry.size})}catch(r){r.code==="ENOENT"?s.info("No existing workspace registry found, starting fresh"):s.error("Failed to load workspace registry",{error:r instanceof Error?r.message:String(r)})}}async saveRegistry(){try{let r=Array.from(this.registry.values());await qt.promises.writeFile(this.registryPath,JSON.stringify(r,null,2),"utf-8"),s.debug("Saved workspace registry to disk",{workspaceCount:r.length})}catch(r){s.error("Failed to save workspace registry",{error:r instanceof Error?r.message:String(r)})}}async addWorkspace(r){let e={workspace:r,discoveredAt:new Date().toISOString(),syncStatus:"pending"},t=this.registry.get(r.workspaceId);t&&(e.lastSyncedAt=t.lastSyncedAt,e.syncStatus=t.syncStatus,e.syncError=t.syncError),this.registry.set(r.workspaceId,e),await this.saveRegistry(),s.info("Added workspace to local registry",{workspaceId:r.workspaceId,name:r.name,syncStatus:e.syncStatus})}async addWorkspaces(r){for(let e of r)await this.addWorkspace(e)}getAllWorkspaces(){return Array.from(this.registry.values())}getWorkspacesBySyncStatus(r){return Array.from(this.registry.values()).filter(e=>e.syncStatus===r)}getWorkspace(r){return this.registry.get(r)}async removeWorkspace(r){this.registry.delete(r)&&(await this.saveRegistry(),s.info("Removed workspace from registry",{workspaceId:r}))}async markWorkspaceSynced(r){let e=this.registry.get(r);e&&(e.syncStatus="synced",e.lastSyncedAt=new Date().toISOString(),e.syncError=void 0,this.registry.set(r,e),await this.saveRegistry(),s.info("Marked workspace as synced",{workspaceId:r,lastSyncedAt:e.lastSyncedAt}))}async markWorkspaceSyncFailed(r,e){let t=this.registry.get(r);t&&(t.syncStatus="failed",t.syncError=e,this.registry.set(r,t),await this.saveRegistry(),s.warn("Marked workspace sync as failed",{workspaceId:r,error:e}))}getSyncStats(){let r=Array.from(this.registry.values());return{total:r.length,synced:r.filter(e=>e.syncStatus==="synced").length,pending:r.filter(e=>e.syncStatus==="pending").length,failed:r.filter(e=>e.syncStatus==="failed").length}}async clearRegistry(){this.registry.clear(),await this.saveRegistry(),s.info("Cleared workspace registry")}},Lr=null});var zr={};be(zr,{WorkspaceSyncService:()=>Gt,getWorkspaceSyncService:()=>Se});function Se(){return Ur||(Ur=new Gt),Ur}var ii,Gt,Ur,nt=M(()=>{"use strict";j();Ce();Ue();ii=require("events"),Gt=class extends ii.EventEmitter{constructor(e=3e4){super();this.syncIntervalMs=e;this.syncInProgress=!1;this.syncTimer=null;this.isConnected=!1}startPeriodicSync(){this.syncTimer||(s.info("Starting periodic workspace sync",{intervalMs:this.syncIntervalMs}),this.syncWorkspaces(),this.syncTimer=setInterval(()=>{this.syncWorkspaces()},this.syncIntervalMs))}stopPeriodicSync(){this.syncTimer&&(clearInterval(this.syncTimer),this.syncTimer=null,s.info("Stopped periodic workspace sync"))}setConnectionStatus(e,t=!0){this.isConnected=e,e&&t?(s.info("Backend connection established, triggering workspace sync"),this.syncWorkspaces()):e?s.info("Backend connection enabled"):s.warn("Backend connection lost, workspace sync will pause")}async forceSyncAllWorkspaces(){if(this.syncInProgress){s.debug("Workspace sync already in progress, skipping");return}if(!this.isConnected){s.debug("Backend not connected, skipping workspace sync");return}this.syncInProgress=!0,this.emit("syncStarted");try{let e=he(),t=e.getAllWorkspaces();if(t.length===0){s.debug("No workspaces to sync"),this.emit("syncCompleted",{synced:0,failed:0}),this.syncInProgress=!1;return}s.info("Force syncing ALL workspaces",{totalCount:t.length});let a=Ne(),i=0,n=0;for(let o of t)try{s.debug("Force syncing workspace",{workspaceId:o.workspace.workspaceId,name:o.workspace.name,currentStatus:o.syncStatus}),await a.registerWorkspace({workspaceId:o.workspace.workspaceId,name:o.workspace.name,path:o.workspace.path,pattern:o.workspace.pattern,description:`${o.workspace.pattern} workspace with ${o.workspace.services.length} services`,services:o.workspace.services.map(c=>({serviceId:c.id,name:c.name,path:c.relativePath||c.path,technology:c.technology,port:c.port}))}),await e.markWorkspaceSynced(o.workspace.workspaceId),i++,this.emit("workspaceSynced",o.workspace)}catch(c){s.error("Failed to force sync workspace",{workspaceId:o.workspace.workspaceId,error:c instanceof Error?c.message:String(c)}),await e.markWorkspaceSyncFailed(o.workspace.workspaceId,c instanceof Error?c.message:"Unknown error"),n++,this.emit("workspaceSyncFailed",o.workspace,c)}s.info("Force workspace sync completed",{total:t.length,synced:i,failed:n}),this.emit("syncCompleted",{synced:i,failed:n})}catch(e){s.error("Force workspace sync failed:",e),this.emit("syncFailed",e)}finally{this.syncInProgress=!1}}async syncWorkspaces(){if(this.syncInProgress){s.debug("Workspace sync already in progress, skipping");return}if(!this.isConnected){s.debug("Backend not connected, skipping workspace sync");return}this.syncInProgress=!0,this.emit("syncStarted");try{let e=he(),t=e.getWorkspacesBySyncStatus("pending"),a=e.getWorkspacesBySyncStatus("failed"),i=[...t,...a];if(i.length===0){s.debug("No workspaces to sync"),this.emit("syncCompleted",{synced:0,failed:0}),this.syncInProgress=!1;return}s.info("Starting workspace sync",{pendingCount:t.length,failedRetryCount:a.length});let n=Ne(),o=0,c=0;for(let d of i)try{s.debug("Syncing workspace",{workspaceId:d.workspace.workspaceId,name:d.workspace.name}),await n.registerWorkspace({workspaceId:d.workspace.workspaceId,name:d.workspace.name,path:d.workspace.path,pattern:d.workspace.pattern,description:`${d.workspace.pattern} workspace with ${d.workspace.services.length} services`,services:d.workspace.services.map(p=>({serviceId:p.id,name:p.name,path:p.relativePath||p.path,technology:p.technology,port:p.port}))}),await e.markWorkspaceSynced(d.workspace.workspaceId),o++,this.emit("workspaceSynced",d.workspace)}catch(p){s.error("Failed to sync workspace",{workspaceId:d.workspace.workspaceId,error:p instanceof Error?p.message:String(p)}),await e.markWorkspaceSyncFailed(d.workspace.workspaceId,p instanceof Error?p.message:"Unknown error"),c++,this.emit("workspaceSyncFailed",d.workspace,p)}s.info("Workspace sync completed",{synced:o,failed:c}),this.emit("syncCompleted",{synced:o,failed:c})}catch(e){s.error("Workspace sync failed",{error:e instanceof Error?e.message:String(e)}),this.emit("syncError",e)}finally{this.syncInProgress=!1}}async syncWorkspace(e){let t=he(),a=t.getWorkspace(e);if(!a)throw new Error(`Workspace not found: ${e}`);try{await Ne().registerWorkspace({workspaceId:a.workspace.workspaceId,name:a.workspace.name,path:a.workspace.path,pattern:a.workspace.pattern,description:`${a.workspace.pattern} workspace with ${a.workspace.services.length} services`,services:a.workspace.services.map(n=>({serviceId:n.id,name:n.name,technology:n.technology,port:n.port}))}),await t.markWorkspaceSynced(a.workspace.workspaceId),this.emit("workspaceSynced",a.workspace)}catch(i){throw await t.markWorkspaceSyncFailed(a.workspace.workspaceId,i instanceof Error?i.message:"Unknown error"),i}}getSyncStatus(){let e=he();return{isConnected:this.isConnected,syncInProgress:this.syncInProgress,stats:e.getSyncStats()}}},Ur=null});var Oe,st,Ie,Pe,ni=M(()=>{"use strict";Oe=class extends Error{constructor(e,t,a){super(e);this.organizationId=t;this.code=a;this.name="OrganizationError"}},st=class extends Oe{constructor(r,e){super(r,e,"CONNECTION_ERROR"),this.name="OrganizationConnectionError"}},Ie=class extends Oe{constructor(r,e){super(r,e,"CONFIG_ERROR"),this.name="OrganizationConfigError"}},Pe=class extends Oe{constructor(r){super(`Organization not found: ${r}`,r,"NOT_FOUND"),this.name="OrganizationNotFoundError"}}});var si,Re,ot,oi,Vt,ci=M(()=>{"use strict";si=require("events"),Re=A(require("fs/promises")),ot=A(require("path")),oi=A(require("os"));j();Ue();Et();nt();ni();Vt=class extends si.EventEmitter{constructor(e){super();this.organizations=new Map;this.clients=new Map;this.healthCheckInterval=null;this.syncInProgress=new Set;let t=e||ot.join(oi.homedir(),".task-shepherd-agent");this.configPath=ot.join(t,"config.json"),this.config={setupCompleted:!1,organizations:{}},s.info("OrganizationManager initialized",{configPath:this.configPath})}async initialize(){try{await this.ensureConfigDirectory(),await this.loadOrganizations(),this.startHealthChecking(),s.info("OrganizationManager initialization complete",{organizationCount:this.organizations.size,setupCompleted:this.config.setupCompleted})}catch(e){throw s.error("Failed to initialize OrganizationManager",{error:e instanceof Error?e.message:String(e)}),e}}async ensureConfigDirectory(){let e=ot.dirname(this.configPath);try{await Re.mkdir(e,{recursive:!0})}catch(t){throw s.error("Failed to create config directory",{directory:e,error:t instanceof Error?t.message:String(t)}),new Ie(`Failed to create config directory: ${e}`)}}async loadOrganizations(){try{if(!await Re.access(this.configPath).then(()=>!0).catch(()=>!1)){s.info("No existing configuration found, starting with empty config"),await this.saveConfiguration();return}let t=await Re.readFile(this.configPath,"utf-8");s.info("Loading organization config from file",{configPath:this.configPath,configSize:t.length});let a=JSON.parse(t);this.config=await this.validateAndMigrateConfig(a),this.organizations.clear();for(let[i,n]of Object.entries(this.config.organizations))this.organizations.set(i,n),s.info("Loaded organization with workspace data",{id:i,name:n.name,apiUrl:n.apiUrl,enabled:n.enabled,hasMetadata:!!n.metadata,workspaceCount:n.metadata?.workspaces?.length||0});s.info("Organizations loaded from configuration",{organizationCount:this.organizations.size,organizations:Array.from(this.organizations.keys())})}catch(e){throw s.error("Failed to load organizations",{configPath:this.configPath,error:e instanceof Error?e.message:String(e)}),e instanceof SyntaxError?new Ie("Invalid configuration file format"):e}}async validateAndMigrateConfig(e){if(e.taskShepherd&&!e.organizations)return s.info("Migrating from single-organization to multi-organization format"),{setupCompleted:!0,defaultOrganization:"default",organizations:{default:{id:"default",name:"Default Organization",apiUrl:e.taskShepherd.apiUrl,apiKey:e.taskShepherd.apiKey,enabled:!0,metadata:{description:"Migrated from single-organization setup",addedAt:new Date().toISOString()}}}};let t={setupCompleted:e.setupCompleted||!1,defaultOrganization:e.defaultOrganization,organizations:e.organizations||{}};for(let[a,i]of Object.entries(t.organizations))this.validateOrganizationConfig(i)||(s.warn("Invalid organization configuration detected",{organizationId:a}),delete t.organizations[a]);return t}validateOrganizationConfig(e){return!!(e.id&&e.name&&e.apiUrl&&e.apiKey&&typeof e.enabled=="boolean")}async saveConfiguration(){try{this.config.organizations={};for(let[a,i]of this.organizations.entries())this.config.organizations[a]=i;let e=JSON.stringify(this.config,null,2);await Re.writeFile(this.configPath,e,"utf-8");let t=Object.entries(this.config.organizations).map(([a,i])=>({orgId:a,workspaceCount:i.metadata?.workspaces?.length||0}));s.info("Configuration saved with workspace data",{configPath:this.configPath,organizationCount:this.organizations.size,workspaceCounts:t})}catch(e){throw s.error("Failed to save configuration",{configPath:this.configPath,error:e instanceof Error?e.message:String(e)}),new Ie("Failed to save configuration")}}async getOrganization(e){return this.organizations.get(e)||null}async getAllOrganizations(){return Array.from(this.organizations.values())}async hasOrganizations(){return this.organizations.size>0}async addOrganization(e){if(s.info("Adding new organization",{organizationId:e.id,name:e.name,apiUrl:e.apiUrl}),!this.validateOrganizationConfig(e))throw new Ie("Invalid organization configuration");if(this.organizations.has(e.id))throw new Ie(`Organization with ID '${e.id}' already exists`);let t=await this.testConnectionConfig(e);if(!t.success)throw new st(`Failed to connect to organization: ${t.error}`,e.id);e.metadata||(e.metadata={}),e.metadata.addedAt||(e.metadata.addedAt=new Date().toISOString()),this.organizations.set(e.id,e),await this.saveConfiguration(),await this.createClient(e.id),this.organizations.size===1&&!this.config.setupCompleted&&(this.config.setupCompleted=!0,this.config.defaultOrganization=e.id,await this.saveConfiguration(),this.emit("setupCompleted")),this.emit("organizationAdded",e),s.info("Organization added successfully",{organizationId:e.id,totalOrganizations:this.organizations.size})}async updateOrganization(e,t){let a=this.organizations.get(e);if(!a)throw new Pe(e);s.info("Updating organization",{organizationId:e,updates:Object.keys(t)});let i={...a,...t,id:e,metadata:{...a.metadata,...t.metadata}};if(!this.validateOrganizationConfig(i))throw new Ie("Invalid organization configuration after update");if(t.apiUrl||t.apiKey){let n=await this.testConnectionConfig(i);if(!n.success)throw new st(`Updated configuration failed connection test: ${n.error}`,e)}this.organizations.set(e,i),await this.saveConfiguration(),(t.apiUrl||t.apiKey)&&(this.clients.delete(e),await this.createClient(e)),this.emit("organizationUpdated",e,t),s.info("Organization updated successfully",{organizationId:e})}async removeOrganization(e){if(!this.organizations.get(e))throw new Pe(e);if(s.info("Removing organization",{organizationId:e}),this.organizations.delete(e),this.clients.delete(e),this.config.defaultOrganization===e){let a=Array.from(this.organizations.keys());this.config.defaultOrganization=a.length>0?a[0]:void 0}this.organizations.size===0&&(this.config.setupCompleted=!1),await this.saveConfiguration(),this.emit("organizationRemoved",e),s.info("Organization removed successfully",{organizationId:e,remainingOrganizations:this.organizations.size})}async getClient(e){let t=this.clients.get(e);return t||(t=await this.createClient(e)),t}async createClient(e){let t=this.organizations.get(e);if(!t)throw new Pe(e);let a=new me({baseUrl:t.apiUrl,apiKey:t.apiKey});return this.clients.set(e,a),s.debug("GraphQL client created for organization",{organizationId:e,apiUrl:t.apiUrl}),a}async testConnection(e){let t=this.organizations.get(e);if(!t)throw new Pe(e);return this.testConnectionConfig(t)}async testConnectionConfig(e){let t=Date.now(),a={organizationId:e.id,success:!1,responseTime:0,timestamp:new Date};try{let i=new me({baseUrl:e.apiUrl,apiKey:e.apiKey,timeout:1e4}),n=await i.checkHealth();a.responseTime=Date.now()-t,n?(a.success=!0,a.details={statusCode:200,authenticated:!0}):a.error="Health check failed",i.destroy()}catch(i){a.responseTime=Date.now()-t,a.error=i instanceof Error?i.message:String(i),s.debug("Organization connection test failed",{organizationId:e.id,apiUrl:e.apiUrl,error:a.error,responseTime:a.responseTime})}return a}async getOrganizationStatus(e){let t=this.organizations.get(e);if(!t)throw new Pe(e);let a=await this.testConnection(e),i=null;if(a.success)try{i=await this.getWorkerRegistrationForOrganization(e)}catch(c){s.debug("Failed to get worker registration for organization",{organizationId:e,error:c instanceof Error?c.message:String(c)})}let n=t.metadata?.workspaceCount||0,o={id:t.id,name:t.name,healthy:a.success,workspaceCount:n,projectCount:0,pendingWork:0,completedWork:0,config:t,workerRegistration:i};return a.success||(o.error=a.error),o}async getAllOrganizationStatuses(){let e=[];for(let t of this.organizations.keys())try{let a=await this.getOrganizationStatus(t);e.push(a)}catch(a){s.error("Failed to get organization status",{organizationId:t,error:a instanceof Error?a.message:String(a)})}return e}async syncOrganization(e){if(this.syncInProgress.has(e))throw new Oe("Sync already in progress for organization",e);this.syncInProgress.add(e);let t={organizationId:e,success:!1,timestamp:new Date};try{s.info("Starting organization sync",{organizationId:e});let a=await this.getClient(e);t.success=!0,t.workspacesSynced=0,t.projectsSynced=0,this.emit("organizationSynced",t),s.info("Organization sync completed",{organizationId:e,success:t.success})}catch(a){t.error=a instanceof Error?a.message:String(a),s.error("Organization sync failed",{organizationId:e,error:t.error})}finally{this.syncInProgress.delete(e)}return t}async getWorkerRegistrationForOrganization(e){try{let t=await this.getOrganization(e);if(!t)throw new Error("Organization not found");let i=await new ye({apiUrl:t.apiUrl,apiKey:t.apiKey,timeout:3e4,retries:3}).getMyAIWorkers();if(i.me?.aiWorkers&&Array.isArray(i.me.aiWorkers)){let o=i.me.aiWorkers.filter(c=>c.status==="ACTIVE").sort((c,d)=>new Date(d.lastHeartbeat||d.createdAt).getTime()-new Date(c.lastHeartbeat||c.createdAt).getTime())[0];if(o)return{registered:!0,workerId:o.workerId,status:o.status,capabilities:o.capabilities||[],lastHeartbeat:o.lastHeartbeat||null,registeredAt:o.createdAt,metadata:o.metadata}}return{registered:!1,workerId:null,status:null,capabilities:[],lastHeartbeat:null,registeredAt:null,metadata:null}}catch(t){return s.warn("Failed to query worker registration for organization",{organizationId:e,error:t instanceof Error?t.message:String(t)}),{registered:!1,workerId:null,status:null,capabilities:[],lastHeartbeat:null,registeredAt:null,metadata:null,error:t instanceof Error?t.message:String(t)}}}async registerWorkerWithOrganization(e,t,a,i){try{let n=await this.getOrganization(e);if(!n)throw new Error("Organization not found");let o=a.map(u=>u.toUpperCase());s.info("REGISTRATION DEBUG: OrganizationManager forwarding capabilities",{organizationId:e,workerId:t,originalCapabilities:a,uppercaseCapabilities:o,capabilityCount:o.length});let c=new ye({apiUrl:n.apiUrl,apiKey:n.apiKey,timeout:3e4,retries:3}),d={input:{workerId:t,workerName:`Agent ${t.substring(0,8)}`,capabilities:o,scope:"USER",scopeId:t,maxConcurrentTasks:i?.maxConcurrentTasks||3}};s.info("REGISTRATION DEBUG: Sending to GraphQL",{organizationId:e,registrationInput:JSON.stringify(d)});let p=await c.registerWorker(d);return s.info("Worker registered with organization",{organizationId:e,organizationName:n.name,workerId:t,success:p.registerAIWorker?.success,message:p.registerAIWorker?.message}),p.registerAIWorker?.success||!1}catch(n){return s.error("Failed to register worker with organization",{organizationId:e,workerId:t,error:n instanceof Error?n.message:String(n)}),!1}}async updateWorkerHeartbeat(e,t,a){try{let i=await this.getOrganization(e);if(!i)throw new Error("Organization not found");return!!(await new ye({apiUrl:i.apiUrl,apiKey:i.apiKey,timeout:3e4,retries:3}).updateWorkerHeartbeat({input:{workerId:t,health:(a?.healthy,"healthy"),currentTaskCount:a?.currentTaskCount||0}})).updateAIWorkerHeartbeat}catch(i){return s.debug("Failed to update worker heartbeat",{organizationId:e,workerId:t,error:i instanceof Error?i.message:String(i)}),!1}}async unregisterWorker(e,t){try{let a=await this.getOrganization(e);if(!a)throw new Error("Organization not found");let o=await(await this.getClient(e)).mutate({query:`
1018
+ mutation UnregisterAIWorker($workerId: String!) {
1019
+ unregisterAIWorker(workerId: $workerId) {
1020
+ success
1021
+ message
1022
+ }
1023
+ }
1024
+ `,variables:{workerId:t}});return s.info("Worker unregistered from organization",{organizationId:e,organizationName:a.name,workerId:t,success:o.data?.unregisterAIWorker?.success}),o.data?.unregisterAIWorker?.success||!1}catch(a){return s.error("Failed to unregister worker from organization",{organizationId:e,workerId:t,error:a instanceof Error?a.message:String(a)}),!1}}async isSetupCompleted(){return this.config.setupCompleted&&this.organizations.size>0}count(){return this.organizations.size}startHealthChecking(){this.healthCheckInterval=setInterval(async()=>{for(let e of this.organizations.keys())try{let t=await this.testConnection(e);this.emit("organizationHealthChanged",e,t.success)}catch(t){s.debug("Health check failed for organization",{organizationId:e,error:t instanceof Error?t.message:String(t)}),this.emit("organizationHealthChanged",e,!1)}},5*60*1e3)}getDefaultOrganization(){return this.config.defaultOrganization?this.organizations.get(this.config.defaultOrganization):Array.from(this.organizations.values()).find(e=>e.enabled)}getDefaultOrgId(){return this.config.defaultOrganization||Array.from(this.organizations.values()).find(e=>e.enabled)?.id}async getWorkspacesForOrganization(e){try{let t=await this.getOrganization(e);if(!t)throw new Error("Organization not found");return s.debug("Getting workspaces for organization",{organizationId:e,hasMetadata:!!t.metadata,hasWorkspaces:!!t.metadata?.workspaces,workspaceCount:t.metadata?.workspaces?.length||0}),t.metadata?.workspaces?(s.info("Returning cached workspaces",{organizationId:e,workspaceCount:t.metadata.workspaces.length,workspaceNames:t.metadata.workspaces.map(a=>a.name)}),t.metadata.workspaces):(s.info("No cached workspaces found, returning empty array",{organizationId:e}),[])}catch(t){return s.error("Failed to get workspaces for organization",{organizationId:e,error:t instanceof Error?t.message:String(t)}),[]}}async addWorkspaceToOrganization(e,t){try{let a=await this.getOrganization(e);if(!a)throw new Error("Organization not found");a.metadata||(a.metadata={}),a.metadata.workspaces||(a.metadata.workspaces=[]);let i={...t,id:`ws_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};a.metadata.workspaces.push(i),a.metadata.workspaceCount=a.metadata.workspaces.length,await this.updateOrganization(e,{metadata:a.metadata}),s.info("Workspace added successfully",{organizationId:e,workspaceId:i.workspaceId,workspaceName:i.name,totalWorkspaces:a.metadata.workspaces.length});try{let n=Se();n.getSyncStatus().isConnected&&(await n.forceSyncAllWorkspaces(),s.info("Triggered workspace sync after adding workspace",{organizationId:e,workspaceId:i.workspaceId}))}catch(n){s.error("Failed to sync workspace after adding",{organizationId:e,workspaceId:i.workspaceId,error:n instanceof Error?n.message:String(n)})}return i}catch(a){throw s.error("Failed to add workspace to organization",{organizationId:e,workspace:t,error:a instanceof Error?a.message:String(a)}),a}}async updateWorkspaceInOrganization(e,t,a){try{let i=await this.getOrganization(e);if(!i)throw new Error("Organization not found");if(!i.metadata?.workspaces)throw new Error("No workspaces found for organization");let n=i.metadata.workspaces.findIndex(o=>o.id===t);if(n===-1)throw new Error("Workspace not found");i.metadata.workspaces[n]={...i.metadata.workspaces[n],...a,id:t,updatedAt:new Date().toISOString()},await this.updateOrganization(e,{metadata:i.metadata});try{let o=Se();o.getSyncStatus().isConnected&&(await o.forceSyncAllWorkspaces(),s.info("Triggered workspace sync after updating workspace",{organizationId:e,workspaceId:t,updates:Object.keys(a)}))}catch(o){s.error("Failed to sync workspace after updating",{organizationId:e,workspaceId:t,error:o instanceof Error?o.message:String(o)})}return i.metadata.workspaces[n]}catch(i){throw s.error("Failed to update workspace in organization",{organizationId:e,workspaceId:t,updates:a,error:i instanceof Error?i.message:String(i)}),i}}inferServiceType(e){let t=e.toLowerCase();return t.includes("backend")||t.includes("api")||t.includes("server")?"backend":t.includes("frontend")||t.includes("web")||t.includes("ui")||t.includes("react")?"frontend":t.includes("database")||t.includes("db")||t.includes("postgres")||t.includes("mysql")?"database":t.includes("cache")||t.includes("redis")?"cache":t.includes("queue")||t.includes("worker")||t.includes("job")?"queue":t.includes("mcp")||t.includes("agent")||t.includes("service")?"service":"other"}async applyWorkspaceImprovements(e,t,a){try{console.log("\u{1F527} OrganizationManager: applyWorkspaceImprovements called",{organizationId:e,workspaceId:t,improvementsCount:a.length});let i=await this.getOrganization(e);if(!i)throw new Error("Organization not found");if(!i.metadata?.workspaces)throw new Error("No workspaces found for organization");let n=i.metadata.workspaces.findIndex(u=>u.id===t);if(n===-1)throw new Error("Workspace not found");let o=i.metadata.workspaces[n];console.log("\u{1F4CD} Found workspace to update:",o.name),o.services||(o.services=[]);let c=0,d=0;for(let u of a){console.log("\u{1F527} Applying improvement:",u);try{switch(u.type){case"add_service":let f={id:`srv_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,name:u.service,type:u.serviceType||this.inferServiceType(u.service),technology:u.technology||"Node.js",port:u.port||null,description:u.description||"",isActive:!0,createdAt:new Date().toISOString(),addedViaAnalysis:!0};o.services.push(f),c++,console.log("\u2705 Added service:",u.service);break;case"update_service":let b=o.services.findIndex(T=>T.name===u.service);b!==-1?(o.services[b]={...o.services[b],type:u.serviceType||o.services[b].type,technology:u.technology||o.services[b].technology,port:u.port||o.services[b].port,description:u.description||o.services[b].description,updatedAt:new Date().toISOString(),updatedViaAnalysis:!0},c++,console.log("\u2705 Updated service:",u.service)):(console.log("\u26A0\uFE0F Service not found for update:",u.service),d++);break;case"remove_service":let w=o.services.findIndex(T=>T.name===u.service);w!==-1?(o.services.splice(w,1),c++,console.log("\u2705 Removed service:",u.service)):(console.log("\u26A0\uFE0F Service not found for removal:",u.service),d++);break;case"update_technology":let B=o.services.findIndex(T=>T.name===u.service);B!==-1?(o.services[B].technology=u.technology,o.services[B].updatedAt=new Date().toISOString(),o.services[B].updatedViaAnalysis=!0,c++,console.log("\u2705 Updated technology for service:",u.service)):(console.log("\u26A0\uFE0F Service not found for technology update:",u.service),d++);break;default:console.log("\u26A0\uFE0F Unknown improvement type:",u.type),d++}}catch(h){console.error("\u274C Failed to apply improvement:",u,h),d++}}o.updatedAt=new Date().toISOString(),o.lastAnalysisApplied=new Date().toISOString(),await this.updateOrganization(e,{metadata:i.metadata});let p={success:!0,appliedCount:c,skippedCount:d,totalCount:a.length,workspace:o};console.log("\u2705 Workspace improvements applied successfully:",p),s.info("Workspace improvements applied",{organizationId:e,workspaceId:t,appliedCount:c,skippedCount:d,totalCount:a.length});try{let u=Se();u.getSyncStatus().isConnected&&(await u.forceSyncAllWorkspaces(),s.info("Triggered workspace sync after applying improvements",{organizationId:e,workspaceId:t,appliedCount:c}))}catch(u){s.error("Failed to sync workspace after applying improvements",{organizationId:e,workspaceId:t,error:u instanceof Error?u.message:String(u)})}return p}catch(i){throw s.error("Failed to apply workspace improvements",{organizationId:e,workspaceId:t,improvements:a,error:i instanceof Error?i.message:String(i)}),i}}async syncWorkspacesFromTaskShepherd(e){try{let t=await this.getOrganization(e);if(!t)throw new Error("Organization not found");let c=((await(await this.getClient(e)).query({query:`
1025
+ query GetWorkspaces {
1026
+ workspaces {
1027
+ id
1028
+ workspaceId
1029
+ name
1030
+ path
1031
+ description
1032
+ isActive
1033
+ projects {
1034
+ id
1035
+ }
1036
+ createdAt
1037
+ updatedAt
1038
+ }
1039
+ }
1040
+ `})).data?.workspaces||[]).map(d=>({id:d.id,workspaceId:d.workspaceId,name:d.name,path:d.path,description:d.description,isActive:d.isActive,projectCount:d.projects?.length||0,createdAt:d.createdAt,updatedAt:d.updatedAt}));return t.metadata||(t.metadata={}),t.metadata.workspaces=c,t.metadata.workspaceCount=c.length,t.metadata.lastWorkspaceSync=new Date().toISOString(),await this.updateOrganization(e,{metadata:t.metadata}),s.info("Workspaces synced from Task Shepherd",{organizationId:e,workspaceCount:c.length}),{success:!0,workspaceCount:c.length,workspaces:c}}catch(t){return s.error("Failed to sync workspaces from Task Shepherd",{organizationId:e,error:t instanceof Error?t.message:String(t)}),{success:!1,workspaceCount:0,workspaces:[],error:t instanceof Error?t.message:String(t)}}}async getServicesForWorkspace(e,t){try{let a=await this.getOrganization(e);if(!a)throw new Error("Organization not found");let i=a.metadata?.workspaces?.find(n=>n.id===t);if(!i)throw new Error("Workspace not found");return i.services||[]}catch(a){return s.error("Failed to get services for workspace",{organizationId:e,workspaceId:t,error:a instanceof Error?a.message:String(a)}),[]}}async addServiceToWorkspace(e,t,a){try{let i=await this.getOrganization(e);if(!i)throw new Error("Organization not found");if(!i.metadata?.workspaces)throw new Error("No workspaces found for organization");let n=i.metadata.workspaces.findIndex(c=>c.id===t);if(n===-1)throw new Error("Workspace not found");i.metadata.workspaces[n].services||(i.metadata.workspaces[n].services=[]);let o={...a,id:`svc_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};i.metadata.workspaces[n].services.push(o),i.metadata.workspaces[n].updatedAt=new Date().toISOString(),await this.updateOrganization(e,{metadata:i.metadata});try{let c=Se();c.getSyncStatus().isConnected&&(await c.forceSyncAllWorkspaces(),s.info("Triggered workspace sync after adding service",{organizationId:e,workspaceId:t,serviceName:o.name}))}catch(c){s.error("Failed to sync workspace after adding service",{organizationId:e,workspaceId:t,serviceName:o.name,error:c instanceof Error?c.message:String(c)})}return o}catch(i){throw s.error("Failed to add service to workspace",{organizationId:e,workspaceId:t,service:a,error:i instanceof Error?i.message:String(i)}),i}}async updateServiceInWorkspace(e,t,a,i){try{let n=await this.getOrganization(e);if(!n)throw new Error("Organization not found");if(!n.metadata?.workspaces)throw new Error("No workspaces found for organization");let o=n.metadata.workspaces.findIndex(d=>d.id===t);if(o===-1)throw new Error("Workspace not found");if(!n.metadata.workspaces[o].services)throw new Error("No services found in workspace");let c=n.metadata.workspaces[o].services.findIndex(d=>d.id===a);if(c===-1)throw new Error("Service not found");n.metadata.workspaces[o].services[c]={...n.metadata.workspaces[o].services[c],...i,id:a,updatedAt:new Date().toISOString()},n.metadata.workspaces[o].updatedAt=new Date().toISOString(),await this.updateOrganization(e,{metadata:n.metadata});try{let d=Se();d.getSyncStatus().isConnected&&(await d.forceSyncAllWorkspaces(),s.info("Triggered workspace sync after updating service",{organizationId:e,workspaceId:t,serviceId:a,updates:Object.keys(i)}))}catch(d){s.error("Failed to sync workspace after updating service",{organizationId:e,workspaceId:t,serviceId:a,error:d instanceof Error?d.message:String(d)})}return n.metadata.workspaces[o].services[c]}catch(n){throw s.error("Failed to update service in workspace",{organizationId:e,workspaceId:t,serviceId:a,updates:i,error:n instanceof Error?n.message:String(n)}),n}}async removeServiceFromWorkspace(e,t,a){try{let i=await this.getOrganization(e);if(!i)throw new Error("Organization not found");if(!i.metadata?.workspaces)throw new Error("No workspaces found for organization");let n=i.metadata.workspaces.findIndex(o=>o.id===t);if(n===-1)throw new Error("Workspace not found");if(!i.metadata.workspaces[n].services)throw new Error("No services found in workspace");i.metadata.workspaces[n].services=i.metadata.workspaces[n].services.filter(o=>o.id!==a),i.metadata.workspaces[n].updatedAt=new Date().toISOString(),await this.updateOrganization(e,{metadata:i.metadata});try{let o=Se();o.getSyncStatus().isConnected&&(await o.forceSyncAllWorkspaces(),s.info("Triggered workspace sync after removing service",{organizationId:e,workspaceId:t,serviceId:a}))}catch(o){s.error("Failed to sync workspace after removing service",{organizationId:e,workspaceId:t,serviceId:a,error:o instanceof Error?o.message:String(o)})}}catch(i){throw s.error("Failed to remove service from workspace",{organizationId:e,workspaceId:t,serviceId:a,error:i instanceof Error?i.message:String(i)}),i}}async destroy(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null);for(let e of this.clients.values())e.destroy();this.clients.clear(),this.removeAllListeners(),s.info("OrganizationManager destroyed")}}});function Hr(l){if(l==null)return"Unknown error";if(typeof l=="string")return l;if(l instanceof Error){let r=[l.message||"Unknown error"];return l.name&&l.name!=="Error"&&r.push(`(${l.name})`),"code"in l&&typeof l.code=="string"&&r.push(`[${l.code}]`),r.join(" ")}if(typeof l=="object"&&"message"in l)return String(l.message);try{return String(l)}catch{return"Error could not be serialized"}}function $r(l){if(l==null)return{message:"Unknown error",name:"UnknownError"};if(typeof l=="string")return{message:l,name:"StringError"};if(l instanceof Error){let r={message:l.message||"Unknown error",name:l.name||"Error",stack:l.stack};"code"in l&&typeof l.code=="string"&&(r.code=l.code);let e={};for(let t of Object.keys(l))if(!["message","name","stack","code"].includes(t)){let a=l[t];if(typeof a=="string"||typeof a=="number"||typeof a=="boolean")e[t]=a;else if(a&&typeof a=="object")try{e[t]=JSON.stringify(a)}catch{e[t]="[Complex Object]"}}return Object.keys(e).length>0&&(r.details=e),r}if(typeof l=="object"){let r={message:"",name:"ObjectError"};if("message"in l&&typeof l.message=="string")r.message=l.message;else try{r.message=JSON.stringify(l)}catch{r.message="[Complex Object]"}let e={};for(let t of Object.keys(l))if(t!=="message"){let a=l[t];if(typeof a=="string"||typeof a=="number"||typeof a=="boolean")e[t]=a;else if(a&&typeof a=="object")try{e[t]=JSON.stringify(a)}catch{e[t]="[Complex Object]"}}return Object.keys(e).length>0&&(r.details=e),r}return{message:String(l),name:"UnknownError"}}function qr(l){let r=[l.message];if(l.name&&l.name!=="Error"&&r.push(`(${l.name})`),l.code&&r.push(`[${l.code}]`),l.details&&Object.keys(l.details).length>0){let e=Object.entries(l.details).map(([t,a])=>`${t}: ${a}`).join(", ");r.push(`{${e}}`)}return r.join(" ")}var Br=M(()=>{"use strict"});var Gr,se,li=M(()=>{"use strict";j();Br();Gr=class{constructor(){this.events=new Map;this.maxEventsPerItem=100}recordClaimed(r){let e={id:this.generateEventId(),workItemId:r.workItemId,workType:r.workType,organizationId:r.organizationId,eventType:"CLAIMED",timestamp:new Date,workerId:r.workerId,priority:r.priority,metadata:r.metadata};return this.addEvent(e),s.info("Work item claimed event recorded",{workItemId:r.workItemId,workType:r.workType,workerId:r.workerId}),e}recordStarted(r){let e={id:this.generateEventId(),workItemId:r.workItemId,workType:r.workType,organizationId:r.organizationId,eventType:"STARTED",timestamp:new Date,workerId:r.workerId};return this.addEvent(e),s.info("Work item started event recorded",{workItemId:r.workItemId,workType:r.workType,workerId:r.workerId}),e}recordProgress(r){let e={id:this.generateEventId(),workItemId:r.workItemId,workType:r.workType,organizationId:r.organizationId,eventType:"PROGRESS",timestamp:new Date,workerId:r.workerId,progress:r.progress};return this.addEvent(e),s.debug("Work item progress event recorded",{workItemId:r.workItemId,progress:r.progress}),e}recordCompleted(r){let e={id:this.generateEventId(),workItemId:r.workItemId,workType:r.workType,organizationId:r.organizationId,eventType:"COMPLETED",timestamp:new Date,workerId:r.workerId,processingTime:r.processingTime,metadata:r.metadata};return this.addEvent(e),s.info("Work item completed event recorded",{workItemId:r.workItemId,workType:r.workType,processingTime:r.processingTime}),e}recordFailed(r){let e=$r(r.error),t=qr(e),a={id:this.generateEventId(),workItemId:r.workItemId,workType:r.workType,organizationId:r.organizationId,eventType:"FAILED",timestamp:new Date,workerId:r.workerId,error:e,errorMessage:t,processingTime:r.processingTime,metadata:r.metadata};return this.addEvent(a),s.error("Work item failed event recorded",{workItemId:r.workItemId,workType:r.workType,error:t,processingTime:r.processingTime}),a}recordRetry(r){let e=r.previousError?$r(r.previousError):void 0,t={id:this.generateEventId(),workItemId:r.workItemId,workType:r.workType,organizationId:r.organizationId,eventType:"RETRY",timestamp:new Date,workerId:r.workerId,error:e,metadata:{attemptNumber:r.attemptNumber,previousError:e?qr(e):void 0}};return this.addEvent(t),s.info("Work item retry event recorded",{workItemId:r.workItemId,attemptNumber:r.attemptNumber}),t}recordCancelled(r){let e={id:this.generateEventId(),workItemId:r.workItemId,workType:r.workType,organizationId:r.organizationId,eventType:"CANCELLED",timestamp:new Date,metadata:{reason:r.reason}};return this.addEvent(e),s.info("Work item cancelled event recorded",{workItemId:r.workItemId,reason:r.reason}),e}getEvents(r){return this.events.get(r)||[]}getLatestEvent(r){let e=this.getEvents(r);return e.length>0?e[e.length-1]:void 0}getFailedEvents(r){return this.getEvents(r).filter(e=>e.eventType==="FAILED")}getRetryCount(r){return this.getEvents(r).filter(e=>e.eventType==="RETRY").length}getSummary(r){let e=this.getEvents(r),t=e.filter(c=>c.eventType==="CLAIMED"),a=e.filter(c=>c.eventType==="FAILED"),i=e.filter(c=>c.eventType==="RETRY"),n=e.filter(c=>c.eventType==="COMPLETED"),o=a.concat(n).reduce((c,d)=>c+(d.processingTime||0),0);return{totalEvents:e.length,claimedCount:t.length,failureCount:a.length,retryCount:i.length,firstClaimed:t.length>0?t[0].timestamp:void 0,lastEvent:e.length>0?e[e.length-1]:void 0,totalProcessingTime:o>0?o:void 0}}getAllWorkItemIds(){return Array.from(this.events.keys())}clearEvents(r){this.events.delete(r)}clearAllEvents(){this.events.clear()}getGlobalStats(){let r=0,e=0,t=0,a=0;for(let i of this.events.values())r+=i.length,e+=i.filter(n=>n.eventType==="FAILED").length,t+=i.filter(n=>n.eventType==="RETRY").length,a+=i.filter(n=>n.eventType==="COMPLETED").length;return{totalWorkItems:this.events.size,totalEvents:r,totalFailures:e,totalRetries:t,totalCompletions:a}}addEvent(r){let e=this.events.get(r.workItemId)||[];e.push(r),e.length>this.maxEventsPerItem&&e.shift(),this.events.set(r.workItemId,e)}generateEventId(){return`evt_${Date.now()}_${Math.random().toString(36).substring(2,11)}`}},se=new Gr});var pi,Kt,ui=M(()=>{"use strict";pi=require("events");j();Et();li();Br();Kt=class extends pi.EventEmitter{constructor(e,t){super();this.pollingTimers=new Map;this.pollingStatus=new Map;this.processingWorkItems=new Map;this.completedWorkItems=new Map;this.failedWorkItems=new Map;this.isRunning=!1;this.strategy={active:15e3,normal:6e4,idle:3e5,backoff:3e4,maxBackoff:3e5};this.organizationManager=e,this.config={capabilities:t?.capabilities||["PROJECT_REVIEW","STORY_IMPLEMENTATION"],maxWorkPerPoll:t?.maxWorkPerPoll||3,autoClaimWork:t?.autoClaimWork??!0,strategy:{...this.strategy,...t?.strategy||{}},jitterPercent:t?.jitterPercent||10},s.info("SmartPollingService initialized",{capabilities:this.config.capabilities,maxWorkPerPoll:this.config.maxWorkPerPoll,autoClaimWork:this.config.autoClaimWork,strategy:this.config.strategy})}setWorkHandlerRegistry(e){this.workHandlerRegistry=e,s.info("WorkHandlerRegistry set for SmartPollingService")}async start(e){if(this.isRunning){s.warn("SmartPollingService already running");return}this.currentIdentity=e,this.isRunning=!0,s.info("Starting smart polling service",{agentId:e.agentId,capabilities:this.config.capabilities,hasWorkHandler:!!this.workHandlerRegistry}),this.setupOrganizationListeners();let t=await this.organizationManager.getAllOrganizations();for(let a of t)a.enabled&&await this.startPollingOrganization(a.id,a.name);this.emit("started",{agentId:e.agentId})}async stop(){if(this.isRunning){s.info("Stopping smart polling service");for(let[e,t]of this.pollingTimers)clearTimeout(t),this.pollingTimers.delete(e);this.isRunning=!1,this.processingWorkItems.clear(),s.info("Cleared all processing work items tracking"),this.emit("stopped")}}clearStuckWorkItems(){let e=Array.from(this.processingWorkItems.keys());this.processingWorkItems.clear(),s.info("Manually cleared stuck work items from processing tracking",{stuckItems:e,count:e.length})}getProcessingWorkItems(){return Array.from(this.processingWorkItems.values())}getCompletedWorkItems(){return Array.from(this.completedWorkItems.values()).sort((e,t)=>t.completedAt.getTime()-e.completedAt.getTime())}getFailedWorkItems(){return Array.from(this.failedWorkItems.values()).sort((e,t)=>t.failedAt.getTime()-e.failedAt.getTime())}getWorkItemHistory(e){return se.getEvents(e)}getWorkItemSummary(e){return se.getSummary(e)}getWorkItemsWithHistory(){return se.getAllWorkItemIds()}getEventStats(){return se.getGlobalStats()}getWorkItemEventStore(){return se}getPollingStatus(){return Array.from(this.pollingStatus.values())}isWorkItemStuck(e,t){if(e.status==="QUEUED"||!t)return!1;let a=e.lastHeartbeat||e.claimedAt;if(!a)return!1;let i=Date.now()-new Date(a).getTime(),n=5*60*1e3;if(i<n)return!1;let o=t.lastKnownProgress||0,c=e.metadata?.progress?.percentage||0;return c>o?(t.lastKnownProgress=c,t.lastProgressUpdate=new Date,!1):!0}async cancelLocalProcessing(e){let t=this.processingWorkItems.get(e);if(t){s.info("Cancelling local processing",{workItemId:e,workType:t.workType});try{t.abortController.abort()}catch(a){s.warn("Error aborting work item controller",{workItemId:e,error:a instanceof Error?a.message:String(a)})}}}setupOrganizationListeners(){this.organizationManager.on("organizationAdded",async e=>{let t=await this.organizationManager.getOrganization(e);t&&t.enabled&&await this.startPollingOrganization(t.id,t.name)}),this.organizationManager.on("organizationRemoved",e=>{this.stopPollingOrganization(e)}),this.organizationManager.on("organizationUpdated",async(e,t)=>{if(t.enabled===!1)this.stopPollingOrganization(e);else if(t.enabled===!0){let a=await this.organizationManager.getOrganization(e);a&&await this.startPollingOrganization(a.id,a.name)}})}async startPollingOrganization(e,t){if(this.pollingTimers.has(e))return;s.info("Starting polling for organization",{orgId:e,orgName:t});let a={organizationId:e,organizationName:t,isPolling:!0,currentInterval:this.config.strategy.normal,consecutiveErrors:0,claimedWorkCount:0,availableWorkCount:0,totalPolls:0,totalErrors:0};this.pollingStatus.set(e,a);let i=Math.random()*5e3,n=setTimeout(()=>this.pollOrganization(e),i);this.pollingTimers.set(e,n),this.emit("organizationPollingStarted",{orgId:e,orgName:t})}stopPollingOrganization(e){let t=this.pollingTimers.get(e);t&&(clearTimeout(t),this.pollingTimers.delete(e));let a=this.pollingStatus.get(e);a&&(a.isPolling=!1),s.info("Stopped polling for organization",{orgId:e}),this.emit("organizationPollingStopped",{orgId:e})}async pollOrganization(e){let t=this.pollingStatus.get(e);if(!(!t||!this.isRunning)){t.lastPollAt=new Date,t.totalPolls++;try{let a=await this.organizationManager.getOrganization(e);if(!a||!a.enabled){this.stopPollingOrganization(e);return}let i=new ye({apiUrl:a.apiUrl,apiKey:a.apiKey,timeout:3e4,retries:2}),n={workerId:this.currentIdentity.agentId,capabilities:this.config.capabilities,maxWork:this.config.maxWorkPerPoll,autoClaimWork:this.config.autoClaimWork};s.info("\u{1F4E4} Sending capabilities to backend",{workerId:this.currentIdentity.agentId,capabilities:this.config.capabilities,capabilitiesCount:this.config.capabilities.length,orgId:e});let c=(await i.pollForWork(n)).pollForWork;if(t.claimedWorkCount=c.myClaimedWork.length+c.claimedWork.length,t.availableWorkCount=c.availableWork.length,t.consecutiveErrors=0,t.lastSuccessAt=new Date,c.myClaimedWork.length>0){s.info("Reconciling previously claimed work",{orgId:e,myClaimedWorkCount:c.myClaimedWork.length});for(let p of c.myClaimedWork){if(p.status==="QUEUED"){s.info("Backend requeued work item - cancelling local processing",{workItemId:p.id,workType:p.workType,status:p.status,orgId:e}),this.processingWorkItems.has(p.id)&&(await this.cancelLocalProcessing(p.id),this.processingWorkItems.delete(p.id));continue}let u=this.processingWorkItems.get(p.id);if(u)if(this.isWorkItemStuck(p,u))s.warn("Work item genuinely stuck - cancelling and retrying",{workItemId:p.id,workType:p.workType,status:p.status,lastHeartbeat:p.lastHeartbeat,lastKnownProgress:u.lastKnownProgress,orgId:e}),await this.cancelLocalProcessing(p.id),this.processingWorkItems.delete(p.id);else{s.debug("Work item is actively processing - skipping duplicate",{workItemId:p.id,workType:p.workType,status:p.status,currentProgress:p.metadata?.progress?.percentage,orgId:e});continue}if(p.status==="IN_PROGRESS"){let b=p.claimedAt?new Date(p.claimedAt).getTime():Date.now(),w=Date.now()-b,B=10*60*1e3;if(w<B){s.debug("Skipping IN_PROGRESS work - too recent to be orphaned (not locally tracked)",{workItemId:p.id,workType:p.workType,ageMinutes:Math.round(w/6e4),claimedAt:p.claimedAt,currentProgress:p.metadata?.progress?.percentage,orgId:e});continue}s.warn("Resuming genuinely orphaned IN_PROGRESS work item (claimed >10min ago)",{workItemId:p.id,workType:p.workType,status:p.status,claimedAt:p.claimedAt,ageMinutes:Math.round(w/6e4),lastHeartbeat:p.lastHeartbeat,currentProgress:p.metadata?.progress?.percentage,orgId:e})}else s.info("Resuming orphaned work item",{workItemId:p.id,workType:p.workType,status:p.status,claimedAt:p.claimedAt,orgId:e});let h={id:p.id,workType:p.workType,workData:p,organizationId:e,priority:p.priority||5,claimedAt:p.claimedAt?new Date(p.claimedAt):new Date,abortController:new AbortController,lastKnownProgress:p.metadata?.progress?.percentage||0,lastProgressUpdate:new Date};this.processingWorkItems.set(p.id,h),se.recordRetry({workItemId:p.id,workType:p.workType,organizationId:e,workerId:this.currentIdentity.agentId,attemptNumber:se.getRetryCount(p.id)+1}),setTimeout(()=>{this.processingWorkItems.has(p.id)&&(this.processingWorkItems.delete(p.id),s.warn("Automatically removed stuck work item from processing tracking after timeout",{workItemId:p.id,workType:p.workType}))},6e5);let f=Date.now();this.processClaimedWork(p,e).then(b=>{if(b){let w=Date.now()-f;this.processingWorkItems.delete(p.id),this.completedWorkItems.set(p.id,{id:p.id,workType:p.workType,organizationId:e,completedAt:new Date,processingTime:w}),se.recordCompleted({workItemId:p.id,workType:p.workType,organizationId:e,workerId:this.currentIdentity.agentId,processingTime:w}),s.debug("Work item processing completed, removed from tracking",{workItemId:p.id,orgId:e})}else s.debug("Work item kept in processing tracking for future processing",{workItemId:p.id,orgId:e})}).catch(b=>{let w=Hr(b);s.error("Failed to process orphaned work item",{workItemId:p.id,orgId:e,error:w});let B=Date.now()-f;this.processingWorkItems.delete(p.id),this.failedWorkItems.set(p.id,{id:p.id,workType:p.workType,organizationId:e,failedAt:new Date,error:w}),se.recordFailed({workItemId:p.id,workType:p.workType,organizationId:e,workerId:this.currentIdentity.agentId,error:b,processingTime:B})})}}if(c.claimedWork.length>0){s.info("Processing newly claimed work items",{orgId:e,claimedCount:c.claimedWork.length,workItems:c.claimedWork.map(p=>({id:p.id,type:p.workType,status:p.status}))});for(let p of c.claimedWork){if(p.status==="IN_PROGRESS"){s.warn("\u{1F6A8} Backend returned IN_PROGRESS work item - skipping to prevent duplicate processing",{workItemId:p.id,workType:p.workType,status:p.status,orgId:e});continue}if(this.processingWorkItems.has(p.id)){let b=p.claimedAt?Date.now()-new Date(p.claimedAt).getTime():0;if(b>3e5)s.warn("Newly claimed work item tracked but stuck - removing from tracking for retry",{workItemId:p.id,workType:p.workType,ageMinutes:Math.round(b/6e4),status:p.status,orgId:e}),this.processingWorkItems.delete(p.id);else{s.debug("Newly claimed work item is already being processed - skipping duplicate",{workItemId:p.id,workType:p.workType,ageMinutes:Math.round(b/6e4),status:p.status,orgId:e});continue}}s.info("\u{1F525} SMART_POLLING: About to process claimed work item",{workItemId:p.id,workType:p.workType,orgId:e,hasWorkHandlerRegistry:!!this.workHandlerRegistry});let u={id:p.id,workType:p.workType,workData:p,organizationId:e,priority:p.priority||5,claimedAt:p.claimedAt?new Date(p.claimedAt):new Date,abortController:new AbortController,lastKnownProgress:p.metadata?.progress?.percentage||0,lastProgressUpdate:new Date};this.processingWorkItems.set(p.id,u),se.recordClaimed({workItemId:p.id,workType:p.workType,organizationId:e,workerId:this.currentIdentity.agentId,priority:p.priority||5});let h=Date.now();this.processClaimedWork(p,e).then(b=>{if(s.info("\u{1F525} SMART_POLLING: Successfully completed processing claimed work item",{workItemId:p.id,workType:p.workType,shouldRemoveFromTracking:b,orgId:e}),b){let w=Date.now()-h;this.processingWorkItems.delete(p.id),this.completedWorkItems.set(p.id,{id:p.id,workType:p.workType,organizationId:e,completedAt:new Date,processingTime:w}),se.recordCompleted({workItemId:p.id,workType:p.workType,organizationId:e,workerId:this.currentIdentity.agentId,processingTime:w}),s.debug("Work item processing completed, removed from tracking",{workItemId:p.id,orgId:e})}else s.debug("Work item kept in processing tracking for future processing",{workItemId:p.id,orgId:e})}).catch(b=>{let w=Hr(b);s.error("\u{1F525} SMART_POLLING: ERROR - Failed to process claimed work item",{workItemId:p.id,workType:p.workType,orgId:e,error:w,stack:b instanceof Error?b.stack:void 0,errorName:b instanceof Error?b.name:"Unknown"});let B=Date.now()-h;this.processingWorkItems.delete(p.id),this.failedWorkItems.set(p.id,{id:p.id,workType:p.workType,organizationId:e,failedAt:new Date,error:w}),se.recordFailed({workItemId:p.id,workType:p.workType,organizationId:e,workerId:this.currentIdentity.agentId,error:b,processingTime:B})}),s.info("\u{1F525} SMART_POLLING: Dispatched processing for work item (async)",{workItemId:p.id,orgId:e})}this.emit("workClaimed",{organizationId:e,claimedWork:c.claimedWork,queueStats:c.queueStats})}c.myClaimedWork.length>0&&this.emit("workReconciled",{organizationId:e,reconciledWork:c.myClaimedWork,queueStats:c.queueStats});let d=this.calculateAdaptiveInterval(c.nextPollInterval,c.myClaimedWork.length+c.claimedWork.length,c.availableWork.length,t.consecutiveErrors);t.currentInterval=d,t.nextPollAt=new Date(Date.now()+d),this.scheduleNextPoll(e,d),s.debug("Smart poll completed",{orgId:e,myClaimedWork:c.myClaimedWork.length,newClaimedWork:c.claimedWork.length,availableWork:c.availableWork.length,nextInterval:d,queueStats:c.queueStats})}catch(a){t.consecutiveErrors++,t.totalErrors++;let i=a instanceof Error?a.message:String(a),n=this.categorizePollingError(a);s.error("Smart poll failed",{orgId:e,error:i,errorType:n,consecutiveErrors:t.consecutiveErrors});let o;n==="authentication"||n==="connection"?o=Math.min(this.config.strategy.maxBackoff,6e4*Math.pow(2,Math.min(t.consecutiveErrors-1,3))):o=this.calculateBackoffInterval(t.consecutiveErrors),t.currentInterval=o,t.nextPollAt=new Date(Date.now()+o),this.scheduleNextPoll(e,o),this.emit("pollingError",{organizationId:e,error:i,errorType:n,consecutiveErrors:t.consecutiveErrors,nextRetryAt:t.nextPollAt}),n==="authentication"&&t.consecutiveErrors>=5&&(s.error("Too many authentication failures, temporarily disabling polling",{orgId:e,consecutiveErrors:t.consecutiveErrors}),this.emit("authenticationFailure",{organizationId:e}))}}}async processClaimedWork(e,t){s.info("\u{1F525} PROCESS_CLAIMED_WORK: Processing claimed work item via WorkHandlerRegistry",{workItemId:e.id,workType:e.workType,status:e.status,orgId:t,workItemKeys:Object.keys(e||{}),hasWorkHandlerRegistry:!!this.workHandlerRegistry});try{if(!this.workHandlerRegistry)throw new Error("WorkHandlerRegistry not set - cannot process work");let a={};if(e.metadataJson)try{a=typeof e.metadataJson=="string"?JSON.parse(e.metadataJson):e.metadataJson,s.info("\u{1F50D} DEBUG: Successfully parsed metadataJson",{workItemId:e.id,workType:e.workType,metadataKeys:Object.keys(a||{}),hasReviewId:!!a.reviewId,reviewId:a.reviewId,metadataPreview:JSON.stringify(a).substring(0,300)})}catch(d){s.warn("Failed to parse work item metadata",{workItemId:e.id,metadataJson:e.metadataJson,error:d instanceof Error?d.message:String(d)})}else e.metadata&&(a=e.metadata,s.info("\u{1F50D} DEBUG: Using metadata object directly",{workItemId:e.id,workType:e.workType,metadataKeys:Object.keys(a||{}),hasReviewId:!!a.reviewId,reviewId:a.reviewId}));let i=await this.organizationManager.getOrganization(t);if(!i)throw new Error(`Organization not found: ${t}`);let n={...a,projectId:e.projectId||e.project?.id||a.projectId,projectName:e.project?.name,project:e.project,storyId:e.storyId||e.story?.id||a.storyId,storyTitle:e.story?.title,story:e.story,workItemId:e.id,workType:e.workType||a.workType||"unknown",status:e.status,priority:e.priority,createdAt:e.createdAt,claimedAt:e.claimedAt,organizationId:t,organizationApiUrl:i.apiUrl,organizationApiKey:i.apiKey},o=e.workType||a.workType||"unknown";o.toLowerCase().includes("review")&&o.toLowerCase().includes("application")&&s.info("\u{1F3AF} REVIEW_APPLICATION work item discovered",{workItemId:e.id,workType:o,metadataWorkType:a.workType,originalWorkType:e.workType,reviewId:a.reviewId,projectId:a.projectId,orgId:t});let c={assignmentId:e.id,workerId:this.currentIdentity.agentId,workItemType:o,workItemId:e.id,priority:e.priority||5,assignedAt:e.claimedAt?new Date(e.claimedAt):new Date,deadline:void 0,workData:n,organizationId:t,organizationApiUrl:i.apiUrl,organizationApiKey:i.apiKey};return s.info("\u{1F525} PROCESS_CLAIMED_WORK: Calling WorkHandlerRegistry.handle()",{workItemId:e.id,workType:o,priority:c.priority,orgId:t}),await this.workHandlerRegistry.handle(c),s.info("\u{1F525} PROCESS_CLAIMED_WORK: Successfully processed work item via WorkHandlerRegistry",{workItemId:e.id,workType:o,orgId:t}),this.emit("workCompleted",{organizationId:t,workItemId:e.id,workType:o}),!0}catch(a){return s.error("\u{1F525} PROCESS_CLAIMED_WORK: ERROR - Failed to process work item",{workItemId:e.id,workType:e.workType,orgId:t,error:a instanceof Error?a.message:String(a),stack:a instanceof Error?a.stack:void 0}),this.emit("workFailed",{organizationId:t,assignmentId:e.id,workType:e.workType,error:a instanceof Error?a.message:String(a)}),!0}}calculateAdaptiveInterval(e,t,a,i){let n=e;t>0?n=Math.min(n,this.config.strategy.active):a>0?n=Math.min(n,this.config.strategy.normal):n=Math.max(n,this.config.strategy.idle);let o=n*(this.config.jitterPercent/100),c=n+(Math.random()*o*2-o);return Math.max(1e3,Math.round(c))}categorizePollingError(e){let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("unauthorized")||t.includes("401")||t.includes("authentication")||t.includes("invalid token")||t.includes("api key")?"authentication":t.includes("econnrefused")||t.includes("enotfound")||t.includes("timeout")||t.includes("network")||t.includes("connection refused")?"connection":t.includes("rate limit")||t.includes("429")||t.includes("too many requests")?"rate_limit":t.includes("500")||t.includes("502")||t.includes("503")||t.includes("504")||t.includes("internal server error")?"server_error":t.includes("graphql")||t.includes("query")||t.includes("mutation")||t.includes("validation")?"graphql_error":"unknown"}calculateBackoffInterval(e){let t=this.config.strategy.backoff,a=Math.pow(2,Math.min(e-1,5)),i=t*a,n=i*(this.config.jitterPercent/100),o=i+(Math.random()*n*2-n);return Math.min(this.config.strategy.maxBackoff,Math.round(o))}scheduleNextPoll(e,t){let a=this.pollingTimers.get(e);a&&clearTimeout(a);let i=setTimeout(()=>this.pollOrganization(e),t);this.pollingTimers.set(e,i)}async forcePolling(){let e=[];for(let[t]of this.pollingStatus){let a=this.pollingTimers.get(t);a&&clearTimeout(a),await this.pollOrganization(t)}return e}updateConfig(e){this.config={...this.config,...e},s.info("Smart polling configuration updated",{updates:e,newConfig:this.config}),this.emit("configUpdated",this.config)}getMetrics(){let e=Array.from(this.pollingStatus.values());return{totalOrganizations:e.length,activePolling:e.filter(t=>t.isPolling).length,totalPolls:e.reduce((t,a)=>t+a.totalPolls,0),totalErrors:e.reduce((t,a)=>t+a.totalErrors,0),totalClaimedWork:e.reduce((t,a)=>t+a.claimedWorkCount,0),averageInterval:e.reduce((t,a)=>t+a.currentInterval,0)/(e.length||1),errorRate:e.reduce((t,a)=>t+a.totalErrors,0)/Math.max(e.reduce((t,a)=>t+a.totalPolls,0),1),organizationStats:e}}}});var di,Qt,gi=M(()=>{"use strict";di=require("events");j();ui();xr();Qt=class extends di.EventEmitter{constructor(e,t,a,i,n,o){super();this.workerRegistrations=new Map;this.isRunning=!1;this.organizationManager=e,this.identityService=t,this.registrationOptions=i,this.workHandlerRegistry=new Ke(n,o),this.smartPollingService=new Kt(e,{capabilities:i.capabilities,maxWorkPerPoll:i.maxConcurrentTasks,autoClaimWork:!0}),this.smartPollingService.setWorkHandlerRegistry(this.workHandlerRegistry),this.setupSmartPollingListeners()}setupSmartPollingListeners(){this.smartPollingService.on("workClaimed",e=>{s.info("Work claimed via smart polling",{organizationId:e.organizationId,claimedWork:e.claimedWork.length,queueStats:e.queueStats});let t=this.workerRegistrations.get(e.organizationId);t&&(t.lastHeartbeat=new Date),this.emit("workClaimed",e)}),this.smartPollingService.on("pollingError",e=>{s.warn("Smart polling error",{organizationId:e.organizationId,error:e.error,consecutiveErrors:e.consecutiveErrors});let t=this.workerRegistrations.get(e.organizationId);t&&e.consecutiveErrors>=5&&(t.error=`Polling failed: ${e.error}`)}),this.smartPollingService.on("workCompleted",e=>{s.info("Work completed successfully",{organizationId:e.organizationId,assignmentId:e.assignmentId,workType:e.workType}),this.emit("workCompleted",e)}),this.smartPollingService.on("workFailed",e=>{s.error("Work processing failed",{organizationId:e.organizationId,assignmentId:e.assignmentId,workType:e.workType,error:e.error}),this.emit("workFailed",e)}),this.smartPollingService.on("organizationPollingStarted",e=>{s.info("Smart polling started for organization",e)}),this.smartPollingService.on("organizationPollingStopped",e=>{s.info("Smart polling stopped for organization",e)})}async start(){if(this.isRunning){s.warn("Multi-organization worker service already running");return}s.info("Starting multi-organization worker service"),this.isRunning=!0,this.currentIdentity=await this.ensureAgentIdentity(),await this.registerWithAllOrganizations(),await this.validateWorkerRegistrations(),await this.smartPollingService.start(this.currentIdentity),this.startRegistrationHealthCheck(),this.setupOrganizationListeners(),s.info("Multi-organization worker service started",{agentId:this.currentIdentity.agentId,organizationCount:this.workerRegistrations.size})}async stop(){this.isRunning&&(s.info("Stopping multi-organization worker service"),this.isRunning=!1,await this.smartPollingService.stop(),await this.unregisterFromAllOrganizations(),this.workerRegistrations.clear(),this.removeAllListeners(),this.organizationManager.removeAllListeners(),s.info("Multi-organization worker service stopped"))}async registerWithAllOrganizations(){let e=await this.organizationManager.getAllOrganizations();s.info("Registering with all organizations",{organizationCount:e.length});let t=e.map(a=>this.registerWithOrganization(a.id).catch(i=>{s.error("Failed to register with organization",{organizationId:a.id,organizationName:a.name,error:i instanceof Error?i.message:String(i)})}));await Promise.all(t),s.info("Organization registrations complete",{successfulRegistrations:this.workerRegistrations.size,totalOrganizations:e.length})}async registerWithOrganization(e){try{let t=await this.organizationManager.getOrganization(e);if(!t||!t.enabled){s.debug("Skipping disabled organization",{organizationId:e});return}s.info("Registering with organization",{organizationId:e,organizationName:t.name,capabilities:this.registrationOptions.capabilities,capabilityCount:this.registrationOptions.capabilities.length}),s.info("REGISTRATION DEBUG: Sending capabilities",{organizationId:e,capabilitiesArray:this.registrationOptions.capabilities,capabilitiesJSON:JSON.stringify(this.registrationOptions.capabilities)}),await this.organizationManager.registerWorkerWithOrganization(e,this.currentIdentity.agentId,this.registrationOptions.capabilities,{maxConcurrentTasks:this.registrationOptions.maxConcurrentTasks,workerType:"AI_AGENT",priority:1})?(this.workerRegistrations.set(e,{organizationId:e,organizationName:t.name,registered:!0,workerId:this.currentIdentity.agentId,registeredAt:new Date,lastHeartbeat:new Date}),s.info("Successfully registered with organization",{organizationId:e,organizationName:t.name,workerId:this.currentIdentity.agentId}),this.emit("organizationRegistered",{organizationId:e,organizationName:t.name,workerId:this.currentIdentity.agentId})):(this.workerRegistrations.set(e,{organizationId:e,organizationName:t.name,registered:!1,error:"Registration failed"}),s.error("Failed to register with organization",{organizationId:e,organizationName:t.name}),this.emit("organizationRegistrationFailed",{organizationId:e,organizationName:t.name,error:"Registration failed"}))}catch(t){s.error("Error registering with organization",{organizationId:e,error:t instanceof Error?t.message:String(t)}),this.emit("organizationRegistrationFailed",{organizationId:e,error:t instanceof Error?t.message:String(t)})}}async unregisterFromAllOrganizations(){let e=Array.from(this.workerRegistrations.keys()).map(t=>this.organizationManager.unregisterWorker(t,this.currentIdentity.agentId).catch(a=>{s.error("Failed to unregister from organization",{organizationId:t,error:a instanceof Error?a.message:String(a)})}));await Promise.all(e)}getSmartPollingMetrics(){return this.smartPollingService.getMetrics()}getPollingStatus(){return this.smartPollingService.getPollingStatus()}setupOrganizationListeners(){this.organizationManager.on("organizationAdded",async e=>{s.info("New organization added, registering worker",{organizationId:e.id,organizationName:e.name}),await this.registerWithOrganization(e.id)}),this.organizationManager.on("organizationRemoved",async e=>{s.info("Organization removed, unregistering worker",{organizationId:e}),await this.organizationManager.unregisterWorker(e,this.currentIdentity.agentId),this.workerRegistrations.delete(e)}),this.organizationManager.on("organizationUpdated",async(e,t)=>{(t.apiUrl||t.apiKey)&&(s.info("Organization connection details updated, re-registering worker",{organizationId:e}),this.workerRegistrations.has(e)&&(await this.organizationManager.unregisterWorker(e,this.currentIdentity.agentId),this.workerRegistrations.delete(e)),await this.registerWithOrganization(e))})}async ensureAgentIdentity(){let e=this.identityService.getCurrentIdentity();return e||await this.identityService.initializeIdentity({strategy:"hybrid",includeEnvironment:!0,persistent:!0})}async getAllOrganizationStatuses(){let e=await this.organizationManager.getAllOrganizations(),t=[];for(let a of e){let i=this.workerRegistrations.get(a.id);i?t.push(i):t.push({organizationId:a.id,organizationName:a.name,registered:!1})}return t}getOrganizationRegistration(e){return this.workerRegistrations.get(e)}getWorkHandlerRegistry(){return this.workHandlerRegistry}getSmartPollingService(){return this.smartPollingService}async forcePollingAll(){s.info("Forcing immediate polling for all organizations"),await this.smartPollingService.forcePolling()}async validateWorkerRegistrations(){s.info("Validating worker registrations across organizations");let e=await this.organizationManager.getAllOrganizations();for(let t of e)t.enabled&&!this.workerRegistrations.has(t.id)&&(s.warn("Missing worker registration, attempting to register",{organizationId:t.id,organizationName:t.name}),await this.registerWithOrganization(t.id));s.info("Worker registration validation complete",{totalOrganizations:this.workerRegistrations.size,configuredOrganizations:e.length})}startRegistrationHealthCheck(){let t=async()=>{if(this.isRunning){s.debug("Performing worker registration health check");try{let a=await this.organizationManager.getAllOrganizations();for(let i of a){if(!i.enabled)continue;let n=this.workerRegistrations.get(i.id);if(!n)s.warn("Missing worker registration, attempting to register",{organizationId:i.id,organizationName:i.name}),await this.registerWithOrganization(i.id);else if(!n.registered)s.warn("Worker registration marked as failed, attempting to re-register",{organizationId:i.id,organizationName:i.name,error:n.error}),await this.registerWithOrganization(i.id);else{let o=n.lastHeartbeat?Date.now()-n.lastHeartbeat.getTime():1/0;o>6e5&&(s.warn("Stale worker registration detected, attempting to refresh",{organizationId:i.id,organizationName:i.name,timeSinceLastHeartbeat:Math.round(o/1e3)+"s"}),await this.organizationManager.unregisterWorker(i.id,this.currentIdentity.agentId),this.workerRegistrations.delete(i.id),await this.registerWithOrganization(i.id))}}}catch(a){s.error("Worker registration health check failed",{error:a instanceof Error?a.message:String(a)})}}};setTimeout(t,3e4),setInterval(t,3e5),s.info("Worker registration health check started",{interval:3e5})}async updateWorkProgress(e,t,a){let i=this.workerRegistrations.get(e);if(i&&i.registered)try{s.info("Work progress update requested",{organizationId:e,workItemId:t,progress:a})}catch(n){s.error("Failed to update work progress",{organizationId:e,workItemId:t,error:n instanceof Error?n.message:String(n)})}else s.warn("Cannot update work progress - organization not registered",{organizationId:e,workItemId:t})}async getRegistrationHealthStatus(){let e=await this.organizationManager.getAllOrganizations(),t=[],a=0,i=0;return e.forEach(n=>{let o=this.workerRegistrations.get(n.id),c=o?.registered||!1,d=!1,p,u;c&&o?(p=o.lastHeartbeat,d=p?Date.now()-p.getTime()<5*60*1e3:!1,d?a++:(i++,u=p?"Heartbeat overdue":"No heartbeat recorded")):o&&!o.registered?(i++,u=o.error||"Registration failed"):(i++,u="Not registered"),t.push({organizationId:n.id,organizationName:n.name,registered:c,healthy:d,lastHeartbeat:p,error:u})}),{totalOrganizations:e.length,registeredOrganizations:this.workerRegistrations.size,healthyRegistrations:a,unhealthyRegistrations:i,registrationDetails:t}}async getOrganizationClient(e){try{return await this.organizationManager.getClient(e)}catch(t){return s.warn("Failed to get organization client",{organizationId:e,error:t instanceof Error?t.message:String(t)}),null}}}});var z,x,ct,mi=M(()=>{"use strict";z=require("fs"),x=A(require("path"));j();ct=class{async analyzeDirectory(r){try{if(!(await z.promises.stat(r)).isDirectory())throw new Error("Path is not a directory");let t=x.basename(r),a=await this.fileExists(x.join(r,"package.json")),i=await this.fileExists(x.join(r,"docker-compose.yml"))||await this.fileExists(x.join(r,"docker-compose.yaml")),n=await this.fileExists(x.join(r,"main.tf"))||await this.fileExists(x.join(r,"terraform")),o=await this.detectGitInfo(r),c=await this.detectServices(r),d,p=[];if(a){let h=await this.analyzePackageJson(x.join(r,"package.json"));d=h.framework,p=h.technologies}let u={name:this.generateWorkspaceName(t),workspaceId:this.generateWorkspaceId(t),description:this.generateDescription(t,d,c),services:c,framework:d,hasPackageJson:a,hasDockerCompose:i,hasTerraform:n,suggestedTech:p,gitInfo:o};return s.info("Workspace analysis complete",{path:r,servicesFound:c.length,framework:d}),u}catch(e){throw s.error("Failed to analyze directory",{path:r,error:e instanceof Error?e.message:String(e)}),e}}async detectServices(r){let e=[];try{let t=await this.detectDockerComposeServices(r);e.push(...t);let a=await this.detectNodeServices(r);e.push(...a);let i=await this.detectPythonServices(r);e.push(...i);let n=await this.detectJavaServices(r);e.push(...n);let o=await this.detectGoServices(r);e.push(...o);let c=await this.detectRustServices(r);e.push(...c);let d=await this.detectDotNetServices(r);e.push(...d);let p=await this.detectPhpServices(r);e.push(...p);let u=await this.detectRubyServices(r);e.push(...u);let h=await this.detectDirectoryServices(r);e.push(...h);let f=await this.detectDatabaseServices(r);e.push(...f);let b=await this.detectAPIServices(r);e.push(...b);let w=this.deduplicateServices(e),B=[];for(let T of w){let $=await this.enhanceServiceSuggestion(T,T.path);B.push($)}return B}catch(t){return s.debug("Error detecting services",{path:r,error:t instanceof Error?t.message:String(t)}),e}}async detectDockerComposeServices(r){let e=[],t=[x.join(r,"docker-compose.yml"),x.join(r,"docker-compose.yaml"),x.join(r,"docker-compose.dev.yml")];for(let a of t)if(await this.fileExists(a))try{let i=await z.promises.readFile(a,"utf-8"),n=i.match(/^\s{0,2}(\w+):\s*$/gm);if(n)for(let o of n){let c=o.trim().replace(":","");if(["version","services","networks","volumes"].includes(c))continue;let d=this.inferServiceType(c,i);e.push({name:c,type:d.type,technology:d.technology,port:d.port,path:a,confidence:"high",reason:"Defined in docker-compose.yml"})}}catch{s.debug("Failed to parse docker-compose",{path:a})}return e}async detectNodeServices(r){let e=[],t=x.join(r,"package.json");if(await this.fileExists(t))try{let i=await z.promises.readFile(t,"utf-8"),n=JSON.parse(i);if(n.scripts){let o=n.scripts;(o.start||o.serve||o["start:server"]||o.dev)&&(o.start?.includes("node")||o.start?.includes("ts-node")||o.dev?.includes("nodemon"))&&e.push({name:n.name||"backend",type:"backend",technology:this.detectNodeFramework(n),port:this.extractPort(o.start||o.dev||""),path:r,confidence:"high",reason:"Node.js backend detected from package.json"}),(o.build?.includes("vite")||o.build?.includes("webpack")||o.build?.includes("react")||o.build?.includes("next"))&&e.push({name:n.name||"frontend",type:"frontend",technology:this.detectFrontendFramework(n),port:this.extractPort(o.dev||o.start||""),path:r,confidence:"high",reason:"Frontend application detected from package.json"})}}catch{s.debug("Failed to parse package.json",{path:t})}let a=x.join(r,"packages");if(await this.fileExists(a)){let i=await z.promises.readdir(a);for(let n of i){let o=x.join(a,n),c=x.join(o,"package.json");if(await this.fileExists(c))try{let d=await z.promises.readFile(c,"utf-8"),p=JSON.parse(d),u=this.inferServiceTypeFromPackage(p,n);e.push({name:p.name||n,type:u.type,technology:u.technology,port:u.port,path:o,relativePath:`packages/${n}`,confidence:"medium",reason:`Detected from packages/${n}/package.json`})}catch{s.debug("Failed to parse sub-package.json",{path:c})}}}return e}async detectDirectoryServices(r){let e=[],t=[{name:"backend",type:"backend"},{name:"frontend",type:"frontend"},{name:"api",type:"api"},{name:"server",type:"backend"},{name:"client",type:"frontend"},{name:"web",type:"frontend"},{name:"app",type:"frontend"},{name:"services",type:"service"},{name:"workers",type:"service"},{name:"database",type:"database"},{name:"db",type:"database"}];for(let a of t){let i=x.join(r,a.name);if(await this.fileExists(i)&&(await z.promises.stat(i)).isDirectory()){let o=await this.detectTechnologyInDirectory(i);e.push({name:a.name,type:a.type,technology:o.technology,port:o.port,path:i,confidence:"medium",reason:`${a.name} directory found`})}}return e}async detectDatabaseServices(r){let e=[],t=["migrations","db/migrations","database/migrations","prisma/migrations","src/migrations"];for(let a of t){let i=x.join(r,a);if(await this.fileExists(i)){let n="PostgreSQL";a.includes("prisma")&&(n="PostgreSQL (Prisma)");let o=x.join(r,"prisma","schema.prisma");if(await this.fileExists(o)){let c=await z.promises.readFile(o,"utf-8");c.includes('provider = "mysql"')?n="MySQL (Prisma)":c.includes('provider = "mongodb"')?n="MongoDB (Prisma)":c.includes('provider = "sqlite"')&&(n="SQLite (Prisma)")}e.push({name:"database",type:"database",technology:n,port:n.includes("PostgreSQL")?5432:n.includes("MySQL")?3306:n.includes("MongoDB")?27017:void 0,path:i,confidence:"high",reason:"Database migrations found"});break}}return e}async detectAPIServices(r){let e=[],t=["schema.graphql","graphql/schema.graphql","src/schema.graphql","src/graphql/schema.graphql"];for(let i of t)if(await this.fileExists(x.join(r,i))){e.push({name:"graphql-api",type:"api",technology:"GraphQL",port:4e3,path:x.join(r,i),confidence:"high",reason:"GraphQL schema file found"});break}let a=["openapi.yaml","openapi.yml","swagger.yaml","swagger.yml","api/openapi.yaml"];for(let i of a)if(await this.fileExists(x.join(r,i))){e.push({name:"rest-api",type:"api",technology:"REST (OpenAPI)",port:3e3,path:x.join(r,i),confidence:"high",reason:"OpenAPI specification found"});break}return e}async analyzePackageJson(r){try{let e=await z.promises.readFile(r,"utf-8"),t=JSON.parse(e),a=[],i,n={...t.dependencies,...t.devDependencies};return n.next?(i="Next.js",a.push("React","Next.js")):n.react?(i="React",a.push("React"),n.vite&&a.push("Vite")):n.vue?(i="Vue",a.push("Vue")):n["@angular/core"]?(i="Angular",a.push("Angular")):n.express?(i="Express",a.push("Express.js")):n.fastify?(i="Fastify",a.push("Fastify")):n.koa?(i="Koa",a.push("Koa")):n["@nestjs/core"]&&(i="NestJS",a.push("NestJS")),n.typescript&&a.push("TypeScript"),n.graphql&&a.push("GraphQL"),n.prisma&&a.push("Prisma"),n.typeorm&&a.push("TypeORM"),n.mongoose&&a.push("MongoDB"),n.pg&&a.push("PostgreSQL"),n.redis&&a.push("Redis"),n["socket.io"]&&a.push("Socket.io"),n.tailwindcss&&a.push("Tailwind CSS"),n["styled-components"]&&a.push("Styled Components"),{framework:i,technologies:[...new Set(a)]}}catch{return{technologies:[]}}}async detectTechnologyInDirectory(r){let e=x.join(r,"package.json");if(await this.fileExists(e)){let{framework:t,technologies:a}=await this.analyzePackageJson(e);return{technology:t||a[0],port:t?.includes("Next")?3e3:t?.includes("React")?5173:t?.includes("Express")?3e3:void 0}}return await this.fileExists(x.join(r,"requirements.txt"))?{technology:"Python",port:8e3}:await this.fileExists(x.join(r,"Gemfile"))?{technology:"Ruby",port:3e3}:await this.fileExists(x.join(r,"go.mod"))?{technology:"Go",port:8080}:await this.fileExists(x.join(r,"Cargo.toml"))?{technology:"Rust",port:8080}:{}}async fileExists(r){try{return await z.promises.access(r),!0}catch{return!1}}async enhanceServiceSuggestion(r,e){let t=await this.detectGitInfo(e),a=await this.detectLanguageAndFrameworks(e),i=r.type,n=r.technology,o=r.name.toLowerCase();return o.includes("backend")||o.includes("api")||o.includes("server")?i="backend":o.includes("frontend")||o.includes("web")||o.includes("ui")?i="frontend":o.includes("database")||o.includes("db")?i="database":o.includes("cache")||o.includes("redis")?i="cache":o.includes("queue")||o.includes("worker")?i="queue":(o.includes("mcp")||o.includes("agent"))&&(i="service"),(!n||n==="unknown")&&(a.frameworks&&a.frameworks.length>0?n=a.frameworks[0]:a.primaryLanguage&&(n=a.primaryLanguage)),{...r,type:i,technology:n,gitInfo:t,primaryLanguage:a.primaryLanguage,frameworks:a.frameworks}}async detectLanguageAndFrameworks(r){try{let e=await z.promises.readdir(r),t=[],a;if(e.includes("package.json")){a="JavaScript/TypeScript";try{let i=await z.promises.readFile(x.join(r,"package.json"),"utf-8"),n=JSON.parse(i),o={...n.dependencies,...n.devDependencies};o.express&&t.push("Express.js"),o.fastify&&t.push("Fastify"),o.koa&&t.push("Koa"),o.next&&t.push("Next.js"),o.react&&t.push("React"),o.vue&&t.push("Vue.js"),o.angular&&t.push("Angular"),o.svelte&&t.push("Svelte"),o.nestjs&&t.push("NestJS")}catch{}}if((e.some(i=>i.endsWith(".py"))||e.includes("requirements.txt")||e.includes("pyproject.toml"))&&(a="Python",(e.includes("manage.py")||e.includes("settings.py"))&&t.push("Django"),(e.includes("app.py")||e.includes("wsgi.py"))&&t.push("Flask"),e.includes("main.py")&&t.push("FastAPI")),(e.some(i=>i.endsWith(".java"))||e.includes("pom.xml")||e.includes("build.gradle"))&&(a="Java",e.includes("pom.xml")))try{let i=await z.promises.readFile(x.join(r,"pom.xml"),"utf-8");i.includes("spring-boot")&&t.push("Spring Boot"),i.includes("spring-web")&&t.push("Spring Web")}catch{}if((e.some(i=>i.endsWith(".go"))||e.includes("go.mod"))&&(a="Go",e.includes("go.mod")))try{let i=await z.promises.readFile(x.join(r,"go.mod"),"utf-8");i.includes("gin-gonic/gin")&&t.push("Gin"),i.includes("gorilla/mux")&&t.push("Gorilla Mux"),i.includes("echo")&&t.push("Echo")}catch{}if((e.some(i=>i.endsWith(".rs"))||e.includes("Cargo.toml"))&&(a="Rust",e.includes("Cargo.toml")))try{let i=await z.promises.readFile(x.join(r,"Cargo.toml"),"utf-8");i.includes("actix-web")&&t.push("Actix Web"),i.includes("warp")&&t.push("Warp"),i.includes("rocket")&&t.push("Rocket")}catch{}return{primaryLanguage:a,frameworks:t}}catch{return{primaryLanguage:void 0,frameworks:[]}}}async detectGitInfo(r){try{let e=x.join(r,".git");if(!await this.fileExists(e))return{isGitRepo:!1,hasRemote:!1};let a,i,n=!1;try{let o=x.join(e,"HEAD");if(await this.fileExists(o)){let d=(await z.promises.readFile(o,"utf-8")).match(/ref: refs\/heads\/(.+)/);d&&(a=d[1].trim())}}catch{}try{let o=x.join(e,"config");if(await this.fileExists(o)){let d=(await z.promises.readFile(o,"utf-8")).match(/\[remote "origin"\][\s\S]*?url = (.+)/);d&&(i=d[1].trim(),n=!0)}}catch{}return{isGitRepo:!0,hasRemote:n,branch:a,remote:i}}catch{return{isGitRepo:!1,hasRemote:!1}}}generateWorkspaceName(r){return r.replace(/[-_]/g," ").replace(/\b\w/g,e=>e.toUpperCase())}generateWorkspaceId(r){return r.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}generateDescription(r,e,t){let a=`${this.generateWorkspaceName(r)} workspace`;if(e&&(a+=` built with ${e}`),t&&t.length>0){let i=[...new Set(t.map(n=>n.type))];a+=` containing ${i.join(", ")} services`}return a}async detectPythonServices(r){let e=[];try{let t=await z.promises.readdir(r),a=t.includes("pyproject.toml"),i=t.includes("requirements.txt"),n=t.includes("Pipfile"),o=t.includes("setup.py"),c=t.includes("manage.py"),d=t.includes("app.py"),p=t.includes("main.py");if(!a&&!i&&!n&&!o&&!c&&!d&&!p)return e;let u="Python",h="backend",f;if(c)u="Django",f=8e3;else if(d)try{let w=await z.promises.readFile(x.join(r,"app.py"),"utf-8");w.includes("from flask")||w.includes("import flask")?(u="Flask",f=5e3):(w.includes("from fastapi")||w.includes("import fastapi"))&&(u="FastAPI",f=8e3)}catch{}if(i)try{let w=await z.promises.readFile(x.join(r,"requirements.txt"),"utf-8");w.includes("django")?(u="Django",f=f||8e3):w.includes("flask")?(u="Flask",f=f||5e3):w.includes("fastapi")?(u="FastAPI",f=f||8e3):w.includes("streamlit")&&(u="Streamlit",h="frontend",f=8501)}catch{}let b=x.basename(r);e.push({name:b,type:h,technology:u,port:f,path:r,confidence:c||d?"high":"medium",reason:`Python project detected with ${u}${f?` on port ${f}`:""}`})}catch{}return e}async detectJavaServices(r){let e=[];try{let t=await z.promises.readdir(r),a=t.includes("pom.xml"),i=t.includes("build.gradle")||t.includes("build.gradle.kts"),n=t.includes("application.properties")||t.includes("application.yml");if(!a&&!i&&!n)return e;let o="Java",c=8080;if(n){o="Spring Boot";try{let p=t.includes("application.properties")?"application.properties":"application.yml",u=await z.promises.readFile(x.join(r,p),"utf-8");if(p.endsWith(".properties")){let h=u.match(/server\.port\s*=\s*(\d+)/);h&&(c=parseInt(h[1]))}else{let h=u.match(/server:\s*\n\s*port:\s*(\d+)/);h&&(c=parseInt(h[1]))}}catch{}}if(a)try{let p=await z.promises.readFile(x.join(r,"pom.xml"),"utf-8");p.includes("spring-boot-starter")?o="Spring Boot":p.includes("quarkus")&&(o="Quarkus")}catch{}let d=x.basename(r);e.push({name:d,type:"backend",technology:o,port:c,path:r,confidence:a||i?"high":"medium",reason:`Java project detected with ${o}${c?` on port ${c}`:""}`})}catch{}return e}async detectGoServices(r){let e=[];try{let t=await z.promises.readdir(r),a=t.includes("go.mod"),i=t.includes("main.go");if(!a&&!i)return e;let n="Go",o;if(a)try{let d=await z.promises.readFile(x.join(r,"go.mod"),"utf-8");d.includes("github.com/gin-gonic/gin")?(n="Go + Gin",o=8080):d.includes("github.com/gorilla/mux")?(n="Go + Gorilla Mux",o=8080):d.includes("github.com/labstack/echo")?(n="Go + Echo",o=1323):d.includes("github.com/gofiber/fiber")&&(n="Go + Fiber",o=3e3)}catch{}if(i)try{let p=(await z.promises.readFile(x.join(r,"main.go"),"utf-8")).match(/:(\d{4})/);p&&(o=parseInt(p[1]))}catch{}let c=x.basename(r);e.push({name:c,type:"backend",technology:n,port:o||8080,path:r,confidence:a?"high":"medium",reason:`Go project detected with ${n}${o?` on port ${o}`:""}`})}catch{}return e}async detectRustServices(r){let e=[];try{if(!(await z.promises.readdir(r)).includes("Cargo.toml"))return e;let i="Rust",n=8e3;try{let c=await z.promises.readFile(x.join(r,"Cargo.toml"),"utf-8");c.includes("actix-web")?(i="Rust + Actix Web",n=8080):c.includes("warp")?(i="Rust + Warp",n=3030):c.includes("rocket")?(i="Rust + Rocket",n=8e3):c.includes("axum")&&(i="Rust + Axum",n=3e3)}catch{}let o=x.basename(r);e.push({name:o,type:"backend",technology:i,port:n,path:r,confidence:"high",reason:`Rust project detected with ${i}${n?` on port ${n}`:""}`})}catch{}return e}async detectDotNetServices(r){let e=[];try{let t=await z.promises.readdir(r),a=t.filter(p=>p.endsWith(".csproj")),i=t.some(p=>p.endsWith(".sln")),n=t.includes("project.json");if(a.length===0&&!i&&!n)return e;let o=".NET",c=5e3;if(a.length>0)try{let p=x.join(r,a[0]),u=await z.promises.readFile(p,"utf-8");u.includes("Microsoft.AspNetCore")||u.includes("Microsoft.NET.Sdk.Web")?(o="ASP.NET Core",c=5e3):u.includes("System.Web.Mvc")&&(o="ASP.NET MVC",c=80)}catch{}let d=x.basename(r);e.push({name:d,type:"backend",technology:o,port:c,path:r,confidence:a.length>0?"high":"medium",reason:`.NET project detected with ${o}${c?` on port ${c}`:""}`})}catch{}return e}async detectPhpServices(r){let e=[];try{let t=await z.promises.readdir(r),a=t.includes("composer.json"),i=t.includes("index.php"),n=t.includes("artisan"),o=t.includes("wp-config.php");if(!a&&!i&&!n&&!o)return e;let c="PHP",d=80;if(n)c="Laravel",d=8e3;else if(o)c="WordPress",d=80;else if(a)try{let u=await z.promises.readFile(x.join(r,"composer.json"),"utf-8"),h=JSON.parse(u);h.require&&h.require["laravel/framework"]?(c="Laravel",d=8e3):h.require&&h.require["symfony/symfony"]?(c="Symfony",d=8e3):h.require&&h.require["cakephp/cakephp"]&&(c="CakePHP",d=8765)}catch{}let p=x.basename(r);e.push({name:p,type:"backend",technology:c,port:d,path:r,confidence:n||a?"high":"medium",reason:`PHP project detected with ${c}${d?` on port ${d}`:""}`})}catch{}return e}async detectRubyServices(r){let e=[];try{let t=await z.promises.readdir(r),a=t.includes("Gemfile"),i=t.includes("config.ru"),n=t.includes("config")&&await this.directoryExists(x.join(r,"config","application.rb"));if(!a&&!i&&!n)return e;let o="Ruby",c=3e3;if(n)o="Ruby on Rails",c=3e3;else if(a)try{let p=await z.promises.readFile(x.join(r,"Gemfile"),"utf-8");p.includes("rails")?(o="Ruby on Rails",c=3e3):p.includes("sinatra")?(o="Sinatra",c=4567):p.includes("grape")&&(o="Grape API",c=9292)}catch{}let d=x.basename(r);e.push({name:d,type:"backend",technology:o,port:c,path:r,confidence:n||a?"high":"medium",reason:`Ruby project detected with ${o}${c?` on port ${c}`:""}`})}catch{}return e}async directoryExists(r){try{return(await z.promises.stat(r)).isDirectory()}catch{return!1}}inferServiceType(r,e){let t=r.toLowerCase();return t.includes("postgres")||t.includes("pg")?{type:"database",technology:"PostgreSQL",port:5432}:t.includes("mysql")||t.includes("mariadb")?{type:"database",technology:"MySQL",port:3306}:t.includes("mongo")?{type:"database",technology:"MongoDB",port:27017}:t.includes("redis")?{type:"cache",technology:"Redis",port:6379}:t.includes("frontend")||t.includes("client")||t.includes("web")?{type:"frontend"}:t.includes("backend")||t.includes("api")||t.includes("server")?{type:"backend"}:t.includes("rabbit")||t.includes("queue")?{type:"queue",technology:t.includes("rabbit")?"RabbitMQ":void 0}:{type:"service"}}inferServiceTypeFromPackage(r,e){let{framework:t,technologies:a}=this.getPackageInfo(r);return a.some(i=>["React","Vue","Angular","Next.js"].includes(i))?{type:"frontend",technology:t,port:t?.includes("Next")?3e3:5173}:a.some(i=>["Express","Fastify","Koa","NestJS"].includes(i))?{type:"backend",technology:t,port:3e3}:a.includes("GraphQL")?{type:"api",technology:"GraphQL",port:4e3}:this.inferServiceType(e,"")}getPackageInfo(r){let e=[],t,a={...r.dependencies,...r.devDependencies};return a.next&&(t="Next.js",e.push("Next.js")),a.react&&(t=t||"React",e.push("React")),a.vue&&(t=t||"Vue",e.push("Vue")),a.express&&(t=t||"Express",e.push("Express")),a.fastify&&(t=t||"Fastify",e.push("Fastify")),{framework:t,technologies:e}}detectNodeFramework(r){let e={...r.dependencies,...r.devDependencies};return e.express?"Express.js":e.fastify?"Fastify":e.koa?"Koa":e["@nestjs/core"]?"NestJS":e["@hapi/hapi"]?"Hapi":"Node.js"}detectFrontendFramework(r){let e={...r.dependencies,...r.devDependencies};if(e.next)return"Next.js";if(e.react)return e.vite?"React + Vite":"React";if(e.vue)return"Vue.js";if(e["@angular/core"])return"Angular";if(e.svelte)return"Svelte"}extractPort(r){let e=r.match(/--port[= ](\d+)|PORT=(\d+)|:(\d{4})/);if(e)return parseInt(e[1]||e[2]||e[3])}deduplicateServices(r){let e=new Map;for(let t of r){let a=`${t.name}-${t.type}`,i=e.get(a);(!i||t.confidence==="high"&&i.confidence!=="high")&&e.set(a,t)}return Array.from(e.values())}async analyzePathAndSuggestWorkspace(r){try{let e=await this.analyzeDirectory(r),t=e.services.map(o=>({name:o.name,type:o.type,path:o.path,port:o.port,description:o.reason,confidence:o.confidence==="high"?.9:o.confidence==="medium"?.7:.5,metadata:{technology:o.technology,originalConfidence:o.confidence}})),a=t.length>0?t.reduce((o,c)=>o+c.confidence,0)/t.length:.5,i=[],n=[];return e.hasPackageJson&&i.push("Found package.json - Node.js project detected"),e.hasDockerCompose&&i.push("Docker Compose found - containerized setup detected"),e.hasTerraform&&i.push("Terraform configuration found - infrastructure as code detected"),t.length===0&&n.push("No services detected - manual configuration may be required"),t.some(o=>o.confidence<.6)&&n.push("Some services detected with low confidence - please review"),{name:e.name,description:e.description,workspaceId:e.workspaceId,path:r,services:t,overallConfidence:a,recommendations:i,warnings:n}}catch(e){throw s.error("Failed to analyze path for workspace suggestion:",{path:r,error:e instanceof Error?e.message:String(e)}),new Error(`Failed to analyze workspace path: ${e instanceof Error?e.message:"Unknown error"}`)}}async analyzeExistingWorkspace(r){try{let e=await this.analyzePathAndSuggestWorkspace(r.path),t=[],a=[],i=[],n=new Map(r.services.map(T=>[T.name.toLowerCase(),T])),o=new Map(e.services.map(T=>[T.name.toLowerCase(),T])),c=r.services.map(T=>{let $=o.get(T.name.toLowerCase());if(!$)return{...T,status:"missing"};let K=T.technology&&$.metadata?.technology&&T.technology!==$.metadata.technology,X=T.port&&$.port&&T.port!==$.port;return{...T,status:K||X?"outdated":"found"}}),d=e.services.filter(T=>!n.has(T.name.toLowerCase())),p=c.filter(T=>T.status==="missing");p.length>0&&(p.forEach(T=>{t.push({type:"remove_service",service:T.name,description:`Service "${T.name}" is configured but no longer exists in the workspace`,action:`Remove ${T.name} from workspace configuration or restore the service`})}),i.push(`${p.length} configured service(s) were not found in the workspace`));let u=c.filter(T=>T.status==="outdated");u.length>0&&(u.forEach(T=>{let $=o.get(T.name.toLowerCase());if($){let K=[];T.technology!==$.metadata?.technology&&K.push(`technology: ${T.technology} \u2192 ${$.metadata?.technology}`),T.port!==$.port&&K.push(`port: ${T.port} \u2192 ${$.port}`),t.push({type:"update_service",service:T.name,description:`Service "${T.name}" configuration is outdated: ${K.join(", ")}`,action:`Update ${T.name} configuration with detected changes`})}}),a.push(`${u.length} service(s) have outdated configuration`)),d.length>0&&(d.forEach(T=>{t.push({type:"add_service",service:T.name,description:`New ${T.type} service "${T.name}" detected with ${T.metadata?.technology||"unknown technology"}`,action:`Add ${T.name} to workspace configuration`})}),a.push(`${d.length} new service(s) detected and can be added to workspace`));let h=e.services.map(T=>T.metadata?.technology).filter(Boolean),f=[...new Set(h)];f.length>1&&a.push(`Multi-technology workspace detected: ${f.join(", ")}`);let b=e.services.some(T=>T.type==="database"),w=e.services.some(T=>T.type==="backend"),B=e.services.some(T=>T.type==="frontend");return w&&B&&!b&&a.push("Consider adding database service for full-stack application"),e.services.length===0&&i.push("No services detected in workspace - workspace may be inactive or misconfigured"),{currentServices:c,discoveredServices:e.services,recommendations:[...e.recommendations,...a],warnings:[...e.warnings,...i],improvements:t}}catch(e){throw s.error("Failed to analyze existing workspace:",{workspace:r.name,path:r.path,error:e instanceof Error?e.message:String(e)}),new Error(`Failed to analyze existing workspace: ${e instanceof Error?e.message:"Unknown error"}`)}}}});var fi={};be(fi,{getAgentServiceRef:()=>Sn,start:()=>Si});async function Si(){let l=new Ut;try{s.info("\u{1F680} Task Shepherd AI Agent starting..."),s.info("Stage 1: Loading configuration...");let r=ha();s.info("\u2713 Configuration loaded and validated",{workerId:r.workerId,capabilities:r.capabilities,websocketEnabled:r.websocketEnabled,environment:r.environment}),s.info("Stage 2: Starting core infrastructure...");let e=(0,lt.default)();e.use(lt.default.json()),e.get("/health",(I,m)=>{let g=yi||r.workerId;m.json({status:"ok",workerId:g,capabilities:r.capabilities,timestamp:new Date().toISOString(),uptime:process.uptime()})}),e.get("/status",(I,m)=>{m.json({workerId:r.workerId,capabilities:r.capabilities,environment:r.environment,resources:l.getRegisteredResources(),uptime:process.uptime(),memory:process.memoryUsage(),timestamp:new Date().toISOString()})}),e.get("/api/status",(I,m)=>{let g=pe?pe.getStatus():{connected:!1,registered:!1,closed:!0,workerId:r.workerId,capabilities:r.capabilities,websocketEnabled:r.websocketEnabled,websocketConnected:!1,authenticated:!1,uptime:0};m.json({...g,system:{uptime:process.uptime(),memory:process.memoryUsage(),platform:process.platform,nodeVersion:process.version},resources:l.getRegisteredResources(),timestamp:new Date().toISOString()})}),e.get("/api/websocket/status",(I,m)=>{let g=pe?.getStatus()||{},y=pe?.isConnected()||!1;m.json({status:y?"connected":"disconnected",connected:y,lastConnectedAt:y?new Date().toISOString():null,lastDisconnectedAt:y?null:new Date().toISOString(),reconnectAttempts:0,maxReconnectAttempts:r.retryAttempts||3,nextReconnectAt:null,activeSubscriptions:g.websocketConnected?1:0})}),e.get("/api/worker",(I,m)=>{m.json({workerId:r.workerId,capabilities:r.capabilities,registered:pe?.isRegistered()||!1,status:pe?.getStatus()||{}})}),e.get("/api/websocket/worker",(I,m)=>{let g=pe?.getStatus()||{};m.json({registered:pe?.isRegistered()||!1,workerId:r.workerId,capabilities:r.capabilities,registeredAt:g.uptime?new Date(Date.now()-g.uptime).toISOString():null,lastHeartbeat:pe?.isConnected()?new Date().toISOString():null})}),e.post("/api/websocket/reconnect",async(I,m)=>{try{pe?m.json({success:!0,message:"Reconnect initiated"}):m.status(400).json({success:!1,message:"Agent service not available"})}catch(g){m.status(500).json({success:!1,message:g instanceof Error?g.message:"Reconnect failed"})}}),e.get("/api/queue/queued",(I,m)=>{m.json({success:!0,data:{items:[],total:0,estimatedWaitTime:0}})}),e.get("/api/queue/completed",(I,m)=>{let g=parseInt(I.query.limit)||10,y=parseInt(I.query.offset)||0,k=b.getCompletedItems(g,y);try{let E=global.multiOrgWorkerService;if(E){let W=E.getSmartPollingService().getWorkItemEventStore?.();if(W){let q=k.items.map(C=>{let P=W.getEvents(C.id),F=W.getSummary(C.id),G=P.filter(ke=>ke.eventType==="FAILED").map((ke,Ye)=>({error:ke.errorMessage||"Unknown error",timestamp:ke.timestamp.toISOString(),failureType:"EXECUTION_ERROR",attemptNumber:Ye+1}));return{...C,metadata:{...C.metadata,errorHistory:G.length>0?G:void 0,retryCount:F.retryCount,totalAttempts:F.claimedCount,firstClaimedAt:F.firstClaimed?.toISOString()}}});return m.json({success:!0,data:{items:q,total:k.total,hasMore:k.hasMore}})}}}catch{}return m.json({success:!0,data:{items:k.items,total:k.total,hasMore:k.hasMore}})}),e.get("/api/queue/failed",(I,m)=>{let g=parseInt(I.query.limit)||10,y=parseInt(I.query.offset)||0,E=b.getCompletedItems(100,0).items.filter(W=>W.status==="failed");try{let W=global.multiOrgWorkerService;if(W){let C=W.getSmartPollingService().getWorkItemEventStore?.();if(C){let F=E.map(G=>{let ke=C.getEvents(G.id),Ye=C.getSummary(G.id),Xr=ke.filter(gt=>gt.eventType==="FAILED").map((gt,_i)=>({error:gt.errorMessage||"Unknown error",timestamp:gt.timestamp.toISOString(),failureType:"EXECUTION_ERROR",attemptNumber:_i+1}));return{...G,metadata:{...G.metadata,errorHistory:Xr.length>0?Xr:void 0,retryCount:Ye.retryCount,totalAttempts:Ye.claimedCount,firstClaimedAt:Ye.firstClaimed?.toISOString()}}}).slice(y,y+g);return m.json({success:!0,data:{items:F,total:E.length,hasMore:E.length>y+g}})}}}catch{}let D=E.slice(y,y+g);return m.json({success:!0,data:{items:D,total:E.length,hasMore:E.length>y+g}})}),e.get("/api/queue/requeued",(I,m)=>{try{let g=global.multiOrgWorkerService;if(!g)return m.json({success:!0,data:{items:[],total:0}});let k=g.getSmartPollingService().getWorkItemEventStore?.();if(!k)return m.json({success:!0,data:{items:[],total:0}});let D=k.getAllWorkItemIds().map(W=>{let C=k.getEvents(W).filter(G=>G.eventType==="RETRY");if(C.length===0)return null;let P=C[C.length-1],F=k.getSummary(W);return{id:W,type:P.workType,status:"requeued",priority:P.priority||0,projectId:P.organizationId,projectName:"Unknown Project",title:`${P.workType} work (retried)`,description:"Work item retried after failure",retryCount:C.length,lastRetryAt:P.timestamp,firstClaimedAt:F.firstClaimed,totalAttempts:F.claimedCount,failureCount:F.failureCount,metadata:P.metadata}}).filter(W=>W!==null);return m.json({success:!0,data:{items:D,total:D.length}})}catch{return m.json({success:!0,data:{items:[],total:0},error:"Event store not available"})}}),e.get("/api/queue/stats",(I,m)=>{let g=b.getCompletedItems(100,0),y=g.items.filter(W=>W.status==="completed"),k=g.items.filter(W=>W.status==="failed"),E=g.total>0?y.length/g.total:0,D=y.length>0?y.reduce((W,q)=>W+(q.actualDuration||0),0)/y.length:0;try{let W=global.multiOrgWorkerService;if(W){let C=W.getSmartPollingService().getMetrics();m.json({queued:0,inProgress:C.totalClaimedWork||0,workers:C.totalOrganizations||0,total:g.total,completed:y.length,failed:k.length,successRate:Math.round(E*100)/100,averageCompletionTime:Math.round(D/1e3),isHealthy:(C.errorRate||0)<.5,lastUpdate:new Date().toISOString()})}else throw new Error("MultiOrganizationWorkerService not available")}catch{m.json({total:g.total,queued:0,inProgress:0,completed:y.length,failed:k.length,averageCompletionTime:Math.round(D/1e3),successRate:Math.round(E*100)/100,error:"Smart polling service not available - showing historical data only"})}}),e.get("/api/errors/recent",(I,m)=>{let g=parseInt(I.query.limit)||50;try{let k=b.getCompletedItems(100,0).items.filter(P=>P.status==="failed"),E=k.slice(0,g).map((P,F)=>{let G="Unknown error";return P.metadata?.error&&(typeof P.metadata.error=="string"?G=P.metadata.error:typeof P.metadata.error=="object"&&(G=P.metadata.error.message||P.metadata.error.reason||P.metadata.error.toString()||"Unknown error (object)")),{id:`error-${P.id}-${F}`,workItemId:P.id,errorType:"EXECUTION_ERROR",message:G,stage:"execution",severity:"HIGH",category:"UNKNOWN",retryable:!0,occurredAt:P.completedAt,resolved:!1,workType:P.type,projectId:P.projectId,projectName:P.projectName,metadata:P.metadata}}),D=k.length,W=k.filter(P=>{let F=new Date(P.completedAt),G=new Date(Date.now()-24*60*60*1e3);return F>G}).length,q=k.reduce((P,F)=>{let G="Unknown error";if(F.metadata?.error){if(typeof F.metadata.error=="string")G=F.metadata.error.substring(0,50);else if(typeof F.metadata.error=="object"){let ke=F.metadata.error;G=(ke.message||ke.reason||"Unknown error object").substring(0,50)}}return P[G]=(P[G]||0)+1,P},{}),C=Object.entries(q).sort(([,P],[,F])=>F-P).slice(0,5).map(([P,F])=>({type:P,count:F}));m.json({errors:E,summary:{totalErrors:D,unresolvedErrors:D,criticalErrors:D,recentErrors:W,topErrorTypes:C}})}catch(y){s.error("Failed to fetch recent errors",{error:y}),m.status(500).json({error:"Failed to fetch error data",details:y instanceof Error?y.message:String(y)})}}),e.post("/api/queue/clear-stuck-items",(I,m)=>{try{let g=global.multiOrgWorkerService;if(g){let y=g.getSmartPollingService(),k=y.getProcessingWorkItems();y.clearStuckWorkItems(),m.json({success:!0,message:"Cleared stuck work items from processing tracking",clearedItems:k,count:k.length})}else m.status(500).json({success:!1,error:"Smart polling service not available"})}catch(g){m.status(500).json({success:!1,error:g instanceof Error?g.message:String(g)})}}),e.get("/api/queue/in-progress",(I,m)=>{try{let g=global.multiOrgWorkerService;if(!g)throw new Error("MultiOrganizationWorkerService not available");let k=g.getSmartPollingService().getProcessingWorkItems?.()||[];m.json({success:!0,data:{items:k.map(E=>{let D=E.workData||{},W=E.workType||"unknown",q=D.projectId||D.project?.id||"unknown",C=D.projectName||D.project?.name||"Unknown Project",P=D.title||D.story?.title||`${W} work`,F=E.claimedAt instanceof Date?E.claimedAt:new Date(E.claimedAt),G=Date.now()-F.getTime();return{id:E.id,type:W,status:"in_progress",priority:E.priority||0,projectId:q,projectName:C,title:P,description:D.description||`Processing ${W} work`,assignedTo:D.workerId||"agent",createdAt:D.createdAt||F.toISOString(),startedAt:F.toISOString(),estimatedDuration:3e5,actualDuration:G,retryCount:0,progress:{percentage:Math.min(90,Math.floor(G/3e5*100)),currentStep:`Processing ${W}`,totalSteps:1}}}),total:k.length,totalEstimatedRemaining:k.reduce((E,D)=>{let W=D.claimedAt instanceof Date?D.claimedAt:new Date(D.claimedAt),q=Date.now()-W.getTime(),C=Math.max(0,3e5-q);return E+Math.floor(C/1e3)},0)}})}catch{m.json({success:!0,data:{items:[],total:0},error:"Smart polling service not available"})}}),e.get("/api/smart-polling/metrics",(I,m)=>{try{let g=global.multiOrgWorkerService;if(!g)return m.json({success:!1,error:"Multi-organization worker service not available",data:{totalOrganizations:0,activePolling:0,totalPolls:0,totalErrors:0,totalClaimedWork:0,averageInterval:6e4,errorRate:0,organizationStats:[]}});let y=g.getSmartPollingMetrics();return m.json({success:!0,data:y})}catch(g){return s.error("Failed to get smart polling metrics",{error:g instanceof Error?g.message:String(g)}),m.status(500).json({success:!1,error:"Failed to retrieve smart polling metrics",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/smart-polling/status",(I,m)=>{try{let g=global.multiOrgWorkerService;if(!g)return m.json({success:!1,error:"Multi-organization worker service not available",data:[]});let y=g.getPollingStatus();return m.json({success:!0,data:y})}catch(g){return s.error("Failed to get smart polling status",{error:g instanceof Error?g.message:String(g)}),m.status(500).json({success:!1,error:"Failed to retrieve smart polling status",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/smart-polling/force",async(I,m)=>{try{let g=global.multiOrgWorkerService;return g?(await g.forcePollingAll(),m.json({success:!0,message:"Forced polling initiated for all organizations"})):m.status(404).json({success:!1,error:"Multi-organization worker service not available"})}catch(g){return s.error("Failed to force smart polling",{error:g instanceof Error?g.message:String(g)}),m.status(500).json({success:!1,error:"Failed to force smart polling",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/workspace/list",async(I,m)=>{try{let g=T.getAllWorkspaces();m.json({success:!0,data:g.map(y=>({id:y.workspace.workspaceId,name:y.workspace.name,description:y.workspace.name?`${y.workspace.name} workspace`:"Workspace",path:y.workspace.path,services:y.workspace.services?.map(k=>k.name)||[],technology:y.workspace.services?.[0]?.technology||"unknown",port:y.workspace.services?.[0]?.port,isActive:y.syncStatus==="synced",createdAt:y.discoveredAt,updatedAt:y.lastSyncedAt||y.discoveredAt}))})}catch(g){s.error("Failed to fetch workspaces:",g),m.status(500).json({success:!1,error:"Failed to fetch workspaces",details:g instanceof Error?g.message:String(g)})}}),e.delete("/api/workspace/:id",async(I,m)=>{try{let g=I.params.id;if(!g)return m.status(400).json({success:!1,error:"Workspace ID is required"});let y=T.getWorkspace(g);return y?(await T.removeWorkspace(g),s.info("Workspace removed via API",{workspaceId:g,name:y.workspace.name}),m.json({success:!0,message:`Workspace "${y.workspace.name}" removed successfully`,removedWorkspace:{id:g,name:y.workspace.name,path:y.workspace.path}})):m.status(404).json({success:!1,error:"Workspace not found"})}catch(g){return s.error("Failed to remove workspace:",g),m.status(500).json({success:!1,error:"Failed to remove workspace",details:g instanceof Error?g.message:String(g)})}}),e.patch("/api/workspace/:id/status",async(I,m)=>{try{let g=I.params.id,{enabled:y}=I.body;if(!g)return m.status(400).json({success:!1,error:"Workspace ID is required"});if(typeof y!="boolean")return m.status(400).json({success:!1,error:"enabled field must be a boolean"});let k=T.getWorkspace(g);return k?(y?await T.markWorkspaceSynced(g):await T.markWorkspaceSyncFailed(g,"Manually disabled"),s.info("Workspace status updated via API",{workspaceId:g,name:k.workspace.name,enabled:y}),m.json({success:!0,message:`Workspace "${k.workspace.name}" ${y?"enabled":"disabled"} successfully`,workspace:{id:g,name:k.workspace.name,enabled:y}})):m.status(404).json({success:!1,error:"Workspace not found"})}catch(g){return s.error("Failed to update workspace status:",g),m.status(500).json({success:!1,error:"Failed to update workspace status",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/websocket/activity",(I,m)=>{m.json({events:[],total:0})}),e.get("/api/usage/stats",(I,m)=>{let g=f.getUsageStats();m.json(g)}),e.get("/api/usage/history",(I,m)=>{let g=parseInt(I.query.limit)||50,y=f.getUsageHistory(g);m.json({history:y})}),e.get("/api/usage/rate-limit",(I,m)=>{let g=f.getCurrentRateLimit();m.json(g)});let t=null,a=3e4;e.get("/api/organizations",async(I,m)=>{try{if(t&&Date.now()-t.timestamp<a)return m.json(t.data);let g=await w.getAllOrganizations(),y=await w.isSetupCompleted(),k=global.multiOrgWorkerService,E=[];if(k)try{E=await k.getAllOrganizationStatuses()}catch(q){s.debug("Failed to get worker statuses from MultiOrganizationWorkerService",{error:q instanceof Error?q.message:String(q)})}let W={success:!0,data:{organizations:g.map(q=>{let C=E.find(F=>F.organizationId===q.id),P=null;return C&&(P={registered:C.registered,workerId:C.workerId||null,status:C.registered?"active":"not_registered",capabilities:[],lastHeartbeat:C.lastHeartbeat instanceof Date?C.lastHeartbeat.toISOString():C.lastHeartbeat||null,registeredAt:C.registeredAt instanceof Date?C.registeredAt.toISOString():C.registeredAt||null,metadata:null}),{...q,status:"unknown",lastConnected:void 0,healthy:!0,error:void 0,workspaces:q.metadata?.workspaces||[],workspaceCount:q.metadata?.workspaceCount||q.metadata?.workspaces?.length||0,projectCount:0,pendingWork:0,completedWork:0,workerRegistration:P}}),setupCompleted:y}};return t={data:W,timestamp:Date.now()},m.json(W)}catch(g){return s.error("Failed to fetch organizations:",g),m.status(500).json({success:!1,error:"Failed to fetch organizations",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/worker-registrations",async(I,m)=>{try{let g=global.multiOrgWorkerService;if(!g)return m.json({success:!0,data:{registrations:[],message:"Worker service not initialized"}});let y=await g.getAllOrganizationStatuses();return m.json({success:!0,data:{registrations:y}})}catch(g){return s.error("Failed to fetch worker registrations:",g),m.status(500).json({success:!1,error:"Failed to fetch worker registrations",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/organizations/worker-status",async(I,m)=>{try{let g=global.multiOrgWorkerService,y=[];if(g)try{y=await g.getAllOrganizationStatuses()}catch(E){s.debug("Failed to get worker statuses from MultiOrganizationWorkerService",{error:E instanceof Error?E.message:String(E)})}let k=y.map(E=>({organizationId:E.organizationId,workerRegistration:{registered:E.registered,workerId:E.workerId||null,status:E.registered?"active":"not_registered",capabilities:[],lastHeartbeat:E.lastHeartbeat instanceof Date?E.lastHeartbeat.toISOString():E.lastHeartbeat||null,registeredAt:E.registeredAt instanceof Date?E.registeredAt.toISOString():E.registeredAt||null,metadata:null}}));return m.json({success:!0,data:k,timestamp:new Date().toISOString()})}catch(g){return s.error("Failed to fetch worker status:",g),m.status(500).json({success:!1,error:"Failed to fetch worker status",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations",async(I,m)=>{try{let{name:g,apiUrl:y,apiKey:k}=I.body;if(!g||!y||!k)return m.status(400).json({success:!1,error:"Missing required fields: name, apiUrl, apiKey"});let E={id:`org-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,name:g,apiUrl:y,apiKey:k,enabled:!0,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await w.addOrganization(E),s.info("Organization created successfully",{id:E.id,name:E.name,apiUrl:y.substring(0,50)+"..."}),m.status(201).json({success:!0,message:"Organization created successfully",data:{id:E.id,name:E.name,apiUrl:E.apiUrl,enabled:E.enabled,createdAt:E.createdAt}})}catch(g){return s.error("Failed to create organization:",g),m.status(500).json({success:!1,error:"Failed to create organization",details:g instanceof Error?g.message:String(g)})}}),e.delete("/api/organizations/:id",async(I,m)=>{try{let g=I.params.id;if(!g)return m.status(400).json({success:!1,error:"Organization ID is required"});let y=await w.getOrganization(g);return y?(await w.removeOrganization(g),s.info("Organization deleted successfully",{organizationId:g,name:y.name}),m.json({success:!0,message:`Organization "${y.name}" deleted successfully`,data:{id:g,name:y.name}})):m.status(404).json({success:!1,error:"Organization not found"})}catch(g){return s.error("Failed to delete organization:",g),m.status(500).json({success:!1,error:"Failed to delete organization",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/organizations/health",async(I,m)=>{try{let y=(await w.getAllOrganizationStatuses()).map(k=>({id:k.id,healthy:k.healthy,status:k.healthy?"connected":k.error?"error":"disconnected",lastConnected:k.healthy?new Date().toISOString():void 0,error:k.error,responseTime:k.healthy?100:void 0}));return m.json({success:!0,data:y})}catch(g){return s.error("Failed to get organization health:",g),m.status(500).json({success:!1,error:"Failed to get organization health",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations/:id/test-connection",async(I,m)=>{try{let g=I.params.id;if(!g)return m.status(400).json({success:!1,error:"Organization ID is required"});let y=await w.getOrganization(g);if(!y)return m.status(404).json({success:!1,error:"Organization not found"});let k=await w.testConnection(g);return s.info("Organization connection test completed",{organizationId:g,name:y.name,success:k.success,responseTime:k.responseTime}),m.json({success:!0,message:k.success?"Connection test successful":"Connection test failed",data:k})}catch(g){return s.error("Failed to test organization connection:",g),m.status(500).json({success:!1,error:"Failed to test organization connection",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/organizations/:id/workspaces",async(I,m)=>{try{let g=I.params.id;if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let k=await w.getWorkspacesForOrganization(g);return m.json({success:!0,data:k,count:k.length})}catch(g){return s.error("Failed to get workspaces:",g),m.status(500).json({success:!1,error:"Failed to get workspaces",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations/:id/workspaces",async(I,m)=>{try{let g=I.params.id,{name:y,id:k,path:E,description:D,services:W}=I.body;if(!y||!k||!E)return m.status(400).json({success:!1,error:"Name, id, and path are required"});if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let C={name:y,id:k,path:E,description:D,isActive:!0};W&&Array.isArray(W)&&(C.services=W.map(F=>({id:`srv_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,name:F.name,type:F.type,technology:F.metadata?.technology||F.technology,port:F.port,description:F.description,isActive:!0,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()})));let P=await w.addWorkspaceToOrganization(g,C);return s.info("Workspace added to organization",{organizationId:g,workspaceId:k,name:y,servicesCount:C.services?.length||0}),m.json({success:!0,message:"Workspace added successfully",data:P})}catch(g){return s.error("Failed to add workspace:",g),m.status(500).json({success:!1,error:"Failed to add workspace",details:g instanceof Error?g.message:String(g)})}}),e.patch("/api/organizations/:orgId/workspaces/:workspaceId",async(I,m)=>{console.log("\u{1F504} PATCH /api/organizations/:orgId/workspaces/:workspaceId called"),console.log("\u{1F4CB} Request params:",{orgId:I.params.orgId,workspaceId:I.params.workspaceId}),console.log("\u{1F4CB} Request body (updates):",I.body);try{let{orgId:g,workspaceId:y}=I.params,k=I.body;if(console.log("\u{1F50D} Looking up organization:",g),!await w.getOrganization(g))return console.log("\u274C Organization not found:",g),m.status(404).json({success:!1,error:"Organization not found"});console.log("\u2705 Organization found, updating workspace:",y);let D=await w.updateWorkspaceInOrganization(g,y,k);return s.info("Workspace updated",{organizationId:g,workspaceId:y,updates:Object.keys(k)}),m.json({success:!0,message:"Workspace updated successfully",data:D})}catch(g){return s.error("Failed to update workspace:",g),m.status(500).json({success:!1,error:"Failed to update workspace",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations/:orgId/workspaces/:workspaceId/apply-improvements",async(I,m)=>{console.log("\u{1F527} POST /api/organizations/:orgId/workspaces/:workspaceId/apply-improvements called"),console.log("\u{1F4CB} Request params:",{orgId:I.params.orgId,workspaceId:I.params.workspaceId}),console.log("\u{1F4CB} Request body:",I.body);try{let{orgId:g,workspaceId:y}=I.params,{improvements:k}=I.body;if(!k||!Array.isArray(k))return m.status(400).json({success:!1,error:"Invalid improvements data"});if(console.log("\u{1F50D} Looking up organization:",g),!await w.getOrganization(g))return console.log("\u274C Organization not found:",g),m.status(404).json({success:!1,error:"Organization not found"});console.log("\u2705 Organization found, applying improvements to workspace:",y),console.log("\u{1F527} Improvements to apply:",k.length);let D=await w.applyWorkspaceImprovements(g,y,k);return s.info("Workspace improvements applied",{organizationId:g,workspaceId:y,improvementsCount:k.length,success:D.success}),m.json({success:!0,message:"Workspace improvements applied successfully",data:D})}catch(g){return console.error("\u274C Failed to apply workspace improvements:",g),s.error("Failed to apply workspace improvements:",g),m.status(500).json({success:!1,error:"Failed to apply workspace improvements",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations/:id/workspaces/sync",async(I,m)=>{try{let g=I.params.id;if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let k=await w.syncWorkspacesFromTaskShepherd(g);return s.info("Workspaces synced from Task Shepherd",{organizationId:g,workspaceCount:k.workspaceCount,success:k.success}),m.json({success:!0,message:`Synced ${k.workspaceCount} workspace(s) from Task Shepherd`,workspaceCount:k.workspaceCount,data:k.workspaces})}catch(g){return s.error("Failed to sync workspaces:",g),m.status(500).json({success:!1,error:"Failed to sync workspaces",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations/:orgId/workspaces/discover",async(I,m)=>{try{let{orgId:g}=I.params,{path:y}=I.body;if(!y)return m.status(400).json({success:!1,error:"Path is required for workspace discovery"});if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let D=await new ct().analyzePathAndSuggestWorkspace(y);return s.info("Workspace discovery completed",{organizationId:g,path:y,confidence:D.overallConfidence,servicesFound:D.services.length}),m.json({success:!0,data:D})}catch(g){return s.error("Failed to discover workspace:",g),m.status(500).json({success:!1,error:"Failed to discover workspace",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations/:orgId/workspaces/:workspaceId/analyze",async(I,m)=>{try{let{orgId:g,workspaceId:y}=I.params;if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let D=(await w.getWorkspacesForOrganization(g)).find(C=>C.workspaceId===y||C.id===y);if(!D)return m.status(404).json({success:!1,error:"Workspace not found"});let q=await new ct().analyzeExistingWorkspace({name:D.name,path:D.path,services:(D.services||[]).map(C=>({name:C.name,type:C.type,technology:C.technology,port:C.port}))});return s.info("Existing workspace analysis completed",{organizationId:g,workspaceId:y,improvements:q.improvements.length,newServices:q.discoveredServices.length}),m.json({success:!0,data:q})}catch(g){return s.error("Failed to analyze existing workspace:",g),m.status(500).json({success:!1,error:"Failed to analyze existing workspace",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/organizations/:orgId/workspaces/:workspaceId/services",async(I,m)=>{try{let{orgId:g,workspaceId:y}=I.params;if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let E=await w.getServicesForWorkspace(g,y);return m.json({success:!0,data:E})}catch(g){return s.error("Failed to get services:",g),m.status(500).json({success:!1,error:"Failed to get services",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/organizations/:orgId/workspaces/:workspaceId/services",async(I,m)=>{try{let{orgId:g,workspaceId:y}=I.params,k=I.body;if(!k.name||!k.type)return m.status(400).json({success:!1,error:"Service name and type are required"});if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let D=await w.addServiceToWorkspace(g,y,k);return s.info("Service added to workspace",{organizationId:g,workspaceId:y,serviceName:k.name}),m.json({success:!0,message:"Service added successfully",data:D})}catch(g){return s.error("Failed to add service:",g),m.status(500).json({success:!1,error:"Failed to add service",details:g instanceof Error?g.message:String(g)})}}),e.patch("/api/organizations/:orgId/workspaces/:workspaceId/services/:serviceId",async(I,m)=>{try{let{orgId:g,workspaceId:y,serviceId:k}=I.params,E=I.body;if(!await w.getOrganization(g))return m.status(404).json({success:!1,error:"Organization not found"});let W=await w.updateServiceInWorkspace(g,y,k,E);return s.info("Service updated",{organizationId:g,workspaceId:y,serviceId:k,updates:Object.keys(E)}),m.json({success:!0,message:"Service updated successfully",data:W})}catch(g){return s.error("Failed to update service:",g),m.status(500).json({success:!1,error:"Failed to update service",details:g instanceof Error?g.message:String(g)})}}),e.delete("/api/organizations/:orgId/workspaces/:workspaceId/services/:serviceId",async(I,m)=>{try{let{orgId:g,workspaceId:y,serviceId:k}=I.params;return await w.getOrganization(g)?(await w.removeServiceFromWorkspace(g,y,k),s.info("Service removed from workspace",{organizationId:g,workspaceId:y,serviceId:k}),m.json({success:!0,message:"Service removed successfully"})):m.status(404).json({success:!1,error:"Organization not found"})}catch(g){return s.error("Failed to remove service:",g),m.status(500).json({success:!1,error:"Failed to remove service",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/workspace/stats/:projectId?",async(I,m)=>{try{let g=I.params.projectId,y=T.getAllWorkspaces(),k=y;g&&(k=y.filter(D=>D.workspace.workspaceId===g));let E={total:k.length,active:k.filter(D=>D.syncStatus==="synced").length,inactive:k.filter(D=>D.syncStatus!=="synced").length,technologies:{}};k.forEach(D=>{let W=D.workspace.services?.[0]?.technology||"unknown";E.technologies[W]=(E.technologies[W]||0)+1}),m.json(E)}catch(g){s.error("Failed to get workspace stats:",g),m.status(500).json({error:"Failed to get workspace stats",details:g instanceof Error?g.message:String(g)})}}),e.get("/api/worker-health",async(I,m)=>{try{let g=global.multiOrgWorkerService;if(!g)return m.json({success:!0,data:{totalOrganizations:0,registeredOrganizations:0,healthyRegistrations:0,unhealthyRegistrations:0,registrationDetails:[],message:"Worker service not initialized"}});let y=await g.getRegistrationHealthStatus();return m.json({success:!0,data:y})}catch(g){return s.error("Failed to fetch worker health status:",g),m.status(500).json({success:!1,error:"Failed to fetch worker health status",details:g instanceof Error?g.message:String(g)})}}),e.post("/api/test/add-completed-work",(I,m)=>{try{let g={id:`test-${Date.now()}`,type:"project_review",status:Math.random()>.2?"completed":"failed",priority:Math.floor(Math.random()*5)+1,projectId:"test-project-1",projectName:"Test Project",title:`Test work item ${Date.now()}`,description:"A test work item for development",assignedTo:"test-agent",estimatedDuration:3e4,actualDuration:Math.floor(Math.random()*45e3)+15e3,createdAt:new Date(Date.now()-Math.random()*864e5).toISOString(),startedAt:new Date(Date.now()-Math.random()*432e5).toISOString(),completedAt:new Date().toISOString(),metadata:{test:!0}};b.addCompletedItem(g),m.json({success:!0,message:"Test work item added",item:g})}catch(g){m.status(500).json({error:"Failed to add test work item",details:g instanceof Error?g.message:String(g)})}});let i=e.listen(r.httpPort);if(l.register("http-server",{close:async()=>{await new Promise(I=>i.close(()=>I()))}}),s.info("\u2713 HTTP server started",{port:r.httpPort}),process.env.TASK_SHEPHERD_ENVIRONMENT==="development"||!1)s.info("Web UI server disabled in development mode (only API server running)");else{let I=(0,lt.default)();I.use("/api",(k,E)=>{let D=`http://localhost:${r.httpPort}/api${k.url}`,W={};for(let[C,P]of Object.entries(k.headers))typeof P=="string"?W[C]=P:Array.isArray(P)&&(W[C]=P.join(", "));W.host=`localhost:${r.httpPort}`;let q={method:k.method,headers:W};if(k.method==="POST"||k.method==="PUT"||k.method==="PATCH"){let C="";k.on("data",P=>C+=P),k.on("end",()=>{fetch(D,{...q,body:C}).then(async P=>{E.status(P.status),P.headers.forEach((F,G)=>E.setHeader(G,F)),E.send(await P.text())}).catch(P=>{console.error("Proxy error:",P),E.status(502).json({error:"Proxy error"})})})}else fetch(D,q).then(async C=>{E.status(C.status),C.headers.forEach((P,F)=>E.setHeader(F,P)),E.send(await C.text())}).catch(C=>{console.error("Proxy error:",C),E.status(502).json({error:"Proxy error"})})});let m=Jt.default.join(__dirname,"../web/dist");I.use(lt.default.static(m)),I.get("*",(k,E)=>{E.sendFile(Jt.default.join(m,"index.html"))});let g=r.webPort,y=I.listen(g);l.register("web-server",{close:async()=>{await new Promise(k=>y.close(()=>k()))}}),s.info("\u2713 Web UI server started",{port:g})}let o=new zt(r.tcpPort);await o.start(),l.register("tcp-server",{close:async()=>await o.stop()}),s.info("\u2713 TCP IPC server started",{port:r.tcpPort}),s.info("\u2713 MCP message handlers configured"),s.info("Stage 4: Updating Claude settings...");let c=Jt.default.resolve(process.cwd(),"../..");await new Ht(c).ensureMCPToolsAllowed(),s.info("\u2713 Claude settings updated with MCP tools"),s.info("Stage 5: Initializing core services..."),s.info("\u2713 Work queue will be managed by SmartPollingService");let h=(await new Z().initializeIdentity({strategy:"hybrid"})).agentId;yi=h;let f=new ze,b=rt(),w=new Vt;if(await w.initialize(),l.register("organization-manager",{close:async()=>{await w.destroy()}}),s.info("\u2713 Organization manager initialized"),await w.hasOrganizations()){let I=await w.getDefaultOrganization();if(I){let{initializeGraphQLHttpClient:m}=await Promise.resolve().then(()=>(Ue(),ga));m({baseUrl:I.apiUrl,apiKey:I.apiKey}),s.info("\u2713 Global GraphQL HTTP client initialized with default organization",{apiUrl:I.apiUrl})}}let T=he();await T.initialize();let $=Se();l.register("workspace-sync-service",{close:async()=>{$.stopPeriodicSync(),$.setConnectionStatus(!1)}}),s.info("\u2713 Core services initialized",{workerId:h,capabilities:r.capabilities}),s.info("Stage 5: Checking backend compatibility..."),It().logVersionInfo();let X=await w.hasOrganizations();X?s.info("Organizations configured - compatibility will be checked per organization during registration"):(s.info("No organizations configured - skipping compatibility check"),s.info("\u2713 Agent will run in standalone mode without backend connectivity")),s.info("Stage 7: Initializing agent service...");let ue=new Lt(r,l,o);pe=ue,l.register("agent-service",ue),s.info("\u2713 Agent service initialized");let dt=new Ve(ue.getTcpService()).getSupportedCapabilities();s.info("\u{1F3AF} Determined capabilities from implemented handlers",{dynamicCapabilities:dt,configCapabilities:r.capabilities,usingDynamic:dt.length>0});let Yr=dt.length>0?dt:r.capabilities;if(X){s.info("Stage 7: Organizations configured - registering with all Task Shepherd backends...");let I=new Qt(w,new Z,f,{capabilities:Yr,maxConcurrentTasks:5,scope:"USER",enableHeartbeat:!0,heartbeatInterval:3e4},ue.getHttpClient(),ue.getTcpService());await I.start(),l.register("multi-org-worker",{close:async()=>{await I.stop()}}),s.info("\u2705 Multi-organization worker service started - registered with all organizations"),global.multiOrgWorkerService=I,$.setConnectionStatus(!0,!1),await $.forceSyncAllWorkspaces(),$.startPeriodicSync(),s.info("\u2713 Workspace sync service started - all workspaces force synced")}else s.info("\u26A0\uFE0F No organizations configured - running in offline mode"),s.info(" Add organizations via the web UI at http://localhost:"+r.webPort),$.setConnectionStatus(!1,!1),s.info("\u2713 Agent running in offline mode - web UI available but no backend integration");s.info("Stage 8: Agent ready for work"),s.info("\u{1F389} Task Shepherd AI Agent fully operational!",{workerId:r.workerId,capabilities:Yr,httpPort:r.httpPort,tcpPort:r.tcpPort,websocketEnabled:r.websocketEnabled,resourceCount:l.getResourceCount(),environment:r.environment}),fn(l)}catch(r){s.error("\u274C Agent startup failed:",{error:r instanceof Error?r.message:String(r),stack:r instanceof Error?r.stack:void 0});try{await l.closeAll()}catch(e){s.error("Error during startup cleanup:",e)}process.exit(1)}}function fn(l){let r=async e=>{s.info(`
1041
+ \u{1F6D1} Shutdown initiated (${e})...`);let t=setTimeout(()=>{s.error("\u26A0\uFE0F Shutdown timeout exceeded - forcing exit"),process.exit(1)},15e3);try{await l.closeAll(),clearTimeout(t),s.info("\u2705 Shutdown completed successfully"),process.exit(0)}catch(a){s.error("\u274C Error during shutdown:",{error:a instanceof Error?a.message:String(a)}),clearTimeout(t),process.exit(1)}};process.on("SIGTERM",()=>r("SIGTERM")),process.on("SIGINT",()=>r("SIGINT")),process.on("uncaughtException",e=>{s.error("\u{1F4A5} Uncaught exception:",{error:e.message,stack:e.stack}),r("UNCAUGHT_EXCEPTION")}),process.on("unhandledRejection",(e,t)=>{s.error("\u{1F4A5} Unhandled promise rejection:",{reason:e instanceof Error?e.message:String(e),stack:e instanceof Error?e.stack:void 0,promise:t}),r("UNHANDLED_REJECTION")})}var hi,lt,Jt,pe,yi,Sn,ki=M(()=>{"use strict";hi=A(require("dotenv")),lt=A(require("express")),Jt=A(require("path"));fa();j();Ze();Za();wr();jr();ei();ri();ai();br();Ce();nt();ci();gi();mi();Nr();hi.default.config();pe=null,yi=null,Sn=()=>pe;require.main===module&&Si().catch(l=>{console.error("Failed to start Task Shepherd AI Agent:",l),process.exit(1)})});var Vr,vi=M(()=>{"use strict";Vr="1.0.0"});var Yt,Ii=M(()=>{"use strict";vi();Yt=class{validate(r){let e=[],t=[];return this.validateRequiredStructure(r,e),this.validateWorkspaceMetadata(r.workspace,e,t),this.validateServicesConfig(r.services,e,t),this.validateAIConfig(r.ai,e,t),this.validatePathsConfig(r.paths,e,t),this.validateDevelopmentConfig(r.development,e,t),this.validateSecurityConfig(r.security,e,t),r.git&&this.validateGitConfig(r.git,e,t),r.integrations&&this.validateIntegrationsConfig(r.integrations,e,t),{valid:e.length===0,errors:e,warnings:t}}validateRequiredStructure(r,e){let t=["workspace","services","ai","paths","development","security"];for(let a of t)r[a]||e.push({path:a,message:`Required field '${a}' is missing`,code:"MISSING_REQUIRED_FIELD",severity:"error"})}validateWorkspaceMetadata(r,e,t){r&&(r.id||e.push({path:"workspace.id",message:"Workspace ID is required",code:"MISSING_WORKSPACE_ID",severity:"error"}),r.name||e.push({path:"workspace.name",message:"Workspace name is required",code:"MISSING_WORKSPACE_NAME",severity:"error"}),r.version?r.version!==Vr&&t.push({path:"workspace.version",message:`Workspace version ${r.version} may not be compatible with current version ${Vr}`,code:"VERSION_MISMATCH",severity:"warning"}):e.push({path:"workspace.version",message:"Workspace version is required",code:"MISSING_VERSION",severity:"error"}),r.id&&!/^[a-zA-Z0-9_-]+$/.test(r.id)&&e.push({path:"workspace.id",message:"Workspace ID must contain only alphanumeric characters, hyphens, and underscores",code:"INVALID_WORKSPACE_ID",severity:"error"}),r.name&&(r.name.length<1||r.name.length>100)&&e.push({path:"workspace.name",message:"Workspace name must be between 1 and 100 characters",code:"INVALID_WORKSPACE_NAME_LENGTH",severity:"error"}))}validateServicesConfig(r,e,t){if(!r)return;let a=Object.keys(r);for(let i of a){let n=r[i];n&&typeof n=="object"&&this.validateServiceEndpoint(n,`services.${i}`,e,t)}a.length===0&&t.push({path:"services",message:"No services are configured",code:"NO_SERVICES_CONFIGURED",severity:"warning"})}validateServiceEndpoint(r,e,t,a){r.name||t.push({path:`${e}.name`,message:"Service name is required",code:"MISSING_SERVICE_NAME",severity:"error"});let i=e.split(".").pop()||"",o=["mcp","shared","cli","tasqhubmcp"].includes(i)||r.port===0;!r.url&&!o&&t.push({path:`${e}.url`,message:"Service URL is required",code:"MISSING_SERVICE_URL",severity:"error"});let d=["mcp","shared","cli","tasqhubmcp"].includes(i)||r.port===0;!r.port&&!d&&t.push({path:`${e}.port`,message:"Service port is required",code:"MISSING_SERVICE_PORT",severity:"error"}),r.protocol||t.push({path:`${e}.protocol`,message:"Service protocol is required",code:"MISSING_SERVICE_PROTOCOL",severity:"error"}),r.port&&(typeof r.port!="number"||r.port<1||r.port>65535)&&t.push({path:`${e}.port`,message:"Service port must be a number between 1 and 65535",code:"INVALID_SERVICE_PORT",severity:"error"});let p=["http","https","ws","wss","tcp","udp","postgresql","redis","mongodb"];r.protocol&&!p.includes(r.protocol)&&t.push({path:`${e}.protocol`,message:`Service protocol must be one of: ${p.join(", ")}`,code:"INVALID_SERVICE_PROTOCOL",severity:"error"}),r.environment&&!["development","staging","production"].includes(r.environment)&&t.push({path:`${e}.environment`,message:"Service environment must be one of: development, staging, production",code:"INVALID_SERVICE_ENVIRONMENT",severity:"error"})}validateAIConfig(r,e,t){r&&(r.provider?["claude","openai","custom"].includes(r.provider)||e.push({path:"ai.provider",message:"AI provider must be one of: claude, openai, custom",code:"INVALID_AI_PROVIDER",severity:"error"}):e.push({path:"ai.provider",message:"AI provider is required",code:"MISSING_AI_PROVIDER",severity:"error"}),r.models?this.validateAIModels(r.models,r.provider,e,t):e.push({path:"ai.models",message:"AI models configuration is required",code:"MISSING_AI_MODELS",severity:"error"}),r.capabilities?this.validateAICapabilities(r.capabilities,e,t):e.push({path:"ai.capabilities",message:"AI capabilities configuration is required",code:"MISSING_AI_CAPABILITIES",severity:"error"}))}validateAIModels(r,e,t,a){e==="claude"&&!r.claude&&t.push({path:"ai.models.claude",message:"Claude model configuration is required when provider is claude",code:"MISSING_CLAUDE_CONFIG",severity:"error"}),e==="openai"&&!r.openai&&t.push({path:"ai.models.openai",message:"OpenAI model configuration is required when provider is openai",code:"MISSING_OPENAI_CONFIG",severity:"error"}),r.claude&&(r.claude.apiKey||t.push({path:"ai.models.claude.apiKey",message:"Claude API key is required",code:"MISSING_CLAUDE_API_KEY",severity:"error"}),r.claude.defaultModel||t.push({path:"ai.models.claude.defaultModel",message:"Claude default model is required",code:"MISSING_CLAUDE_DEFAULT_MODEL",severity:"error"})),r.openai&&(r.openai.apiKey||t.push({path:"ai.models.openai.apiKey",message:"OpenAI API key is required",code:"MISSING_OPENAI_API_KEY",severity:"error"}),r.openai.defaultModel||t.push({path:"ai.models.openai.defaultModel",message:"OpenAI default model is required",code:"MISSING_OPENAI_DEFAULT_MODEL",severity:"error"}))}validateAICapabilities(r,e,t){r.maxConcurrentOperations===void 0?e.push({path:"ai.capabilities.maxConcurrentOperations",message:"Maximum concurrent operations is required",code:"MISSING_MAX_CONCURRENT_OPERATIONS",severity:"error"}):(typeof r.maxConcurrentOperations!="number"||r.maxConcurrentOperations<1||r.maxConcurrentOperations>100)&&e.push({path:"ai.capabilities.maxConcurrentOperations",message:"Maximum concurrent operations must be a number between 1 and 100",code:"INVALID_MAX_CONCURRENT_OPERATIONS",severity:"error"}),r.supportedAnalysisTypes?Array.isArray(r.supportedAnalysisTypes)||e.push({path:"ai.capabilities.supportedAnalysisTypes",message:"Supported analysis types must be an array",code:"INVALID_SUPPORTED_ANALYSIS_TYPES",severity:"error"}):e.push({path:"ai.capabilities.supportedAnalysisTypes",message:"Supported analysis types are required",code:"MISSING_SUPPORTED_ANALYSIS_TYPES",severity:"error"}),r.isolationLevel?["strict","moderate","relaxed"].includes(r.isolationLevel)||e.push({path:"ai.capabilities.isolationLevel",message:"Isolation level must be one of: strict, moderate, relaxed",code:"INVALID_ISOLATION_LEVEL",severity:"error"}):t.push({path:"ai.capabilities.isolationLevel",message:"Isolation level not specified, defaulting to moderate",code:"MISSING_ISOLATION_LEVEL",severity:"warning"})}validatePathsConfig(r,e,t){if(!r)return;r.root||e.push({path:"paths.root",message:"Root path is required",code:"MISSING_ROOT_PATH",severity:"error"});let a=["src","tests","docs","config","build","temp","logs","excluded"];for(let i of a)r[i]&&!Array.isArray(r[i])&&e.push({path:`paths.${i}`,message:`${i} must be an array of paths`,code:"INVALID_PATH_ARRAY",severity:"error"});(!r.src||r.src.length===0)&&t.push({path:"paths.src",message:"No source paths specified",code:"NO_SOURCE_PATHS",severity:"warning"})}validateDevelopmentConfig(r,e,t){r&&(r.packageManager?["npm","yarn","pnpm"].includes(r.packageManager)||e.push({path:"development.packageManager",message:"Package manager must be one of: npm, yarn, pnpm",code:"INVALID_PACKAGE_MANAGER",severity:"error"}):e.push({path:"development.packageManager",message:"Package manager is required",code:"MISSING_PACKAGE_MANAGER",severity:"error"}),r.nodeVersion&&!/^\d+\.\d+\.\d+$/.test(r.nodeVersion)&&t.push({path:"development.nodeVersion",message:"Node.js version should be in format x.y.z",code:"INVALID_NODE_VERSION_FORMAT",severity:"warning"}))}validateSecurityConfig(r,e,t){r&&(r.filePermissions?this.validateFilePermissions(r.filePermissions,e,t):e.push({path:"security.filePermissions",message:"File permissions configuration is required",code:"MISSING_FILE_PERMISSIONS",severity:"error"}),r.networkPermissions?this.validateNetworkPermissions(r.networkPermissions,e,t):e.push({path:"security.networkPermissions",message:"Network permissions configuration is required",code:"MISSING_NETWORK_PERMISSIONS",severity:"error"}))}validateFilePermissions(r,e,t){let a=["read","write","execute"];for(let i of a)typeof r[i]!="boolean"&&e.push({path:`security.filePermissions.${i}`,message:`${i} permission must be a boolean`,code:"INVALID_FILE_PERMISSION",severity:"error"});r.restricted&&!Array.isArray(r.restricted)&&e.push({path:"security.filePermissions.restricted",message:"Restricted paths must be an array",code:"INVALID_RESTRICTED_PATHS",severity:"error"}),r.write&&r.execute&&t.push({path:"security.filePermissions",message:"Both write and execute permissions are enabled, this may pose security risks",code:"SECURITY_RISK_WRITE_EXECUTE",severity:"warning"})}validateNetworkPermissions(r,e,t){let a=["http","https"];for(let n of a)typeof r[n]!="boolean"&&e.push({path:`security.networkPermissions.${n}`,message:`${n} permission must be a boolean`,code:"INVALID_NETWORK_PERMISSION",severity:"error"});let i=["allowedDomains","blockedDomains"];for(let n of i)r[n]&&!Array.isArray(r[n])&&e.push({path:`security.networkPermissions.${n}`,message:`${n} must be an array`,code:"INVALID_DOMAIN_ARRAY",severity:"error"});r.http&&!r.https&&t.push({path:"security.networkPermissions",message:"HTTP is enabled but HTTPS is not, consider enabling HTTPS for better security",code:"SECURITY_RISK_HTTP_ONLY",severity:"warning"})}validateGitConfig(r,e,t){r.repositoryUrl&&!this.isValidUrl(r.repositoryUrl)&&e.push({path:"git.repositoryUrl",message:"Repository URL must be a valid URL",code:"INVALID_REPOSITORY_URL",severity:"error"}),r.defaultBranch&&!/^[a-zA-Z0-9/_-]+$/.test(r.defaultBranch)&&e.push({path:"git.defaultBranch",message:"Default branch name contains invalid characters",code:"INVALID_BRANCH_NAME",severity:"error"}),r.remoteName&&!/^[a-zA-Z0-9_-]+$/.test(r.remoteName)&&e.push({path:"git.remoteName",message:"Remote name contains invalid characters",code:"INVALID_REMOTE_NAME",severity:"error"})}validateIntegrationsConfig(r,e,t){r.taskShepherd&&(r.taskShepherd.apiUrl?this.isValidUrl(r.taskShepherd.apiUrl)||e.push({path:"integrations.taskShepherd.apiUrl",message:"Task Shepherd API URL must be a valid URL",code:"INVALID_TASK_SHEPHERD_API_URL",severity:"error"}):e.push({path:"integrations.taskShepherd.apiUrl",message:"Task Shepherd API URL is required",code:"MISSING_TASK_SHEPHERD_API_URL",severity:"error"}),r.taskShepherd.apiKey||e.push({path:"integrations.taskShepherd.apiKey",message:"Task Shepherd API key is required",code:"MISSING_TASK_SHEPHERD_API_KEY",severity:"error"}))}isValidUrl(r){try{return new URL(r),!0}catch{return!1}}}});var _e,Je,Xt,wi=M(()=>{"use strict";_e=require("fs"),Je=A(require("path"));Ii();j();Ce();Xt=class{constructor(){this.validator=new Yt}async discoverWorkspaces(r){try{if(s.info("Starting workspace discovery",{rootPath:r}),!(await _e.promises.stat(r)).isDirectory())throw new Error(`Path ${r} is not a directory`);let t=await this.detectTaskShepherdMonorepo(r),a;return t?a=await this.discoverTaskShepherdWorkspaces(r):a=await this.discoverGenericWorkspaces(r),await this.saveDiscoveredWorkspaces(a),a}catch(e){return s.error("Workspace discovery failed",{rootPath:r,error:e instanceof Error?e.message:e}),[{workspaceId:"error",name:"Discovery Error",path:r,pattern:"monorepo",services:[],config:{},errors:[e instanceof Error?e.message:"Unknown error occurred"]}]}}async detectTaskShepherdMonorepo(r){try{let e=Je.join(r,"package.json"),t=await _e.promises.readFile(e,"utf-8"),a=JSON.parse(t),i=a.name==="task-shepherd"||a.workspaces&&Array.isArray(a.workspaces)&&a.workspaces.includes("packages/*"),n=["packages/frontend","packages/backend","packages/agent"],o=await Promise.all(n.map(async c=>{try{let d=Je.join(r,c);return(await _e.promises.stat(d)).isDirectory()}catch{return!1}}));return i&&o.some(c=>c)}catch{return!1}}async discoverTaskShepherdWorkspaces(r){let e=[],t=[{path:"packages/frontend",name:"Frontend App",technology:"react",port:5173},{path:"packages/backend",name:"GraphQL Backend",technology:"nodejs",port:4002},{path:"packages/agent",name:"AI Agent Service",technology:"nodejs",port:8547},{path:"packages/mcp",name:"MCP Server",technology:"nodejs",port:3001},{path:"packages/shared",name:"Shared Types",technology:"other"}];for(let a of t){let i=Je.join(r,a.path);try{if((await _e.promises.stat(i)).isDirectory()){let o=Je.join(i,"package.json");try{await _e.promises.access(o),e.push({id:a.path.replace("packages/",""),name:a.name,path:i,relativePath:a.path,technology:a.technology,port:a.port})}catch{s.warn("Package directory found but no package.json",{path:i})}}}catch{s.debug("Package not found",{path:i})}}return[{workspaceId:"task-shepherd-monorepo",name:"Task Shepherd Monorepo",path:r,pattern:"monorepo",services:e,config:{},errors:[]}]}async discoverGenericWorkspaces(r){let e=[];try{let t=Je.join(r,"package.json");try{let a=await _e.promises.readFile(t,"utf-8"),i=JSON.parse(a);if(i.name){let n=[],o={...i.dependencies,...i.devDependencies};(o.react||o["@types/react"])&&n.push({id:"frontend",name:"React Frontend",path:r,technology:"react"}),(o.express||o.fastify||o.koa)&&n.push({id:"backend",name:"Node.js Backend",path:r,technology:"nodejs"}),o.next&&n.push({id:"nextjs",name:"Next.js App",path:r,technology:"other"}),(n.length>0||i.scripts)&&e.push({workspaceId:`generic-${i.name.replace(/[^a-zA-Z0-9]/g,"-")}`,name:i.name,path:r,pattern:"monorepo",services:n,config:{},errors:[]})}}catch(a){s.debug("No package.json found or invalid",{rootPath:r,error:a instanceof Error?a.message:a})}return e}catch(t){return s.warn("Generic workspace discovery failed",{rootPath:r,error:t instanceof Error?t.message:t}),[]}}async discoverWorkspacesFromPaths(r){let e=[];for(let t of r)try{s.info("Scanning directory for workspaces",{searchPath:t});let i=(await this.discoverWorkspaces(t)).filter(n=>n.errors.length===0);e.push(...i),s.info("Directory scan completed",{searchPath:t,foundWorkspaces:i.length,totalWorkspaces:e.length})}catch(a){s.warn("Failed to scan directory for workspaces",{searchPath:t,error:a instanceof Error?a.message:String(a)})}return e}async generateWorkspaceConfig(r){return s.info("Generating workspace configuration",{workspaceId:r.workspaceId}),{workspace:{id:r.workspaceId,name:r.name,pattern:r.pattern,rootPath:r.path},services:r.services.reduce((e,t)=>(e[t.id]={name:t.name,path:t.path,technology:t.technology,port:t.port,enabled:!0},e),{}),ai:{models:{claude:{provider:"anthropic",model:"claude-3-sonnet",enabled:!0}},defaultModel:"claude",capabilities:{codeGeneration:!0,codeReview:!0,projectAnalysis:!0}},development:{hotReload:!0,debugMode:!0,testRunner:"jest"},integrations:{github:{enabled:!1},slack:{enabled:!1}}}}async saveDiscoveredWorkspaces(r){let e=he();await e.initialize();for(let t of r){if(t.errors.length>0){s.warn("Skipping workspace due to errors",{workspaceId:t.workspaceId,errors:t.errors});continue}try{s.info("Saving workspace to local registry",{workspaceId:t.workspaceId,servicesCount:t.services.length,note:"Will be synced with backend when connected"}),await e.addWorkspace(t),s.info("Successfully saved workspace to local registry",{workspaceId:t.workspaceId,capabilities:t.services.map(a=>`${a.name} (${a.technology})`).join(", ")})}catch(a){s.error("Failed to save workspace to local registry",{workspaceId:t.workspaceId,error:a instanceof Error?a.message:String(a)})}}}async validateWorkspaceConfig(r){try{let e=this.validator.validate(r);return{isValid:e.valid,errors:e.errors?.map(t=>t.message)||[]}}catch(e){return{isValid:!1,errors:[e instanceof Error?e.message:"Validation failed"]}}}}});var we,J,Zt,bi=M(()=>{"use strict";we=A(require("fs")),J=A(require("path"));j();Zt=class{async detect(r){try{if(s.info("Starting .NET workspace detection",{workspacePath:r}),!await this.hasDotNetIndicators(r))return null;let t=await this.detectSolutions(r),a=await this.detectStandaloneProjects(r,t),i=this.identifySharedProjects(t),n=we.existsSync(J.join(r,"global.json")),o=this.findNuGetConfig(r),c=await this.detectDockerFiles(r),d;return t.length>1?d="dotnet-multi-solution":t.length===1?d="dotnet-single-solution":d="dotnet-project-only",{pattern:d,solutions:t,standaloneProjects:a,sharedProjects:i,globalJsonExists:n,nugetConfig:o,dockerFiles:c}}catch(e){return s.error("Failed to detect .NET workspace",{error:e,workspacePath:r}),null}}async hasDotNetIndicators(r){let e=["**/*.sln","**/*.csproj","**/*.fsproj","**/*.vbproj","global.json","nuget.config","Directory.Build.props","Directory.Build.targets"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r})).length>0)return!0}return!1}async detectSolutions(r){let{glob:e}=await import("glob"),t=await e("**/*.sln",{cwd:r}),a=[];for(let i of t)try{let n=J.join(r,i),o=we.readFileSync(n,"utf8"),c=await this.parseSolutionProjects(n,o),d=this.parseSolutionConfigurations(o);a.push({name:J.basename(i,".sln"),file:i,path:J.dirname(n),projects:c,configurations:d})}catch(n){s.warn("Failed to parse solution file",{error:n,file:i})}return a}async parseSolutionProjects(r,e){let t=[],a=J.dirname(r),i=/Project\("[^"]+"\)\s*=\s*"([^"]+)",\s*"([^"]+)",\s*"[^"]+"/g,n;for(;(n=i.exec(e))!==null;){let o=n[1],c=n[2];if(c.endsWith(".sln"))continue;let d=J.resolve(a,c);if(we.existsSync(d))try{let p=await this.analyzeProject(d);p&&t.push({...p,name:o})}catch(p){s.warn("Failed to analyze project",{error:p,projectPath:d})}}return t}parseSolutionConfigurations(r){let e=[],t=/^\s*([^|]+)\|([^=]+)\s*=/gm,a;for(;(a=t.exec(r))!==null;){let i=`${a[1].trim()}|${a[2].trim()}`;e.includes(i)||e.push(i)}return e}async detectStandaloneProjects(r,e){let{glob:t}=await import("glob"),a=await t("**/*.csproj",{cwd:r}),i=new Set;e.forEach(o=>{o.projects.forEach(c=>{i.add(J.resolve(c.path,c.file))})});let n=[];for(let o of a){let c=J.resolve(r,o);if(!i.has(c))try{let d=await this.analyzeProject(c);d&&n.push(d)}catch(d){s.warn("Failed to analyze standalone project",{error:d,projectFile:o})}}return n}async analyzeProject(r){try{let e=we.readFileSync(r,"utf8"),t=J.dirname(r),a=J.basename(r,".csproj"),i=this.extractTargetFrameworks(e),n=this.extractPackageReferences(e),o=this.determineProjectType(e,n),c=this.isTestProject(e,n),d=await this.extractPort(t,o);return{name:a,file:J.basename(r),path:t,type:o,frameworks:i,port:d,packageReferences:n,isShared:!1,isTest:c}}catch(e){return s.error("Failed to analyze project file",{error:e,projectPath:r}),null}}extractTargetFrameworks(r){let e=[],t=r.match(/<TargetFramework>([^<]+)<\/TargetFramework>/);t&&e.push(t[1]);let a=r.match(/<TargetFrameworks>([^<]+)<\/TargetFrameworks>/);return a&&e.push(...a[1].split(";").map(i=>i.trim())),e}extractPackageReferences(r){let e=[],t=/<PackageReference\s+Include="([^"]+)"/g,a;for(;(a=t.exec(r))!==null;)e.push(a[1]);return e}determineProjectType(r,e){if(r.includes("Microsoft.NET.Sdk.Web"))return e.some(t=>t.includes("Blazor"))?"blazor":e.some(t=>t.includes("Mvc"))||r.includes("Microsoft.AspNetCore.Mvc")?"mvc":"aspnetcore";if(r.includes("Microsoft.NET.Sdk")){if(e.some(a=>["xunit","NUnit","MSTest"].some(i=>a.includes(i)))){if(e.some(a=>a.includes("xunit")))return"xunit";if(e.some(a=>a.includes("NUnit")))return"nunit";if(e.some(a=>a.includes("MSTest")))return"mstest"}let t=r.match(/<OutputType>([^<]+)<\/OutputType>/);return t&&t[1].toLowerCase()==="exe"?"console":"classlib"}return"unknown"}isTestProject(r,e){return e.some(t=>["xunit","nunit","mstest","Microsoft.NET.Test.Sdk"].some(a=>t.toLowerCase().includes(a.toLowerCase())))||r.toLowerCase().includes("test")}async extractPort(r,e){if(!["aspnetcore","mvc","webapi","blazor"].includes(e))return;let t=J.join(r,"Properties","launchSettings.json");if(we.existsSync(t))try{let i=JSON.parse(we.readFileSync(t,"utf8"));for(let n of Object.values(i.profiles||{})){let o=n;if(o.applicationUrl){let c=o.applicationUrl.match(/:(\d+)/);if(c)return parseInt(c[1])}}}catch(i){s.warn("Failed to parse launchSettings.json",{error:i,path:t})}return{aspnetcore:5e3,mvc:5e3,webapi:5001,blazor:5002}[e]}identifySharedProjects(r){if(r.length<2)return[];let e=new Map;r.forEach(a=>{a.projects.forEach(i=>{let n=J.resolve(i.path,i.file);e.has(n)?e.get(n).count++:e.set(n,{project:i,count:1})})});let t=[];for(let[,{project:a,count:i}]of e)i>1&&(a.isShared=!0,t.push(a));return t}findNuGetConfig(r){let e=["nuget.config","NuGet.config","NuGet.Config"];for(let t of e){let a=J.join(r,t);if(we.existsSync(a))return t}}async detectDockerFiles(r){let{glob:e}=await import("glob");return await e("**/Dockerfile*",{cwd:r})}}});var _,N,er,Ai=M(()=>{"use strict";_=A(require("fs")),N=A(require("path"));j();er=class{async detect(r){try{if(s.info("Starting Python workspace detection",{workspacePath:r}),!await this.hasPythonIndicators(r))return null;let t=await this.detectVirtualEnvironments(r),a=await this.detectPythonProjects(r),i=await this.detectGlobalPythonVersion(r),n=_.existsSync(N.join(r,"pyproject.toml"))&&_.readFileSync(N.join(r,"pyproject.toml"),"utf8").includes("[tool.poetry]"),o=_.existsSync(N.join(r,"Pipfile")),c=_.existsSync(N.join(r,"environment.yml"))||_.existsSync(N.join(r,"conda-env.yml")),d=await this.detectDockerFiles(r),p=await this.detectJupyterNotebooks(r),u;return a.length>1?u="python-monorepo":a.length===1&&a[0].apps.length>1?u="python-multi-app":u="python-single-project",{pattern:u,projects:a,virtualEnvironments:t,globalPythonVersion:i,hasPoetry:n,hasPipenv:o,hasCondaEnv:c,dockerFiles:d,jupyterNotebooks:p}}catch(e){return s.error("Failed to detect Python workspace",{error:e,workspacePath:r}),null}}async hasPythonIndicators(r){let e=["**/*.py","requirements.txt","requirements/**/*.txt","pyproject.toml","setup.py","setup.cfg","Pipfile","environment.yml","conda-env.yml","manage.py","app.py","main.py","**/__init__.py"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r,maxDepth:3})).length>0)return!0}return!1}async detectVirtualEnvironments(r){let e=["venv","env",".venv",".env","virtualenv"],t=[];for(let a of e){let i=N.join(r,a);if(_.existsSync(i)&&_.statSync(i).isDirectory()){let n=process.platform==="win32"?"Scripts/python.exe":"bin/python";_.existsSync(N.join(i,n))&&t.push(a)}}return t}async detectPythonProjects(r){let e=[];if(_.existsSync(N.join(r,"manage.py"))){let t=await this.analyzeDjangoProject(r);t&&e.push(t)}else{let t=await this.findPythonProjectDirectories(r);for(let a of t){let i=await this.analyzePythonProject(a);i&&e.push(i)}}return e}async findPythonProjectDirectories(r){let e=[r],{glob:t}=await import("glob"),a=await t("**/setup.py",{cwd:r,maxDepth:2}),i=await t("**/pyproject.toml",{cwd:r,maxDepth:2}),n=await t("**/app.py",{cwd:r,maxDepth:2}),o=await t("**/main.py",{cwd:r,maxDepth:2});return[...a,...i,...n,...o].forEach(c=>{let d=N.dirname(N.resolve(r,c));e.includes(d)||e.push(d)}),e}async analyzeDjangoProject(r){try{let e=N.basename(r),t=await this.detectDjangoApps(r),{dependencies:a,devDependencies:i}=await this.analyzeDependencies(r),n=_.existsSync(N.join(r,"manage.py"));return{name:e,path:r,type:"django-project",framework:"django",apps:t,dependencies:a,devDependencies:i,virtualEnv:await this.findVirtualEnv(r),hasDockerfile:_.existsSync(N.join(r,"Dockerfile")),hasRequirements:await this.hasRequirementsFiles(r),hasPyprojectToml:_.existsSync(N.join(r,"pyproject.toml")),hasSetupPy:_.existsSync(N.join(r,"setup.py")),hasManagePy:n,testFramework:await this.detectTestFramework(r,a)}}catch(e){return s.error("Failed to analyze Django project",{error:e,projectPath:r}),null}}async detectDjangoApps(r){let e=[];try{let{glob:t}=await import("glob"),a=await t("**/apps.py",{cwd:r,maxDepth:3});for(let i of a){let n=N.dirname(N.resolve(r,i)),o=N.basename(n);if(o===N.basename(r))continue;let c=await this.analyzeDjangoApp(n,o);c&&e.push(c)}if(e.length===0){let i=await t("**/models.py",{cwd:r,maxDepth:2}),n=await t("**/views.py",{cwd:r,maxDepth:2}),o=new Set;[...i,...n].forEach(c=>{let d=N.dirname(N.resolve(r,c));N.basename(d)!==N.basename(r)&&o.add(d)});for(let c of o){let d=N.basename(c),p=await this.analyzeDjangoApp(c,d);p&&e.push(p)}}}catch(t){s.warn("Failed to detect Django apps",{error:t,projectPath:r})}return e}async analyzeDjangoApp(r,e){try{let t=_.existsSync(N.join(r,"models.py"))?await this.extractDjangoModels(N.join(r,"models.py")):[],a=_.existsSync(N.join(r,"urls.py"))?[e]:[],i=await this.findManagementCommands(r),n=_.existsSync(N.join(r,"tests.py"))||_.existsSync(N.join(r,"tests"));return{name:e,path:r,type:"django",models:t,urls:a,managementCommands:i,hasTests:n,isPackage:_.existsSync(N.join(r,"__init__.py"))}}catch(t){return s.warn("Failed to analyze Django app",{error:t,appPath:r,appName:e}),null}}async analyzePythonProject(r){try{let e=N.basename(r),{dependencies:t,devDependencies:a}=await this.analyzeDependencies(r),i="unknown",n;t.some(c=>c.includes("flask"))?(i="flask-app",n="flask"):t.some(c=>c.includes("fastapi"))?(i="fastapi-app",n="fastapi"):(_.existsSync(N.join(r,"setup.py"))||_.existsSync(N.join(r,"pyproject.toml")))&&(i="package");let o=await this.detectPythonApps(r,i);return{name:e,path:r,type:i,framework:n,apps:o,dependencies:t,devDependencies:a,virtualEnv:await this.findVirtualEnv(r),hasDockerfile:_.existsSync(N.join(r,"Dockerfile")),hasRequirements:await this.hasRequirementsFiles(r),hasPyprojectToml:_.existsSync(N.join(r,"pyproject.toml")),hasSetupPy:_.existsSync(N.join(r,"setup.py")),hasManagePy:_.existsSync(N.join(r,"manage.py")),testFramework:await this.detectTestFramework(r,t)}}catch(e){return s.error("Failed to analyze Python project",{error:e,projectPath:r}),null}}async detectPythonApps(r,e){let t=[];if(e==="flask-app"||e==="fastapi-app"){let a=["app.py","main.py","server.py","api.py"];for(let i of a){let n=N.join(r,i);if(_.existsSync(n)){let o=await this.extractPortFromPythonFile(n);t.push({name:N.basename(i,".py"),path:r,type:e==="flask-app"?"flask":"fastapi",port:o,hasTests:await this.hasTestFiles(r),isPackage:_.existsSync(N.join(r,"__init__.py"))});break}}}return t}async analyzeDependencies(r){let e=[],t=[],a=N.join(r,"requirements.txt");if(_.existsSync(a)){let c=_.readFileSync(a,"utf8");e.push(...this.parseRequirements(c))}let i=N.join(r,"requirements-dev.txt");if(_.existsSync(i)){let c=_.readFileSync(i,"utf8");t.push(...this.parseRequirements(c))}let n=N.join(r,"pyproject.toml");if(_.existsSync(n)){let c=_.readFileSync(n,"utf8"),{deps:d,devDeps:p}=this.parsePyprojectToml(c);e.push(...d),t.push(...p)}let o=N.join(r,"Pipfile");if(_.existsSync(o)){let c=_.readFileSync(o,"utf8"),{deps:d,devDeps:p}=this.parsePipfile(c);e.push(...d),t.push(...p)}return{dependencies:e,devDependencies:t}}parseRequirements(r){return r.split(`
1042
+ `).map(e=>e.trim()).filter(e=>e&&!e.startsWith("#")&&!e.startsWith("-")).map(e=>e.split("==")[0].split(">=")[0].split("<=")[0].split("~=")[0].trim())}parsePyprojectToml(r){let e=[],t=[],a=r.match(/\[tool\.poetry\.dependencies\]([\s\S]*?)(\[|$)/);if(a){let o=a[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&e.push(...o.map(c=>c.split("=")[0].trim()))}let i=r.match(/\[tool\.poetry\.group\.dev\.dependencies\]([\s\S]*?)(\[|$)/);if(i){let o=i[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&t.push(...o.map(c=>c.split("=")[0].trim()))}return{deps:e,devDeps:t}}parsePipfile(r){let e=[],t=[],a=r.match(/\[packages\]([\s\S]*?)(\[|$)/);if(a){let o=a[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&e.push(...o.map(c=>c.split("=")[0].trim()))}let i=r.match(/\[dev-packages\]([\s\S]*?)(\[|$)/);if(i){let o=i[1].match(/^([a-zA-Z0-9-_]+)\s*=/gm);o&&t.push(...o.map(c=>c.split("=")[0].trim()))}return{deps:e,devDeps:t}}async extractPortFromPythonFile(r){try{let e=_.readFileSync(r,"utf8"),t=[/\.run\([^)]*port\s*=\s*(\d+)/,/uvicorn\.run\([^)]*port\s*=\s*(\d+)/,/app\.run\([^)]*port\s*=\s*(\d+)/,/PORT\s*=\s*(\d+)/,/port\s*=\s*(\d+)/];for(let a of t){let i=e.match(a);if(i)return parseInt(i[1])}}catch(e){s.warn("Failed to extract port from Python file",{error:e,filePath:r})}}async extractDjangoModels(r){try{return(_.readFileSync(r,"utf8").match(/class\s+(\w+)\s*\([^)]*Model[^)]*\)/g)||[]).map(a=>{let i=a.match(/class\s+(\w+)/);return i?i[1]:""}).filter(a=>a)}catch{return[]}}async findManagementCommands(r){let e=N.join(r,"management","commands");if(!_.existsSync(e))return[];try{return _.readdirSync(e).filter(a=>a.endsWith(".py")&&a!=="__init__.py").map(a=>N.basename(a,".py"))}catch{return[]}}async findVirtualEnv(r){let e=["venv","env",".venv",".env"];for(let t of e){let a=N.join(r,t);if(_.existsSync(a))return t}}async hasRequirementsFiles(r){let e=["requirements.txt","requirements-dev.txt","requirements"];for(let a of e)if(_.existsSync(N.join(r,a)))return!0;let t=N.join(r,"requirements");return!!(_.existsSync(t)&&_.statSync(t).isDirectory())}async hasTestFiles(r){let{glob:e}=await import("glob");return(await e("**/test*.py",{cwd:r,maxDepth:2})).length>0}async detectTestFramework(r,e){if(e.some(i=>i.includes("pytest")))return"pytest";if(e.some(i=>i.includes("nose")))return"nose";if(e.some(i=>i.includes("tox")))return"tox";let{glob:t}=await import("glob"),a=await t("**/test*.py",{cwd:r,maxDepth:2});for(let i of a)try{let n=_.readFileSync(N.join(r,i),"utf8");if(n.includes("import unittest")||n.includes("from unittest"))return"unittest"}catch{}}async detectGlobalPythonVersion(r){let e=N.join(r,".python-version");if(_.existsSync(e))try{return _.readFileSync(e,"utf8").trim()}catch{}let t=N.join(r,"runtime.txt");if(_.existsSync(t))try{let i=_.readFileSync(t,"utf8").trim().match(/python-(\d+\.\d+(?:\.\d+)?)/);if(i)return i[1]}catch{}}async detectDockerFiles(r){let{glob:e}=await import("glob");return await e("**/Dockerfile*",{cwd:r,maxDepth:2})}async detectJupyterNotebooks(r){let{glob:e}=await import("glob");return await e("**/*.ipynb",{cwd:r,maxDepth:3})}}});var oe,Y,tr,Ei=M(()=>{"use strict";oe=A(require("fs")),Y=A(require("path"));j();tr=class{async detect(r){try{if(s.info("Starting Serverless Framework workspace detection",{workspacePath:r}),!await this.hasServerlessIndicators(r))return null;let t=await this.detectServerlessServices(r);if(t.length===0)return null;let a=await this.detectSharedResources(r),i=await this.detectGlobalPlugins(r),n=oe.existsSync(Y.join(r,"package.json")),o=oe.existsSync(Y.join(r,"lerna.json")),c=oe.existsSync(Y.join(r,"serverless.yml"))||oe.existsSync(Y.join(r,"serverless.yaml")),d=await this.detectFrameworkVersion(r),p=this.extractDeploymentBuckets(t),u=this.extractCustomDomains(t),h;return t.length>1?h=n||o?"serverless-monorepo":"serverless-multi-service":h="serverless-single-service",{pattern:h,services:t,sharedResources:a,globalPlugins:i,hasCommonPackageJson:n,hasLernaConfig:o,hasWorkspaceConfig:c,frameworkVersion:d,deploymentBuckets:p,customDomains:u}}catch(e){return s.error("Failed to detect Serverless workspace",{error:e,workspacePath:r}),null}}async hasServerlessIndicators(r){let e=["serverless.yml","serverless.yaml","serverless.json","**/serverless.yml","**/serverless.yaml","sls.yml","sls.yaml"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r,maxDepth:3})).length>0)return!0}return!1}async detectServerlessServices(r){let{glob:e}=await import("glob"),t=await e("**/serverless.{yml,yaml,json}",{cwd:r,maxDepth:3}),a=[];for(let i of t)try{let n=Y.dirname(Y.resolve(r,i)),o=await this.analyzeServerlessService(n,i);o&&a.push(o)}catch(n){s.warn("Failed to analyze Serverless service",{error:n,configFile:i})}return a}async analyzeServerlessService(r,e){try{let t=Y.resolve(r,Y.basename(e)),a;if(e.endsWith(".json"))a=JSON.parse(oe.readFileSync(t,"utf8"));else{let B=oe.readFileSync(t,"utf8");a=await this.parseServerlessYaml(B)}let i=a.service||Y.basename(r),n=this.normalizeProvider(a.provider?.name||a.provider||"aws"),o=a.provider?.runtime||"nodejs18.x",c=a.provider?.region,d=a.provider?.stage,p=await this.parseFunctions(a.functions||{},r),u=await this.parseResources(a.resources||{}),h=await this.parseStages(a),f=a.plugins||[],b=a.custom||{},w=this.analyzeServiceCapabilities(a,p,u);return{name:i,path:r,provider:n,runtime:o,region:c,stage:d,functions:p,resources:u,stages:h,plugins:f,customVariables:b,...w}}catch(t){return s.error("Failed to analyze Serverless service",{error:t,servicePath:r,configFile:e}),null}}async parseServerlessYaml(r){let e=r.split(`
1043
+ `),t={},a="";for(let i of e){let n=i.trim();if(!n||n.startsWith("#"))continue;let o=i.length-i.trimStart().length;if(n.includes(":")){let[c,d]=n.split(":",2),p=c.trim(),u=d?.trim()||"";o===0?(a=p,t[p]=u||{}):a&&((!t[a]||typeof t[a]!="object")&&(t[a]={}),t[a][p]=u||{})}}return t}normalizeProvider(r){switch(r.toLowerCase()){case"aws":case"amazon":return"aws";case"azure":case"microsoft":return"azure";case"gcp":case"google":case"google-cloud":return"gcp";case"cloudflare":return"cloudflare";case"knative":return"knative";case"openwhisk":return"openwhisk";default:return"unknown"}}async parseFunctions(r,e){let t=[];for(let[a,i]of Object.entries(r))if(typeof i=="object"&&i!==null){let n=i,o={name:a,handler:n.handler||`${a}.handler`,runtime:n.runtime,events:this.parseEvents(n.events||[]),environment:n.environment,layers:n.layers,timeout:n.timeout,memorySize:n.memorySize,path:await this.findFunctionPath(e,a,n.handler)};t.push(o)}return t}parseEvents(r){let e=[];for(let t of r)if(typeof t=="object"){let a=Object.keys(t)[0];a&&e.push(a)}else typeof t=="string"&&e.push(t);return e}async parseResources(r){let e=[];if(r.Resources){for(let[t,a]of Object.entries(r.Resources))if(typeof a=="object"&&a!==null){let i=a;e.push({type:i.Type||"Unknown",name:t,properties:i.Properties||{}})}}return e}async parseStages(r){let e=[];if(r.provider?.stage&&e.push({name:r.provider.stage,region:r.provider.region,environment:r.provider.environment}),r.custom?.stages){for(let[t,a]of Object.entries(r.custom.stages))if(typeof a=="object"){let i=a;e.push({name:t,region:i.region,environment:i.environment,customDomain:i.customDomain})}}return e}analyzeServiceCapabilities(r,e,t){let a=t.length>0,i=t.some(u=>u.type.includes("StepFunctions"))||r.stepFunctions!==void 0,n=e.some(u=>u.events.includes("http")||u.events.includes("httpApi"))||t.some(u=>u.type.includes("ApiGateway")),o=e.some(u=>u.events.includes("eventBridge"))||t.some(u=>u.type.includes("Events")),c=t.some(u=>u.type.includes("DynamoDB"))||e.some(u=>u.environment&&Object.values(u.environment).some(h=>typeof h=="string"&&h.includes("dynamodb"))),d=e.some(u=>u.events.includes("s3"))||t.some(u=>u.type.includes("S3")),p=e.some(u=>u.layers&&u.layers.length>0);return{hasCustomResources:a,hasStepFunctions:i,hasApiGateway:n,hasEventBridge:o,hasDynamoDB:c,hasS3:d,hasLambdaLayers:p}}async findFunctionPath(r,e,t){let a=t.split(".");if(a.length<2)return;let i=a[0],n=[".js",".ts",".py",".cs",".java",".go"];for(let o of n){let c=Y.join(r,i+o);if(oe.existsSync(c))return Y.relative(r,c)}}async detectSharedResources(r){let e=[],t=["shared/**/*.yml","shared/**/*.yaml","resources/**/*.yml","resources/**/*.yaml","common/**/*.yml","common/**/*.yaml"];for(let a of t){let{glob:i}=await import("glob"),n=await i(a,{cwd:r,maxDepth:3});e.push(...n)}return e}async detectGlobalPlugins(r){let e=[],t=Y.join(r,"package.json");if(oe.existsSync(t))try{let a=JSON.parse(oe.readFileSync(t,"utf8")),i={...a.dependencies,...a.devDependencies};for(let n of Object.keys(i))(n.startsWith("serverless-")||n.includes("serverless"))&&e.push(n)}catch(a){s.warn("Failed to parse root package.json",{error:a})}return e}async detectFrameworkVersion(r){let e=Y.join(r,"package.json");if(oe.existsSync(e))try{let t=JSON.parse(oe.readFileSync(e,"utf8")),a={...t.dependencies,...t.devDependencies};if(a.serverless)return a.serverless.replace(/[\^~]/,"")}catch(t){s.warn("Failed to detect Serverless Framework version",{error:t})}}extractDeploymentBuckets(r){let e=[];for(let t of r){t.customVariables.deploymentBucket&&e.push(t.customVariables.deploymentBucket);for(let a of t.resources)a.type.includes("S3")&&a.properties.BucketName&&e.push(a.properties.BucketName)}return[...new Set(e)]}extractCustomDomains(r){let e=[];for(let t of r){if(t.customVariables.customDomain){let a=t.customVariables.customDomain;typeof a=="object"&&a.domainName?e.push(a.domainName):typeof a=="string"&&e.push(a)}for(let a of t.stages)a.customDomain&&e.push(a.customDomain)}return[...new Set(e)]}}});var te,ne,rr,Ti=M(()=>{"use strict";te=A(require("fs")),ne=A(require("path"));j();rr=class{async detect(r){try{if(s.info("Starting AWS SAM workspace detection",{workspacePath:r}),!await this.hasSamIndicators(r))return null;let t=await this.detectSamApplications(r);if(t.length===0)return null;let a=await this.detectSharedLayers(r),i=await this.detectSharedTemplates(r),n=await this.detectSamCliVersion(r),o=await this.detectAwsRegion(r),c=await this.detectDeploymentBucket(r),d=this.analyzeWorkspaceCapabilities(t),p;return t.some(h=>h.nestedApplications.length>0)?p="sam-nested-apps":t.length>1?p="sam-multi-app":p="sam-single-app",{pattern:p,applications:t,sharedLayers:a,sharedTemplates:i,samCliVersion:n,awsRegion:o,deploymentBucket:c,...d}}catch(e){return s.error("Failed to detect AWS SAM workspace",{error:e,workspacePath:r}),null}}async hasSamIndicators(r){let e=["template.yaml","template.yml","sam.yaml","sam.yml","**/template.yaml","**/template.yml","samconfig.toml",".aws-sam/**"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r,maxDepth:3})).length>0)return!0}return!1}async detectSamApplications(r){let{glob:e}=await import("glob"),t=await e("**/template.{yaml,yml}",{cwd:r,maxDepth:3}),a=[];for(let i of t)try{let n=ne.dirname(ne.resolve(r,i)),o=await this.analyzeSamApplication(n,i);o&&a.push(o)}catch(n){s.warn("Failed to analyze SAM application",{error:n,templateFile:i})}return a}async analyzeSamApplication(r,e){try{let t=ne.resolve(r,ne.basename(e)),a=te.readFileSync(t,"utf8"),i=await this.parseSamTemplate(a);if(!this.isSamTemplate(i))return null;let n=i.Parameters?.ApplicationName?.Default||ne.basename(r),o=await this.parseSamFunctions(i.Resources||{},r),c=await this.parseSamApis(i.Resources||{},o),d=await this.parseSamTables(i.Resources||{}),p=await this.parseSamLayers(i.Resources||{},r),u=await this.findNestedApplications(i.Resources||{}),h=await this.hasLocalTesting(r),f=await this.hasIntegrationTests(r),b=await this.hasPipeline(r);return{name:n,path:r,templatePath:t,samVersion:i.AWSTemplateFormatVersion||"2010-09-09",transform:i.Transform||"AWS::Serverless-2016-10-31",description:i.Description,globals:i.Globals,parameters:i.Parameters,mappings:i.Mappings,conditions:i.Conditions,functions:o,apis:c,tables:d,layers:p,nestedApplications:u,outputs:i.Outputs,hasLocalTesting:h,hasIntegrationTests:f,hasPipeline:b}}catch(t){return s.error("Failed to analyze SAM application",{error:t,appPath:r,templateFile:e}),null}}async parseSamTemplate(r){let e=r.split(`
1044
+ `),t={},a="",i="",n=0;for(let o of e){let c=o.trim();if(!c||c.startsWith("#"))continue;let d=o.length-o.trimStart().length;if(c.includes(":")){let[p,u]=c.split(":",2),h=p.trim(),f=u?.trim()||"";d===0?(a=h,t[h]=f||{},n=0):d===2&&a?(i=h,(!t[a]||typeof t[a]!="object")&&(t[a]={}),t[a][h]=f||{},n=2):d>n&&a&&i&&((!t[a][i]||typeof t[a][i]!="object")&&(t[a][i]={}),t[a][i][h]=f||{})}}return t}isSamTemplate(r){return r.Transform==="AWS::Serverless-2016-10-31"||r.Resources&&Object.values(r.Resources).some(e=>e.Type&&e.Type.startsWith("AWS::Serverless::"))}async parseSamFunctions(r,e){let t=[];for(let[a,i]of Object.entries(r)){let n=i;if(n.Type==="AWS::Serverless::Function"){let o=n.Properties||{},c={name:a,handler:o.Handler||"index.handler",runtime:o.Runtime||"nodejs18.x",codeUri:o.CodeUri||".",events:await this.parseSamEvents(o.Events||{}),environment:o.Environment?.Variables,layers:o.Layers,timeout:o.Timeout,memorySize:o.MemorySize,reservedConcurrency:o.ReservedConcurrencyLimit,policies:o.Policies};t.push(c)}}return t}async parseSamEvents(r){let e=[];for(let[t,a]of Object.entries(r)){let i=a,n=i.Type||"Unknown";e.push({type:this.normalizeSamEventType(n),properties:i.Properties||{}})}return e}normalizeSamEventType(r){switch(r){case"Api":return"Api";case"HttpApi":return"HttpApi";case"S3":return"S3";case"DynamoDB":return"DynamoDB";case"SQS":return"SQS";case"SNS":return"SNS";case"EventBridge":case"EventBridgeRule":return"EventBridge";case"Schedule":return"Schedule";case"CloudWatchEvent":return"CloudWatchEvent";default:return"Unknown"}}async parseSamApis(r,e){let t=[];for(let[a,i]of Object.entries(r)){let n=i;if(n.Type==="AWS::Serverless::Api"||n.Type==="AWS::Serverless::HttpApi"){let o=n.Properties||{},c={name:a,type:n.Type==="AWS::Serverless::HttpApi"?"HttpApi":"Api",stageName:o.StageName,cors:o.Cors!==void 0,auth:o.Auth,domain:o.Domain?.DomainName,endpoints:[]};for(let d of e)for(let p of d.events)(p.type==="Api"||p.type==="HttpApi")&&(p.properties.RestApiId===a||!p.properties.RestApiId)&&c.endpoints.push({method:p.properties.Method||"ANY",path:p.properties.Path||"/",functionName:d.name});t.push(c)}}if(t.length===0){let a=[],i=[];for(let n of e)for(let o of n.events)o.type==="Api"?a.push({method:o.properties.Method||"ANY",path:o.properties.Path||"/",functionName:n.name}):o.type==="HttpApi"&&i.push({method:o.properties.Method||"ANY",path:o.properties.Path||"/",functionName:n.name});a.length>0&&t.push({name:"ImplicitApi",type:"Api",endpoints:a}),i.length>0&&t.push({name:"ImplicitHttpApi",type:"HttpApi",endpoints:i})}return t}async parseSamTables(r){let e=[];for(let[t,a]of Object.entries(r)){let i=a;if(i.Type==="AWS::Serverless::SimpleTable"||i.Type==="AWS::DynamoDB::Table"){let n=i.Properties||{};e.push({name:t,attributeDefinitions:n.AttributeDefinitions||[],keySchema:n.KeySchema||[],billingMode:n.BillingMode,streamSpecification:n.StreamSpecification})}}return e}async parseSamLayers(r,e){let t=[];for(let[a,i]of Object.entries(r)){let n=i;if(n.Type==="AWS::Serverless::LayerVersion"){let o=n.Properties||{};t.push({name:a,contentUri:o.ContentUri||"layers/",compatibleRuntimes:o.CompatibleRuntimes||[],description:o.Description})}}return t}async findNestedApplications(r){let e=[];for(let[t,a]of Object.entries(r))a.Type==="AWS::Serverless::Application"&&e.push(t);return e}async hasLocalTesting(r){let e=["tests/**","test/**","**/test_*.py","**/test_*.js","**/test_*.ts","**/spec_*.js","**/spec_*.ts","pytest.ini","jest.config.js","jest.config.ts"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r,maxDepth:2})).length>0)return!0}return!1}async hasIntegrationTests(r){let e=["integration/**","integration-tests/**","e2e/**","end-to-end/**","**/integration_*.py","**/integration_*.js","**/integration_*.ts","**/e2e_*.js","**/e2e_*.ts"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r,maxDepth:2})).length>0)return!0}return!1}async hasPipeline(r){let e=["pipeline.yaml","pipeline.yml","buildspec.yml","buildspec.yaml",".github/workflows/**",".gitlab-ci.yml","Jenkinsfile","azure-pipelines.yml","codepipeline/**"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r,maxDepth:2})).length>0)return!0}return!1}async detectSharedLayers(r){let e=[],t=ne.join(r,"layers");if(te.existsSync(t)&&te.statSync(t).isDirectory()){let a=te.readdirSync(t).filter(i=>te.statSync(ne.join(t,i)).isDirectory());for(let i of a)e.push({name:i,contentUri:`layers/${i}`,compatibleRuntimes:[],description:`Shared layer: ${i}`})}return e}async detectSharedTemplates(r){let{glob:e}=await import("glob"),t=["shared/**/*.{yaml,yml}","templates/**/*.{yaml,yml}","common/**/*.{yaml,yml}"],a=[];for(let i of t){let n=await e(i,{cwd:r,maxDepth:2});a.push(...n)}return a}async detectSamCliVersion(r){let e=ne.join(r,"samconfig.toml");if(te.existsSync(e))try{let a=te.readFileSync(e,"utf8").match(/version\s*=\s*["']([^"']+)["']/);if(a)return a[1]}catch(t){s.warn("Failed to parse samconfig.toml",{error:t})}}async detectAwsRegion(r){let e=ne.join(r,"samconfig.toml");if(te.existsSync(e))try{let a=te.readFileSync(e,"utf8").match(/region\s*=\s*["']([^"']+)["']/);if(a)return a[1]}catch(t){s.warn("Failed to parse region from samconfig.toml",{error:t})}}async detectDeploymentBucket(r){let e=ne.join(r,"samconfig.toml");if(te.existsSync(e))try{let a=te.readFileSync(e,"utf8").match(/s3_bucket\s*=\s*["']([^"']+)["']/);if(a)return a[1]}catch(t){s.warn("Failed to parse deployment bucket from samconfig.toml",{error:t})}}analyzeWorkspaceCapabilities(r){let e=r.some(u=>u.layers.length>0),t=r.some(u=>u.hasPipeline),a=r.some(u=>u.hasLocalTesting),i=r.some(u=>u.apis.length>0),n=r.some(u=>u.tables.length>0),o=!1,c=!1,d=!1,p=!1;for(let u of r)for(let h of u.functions)for(let f of h.events)switch(f.type){case"S3":o=!0;break;case"EventBridge":c=!0;break;case"SQS":d=!0;break;case"SNS":p=!0;break}return{hasSharedResources:e,hasPipeline:t,hasLocalInvoke:a,hasApiGateway:i,hasDynamoDB:n,hasS3:o,hasEventBridge:c,hasSQS:d,hasSNS:p}}}});var L,U,ar,Ci=M(()=>{"use strict";L=A(require("fs")),U=A(require("path"));j();ar=class{async detect(r){try{if(s.info("Starting JavaScript/TypeScript workspace detection",{workspacePath:r}),!await this.hasJavaScriptIndicators(r))return null;let t=await this.detectPackageManager(r),a=await this.detectWorkspaceManager(r),i=await this.detectJavaScriptPackages(r,a);if(i.length===0)return null;let n=await this.detectNodeVersion(r),o=L.existsSync(U.join(r,"docker-compose.yml"))||L.existsSync(U.join(r,"docker-compose.yaml")),c=await this.hasCI(r),d=await this.hasHusky(r),p=await this.hasCommitizen(r),u=await this.hasRenovate(r),h=await this.hasSemanticRelease(r),f=await this.hasTurbo(r),b=await this.hasNx(r),w=await this.hasLerna(r),B=await this.detectSharedConfigs(r),T=await this.detectGlobalDependencies(r),$;return this.hasFullstackPattern(i)?$="js-fullstack":a||i.length>1?$=a?"js-monorepo":"js-multi-package":$="js-single-package",{pattern:$,packages:i,workspaceManager:a,nodeVersion:n,packageManager:t,hasDockerCompose:o,hasCI:c,hasHusky:d,hasCommitizen:p,hasRenovate:u,hasSemanticRelease:h,hasTurbo:f,hasNx:b,hasLerna:w,sharedConfigs:B,globalDependencies:T}}catch(e){return s.error("Failed to detect JavaScript workspace",{error:e,workspacePath:r}),null}}async hasJavaScriptIndicators(r){let e=["package.json","**/*.js","**/*.ts","**/*.jsx","**/*.tsx","**/*.vue","node_modules/","yarn.lock","package-lock.json","pnpm-lock.yaml","bun.lockb"];for(let t of e){let{glob:a}=await import("glob");if((await a(t,{cwd:r,maxDepth:2})).length>0)return!0}return!1}async detectPackageManager(r){return L.existsSync(U.join(r,"bun.lockb"))?"bun":L.existsSync(U.join(r,"pnpm-lock.yaml"))?"pnpm":L.existsSync(U.join(r,"yarn.lock"))?"yarn":"npm"}async detectWorkspaceManager(r){if(L.existsSync(U.join(r,"nx.json")))return"nx";if(L.existsSync(U.join(r,"lerna.json")))return"lerna";if(L.existsSync(U.join(r,"rush.json")))return"rush";let e=U.join(r,"package.json");if(L.existsSync(e))try{if(JSON.parse(L.readFileSync(e,"utf8")).workspaces)switch(await this.detectPackageManager(r)){case"yarn":return"yarn-workspaces";case"npm":return"npm-workspaces";case"pnpm":return"pnpm-workspaces"}}catch(t){s.warn("Failed to parse root package.json",{error:t})}}async detectJavaScriptPackages(r,e){let t=[],{glob:a}=await import("glob"),i=await a("**/package.json",{cwd:r,maxDepth:3,ignore:["**/node_modules/**"]});for(let n of i)try{let o=U.dirname(U.resolve(r,n)),c=await this.analyzeJavaScriptPackage(o);c&&t.push(c)}catch(o){s.warn("Failed to analyze JavaScript package",{error:o,packageJsonFile:n})}return t}async analyzeJavaScriptPackage(r){try{let e=U.join(r,"package.json"),t=JSON.parse(L.readFileSync(e,"utf8")),a=Object.keys(t.dependencies||{}),i=Object.keys(t.devDependencies||{}),n=[...a,...i],o=this.detectFramework(n,r),c=this.detectBuildTool(n,r),d=await this.detectPackageManager(r),p=this.detectRuntime(o,n),u=await this.detectLanguage(r,n),h=this.detectPackageType(t,o,n),f=await this.extractPort(r,t.scripts||{}),b=this.detectTestFramework(n),w=await this.hasTestFiles(r)||b!==void 0,B=this.hasLinting(n,r),T=u!=="javascript"||n.includes("typescript"),$=L.existsSync(U.join(r,"Dockerfile")),K=!!(t.workspaces||t.nx),X=this.extractWorkspacePackages(t);return{name:t.name||U.basename(r),path:r,type:h,framework:o,buildTool:c,packageManager:d,runtime:p,language:u,port:f,scripts:t.scripts||{},dependencies:a,devDependencies:i,hasTests:w,testFramework:b,hasLinting:B,hasTypeChecking:T,hasDockerfile:$,isWorkspaceRoot:K,workspacePackages:X}}catch(e){return s.error("Failed to analyze JavaScript package",{error:e,packagePath:r}),null}}detectFramework(r,e){return r.includes("react")?r.includes("next")?"next":"react":r.some(t=>t.startsWith("@angular/"))||L.existsSync(U.join(e,"angular.json"))?"angular":r.includes("vue")?r.includes("nuxt")?"nuxt":"vue":r.includes("svelte")?"svelte":r.includes("@nestjs/core")?"nest":r.includes("fastify")?"fastify":r.includes("express")?"express":r.some(t=>["node","nodemon","@types/node"].includes(t))?"node":"none"}detectBuildTool(r,e){return r.includes("@angular/cli")||L.existsSync(U.join(e,"angular.json"))?"angular-cli":r.includes("turbo")?"turbo":r.includes("vite")?"vite":r.includes("webpack")?"webpack":r.includes("rollup")?"rollup":r.includes("parcel")?"parcel":r.includes("esbuild")?"esbuild":"none"}detectRuntime(r,e){return["react","angular","vue","svelte"].includes(r)?"browser":["next","nuxt"].includes(r)?"both":["express","fastify","nest","node"].includes(r)||e.some(t=>["express","fastify","@nestjs/core","http-server"].includes(t))?"node":e.some(t=>["react-dom","@angular/platform-browser","vue"].includes(t))?"browser":"node"}async detectLanguage(r,e){let t=e.includes("typescript")||L.existsSync(U.join(r,"tsconfig.json")),{glob:a}=await import("glob"),i=await a("**/*.{js,jsx}",{cwd:r,maxDepth:2,ignore:["**/node_modules/**"]}),n=await a("**/*.{ts,tsx}",{cwd:r,maxDepth:2,ignore:["**/node_modules/**"]});return n.length===0&&i.length>0?"javascript":i.length===0&&n.length>0?"typescript":i.length>0&&n.length>0?"mixed":t?"typescript":"javascript"}detectPackageType(r,e,t){return r.private===!1||r.publishConfig?"library":["react","angular","vue","svelte","next","nuxt"].includes(e)||["express","fastify","nest","node"].includes(e)?"app":r.name?.includes("config")||r.name?.includes("eslint")?"config":t.some(a=>["storybook","@storybook/react","@storybook/angular"].includes(a))?"component":r.bin||t.some(a=>["commander","yargs","inquirer"].includes(a))?"tool":"app"}async extractPort(r,e){for(let[a,i]of Object.entries(e))if(["start","dev","serve"].includes(a)){let n=i.match(/--port[=\s]+(\d+)|-p[=\s]+(\d+)|PORT[=\s]+(\d+)/);if(n)return parseInt(n[1]||n[2]||n[3])}let t=["vite.config.js","vite.config.ts","vue.config.js","angular.json",".env",".env.local"];for(let a of t){let i=U.join(r,a);if(L.existsSync(i))try{let n=L.readFileSync(i,"utf8");if(a==="angular.json"){let o=JSON.parse(n),d=Object.values(o.projects||{})[0]?.architect?.serve?.options?.port;if(d)return d}else{let o=n.match(/port[:\s=]+(\d+)/i);if(o)return parseInt(o[1])}}catch{}}}detectTestFramework(r){if(r.includes("jest"))return"jest";if(r.includes("vitest"))return"vitest";if(r.includes("mocha"))return"mocha";if(r.includes("cypress"))return"cypress";if(r.includes("playwright")||r.includes("@playwright/test"))return"playwright";if(r.includes("jasmine"))return"jasmine";if(r.includes("karma"))return"karma"}async hasTestFiles(r){let{glob:e}=await import("glob"),t=["**/*.test.{js,ts,jsx,tsx}","**/*.spec.{js,ts,jsx,tsx}","**/test/**/*.{js,ts,jsx,tsx}","**/tests/**/*.{js,ts,jsx,tsx}","**/__tests__/**/*.{js,ts,jsx,tsx}"];for(let a of t)if((await e(a,{cwd:r,maxDepth:3,ignore:["**/node_modules/**"]})).length>0)return!0;return!1}hasLinting(r,e){return r.some(t=>t.includes("eslint"))||L.existsSync(U.join(e,".eslintrc.js"))||L.existsSync(U.join(e,".eslintrc.json"))||L.existsSync(U.join(e,"eslint.config.js"))}extractWorkspacePackages(r){if(r.workspaces){if(Array.isArray(r.workspaces))return r.workspaces;if(r.workspaces.packages)return r.workspaces.packages}}hasFullstackPattern(r){let e=["react","angular","vue","svelte"],t=["express","fastify","nest","node"],a=r.some(n=>e.includes(n.framework)),i=r.some(n=>t.includes(n.framework));return a&&i}async detectNodeVersion(r){let e=U.join(r,".nvmrc");if(L.existsSync(e))try{return L.readFileSync(e,"utf8").trim()}catch{}let t=U.join(r,"package.json");if(L.existsSync(t))try{let a=JSON.parse(L.readFileSync(t,"utf8"));if(a.engines?.node)return a.engines.node}catch{}}async hasCI(r){let e=[".github/workflows",".gitlab-ci.yml","azure-pipelines.yml","Jenkinsfile",".circleci/config.yml",".travis.yml"];for(let t of e)if(L.existsSync(U.join(r,t)))return!0;return!1}async hasHusky(r){return L.existsSync(U.join(r,".husky"))||await this.packageHasDependency(r,"husky")}async hasCommitizen(r){return await this.packageHasDependency(r,"commitizen")||await this.packageHasDependency(r,"cz-conventional-changelog")}async hasRenovate(r){return L.existsSync(U.join(r,"renovate.json"))||L.existsSync(U.join(r,".renovaterc"))}async hasSemanticRelease(r){return await this.packageHasDependency(r,"semantic-release")}async hasTurbo(r){return L.existsSync(U.join(r,"turbo.json"))||await this.packageHasDependency(r,"turbo")}async hasNx(r){return L.existsSync(U.join(r,"nx.json"))}async hasLerna(r){return L.existsSync(U.join(r,"lerna.json"))}async packageHasDependency(r,e){let t=U.join(r,"package.json");if(!L.existsSync(t))return!1;try{let a=JSON.parse(L.readFileSync(t,"utf8")),i={...a.dependencies,...a.devDependencies};return e in i}catch{return!1}}async detectSharedConfigs(r){let e=[".eslintrc.js",".eslintrc.json","eslint.config.js","prettier.config.js",".prettierrc","jest.config.js","vitest.config.js","tsconfig.json","tsconfig.base.json","babel.config.js",".babelrc","webpack.config.js","vite.config.js","tailwind.config.js",".editorconfig",".gitignore"],t=[];for(let a of e)L.existsSync(U.join(r,a))&&t.push(a);return t}async detectGlobalDependencies(r){let e=U.join(r,"package.json");if(!L.existsSync(e))return[];try{let t=JSON.parse(L.readFileSync(e,"utf8"));return Object.keys({...t.dependencies,...t.devDependencies})}catch{return[]}}}});var Pi={};be(Pi,{WorkspaceRegistrationWizard:()=>Kr});var fe,O,ee,V,Kr,Ri=M(()=>{"use strict";fe=A(require("prompts")),O=A(require("chalk")),ee=A(require("fs")),V=A(require("path"));wi();j();bi();Ai();Ei();Ti();Ci();Kr=class{constructor(){this.configService=new Xt,this.dotNetDetector=new Zt,this.pythonDetector=new er,this.serverlessDetector=new tr,this.awsSamDetector=new rr,this.jsDetector=new ar}async run(r){try{console.log(O.default.blue.bold(`
1045
+ \u{1F680} Task Shepherd Workspace Registration`)),console.log(O.default.gray("\u2550".repeat(50))),console.log(O.default.gray(`Registering workspace at: ${r}`)),console.log();let e=V.join(r,"task-shepherd-workspace.json"),t=ee.existsSync(e);if(t){console.log(O.default.yellow("\u26A0\uFE0F Existing workspace configuration found"));let n=await(0,fe.default)({type:"select",name:"action",message:"What would you like to do?",choices:[{title:"Register workspace with existing configuration",value:"register"},{title:"Edit configuration and register",value:"edit"},{title:"Cancel",value:"cancel"}],initial:0});if(n.action==="cancel"){console.log(O.default.yellow("Registration cancelled"));return}if(n.action==="register"){await this.registerExistingConfig(r,e);return}}console.log(O.default.blue("\u{1F50D} Analyzing workspace..."));let a=await this.analyzeWorkspace(r);if(t)try{let n=ee.readFileSync(e,"utf8"),o=JSON.parse(n);a=this.mergeWithExistingConfig(a,o.workspace)}catch(n){s.warn("Could not load existing config for editing",{error:n})}let i=await this.collectWorkspaceInfo(a);await this.saveWorkspaceConfig(r,i),this.displaySummary(r,i)}catch(e){throw s.error("Workspace registration failed",{error:e,workspacePath:r}),e}}async registerExistingConfig(r,e){try{let t=ee.readFileSync(e,"utf8"),a=JSON.parse(t);console.log(O.default.blue(`
1046
+ \u{1F4CB} Existing Configuration`)),console.log(O.default.gray("\u2550".repeat(30)));let i=a.workspace;if(console.log(O.default.cyan("Workspace:")),console.log(` Name: ${O.default.white(i.name)}`),i.description&&console.log(` Description: ${O.default.white(i.description)}`),console.log(` Pattern: ${O.default.white(i.pattern)}`),i.services&&i.services.length>0&&(console.log(O.default.cyan(`
1047
+ Services:`)),i.services.forEach(o=>{console.log(` \u2022 ${O.default.white(o.name)} (${o.technology})`)})),!(await(0,fe.default)({type:"confirm",name:"proceed",message:"Register this workspace with the backend?",initial:!0})).proceed){console.log(O.default.yellow("Registration cancelled"));return}console.log(O.default.green(`
1048
+ \u2705 Workspace registered successfully with existing configuration`)),console.log(O.default.gray("Run `task-shepherd-agent workspace sync` to sync with backend"))}catch(t){throw s.error("Failed to load existing configuration",{error:t,configPath:e}),new Error(`Failed to load existing configuration: ${t instanceof Error?t.message:t}`)}}mergeWithExistingConfig(r,e){return{name:e.name||r.name,description:e.description||r.description,pattern:e.pattern||r.pattern,detectedTechnologies:r.detectedTechnologies,services:e.services||r.services,capabilities:e.capabilities||r.capabilities,tags:e.tags||r.tags}}async analyzeWorkspace(r){let e={};try{console.log(O.default.gray(" Detecting workspace technologies..."));let[t,a,i,n,o]=await Promise.all([this.dotNetDetector.detect(r).catch(()=>null),this.pythonDetector.detect(r).catch(()=>null),this.serverlessDetector.detect(r).catch(()=>null),this.awsSamDetector.detect(r).catch(()=>null),this.jsDetector.detect(r).catch(()=>null)]),c=[],d=[],p="multi-repo";if(t&&(console.log(O.default.gray(` \u2713 Detected .NET workspace (${t.pattern})`)),d.push("dotnet","csharp"),t.solutions.forEach(u=>{c.push({name:u.name,technology:"dotnet-solution",framework:"dotnet",path:V.relative(r,u.path)||"."})}),[...t.standaloneProjects,...t.sharedProjects].forEach(u=>{c.push({name:u.name,technology:u.type,framework:"dotnet",port:u.port,path:V.relative(r,u.path)||"."})}),t.solutions.length>1&&(p="monorepo")),a&&(console.log(O.default.gray(` \u2713 Detected Python workspace (${a.pattern})`)),d.push("python"),a.projects.forEach(u=>{d.push(u.framework||"python"),u.apps.forEach(h=>{c.push({name:h.name,technology:h.type,framework:u.framework,runtime:"python",port:h.port,path:V.relative(r,h.path)||"."})})}),a.pattern==="python-monorepo"&&(p="monorepo")),i&&(console.log(O.default.gray(` \u2713 Detected Serverless workspace (${i.pattern})`)),d.push("serverless"),i.services.forEach(u=>{c.push({name:u.name,technology:"serverless",framework:"serverless-framework",runtime:u.runtime,path:V.relative(r,u.path)||"."})}),i.pattern==="serverless-monorepo"&&(p="monorepo")),n&&(console.log(O.default.gray(` \u2713 Detected AWS SAM workspace (${n.pattern})`)),d.push("aws-sam","serverless"),n.applications.forEach(u=>{c.push({name:u.name,technology:"aws-sam",framework:"aws-sam",runtime:"serverless",path:V.relative(r,u.path)||"."})}),n.pattern==="sam-multi-app"&&(p="monorepo")),o&&(console.log(O.default.gray(` \u2713 Detected JavaScript/TypeScript workspace (${o.pattern})`)),d.push("javascript","typescript","nodejs"),o.packages.forEach(u=>{u.framework!=="none"&&d.push(u.framework),c.push({name:u.name,technology:u.type,framework:u.framework,runtime:u.runtime,port:u.port,path:V.relative(r,u.path)||"."})}),o.pattern==="js-monorepo"&&(p="monorepo")),c.length===0){console.log(O.default.gray(" Using generic workspace detection..."));let u=await this.configService.discoverWorkspaces(r);if(u.length>0){let h=u[0];e.name=h.name,e.pattern=h.pattern,e.services=h.services.map(f=>({name:f.name,technology:f.technology,port:f.port,path:V.relative(r,f.path)||"."}))}}else e.name=V.basename(r),e.pattern=p,e.detectedTechnologies=[...new Set(d)],e.services=c;e.capabilities=await this.detectCapabilities(r,e.detectedTechnologies),e.tags=await this.suggestTags(r,e),e.detectedTechnologies&&e.detectedTechnologies.length>0&&console.log(O.default.gray(` Technologies: ${e.detectedTechnologies.join(", ")}`))}catch(t){s.warn("Failed to analyze workspace, will use defaults",{error:t,workspacePath:r}),e.name=V.basename(r),e.pattern="multi-repo",e.services=[],e.capabilities=[],e.tags=[]}return e}async collectWorkspaceInfo(r){console.log(O.default.blue(`
1049
+ \u{1F4CB} Workspace Configuration`)),console.log(O.default.gray(`Press Enter to accept suggested values
1050
+ `)),r.detectedTechnologies&&r.detectedTechnologies.length>0&&(console.log(O.default.cyan("Detected Technologies:")),console.log(` ${r.detectedTechnologies.map(n=>O.default.white(n)).join(", ")}`),console.log());let e=await(0,fe.default)([{type:"text",name:"name",message:"Workspace name:",initial:r.name||V.basename(process.cwd()),validate:n=>n.trim().length>0?!0:"Name is required"},{type:"text",name:"description",message:"Description (optional):",initial:this.generateDescription(r)},{type:"select",name:"pattern",message:"Workspace pattern:",choices:[{title:"Monorepo - Single repository with multiple services",value:"monorepo"},{title:"Multi-repo - Multiple related repositories",value:"multi-repo"},{title:"Hybrid - Mix of monorepo and multi-repo patterns",value:"hybrid"}],initial:r.pattern==="monorepo"?0:r.pattern==="hybrid"?2:1}]);if(!e.name)throw new Error("Workspace registration cancelled");let t=await this.collectServicesInfo(r.services||[]);if((await(0,fe.default)({type:"confirm",name:"manual",message:"Add services manually (if auto-detection missed anything)?",initial:!1})).manual){let n=await this.collectManualServices();t.push(...n)}let i=await(0,fe.default)([{type:"list",name:"capabilities",message:"Capabilities (comma-separated):",initial:(r.capabilities||[]).join(", "),separator:","},{type:"list",name:"tags",message:"Tags (comma-separated):",initial:(r.tags||[]).join(", "),separator:","}]);return{name:e.name,description:e.description||void 0,pattern:e.pattern,detectedTechnologies:r.detectedTechnologies,services:t,capabilities:i.capabilities?.filter(n=>n.trim())||[],tags:i.tags?.filter(n=>n.trim())||[]}}async collectServicesInfo(r){console.log(O.default.blue(`
1051
+ \u2699\uFE0F Services Configuration`));let e=[];if(r.length===0)return console.log(O.default.gray(" No services were automatically detected")),e;console.log(O.default.gray(` Found ${r.length} potential service(s)
1052
+ `));for(let t of r){let a=this.formatServiceDescription(t);if((await(0,fe.default)({type:"confirm",name:"include",message:`Include detected service: ${a}?`,initial:!0})).include){let n=await(0,fe.default)([{type:"text",name:"name",message:"Service name:",initial:t.name,validate:o=>o.trim().length>0?!0:"Name is required"},{type:"text",name:"technology",message:"Technology/Framework:",initial:t.technology},{type:"number",name:"port",message:"Port (optional):",initial:t.port,min:1,max:65535},{type:"text",name:"path",message:"Relative path:",initial:t.path||"."}]);n.name&&e.push({name:n.name,technology:n.technology||"unknown",framework:t.framework,runtime:t.runtime,port:n.port||void 0,path:n.path||"."})}}return e}async detectCapabilities(r,e){let t=[];try{e&&((e.includes("dotnet")||e.includes("csharp"))&&t.push("dotnet-development","enterprise-development"),e.includes("python")&&t.push("python-development"),e.includes("django")&&t.push("web-development","orm-development"),(e.includes("flask")||e.includes("fastapi"))&&t.push("api-development","microservices"),(e.includes("serverless")||e.includes("aws-sam"))&&t.push("serverless-development","cloud-native"),e.includes("react")&&t.push("frontend-development","spa-development"),e.includes("angular")&&t.push("frontend-development","enterprise-frontend"),e.includes("nodejs")&&t.push("backend-development","javascript-development"),e.includes("typescript")&&t.push("type-safe-development"));let a=V.join(r,"package.json");if(ee.existsSync(a)){t.push("nodejs-development");let i=JSON.parse(ee.readFileSync(a,"utf8")),n={...i.dependencies,...i.devDependencies};n.react&&t.push("react-development"),n.typescript&&t.push("typescript-development"),n.graphql&&t.push("graphql-api"),n.express&&t.push("rest-api"),(n.jest||n.vitest)&&t.push("automated-testing"),n.docker&&t.push("containerization")}(ee.existsSync(V.join(r,"requirements.txt"))||ee.existsSync(V.join(r,"pyproject.toml")))&&t.push("python-development"),ee.existsSync(V.join(r,"global.json"))&&t.push("dotnet-development"),ee.existsSync(V.join(r,"Dockerfile"))&&t.push("containerization"),ee.existsSync(V.join(r,".github"))&&t.push("ci-cd"),ee.existsSync(V.join(r,"docker-compose.yml"))&&t.push("multi-service-orchestration"),ee.existsSync(V.join(r,"serverless.yml"))&&t.push("serverless-development"),ee.existsSync(V.join(r,"template.yaml"))&&t.push("aws-sam-development")}catch(a){s.warn("Failed to detect capabilities",{error:a,workspacePath:r})}return[...new Set(t)]}async suggestTags(r,e){let t=[];e.pattern&&t.push(e.pattern),e.services?.forEach(i=>{i.technology&&!t.includes(i.technology)&&t.push(i.technology)});let a=e.name?.toLowerCase()||"";return a.includes("api")&&t.push("api"),a.includes("web")&&t.push("web"),a.includes("mobile")&&t.push("mobile"),a.includes("admin")&&t.push("admin"),a.includes("dashboard")&&t.push("dashboard"),t}async saveWorkspaceConfig(r,e){let t=V.join(r,"task-shepherd-workspace.json"),a={version:"1.0",workspace:{name:e.name,description:e.description,pattern:e.pattern,services:e.services.map(i=>({name:i.name,technology:i.technology,port:i.port,path:i.path})),capabilities:e.capabilities,tags:e.tags},metadata:{createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),configVersion:"1.0"}};try{await ee.promises.writeFile(t,JSON.stringify(a,null,2)+`
1053
+ `,"utf8"),console.log(O.default.green(`
1054
+ \u2705 Workspace configuration saved to ${O.default.bold("task-shepherd-workspace.json")}`))}catch(i){throw s.error("Failed to save workspace configuration",{error:i,configPath:t}),new Error(`Failed to save configuration: ${i instanceof Error?i.message:i}`)}}displaySummary(r,e){console.log(O.default.blue.bold(`
1055
+ \u{1F4CB} Registration Summary`)),console.log(O.default.gray("\u2550".repeat(40))),console.log(O.default.cyan("Workspace:")),console.log(` Name: ${O.default.white(e.name)}`),e.description&&console.log(` Description: ${O.default.white(e.description)}`),console.log(` Pattern: ${O.default.white(e.pattern)}`),e.services.length>0&&(console.log(O.default.cyan(`
1056
+ Services:`)),e.services.forEach(t=>{let a=t.framework?`${t.technology}/${t.framework}`:t.technology;console.log(` \u2022 ${O.default.white(t.name)} (${a})`),t.runtime&&t.runtime!==t.framework&&console.log(` Runtime: ${t.runtime}`),t.port&&console.log(` Port: ${t.port}`),t.path&&t.path!=="."&&console.log(` Path: ${t.path}`)})),e.capabilities&&e.capabilities.length>0&&(console.log(O.default.cyan(`
1057
+ Capabilities:`)),console.log(` ${e.capabilities.map(t=>O.default.white(t)).join(", ")}`)),e.tags&&e.tags.length>0&&(console.log(O.default.cyan(`
1058
+ Tags:`)),console.log(` ${e.tags.map(t=>O.default.white(t)).join(", ")}`)),console.log(O.default.cyan(`
1059
+ Next Steps:`)),console.log(` \u2022 Configuration saved to ${O.default.bold("task-shepherd-workspace.json")}`),console.log(" \u2022 Commit this file to version control"),console.log(` \u2022 Run ${O.default.bold("task-shepherd-agent workspace sync")} to sync with backend`),console.log()}generateDescription(r){if(!r.detectedTechnologies||r.detectedTechnologies.length===0)return"";let e=r.detectedTechnologies,t=[];return(e.includes("react")||e.includes("angular")||e.includes("vue"))&&t.push("frontend application"),e.includes("nodejs")&&(e.includes("express")||e.includes("fastify"))&&t.push("backend API"),e.includes("dotnet")&&t.push(".NET application"),e.includes("python")&&(e.includes("django")?t.push("Django web application"):e.includes("flask")||e.includes("fastapi")?t.push("Python API"):t.push("Python application")),(e.includes("serverless")||e.includes("aws-sam"))&&t.push("serverless application"),t.length===0?`Application built with ${e.slice(0,3).join(", ")}`:t.join(" and ")}formatServiceDescription(r){let e=`${O.default.cyan(r.name)}`;return r.framework&&r.framework!=="none"?e+=` (${r.framework})`:e+=` (${r.technology})`,r.port&&(e+=` on port ${r.port}`),r.path&&r.path!=="."&&(e+=` at ${r.path}`),e}async collectManualServices(){console.log(O.default.blue(`
1060
+ \u2795 Manual Service Entry`));let r=[],e=!0;for(;e;){let t=await(0,fe.default)([{type:"text",name:"name",message:"Service name:",validate:i=>i.trim().length>0?!0:"Name is required"},{type:"select",name:"technology",message:"Technology/Framework:",choices:[{title:"Node.js/Express",value:"nodejs-express"},{title:"React",value:"react"},{title:"Angular",value:"angular"},{title:"Vue.js",value:"vue"},{title:".NET Core API",value:"dotnet-webapi"},{title:".NET Core MVC",value:"dotnet-mvc"},{title:"Python/Django",value:"python-django"},{title:"Python/Flask",value:"python-flask"},{title:"Python/FastAPI",value:"python-fastapi"},{title:"AWS Lambda",value:"aws-lambda"},{title:"Serverless Function",value:"serverless-function"},{title:"Database",value:"database"},{title:"Other",value:"other"}]},{type:"text",name:"framework",message:"Framework (if different from technology):",initial:""},{type:"number",name:"port",message:"Port (optional):",min:1,max:65535},{type:"text",name:"path",message:"Relative path:",initial:"."}]);t.name&&r.push({name:t.name,technology:t.technology,framework:t.framework||void 0,port:t.port||void 0,path:t.path||"."}),e=(await(0,fe.default)({type:"confirm",name:"continue",message:"Add another service?",initial:!1})).continue}return r}}});var ir={};be(ir,{createDebugWorkItemCommand:()=>kn});function kn(){let l=new Di.Command("debug");return l.description("Debug work items and analyze error patterns").option("-i, --work-item-id <id>","Debug specific work item by ID").option("-t, --work-type <type>","Analyze error patterns for work type").option("-v, --verbose","Show detailed information").option("--timeline","Show execution timeline").option("--suggestions","Show fix suggestions").option("--export <format>","Export debug data (json|csv)").action(async r=>{try{r.workItemId?await vn(r.workItemId,r):r.workType?await In(r.workType,r):await wn(r)}catch(e){console.error(H.default.red("\u274C Debug command failed:"),e instanceof Error?e.message:e),process.exit(1)}}),l}async function vn(l,r){console.log(H.default.blue(`\u{1F50D} Debugging work item: ${l}
1061
+ `));try{let e=$e(),t=e.getErrorHistory(l),a=e.getLogHistory(l);if(t.length===0&&a.length===0){console.log(H.default.yellow("\u26A0\uFE0F No debug data found for this work item")),console.log(H.default.gray("This could mean:")),console.log(H.default.gray(" \u2022 Work item hasn't been processed yet")),console.log(H.default.gray(" \u2022 Work item ID is incorrect")),console.log(H.default.gray(" \u2022 Error tracking wasn't enabled when processed"));return}if(a.length>0){let i=a[0];console.log(H.default.green("\u{1F4CB} Work Item Information:")),console.log(` Work Type: ${i.workType}`),console.log(` Status: ${Mi(i.status)} ${i.status}`),console.log(` Worker ID: ${i.metadata.workerId}`),i.metadata.projectId&&console.log(` Project ID: ${i.metadata.projectId}`),console.log()}r.timeline&&a.length>0&&bn(a),t.length>0?An(t,r.verbose||!1):console.log(H.default.green("\u2705 No errors found for this work item")),r.suggestions&&t.length>0&&En(t),r.export&&await Tn(l,{errors:t,logs:a},r.export)}catch(e){console.error(H.default.red("\u274C Failed to debug work item:"),e instanceof Error?e.message:e)}}async function In(l,r){console.log(H.default.blue(`\u{1F4CA} Analyzing error patterns for work type: ${l}
1062
+ `));try{let t=$e().getFailurePattern(l);if(!t||t.frequency===0){console.log(H.default.yellow("\u26A0\uFE0F No error data found for this work type"));return}console.log(H.default.green("\u{1F4C8} Error Pattern Analysis:")),console.log(` Most Common Error: ${t.errorType}`),console.log(` Frequency: ${t.frequency} occurrences`),console.log(` Average Retry Count: ${t.averageRetryCount.toFixed(1)}`),console.log(` Success Rate After Retry: ${t.successRateAfterRetry.toFixed(1)}%`),console.log(),Object.keys(t.commonContext).length>0&&(console.log(H.default.cyan("\u{1F50D} Common Context Patterns:")),Object.entries(t.commonContext).forEach(([a,i])=>{console.log(` ${a}: ${i}`)}),console.log()),t.suggestedFixes.length>0&&(console.log(H.default.yellow("\u{1F4A1} Suggested Fixes:")),t.suggestedFixes.forEach((a,i)=>{console.log(` ${i+1}. ${a}`)}),console.log()),r.export&&await Cn(l,t,r.export)}catch(e){console.error(H.default.red("\u274C Failed to analyze work type:"),e instanceof Error?e.message:e)}}async function wn(l){console.log(H.default.blue(`\u{1F3E5} Work Item Health Overview
1063
+ `));try{let e=await $e().getHealthStatus();console.log(H.default.green("\u{1F4CA} Current Status:")),console.log(` Active Work Items: ${e.activeWorkItems}`),console.log(` Failed (24h): ${e.failedInLast24Hours}`),console.log(` Success Rate: ${e.successRate.toFixed(1)}%`),console.log(` Avg Processing Time: ${e.averageProcessingTime}ms`),console.log(),e.topErrors.length>0&&(console.log(H.default.red("\u{1F6A8} Top Errors (24h):")),e.topErrors.slice(0,5).forEach((t,a)=>{let i=Ni(t.lastOccurrence);console.log(` ${a+1}. ${t.type} (${t.count}x) - ${i}`)}),console.log()),console.log(H.default.cyan("\u{1F4BB} System Resources:")),console.log(` Memory Usage: ${e.systemResources.memoryUsage}MB`),console.log(` CPU Usage: ${e.systemResources.cpuUsage}%`),console.log(` Disk Space: ${e.systemResources.diskSpace}MB`),console.log(),console.log(H.default.magenta("\u{1F310} External Services:")),Object.entries(e.externalServices).forEach(([t,a])=>{console.log(` ${t}: ${a==="healthy"?"\u2705":a==="degraded"?"\u26A0\uFE0F":"\u274C"} ${a}`)}),console.log(),l.export&&await Pn(e,l.export)}catch(r){console.error(H.default.red("\u274C Failed to get health overview:"),r instanceof Error?r.message:r)}}function bn(l){console.log(H.default.cyan("\u23F1\uFE0F Execution Timeline:"));let r=l.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());r.forEach((e,t)=>{let a=e.timestamp.toLocaleTimeString(),i=e.duration?` (${Math.round(e.duration/1e3)}s)`:"",n=e.progress?.percentage?` - ${e.progress.percentage}%`:"";console.log(` ${a} ${Mi(e.status)} ${e.stage}${n}${i}`),e.errorData&&t<r.length-1&&console.log(H.default.red(` \u274C ${e.errorData.message}`))}),console.log()}function An(l,r){console.log(H.default.red(`\u{1F6A8} Errors Found (${l.length}):`)),l.slice(0,r?l.length:5).forEach((e,t)=>{let a=Ni(e.context.timestamp);console.log(`
1064
+ ${t+1}. ${e.errorType} (${e.metadata.severity})`),console.log(` Message: ${e.message}`),console.log(` Stage: ${e.stage}`),console.log(` Occurred: ${a}`),console.log(` Retryable: ${e.metadata.retryable?"\u2705":"\u274C"}`),r&&e.stack&&console.log(H.default.gray(` Stack: ${e.stack.split(`
1065
+ `)[0]}`)),e.metadata.tags.length>0&&console.log(` Tags: ${e.metadata.tags.join(", ")}`)}),!r&&l.length>5&&console.log(H.default.gray(`
1066
+ ... and ${l.length-5} more errors (use --verbose to see all)`)),console.log()}function En(l){let r=l[0];if(!r)return;console.log(H.default.yellow("\u{1F4A1} Suggested Fixes:")),Rn(r.errorType,r.metadata.category).forEach((t,a)=>{console.log(` ${a+1}. ${t}`)}),console.log()}async function Tn(l,r,e){let t=new Date().toISOString().replace(/[:.]/g,"-"),a=`work-item-debug-${l}-${t}.${e}`;try{let i=await import("fs/promises");if(e==="json")await i.writeFile(a,JSON.stringify(r,null,2));else if(e==="csv"){let n=r.errors.map(c=>`"${c.id}","${c.errorType}","${c.stage}","${c.message}","${c.context.timestamp}"`).join(`
1067
+ `);await i.writeFile(a,`ID,Error Type,Stage,Message,Timestamp
1068
+ `+n)}console.log(H.default.green(`\u2705 Debug data exported to: ${a}`))}catch(i){console.error(H.default.red("\u274C Failed to export debug data:"),i instanceof Error?i.message:i)}}async function Cn(l,r,e){let t=new Date().toISOString().replace(/[:.]/g,"-"),a=`work-type-analysis-${l}-${t}.${e}`;try{let i=await import("fs/promises");e==="json"&&await i.writeFile(a,JSON.stringify(r,null,2)),console.log(H.default.green(`\u2705 Pattern data exported to: ${a}`))}catch(i){console.error(H.default.red("\u274C Failed to export pattern data:"),i instanceof Error?i.message:i)}}async function Pn(l,r){let t=`health-overview-${new Date().toISOString().replace(/[:.]/g,"-")}.${r}`;try{let a=await import("fs/promises");r==="json"&&await a.writeFile(t,JSON.stringify(l,null,2)),console.log(H.default.green(`\u2705 Health data exported to: ${t}`))}catch(a){console.error(H.default.red("\u274C Failed to export health data:"),a instanceof Error?a.message:a)}}function Mi(l){switch(l){case"ASSIGNED":return"\u{1F4CB}";case"PROCESSING":return"\u2699\uFE0F";case"COMPLETED":return"\u2705";case"FAILED":return"\u274C";case"RETRYING":return"\u{1F504}";default:return"\u2753"}}function Ni(l){let e=new Date().getTime()-l.getTime(),t=Math.floor(e/(1e3*60)),a=Math.floor(t/60),i=Math.floor(a/24);return t<1?"just now":t<60?`${t}m ago`:a<24?`${a}h ago`:`${i}d ago`}function Rn(l,r){let e=[];switch(l){case"network_error":e.push("Check network connectivity"),e.push("Verify API endpoint URLs"),e.push("Increase request timeout");break;case"authentication_error":e.push("Refresh authentication token"),e.push("Verify API key is valid"),e.push("Check user permissions");break;case"claude_api_error":e.push("Check Claude API key"),e.push("Verify Claude CLI installation"),e.push("Check token usage limits");break;case"missing_project":e.push("Verify project ID exists in database"),e.push("Check project access permissions"),e.push("Refresh project data cache");break;case"timeout_error":e.push("Increase operation timeout"),e.push("Break down large operations"),e.push("Check system resource usage");break;default:e.push("Check logs for detailed error information"),e.push("Verify system configuration"),e.push("Contact system administrator")}return e}var Di,H,nr=M(()=>{"use strict";Di=require("commander"),H=A(require("chalk"));Rt();Tt()});var Mn={};be(Mn,{program:()=>ce});module.exports=ea(Mn);var xi=require("commander"),S=A(require("chalk"));var ca=A(require("readline")),R=A(require("chalk"));Ze();var et=class{constructor(){this.rl=ca.default.createInterface({input:process.stdin,output:process.stdout}),this.identityService=new Z}async run(){try{if(console.log(R.default.blue.bold(`
1069
+ \u{1F916} Task Shepherd AI Agent Setup Wizard`)),console.log(R.default.gray(`Let's configure your AI agent for optimal performance
1070
+ `)),!await this.checkExistingConfiguration())return;let e=await this.gatherConfiguration(),t=await this.identityService.initializeIdentity(e.identity);await this.saveConfiguration(e,t.agentId),this.showSummary(t,e),console.log(R.default.green.bold(`
1071
+ \u2705 Agent setup complete!`)),console.log(R.default.gray(`You can now start your agent with: npm run dev
1072
+ `))}catch(r){console.error(R.default.red(`
1073
+ \u274C Setup failed:`),r instanceof Error?r.message:r),process.exit(1)}finally{this.rl.close()}}async checkExistingConfiguration(){if(await this.identityService.identityExists()){let e=await this.ask(R.default.yellow("\u26A0\uFE0F An agent identity already exists. Do you want to reconfigure? (y/N): "));if(e.toLowerCase()!=="y"&&e.toLowerCase()!=="yes")return console.log(R.default.gray("Setup cancelled. Existing configuration preserved.")),!1;await this.identityService.resetIdentity()}return!0}async gatherConfiguration(){let r={identity:{strategy:"hostname",persistent:!0},backend:{apiUrl:"http://localhost:4002/graphql"},capabilities:[],features:{enableHeartbeat:!0,enableMetrics:!0,enableWebUI:!0},advanced:{heartbeatInterval:3e4,logLevel:"info",webPort:8548}};return await this.configureIdentity(r),await this.configureBackend(r),await this.configureCapabilities(r),await this.configureFeatures(r),await this.askBoolean("Configure advanced settings? (heartbeat interval, logging, etc.)",!1)&&await this.configureAdvanced(r),r}async configureIdentity(r){console.log(R.default.blue.bold(`
1074
+ \u{1F4DD} Step 1: Agent Identity`)),console.log(R.default.gray(`Choose how your agent will be identified in the system
1075
+ `));let e=this.identityService.getAvailableStrategies();console.log("Available identity strategies:"),e.forEach((n,o)=>{console.log(R.default.cyan(`${o+1}. ${n.strategy}`)+R.default.gray(` - ${n.description}`)),console.log(R.default.gray(` Example: ${n.example}
1076
+ `))});let t=await this.askChoice("Select identity strategy",e.map(n=>n.strategy),"hostname");if(r.identity.strategy=t,t==="user-configured"){let n=await this.ask("Enter a custom name for your agent: ");n.trim()&&(r.identity.customName=n.trim())}let a=await this.askBoolean("Include environment in agent ID? (dev, prod, etc.)",!0);if(r.identity.includeEnvironment=a,t==="hostname"||t==="hybrid"){let n=await this.askBoolean("Include username in agent ID?",!1);r.identity.includeUser=n}if(await this.askBoolean("Add prefix to agent ID?",!1)){let n=await this.ask("Enter prefix: ");n.trim()&&(r.identity.prefix=n.trim().toLowerCase().replace(/[^a-z0-9]/g,""))}console.log(R.default.green("\u2713 Identity configuration complete"))}async configureBackend(r){console.log(R.default.blue.bold(`
1077
+ \u{1F517} Step 2: Backend Connection`)),console.log(R.default.gray(`Configure connection to Task Shepherd backend
1078
+ `));let e="http://localhost:4002/graphql",t=await this.ask(`Backend GraphQL URL (${e}): `);if(r.backend.apiUrl=t.trim()||e,console.log(R.default.yellow(`
1079
+ \u{1F511} API Key Setup`)),console.log(R.default.gray("You need an API key to authenticate with the backend.")),console.log(R.default.gray("You can generate one in the Task Shepherd admin panel.")),await this.askBoolean("Do you have an API key?",!1)){let i=await this.askPassword("Enter API key: ");i.trim()&&(r.backend.apiKey=i.trim())}else console.log(R.default.yellow("\u26A0\uFE0F You can add an API key later in the configuration file."));console.log(R.default.green("\u2713 Backend configuration complete"))}async configureCapabilities(r){console.log(R.default.blue.bold(`
1080
+ \u26A1 Step 3: Agent Capabilities`)),console.log(R.default.gray(`Select what your agent can do
1081
+ `));let e=[{key:"project_review",name:"Project Review",description:"Analyze and review project requirements"},{key:"code_review",name:"Code Review",description:"Review code for quality and best practices"},{key:"development_planning",name:"Development Planning",description:"Create development plans and estimates"},{key:"story_implementation",name:"Story Implementation",description:"Implement user stories and features"},{key:"documentation",name:"Documentation",description:"Generate and maintain documentation"},{key:"testing",name:"Testing",description:"Create and execute tests"}];console.log("Available capabilities:"),e.forEach((a,i)=>{console.log(R.default.cyan(`${i+1}. ${a.name}`)+R.default.gray(` - ${a.description}`))}),console.log(R.default.gray(`
1082
+ Enter capability numbers separated by commas (e.g., 1,2,3):`));let t=await this.ask("Select capabilities: ");if(t.trim()){let a=t.split(",").map(i=>parseInt(i.trim())-1).filter(i=>i>=0&&i<e.length);r.capabilities=a.map(i=>e[i].key)}r.capabilities.length===0&&(console.log(R.default.yellow("\u26A0\uFE0F No capabilities selected. Adding default project_review capability.")),r.capabilities=["project_review"]),console.log(R.default.green(`\u2713 Selected capabilities: ${r.capabilities.join(", ")}`))}async configureFeatures(r){console.log(R.default.blue.bold(`
1083
+ \u{1F6E0}\uFE0F Step 4: Features`)),console.log(R.default.gray(`Enable/disable agent features
1084
+ `)),r.features.enableHeartbeat=await this.askBoolean("Enable heartbeat monitoring?",!0),r.features.enableMetrics=await this.askBoolean("Enable performance metrics collection?",!0),r.features.enableWebUI=await this.askBoolean("Enable web dashboard?",!0),console.log(R.default.green("\u2713 Features configured"))}async configureAdvanced(r){if(console.log(R.default.blue.bold(`
1085
+ \u{1F527} Step 5: Advanced Settings`)),console.log(R.default.gray(`Fine-tune agent behavior
1086
+ `)),r.features.enableHeartbeat){let t=await this.askNumber("Heartbeat interval (seconds)",30);r.advanced.heartbeatInterval=t*1e3}let e=await this.askChoice("Log level",["error","warn","info","debug"],"info");if(r.advanced.logLevel=e,r.features.enableWebUI){let t=await this.askNumber("Web dashboard port",8548);r.advanced.webPort=t}console.log(R.default.green("\u2713 Advanced settings configured"))}async saveConfiguration(r,e){console.log(R.default.blue.bold(`
1087
+ \u{1F4BE} Saving Configuration...`));let t=this.generateEnvContent(r,e),a=".env";require("fs").writeFileSync(a,t),console.log(R.default.green(`\u2713 Configuration saved to ${a}`))}generateEnvContent(r,e){let t=["# AI Worker Service Configuration",`AGENT_ID=${e}`,`AGENT_NAME=${r.identity.customName||"AI Agent"}`,"PORT=8547","NODE_ENV=production","","# Task Shepherd API Configuration",`TASK_SHEPHERD_API_URL=${r.backend.apiUrl}`];return r.backend.apiKey?t.push(`TASK_SHEPHERD_API_KEY=${r.backend.apiKey}`):t.push("# TASK_SHEPHERD_API_KEY=your-api-key-here"),t.push("","# Agent Features",`ENABLE_HEARTBEAT=${r.features.enableHeartbeat}`,`ENABLE_METRICS=${r.features.enableMetrics}`,`ENABLE_WEB_UI=${r.features.enableWebUI}`,"","# Agent Capabilities",`AGENT_CAPABILITIES=${r.capabilities.join(",")}`,"","# Advanced Settings",`HEARTBEAT_INTERVAL=${r.advanced.heartbeatInterval}`,`LOG_LEVEL=${r.advanced.logLevel}`,`WEB_PORT=${r.advanced.webPort}`,"","# Redis Configuration","REDIS_URL=redis://localhost:6379","","# Claude CLI Configuration (Primary Method)","CLAUDE_COMMAND_PATH=/Users/$USER/.claude/local/claude","","# Claude API Configuration (Optional - Enables Enhanced Features)","# ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}","# ANTHROPIC_BASE_URL=https://api.anthropic.com","# CLAUDE_MODEL=claude-3-5-sonnet-20241022","# CLAUDE_MAX_RETRIES=3","# CLAUDE_TIMEOUT_MS=60000","","# Service Configuration","MAX_CONCURRENT_JOBS=3","TOKEN_RATE_LIMIT=10000",""),t.join(`
1088
+ `)}showSummary(r,e){console.log(R.default.blue.bold(`
1089
+ \u{1F4CB} Configuration Summary`)),console.log(R.default.gray("\u2550".repeat(50))),console.log(R.default.cyan("Agent Identity:")),console.log(` ID: ${R.default.white(r.agentId)}`),console.log(` Name: ${R.default.white(r.agentName)}`),console.log(` Strategy: ${R.default.white(e.identity.strategy)}`),console.log(R.default.cyan(`
1090
+ Backend Connection:`)),console.log(` URL: ${R.default.white(e.backend.apiUrl)}`),console.log(` API Key: ${e.backend.apiKey?R.default.green("\u2713 Configured"):R.default.yellow("\u26A0\uFE0F Not set")}`),console.log(R.default.cyan(`
1091
+ Capabilities:`)),e.capabilities.forEach(t=>{console.log(` \u2022 ${R.default.white(t)}`)}),console.log(R.default.cyan(`
1092
+ Features:`)),console.log(` Heartbeat: ${e.features.enableHeartbeat?R.default.green("\u2713"):R.default.red("\u2717")}`),console.log(` Metrics: ${e.features.enableMetrics?R.default.green("\u2713"):R.default.red("\u2717")}`),console.log(` Web UI: ${e.features.enableWebUI?R.default.green("\u2713"):R.default.red("\u2717")}`),e.features.enableWebUI&&(console.log(R.default.cyan(`
1093
+ Web Dashboard:`)),console.log(` URL: ${R.default.white(`http://localhost:${e.advanced.webPort}`)}`))}ask(r){return new Promise(e=>{this.rl.question(r,e)})}async askPassword(r){return this.ask(r)}async askBoolean(r,e=!1){let t=e?"Y/n":"y/N",a=await this.ask(`${r} (${t}): `);return a.trim()?a.toLowerCase().startsWith("y"):e}async askNumber(r,e){let t=await this.ask(`${r} (${e}): `);if(!t.trim())return e;let a=parseInt(t);return isNaN(a)?e:a}async askChoice(r,e,t){let a=e.map((d,p)=>`${p+1}. ${d}`).join(", "),i=t?` (default: ${t})`:"",n=await this.ask(`${r} [${a}]${i}: `);if(!n.trim()&&t)return t;let o=parseInt(n)-1;if(o>=0&&o<e.length)return e[o];let c=e.find(d=>d.toLowerCase()===n.toLowerCase());return c||t||e[0]}};require.main===module&&new et().run().catch(r=>{console.error(R.default.red("Wizard failed:"),r),process.exit(1)});Ze();var pa=require("events");Ze();var la=require("events");j();var Le=A(require("os")),Te=A(require("process")),kt=class extends la.EventEmitter{constructor(e,t,a,i={}){super();this.responseTimes=[];this.maxResponseTimeHistory=50;this.metricsProviders=new Map;this.workerId=e,this.tokenTracker=t,this.httpClient=a,this.options={interval:3e4,timeout:1e4,retryAttempts:3,retryDelay:5e3,enableMetrics:!0,preferWebSocket:!0,fallbackToHttp:!0,...i},this.metrics=this.getInitialMetrics(),this.status={isRunning:!1,consecutiveFailures:0,totalSent:0,totalSuccessful:0,totalFailed:0,averageResponseTime:0,currentStatus:"offline"},this.setupDefaultMetricsProviders()}start(){if(this.intervalId){s.warn("Heartbeat service is already running",{workerId:this.workerId,service:"heartbeat"});return}s.info("Starting heartbeat service",{workerId:this.workerId,interval:this.options.interval,service:"heartbeat"}),this.status.isRunning=!0,this.status.currentStatus="healthy",this.sendHeartbeat(),this.intervalId=setInterval(()=>{this.sendHeartbeat()},this.options.interval),this.emit("started",{workerId:this.workerId})}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0),this.status.isRunning=!1,this.status.currentStatus="offline",s.info("Heartbeat service stopped",{workerId:this.workerId,service:"heartbeat"}),this.emit("stopped",{workerId:this.workerId})}async sendHeartbeat(){let e=Date.now();try{await this.collectMetrics();let t={workerId:this.workerId,timestamp:new Date().toISOString(),isHealthy:this.isAgentHealthy(),metrics:this.options.enableMetrics?this.metrics:void 0,status:this.determineAgentStatus(),version:Te.default.env.npm_package_version||"1.0.0",localWorkState:await this.collectLocalWorkState()},a=await this.sendHeartbeatMessage(t),i=Date.now()-e;return this.updateResponseTimeHistory(i),a?(this.handleHeartbeatSuccess(),this.emit("heartbeat_sent",{workerId:this.workerId,responseTime:i,metrics:this.metrics})):(this.handleHeartbeatFailure(),this.emit("heartbeat_failed",{workerId:this.workerId,consecutiveFailures:this.status.consecutiveFailures})),a}catch(t){let a=Date.now()-e;return this.updateResponseTimeHistory(a),this.handleHeartbeatFailure(),s.error("Heartbeat error",{workerId:this.workerId,error:t instanceof Error?t.message:String(t),responseTime:a,service:"heartbeat"}),this.emit("heartbeat_error",{workerId:this.workerId,error:t,consecutiveFailures:this.status.consecutiveFailures}),!1}}async sendHeartbeatMessage(e){if(this.httpClient)return this.sendHttpHeartbeat(e);throw new Error("No available heartbeat transport (WebSocket failed and HTTP not configured)")}async sendHttpHeartbeat(e){s.debug("Sending heartbeat via HTTP GraphQL",{workerId:this.workerId,service:"heartbeat"});let t=0;for(;t<this.options.retryAttempts;)try{let a=`
115
1094
  mutation UpdateWorkerHeartbeat($input: WorkerHeartbeatInput!) {
116
1095
  updateWorkerHeartbeat(input: $input)
117
1096
  }
118
- `,n={input:{workerId:e.workerId,isHealthy:e.isHealthy,cpuUsage:e.metrics?.cpuUsage,memoryUsage:e.metrics?.memoryUsage,responseTime:this.status.averageResponseTime||void 0,errorRate:this.getErrorRate(),localWorkState:e.localWorkState||void 0}};if((await this.httpClient?.mutate({query:s,variables:n}))?.data?.updateAIWorkerHeartbeat?.success)return c.debug("AI Worker heartbeat sent successfully",{workerId:this.workerId,service:"heartbeat"}),!0;throw new Error("AI Worker heartbeat failed")}catch(s){if(r++,r<this.options.retryAttempts)c.warn(`HTTP heartbeat attempt ${r} failed, retrying in ${this.options.retryDelay}ms`,{workerId:this.workerId,error:s instanceof Error?s.message:String(s),service:"heartbeat"}),await this.sleep(this.options.retryDelay);else throw s}return!1}async collectMetrics(){try{let e=K.default.memoryUsage(),r=ee.default.freemem(),s=await this.getCPUUsage();this.metrics={cpuUsage:s,memoryUsage:Math.round(e.heapUsed/1024/1024),freeMemory:Math.round(r/1024/1024),uptime:Math.round(K.default.uptime()),activeConnections:this.getActiveConnectionsCount(),queueSize:this.getQueueSize(),completedTasks:this.getCompletedTasksCount(),failedTasks:this.getFailedTasksCount(),lastActivity:this.getLastActivityTimestamp(),customMetrics:await this.collectCustomMetrics()}}catch(e){c.warn("Failed to collect metrics",{workerId:this.workerId,error:e instanceof Error?e.message:String(e),service:"heartbeat"}),this.metrics=this.getInitialMetrics()}}async getCPUUsage(){return new Promise(e=>{let r=K.default.cpuUsage();setTimeout(()=>{let s=K.default.cpuUsage(r),i=(s.user+s.system)/1e6/.1*100;e(Math.min(100,Math.max(0,i)))},100)})}setupDefaultMetricsProviders(){this.metricsProviders.set("tokenUsage",async()=>{let e=this.tokenTracker.getDailyUsage();return{totalTokens:e.totalTokens,totalCost:e.totalCost,requestsToday:e.operationCount}}),this.metricsProviders.set("systemLoad",async()=>{let e=ee.default.loadavg();return{load1m:e[0],load5m:e[1],load15m:e[2],platform:ee.default.platform(),arch:ee.default.arch()}})}async collectCustomMetrics(){let e={};for(let[r,s]of this.metricsProviders.entries())try{e[r]=await s()}catch(n){c.warn(`Failed to collect custom metric: ${r}`,{workerId:this.workerId,error:n instanceof Error?n.message:String(n),service:"heartbeat"})}return e}addMetricsProvider(e,r){this.metricsProviders.set(e,r),c.info(`Added custom metrics provider: ${e}`,{workerId:this.workerId,service:"heartbeat"})}removeMetricsProvider(e){this.metricsProviders.delete(e),c.info(`Removed custom metrics provider: ${e}`,{workerId:this.workerId,service:"heartbeat"})}isAgentHealthy(){let e=K.default.memoryUsage(),r=e.heapUsed/1024/1024,s=e.heapTotal*1.5/1024/1024;return!(r>s||this.getQueueSize()>100||this.status.consecutiveFailures>=5)}determineAgentStatus(){return this.isAgentHealthy()?this.getQueueSize()>0?"WORKING":Date.now()-(this.getLastActivityTime()||0)<3e5?"ACTIVE":"IDLE":"UNHEALTHY"}handleHeartbeatSuccess(){this.status.lastHeartbeat=new Date,this.status.lastSuccessfulHeartbeat=new Date,this.status.consecutiveFailures=0,this.status.totalSent++,this.status.totalSuccessful++,this.status.currentStatus="healthy"}handleHeartbeatFailure(){this.status.lastHeartbeat=new Date,this.status.consecutiveFailures++,this.status.totalSent++,this.status.totalFailed++,this.status.consecutiveFailures>=5?this.status.currentStatus="critical":this.status.consecutiveFailures>=3&&(this.status.currentStatus="warning")}updateResponseTimeHistory(e){this.responseTimes.push(e),this.responseTimes.length>this.maxResponseTimeHistory&&this.responseTimes.shift(),this.status.averageResponseTime=this.responseTimes.reduce((r,s)=>r+s,0)/this.responseTimes.length}getStatus(){return{...this.status}}getMetrics(){return{...this.metrics}}updateOptions(e){let r=this.status.isRunning;r&&this.stop(),this.options={...this.options,...e},r&&this.start(),c.info("Heartbeat options updated",{workerId:this.workerId,options:this.options,service:"heartbeat"})}async forceHealthCheck(){return await this.collectMetrics(),this.getMetrics()}getInitialMetrics(){return{cpuUsage:0,memoryUsage:0,freeMemory:Math.round(ee.default.freemem()/1024/1024),uptime:Math.round(K.default.uptime()),activeConnections:0,queueSize:0,completedTasks:0,failedTasks:0}}getActiveConnectionsCount(){return 1}getQueueSize(){return 0}getCompletedTasksCount(){return 0}getFailedTasksCount(){return 0}getLastActivityTimestamp(){return new Date().toISOString()}getLastActivityTime(){return Date.now()}sleep(e){return new Promise(r=>setTimeout(r,e))}getErrorRate(){return this.status.totalSent===0?0:this.status.totalFailed/this.status.totalSent}setSubscriptionHandler(e){this.subscriptionHandler=e}setCompletedWorkService(e){this.completedWorkService=e}async collectLocalWorkState(){let e=[];try{if(this.subscriptionHandler&&typeof this.subscriptionHandler.getActiveAssignments=="function"){let r=this.subscriptionHandler.getActiveAssignments();for(let s of r)e.push({workItemId:s.workItemId,status:s.status==="in_progress"?"in_progress":s.status,startedAt:s.startedAt?.toISOString(),completedAt:s.completedAt?.toISOString(),lastUpdate:new Date().toISOString()})}if(this.completedWorkService&&typeof this.completedWorkService.getCompletedItems=="function"){let r=this.completedWorkService.getCompletedItems(5,0);if(r&&r.items)for(let s of r.items){let n=new Date(s.completedAt).getTime(),i=Date.now()-30*60*1e3;n>i&&e.push({workItemId:s.id,status:s.status==="completed"?"completed":"failed",startedAt:s.startedAt,completedAt:s.completedAt,lastUpdate:new Date().toISOString()})}}return e}catch(r){return c.warn("Failed to collect local work state for heartbeat",{workerId:this.workerId,error:r instanceof Error?r.message:String(r),service:"heartbeat"}),[]}}};R();var qe=h(require("os")),ve=class extends yt.EventEmitter{constructor(e,r,s){super();this.registered=!1;this.httpClient=e,this.tokenTracker=r,this.identityService=s||new N}async initializeAndRegister(e){let r=await this.ensureAgentIdentity();return this.registerWorker(r,e)}async registerWorker(e,r){this.currentIdentity=e,c.info("Registering AI Agent with Task Shepherd backend",{workerId:e.agentId,workerName:e.agentName,capabilities:r.capabilities,scope:r.scope||"USER",service:"worker-registration"});let s=r.scopeId,n=r.scope||"USER";if(n==="USER"&&!s){let l=0,u=3;for(;l<u;){try{c.debug("Attempting to retrieve authenticated user ID",{attempt:l+1,maxRetries:u});let p=await this.httpClient.query({query:"query { me { id email } }",variables:{}});if(p.data?.me?.id){s=p.data.me.id,c.debug("Retrieved authenticated user ID for worker registration",{userId:s,userEmail:p.data.me.email});break}else if(c.warn("Received empty user response, retrying",{response:p,attempt:l+1}),l===u-1)return c.error("Failed to retrieve authenticated user ID after all retries",{response:p}),{success:!1,message:"Failed to retrieve authenticated user ID for registration - user may not be authenticated"}}catch(m){let p=m instanceof Error?m.message:String(m);if(c.warn("Failed to query authenticated user",{error:p,attempt:l+1,maxRetries:u}),p.toLowerCase().includes("unauthorized")||p.toLowerCase().includes("401")||p.toLowerCase().includes("authentication"))return c.error("Authentication failed - invalid API key or token",{error:p}),{success:!1,message:"Authentication failed - please check API key configuration"};if(l===u-1)return c.error("Failed to authenticate with backend after all retries",{error:p}),{success:!1,message:`Failed to authenticate with backend: ${p}`}}if(l++,l<u){let m=Math.min(1e3*Math.pow(2,l),5e3);c.debug("Waiting before retry",{delay:m,nextAttempt:l+1}),await new Promise(p=>setTimeout(p,m))}}}let i=`
1097
+ `,i={input:{workerId:e.workerId,isHealthy:e.isHealthy,cpuUsage:e.metrics?.cpuUsage,memoryUsage:e.metrics?.memoryUsage,responseTime:this.status.averageResponseTime||void 0,errorRate:this.getErrorRate(),localWorkState:e.localWorkState||void 0}};if((await this.httpClient?.mutate({query:a,variables:i}))?.data?.updateAIWorkerHeartbeat?.success)return s.debug("AI Worker heartbeat sent successfully",{workerId:this.workerId,service:"heartbeat"}),!0;throw new Error("AI Worker heartbeat failed")}catch(a){if(t++,t<this.options.retryAttempts)s.warn(`HTTP heartbeat attempt ${t} failed, retrying in ${this.options.retryDelay}ms`,{workerId:this.workerId,error:a instanceof Error?a.message:String(a),service:"heartbeat"}),await this.sleep(this.options.retryDelay);else throw a}return!1}async collectMetrics(){try{let e=Te.default.memoryUsage(),t=Le.default.freemem(),a=await this.getCPUUsage();this.metrics={cpuUsage:a,memoryUsage:Math.round(e.heapUsed/1024/1024),freeMemory:Math.round(t/1024/1024),uptime:Math.round(Te.default.uptime()),activeConnections:this.getActiveConnectionsCount(),queueSize:this.getQueueSize(),completedTasks:this.getCompletedTasksCount(),failedTasks:this.getFailedTasksCount(),lastActivity:this.getLastActivityTimestamp(),customMetrics:await this.collectCustomMetrics()}}catch(e){s.warn("Failed to collect metrics",{workerId:this.workerId,error:e instanceof Error?e.message:String(e),service:"heartbeat"}),this.metrics=this.getInitialMetrics()}}async getCPUUsage(){return new Promise(e=>{let t=Te.default.cpuUsage();setTimeout(()=>{let a=Te.default.cpuUsage(t),n=(a.user+a.system)/1e6/.1*100;e(Math.min(100,Math.max(0,n)))},100)})}setupDefaultMetricsProviders(){this.metricsProviders.set("tokenUsage",async()=>{let e=this.tokenTracker.getDailyUsage();return{totalTokens:e.totalTokens,totalCost:e.totalCost,requestsToday:e.operationCount}}),this.metricsProviders.set("systemLoad",async()=>{let e=Le.default.loadavg();return{load1m:e[0],load5m:e[1],load15m:e[2],platform:Le.default.platform(),arch:Le.default.arch()}})}async collectCustomMetrics(){let e={};for(let[t,a]of this.metricsProviders.entries())try{e[t]=await a()}catch(i){s.warn(`Failed to collect custom metric: ${t}`,{workerId:this.workerId,error:i instanceof Error?i.message:String(i),service:"heartbeat"})}return e}addMetricsProvider(e,t){this.metricsProviders.set(e,t),s.info(`Added custom metrics provider: ${e}`,{workerId:this.workerId,service:"heartbeat"})}removeMetricsProvider(e){this.metricsProviders.delete(e),s.info(`Removed custom metrics provider: ${e}`,{workerId:this.workerId,service:"heartbeat"})}isAgentHealthy(){let e=Te.default.memoryUsage(),t=e.heapUsed/1024/1024,a=e.heapTotal*1.5/1024/1024;return!(t>a||this.getQueueSize()>100||this.status.consecutiveFailures>=5)}determineAgentStatus(){return this.isAgentHealthy()?this.getQueueSize()>0?"WORKING":Date.now()-(this.getLastActivityTime()||0)<3e5?"ACTIVE":"IDLE":"UNHEALTHY"}handleHeartbeatSuccess(){this.status.lastHeartbeat=new Date,this.status.lastSuccessfulHeartbeat=new Date,this.status.consecutiveFailures=0,this.status.totalSent++,this.status.totalSuccessful++,this.status.currentStatus="healthy"}handleHeartbeatFailure(){this.status.lastHeartbeat=new Date,this.status.consecutiveFailures++,this.status.totalSent++,this.status.totalFailed++,this.status.consecutiveFailures>=5?this.status.currentStatus="critical":this.status.consecutiveFailures>=3&&(this.status.currentStatus="warning")}updateResponseTimeHistory(e){this.responseTimes.push(e),this.responseTimes.length>this.maxResponseTimeHistory&&this.responseTimes.shift(),this.status.averageResponseTime=this.responseTimes.reduce((t,a)=>t+a,0)/this.responseTimes.length}getStatus(){return{...this.status}}getMetrics(){return{...this.metrics}}updateOptions(e){let t=this.status.isRunning;t&&this.stop(),this.options={...this.options,...e},t&&this.start(),s.info("Heartbeat options updated",{workerId:this.workerId,options:this.options,service:"heartbeat"})}async forceHealthCheck(){return await this.collectMetrics(),this.getMetrics()}getInitialMetrics(){return{cpuUsage:0,memoryUsage:0,freeMemory:Math.round(Le.default.freemem()/1024/1024),uptime:Math.round(Te.default.uptime()),activeConnections:0,queueSize:0,completedTasks:0,failedTasks:0}}getActiveConnectionsCount(){return 1}getQueueSize(){return 0}getCompletedTasksCount(){return 0}getFailedTasksCount(){return 0}getLastActivityTimestamp(){return new Date().toISOString()}getLastActivityTime(){return Date.now()}sleep(e){return new Promise(t=>setTimeout(t,e))}getErrorRate(){return this.status.totalSent===0?0:this.status.totalFailed/this.status.totalSent}setSubscriptionHandler(e){this.subscriptionHandler=e}setCompletedWorkService(e){this.completedWorkService=e}async collectLocalWorkState(){let e=[];try{if(this.subscriptionHandler&&typeof this.subscriptionHandler.getActiveAssignments=="function"){let t=this.subscriptionHandler.getActiveAssignments();for(let a of t)e.push({workItemId:a.workItemId,status:a.status==="in_progress"?"in_progress":a.status,startedAt:a.startedAt?.toISOString(),completedAt:a.completedAt?.toISOString(),lastUpdate:new Date().toISOString()})}if(this.completedWorkService&&typeof this.completedWorkService.getCompletedItems=="function"){let t=this.completedWorkService.getCompletedItems(5,0);if(t&&t.items)for(let a of t.items){let i=new Date(a.completedAt).getTime(),n=Date.now()-30*60*1e3;i>n&&e.push({workItemId:a.id,status:a.status==="completed"?"completed":"failed",startedAt:a.startedAt,completedAt:a.completedAt,lastUpdate:new Date().toISOString()})}}return e}catch(t){return s.warn("Failed to collect local work state for heartbeat",{workerId:this.workerId,error:t instanceof Error?t.message:String(t),service:"heartbeat"}),[]}}};j();var kr=A(require("os")),vt=class extends pa.EventEmitter{constructor(e,t,a){super();this.registered=!1;this.httpClient=e,this.tokenTracker=t,this.identityService=a||new Z}async initializeAndRegister(e){let t=await this.ensureAgentIdentity();return this.registerWorker(t,e)}async registerWorker(e,t){this.currentIdentity=e,s.info("Registering AI Agent with Task Shepherd backend",{workerId:e.agentId,workerName:e.agentName,capabilities:t.capabilities,scope:t.scope||"USER",service:"worker-registration"});let a=t.scopeId,i=t.scope||"USER";if(i==="USER"&&!a){let c=0,d=3;for(;c<d;){try{s.debug("Attempting to retrieve authenticated user ID",{attempt:c+1,maxRetries:d});let u=await this.httpClient.query({query:"query { me { id email } }",variables:{}});if(u.data?.me?.id){a=u.data.me.id,s.debug("Retrieved authenticated user ID for worker registration",{userId:a,userEmail:u.data.me.email});break}else if(s.warn("Received empty user response, retrying",{response:u,attempt:c+1}),c===d-1)return s.error("Failed to retrieve authenticated user ID after all retries",{response:u}),{success:!1,message:"Failed to retrieve authenticated user ID for registration - user may not be authenticated"}}catch(p){let u=p instanceof Error?p.message:String(p);if(s.warn("Failed to query authenticated user",{error:u,attempt:c+1,maxRetries:d}),u.toLowerCase().includes("unauthorized")||u.toLowerCase().includes("401")||u.toLowerCase().includes("authentication"))return s.error("Authentication failed - invalid API key or token",{error:u}),{success:!1,message:"Authentication failed - please check API key configuration"};if(c===d-1)return s.error("Failed to authenticate with backend after all retries",{error:u}),{success:!1,message:`Failed to authenticate with backend: ${u}`}}if(c++,c<d){let p=Math.min(1e3*Math.pow(2,c),5e3);s.debug("Waiting before retry",{delay:p,nextAttempt:c+1}),await new Promise(u=>setTimeout(u,p))}}}let n=`
119
1098
  mutation RegisterWorker($input: WorkerRegistrationInput!) {
120
1099
  registerWorker(input: $input)
121
1100
  }
122
- `,o={input:{workerId:e.agentId,workerName:e.agentName,capabilities:this.mapCapabilities(r.capabilities),scope:n,scopeId:s||"",maxConcurrentTasks:r.maxConcurrentTasks,metadata:{hostname:e.hostname,platform:e.platform,environment:e.environment,version:e.version,userId:e.userId,createdAt:e.createdAt}}};try{if((await this.httpClient.mutate({query:i,variables:o})).data?.registerWorker)return this.registered=!0,c.info("AI Agent registered successfully",{workerId:e.agentId,status:"ACTIVE",service:"worker-registration"}),r.enableHeartbeat!==!1&&await this.initializeHeartbeat(e,r),await this.identityService.updateIdentity({lastUsed:new Date().toISOString()}),this.emit("registered",{workerId:e.agentId,identity:e}),{success:!0,message:"Worker registered successfully",workerId:e.agentId,identity:e};{let u="Registration failed";return c.error("Worker registration failed",{error:u}),{success:!1,message:u}}}catch(l){return c.error("Worker registration error",{error:l instanceof Error?l.message:String(l),workerId:e.agentId,service:"worker-registration"}),{success:!1,message:l instanceof Error?l.message:"Registration request failed"}}}async ensureAgentIdentity(){let e=process.env.AGENT_ID,r=process.env.AGENT_NAME;if(e&&r){let i={agentId:e,agentName:r,hostname:qe.default.hostname(),platform:qe.default.platform(),environment:"production",createdAt:new Date().toISOString(),lastUsed:new Date().toISOString(),version:process.env.npm_package_version||"1.0.0"};return c.info("Using environment-configured agent identity",{agentId:i.agentId,agentName:i.agentName,service:"worker-registration"}),i}let s=this.identityService.getCurrentIdentity();return s?(c.info("Using existing agent identity",{agentId:s.agentId,agentName:s.agentName,service:"worker-registration"}),s):(c.info("Generating new agent identity with default configuration",{service:"worker-registration"}),await this.identityService.initializeIdentity({strategy:"hybrid",includeEnvironment:!0,persistent:!0}))}async initializeHeartbeat(e,r){this.heartbeatService&&this.heartbeatService.stop(),this.heartbeatService=new ye(e.agentId,this.tokenTracker,this.httpClient,{interval:r.heartbeatInterval||3e4,enableMetrics:!0,retryAttempts:3,timeout:1e4,retryDelay:5e3,preferWebSocket:!0,fallbackToHttp:!0}),this.heartbeatService.on("heartbeat_sent",s=>{c.debug("Heartbeat sent successfully",{workerId:s.workerId,responseTime:s.responseTime,service:"worker-registration"})}),this.heartbeatService.on("heartbeat_failed",s=>{c.warn("Heartbeat failed",{workerId:s.workerId,consecutiveFailures:s.consecutiveFailures,service:"worker-registration"}),s.consecutiveFailures>=5&&this.emit("heartbeatCritical",s)}),this.heartbeatService.on("heartbeat_error",s=>{c.error("Heartbeat error",{workerId:s.workerId,error:s.error instanceof Error?s.error.message:String(s.error),service:"worker-registration"})}),this.heartbeatService.start(),c.info("Heartbeat service initialized and started",{workerId:e.agentId,interval:r.heartbeatInterval||3e4,service:"worker-registration"})}async unregisterWorker(){if(!this.registered||!this.currentIdentity)return;let e=this.currentIdentity.agentId;c.info("Unregistering AI Agent",{workerId:e,service:"worker-registration"});let r=`
1101
+ `,o={input:{workerId:e.agentId,workerName:e.agentName,capabilities:this.mapCapabilities(t.capabilities),scope:i,scopeId:a||"",maxConcurrentTasks:t.maxConcurrentTasks,metadata:{hostname:e.hostname,platform:e.platform,environment:e.environment,version:e.version,userId:e.userId,createdAt:e.createdAt}}};try{if((await this.httpClient.mutate({query:n,variables:o})).data?.registerWorker)return this.registered=!0,s.info("AI Agent registered successfully",{workerId:e.agentId,status:"ACTIVE",service:"worker-registration"}),t.enableHeartbeat!==!1&&await this.initializeHeartbeat(e,t),await this.identityService.updateIdentity({lastUsed:new Date().toISOString()}),this.emit("registered",{workerId:e.agentId,identity:e}),{success:!0,message:"Worker registered successfully",workerId:e.agentId,identity:e};{let d="Registration failed";return s.error("Worker registration failed",{error:d}),{success:!1,message:d}}}catch(c){return s.error("Worker registration error",{error:c instanceof Error?c.message:String(c),workerId:e.agentId,service:"worker-registration"}),{success:!1,message:c instanceof Error?c.message:"Registration request failed"}}}async ensureAgentIdentity(){let e=process.env.AGENT_ID,t=process.env.AGENT_NAME;if(e&&t){let n={agentId:e,agentName:t,hostname:kr.default.hostname(),platform:kr.default.platform(),environment:"production",createdAt:new Date().toISOString(),lastUsed:new Date().toISOString(),version:process.env.npm_package_version||"1.0.0"};return s.info("Using environment-configured agent identity",{agentId:n.agentId,agentName:n.agentName,service:"worker-registration"}),n}let a=this.identityService.getCurrentIdentity();return a?(s.info("Using existing agent identity",{agentId:a.agentId,agentName:a.agentName,service:"worker-registration"}),a):(s.info("Generating new agent identity with default configuration",{service:"worker-registration"}),await this.identityService.initializeIdentity({strategy:"hybrid",includeEnvironment:!0,persistent:!0}))}async initializeHeartbeat(e,t){this.heartbeatService&&this.heartbeatService.stop(),this.heartbeatService=new kt(e.agentId,this.tokenTracker,this.httpClient,{interval:t.heartbeatInterval||3e4,enableMetrics:!0,retryAttempts:3,timeout:1e4,retryDelay:5e3,preferWebSocket:!0,fallbackToHttp:!0}),this.heartbeatService.on("heartbeat_sent",a=>{s.debug("Heartbeat sent successfully",{workerId:a.workerId,responseTime:a.responseTime,service:"worker-registration"})}),this.heartbeatService.on("heartbeat_failed",a=>{s.warn("Heartbeat failed",{workerId:a.workerId,consecutiveFailures:a.consecutiveFailures,service:"worker-registration"}),a.consecutiveFailures>=5&&this.emit("heartbeatCritical",a)}),this.heartbeatService.on("heartbeat_error",a=>{s.error("Heartbeat error",{workerId:a.workerId,error:a.error instanceof Error?a.error.message:String(a.error),service:"worker-registration"})}),this.heartbeatService.start(),s.info("Heartbeat service initialized and started",{workerId:e.agentId,interval:t.heartbeatInterval||3e4,service:"worker-registration"})}async unregisterWorker(){if(!this.registered||!this.currentIdentity)return;let e=this.currentIdentity.agentId;s.info("Unregistering AI Agent",{workerId:e,service:"worker-registration"});let t=`
123
1102
  mutation UnregisterWorker($workerId: String!) {
124
1103
  unregisterWorker(workerId: $workerId)
125
1104
  }
126
- `;try{await this.httpClient.mutate({query:r,variables:{workerId:e}}),this.registered=!1,this.heartbeatService&&(this.heartbeatService.stop(),this.heartbeatService=void 0),c.info("AI Agent unregistered successfully",{workerId:e,service:"worker-registration"}),this.emit("unregistered",{workerId:e,identity:this.currentIdentity}),this.currentIdentity=void 0}catch(s){c.error("Worker unregistration failed",{error:s instanceof Error?s.message:String(s),workerId:e,service:"worker-registration"})}}getCurrentIdentity(){return this.currentIdentity||null}getRegistrationInfo(){return!this.registered||!this.currentIdentity?null:{workerId:this.currentIdentity.agentId,workerName:this.currentIdentity.agentName,capabilities:["project_review","code_review","development_planning"],registeredAt:new Date,hostname:this.currentIdentity.hostname,platform:this.currentIdentity.platform,environment:this.currentIdentity.environment}}getHeartbeatStatus(){return this.heartbeatService?.getStatus()||null}getHeartbeatMetrics(){return this.heartbeatService?.getMetrics()||null}async forceHeartbeat(){return this.heartbeatService?await this.heartbeatService.sendHeartbeat():!1}addMetricsProvider(e,r){this.heartbeatService&&this.heartbeatService.addMetricsProvider(e,r)}mapCapabilities(e){let r={project_review:"PROJECT_REVIEW",development_planning:"DEVELOPMENT_PLANNING",story_implementation:"STORY_IMPLEMENTATION",code_review:"CODE_REVIEW",testing:"TESTING",documentation:"DOCUMENTATION","project-reviewer":"PROJECT_REVIEW","development-planner":"DEVELOPMENT_PLANNING","code-reviewer":"CODE_REVIEW"};return e.map(s=>r[s]||s.toUpperCase())}isRegistered(){return this.registered}async updateWorkProgress(e,r){if(!this.registered||!this.currentIdentity){c.warn("Cannot update work progress - worker not registered",{workItemId:e});return}let s=`
1105
+ `;try{await this.httpClient.mutate({query:t,variables:{workerId:e}}),this.registered=!1,this.heartbeatService&&(this.heartbeatService.stop(),this.heartbeatService=void 0),s.info("AI Agent unregistered successfully",{workerId:e,service:"worker-registration"}),this.emit("unregistered",{workerId:e,identity:this.currentIdentity}),this.currentIdentity=void 0}catch(a){s.error("Worker unregistration failed",{error:a instanceof Error?a.message:String(a),workerId:e,service:"worker-registration"})}}getCurrentIdentity(){return this.currentIdentity||null}getRegistrationInfo(){return!this.registered||!this.currentIdentity?null:{workerId:this.currentIdentity.agentId,workerName:this.currentIdentity.agentName,capabilities:["project_review","code_review","development_planning"],registeredAt:new Date,hostname:this.currentIdentity.hostname,platform:this.currentIdentity.platform,environment:this.currentIdentity.environment}}getHeartbeatStatus(){return this.heartbeatService?.getStatus()||null}getHeartbeatMetrics(){return this.heartbeatService?.getMetrics()||null}async forceHeartbeat(){return this.heartbeatService?await this.heartbeatService.sendHeartbeat():!1}addMetricsProvider(e,t){this.heartbeatService&&this.heartbeatService.addMetricsProvider(e,t)}mapCapabilities(e){let t={project_review:"PROJECT_REVIEW",development_planning:"DEVELOPMENT_PLANNING",story_implementation:"STORY_IMPLEMENTATION",code_review:"CODE_REVIEW",testing:"TESTING",documentation:"DOCUMENTATION","project-reviewer":"PROJECT_REVIEW","development-planner":"DEVELOPMENT_PLANNING","code-reviewer":"CODE_REVIEW"};return e.map(a=>t[a]||a.toUpperCase())}isRegistered(){return this.registered}async updateWorkProgress(e,t){if(!this.registered||!this.currentIdentity){s.warn("Cannot update work progress - worker not registered",{workItemId:e});return}let a=`
127
1106
  mutation UpdateWorkerHeartbeat($input: WorkerHeartbeatInput!) {
128
1107
  updateWorkerHeartbeat(input: $input)
129
1108
  }
130
- `,n={input:{workerId:this.currentIdentity.agentId,isHealthy:!0,workProgress:[{workItemId:e,percentage:r.percentage,currentStep:r.currentStep,completedSteps:r.completedSteps||[],estimatedTimeRemaining:r.estimatedTimeRemaining,lastError:r.lastError}]}};try{(await this.httpClient.mutate({query:s,variables:n})).data?.updateWorkerHeartbeat?c.debug("Work progress updated successfully",{workItemId:e,percentage:r.percentage,currentStep:r.currentStep,workerId:this.currentIdentity.agentId}):c.warn("Work progress update failed",{workItemId:e,message:"Work progress update failed",workerId:this.currentIdentity.agentId})}catch(i){c.error("Error updating work progress",{workItemId:e,error:i instanceof Error?i.message:String(i),workerId:this.currentIdentity.agentId,service:"worker-registration"})}}connectSubscriptionHandler(e){this.heartbeatService?(this.heartbeatService.setSubscriptionHandler(e),c.info("Subscription handler connected to heartbeat service",{workerId:this.currentIdentity?.agentId,service:"worker-registration"})):c.warn("Cannot connect subscription handler - heartbeat service not initialized",{service:"worker-registration"})}connectCompletedWorkService(e){this.heartbeatService?(this.heartbeatService.setCompletedWorkService(e),c.info("Completed work service connected to heartbeat service",{workerId:this.currentIdentity?.agentId,service:"worker-registration"})):c.warn("Cannot connect completed work service - heartbeat service not initialized",{service:"worker-registration"})}getHeartbeatService(){return this.heartbeatService}destroy(){this.heartbeatService&&(this.heartbeatService.stop(),this.heartbeatService=void 0),this.removeAllListeners(),this.registered=!1,this.currentIdentity=void 0}};ke();R();ke();var be=class{constructor(){this.usageHistory=[];this.COST_PER_1K_INPUT_TOKENS=.003;this.COST_PER_1K_OUTPUT_TOKENS=.015;this.MAX_HISTORY_SIZE=1e4}async trackUsage(t){t.cost||(t.cost=this.calculateCost(t.inputTokens,t.outputTokens)),this.usageHistory.push(t),this.usageHistory.length>this.MAX_HISTORY_SIZE&&(this.usageHistory=this.usageHistory.slice(-this.MAX_HISTORY_SIZE)),c.info("Token usage tracked",{sessionId:t.sessionId,inputTokens:t.inputTokens,outputTokens:t.outputTokens,totalTokens:t.totalTokens,cost:t.cost,analysisType:t.analysisType});try{await this.persistUsage(t)}catch(e){c.error("Failed to persist usage to backend",{sessionId:t.sessionId,error:e instanceof Error?e.message:String(e)})}}getUsageStats(t){let e=this.usageHistory;t&&(e=this.usageHistory.filter(f=>f.timestamp>=t.start&&f.timestamp<=t.end));let r=e.length,s=e.reduce((f,S)=>f+S.inputTokens,0),n=e.reduce((f,S)=>f+S.outputTokens,0),i=e.reduce((f,S)=>f+S.totalTokens,0),o=e.reduce((f,S)=>f+S.cost,0),l=r>0?s/r:0,u=r>0?n/r:0,m=r>0?o/r:0,p=e.reduce((f,S)=>(f[S.analysisType]||(f[S.analysisType]={sessions:0,inputTokens:0,outputTokens:0,totalTokens:0,cost:0}),f[S.analysisType].sessions++,f[S.analysisType].inputTokens+=S.inputTokens,f[S.analysisType].outputTokens+=S.outputTokens,f[S.analysisType].totalTokens+=S.totalTokens,f[S.analysisType].cost+=S.cost,f),{});return{summary:{totalSessions:r,totalInputTokens:s,totalOutputTokens:n,totalTokens:i,totalCost:o,avgInputTokens:l,avgOutputTokens:u,avgCost:m},byAnalysisType:p,recentUsage:e.slice(-10)}}getUsageHistory(t=100){return this.usageHistory.slice(-t)}getTotalTokens(){return this.usageHistory.reduce((t,e)=>t+e.totalTokens,0)}getApiCallCount(){return this.usageHistory.length}getEstimatedCost(){return this.usageHistory.reduce((t,e)=>t+e.cost,0)}getDailyUsage(){let t=new Date,e=new Date(t.getFullYear(),t.getMonth(),t.getDate()),r=this.usageHistory.filter(o=>o.timestamp>=e),s=r.reduce((o,l)=>o+l.totalTokens,0),n=r.reduce((o,l)=>o+l.cost,0),i=r.length;return{totalTokens:s,totalCost:n,operationCount:i}}getCurrentRateLimit(){let t=new Date,e=new Date(t.getTime()-60*60*1e3),s=this.usageHistory.filter(i=>i.timestamp>=e).reduce((i,o)=>i+o.totalTokens,0),n=new Date(Math.ceil(t.getTime()/(60*60*1e3))*(60*60*1e3));return{used:s,limit:1e4,resetTime:n}}calculateCost(t,e){let r=t/1e3*this.COST_PER_1K_INPUT_TOKENS,s=e/1e3*this.COST_PER_1K_OUTPUT_TOKENS;return Number((r+s).toFixed(6))}async persistUsage(t){try{let e=te(),r=`
131
- mutation CreateClaudeUsageSession($input: CreateClaudeUsageSessionInput!) {
132
- createClaudeUsageSession(input: $input) {
133
- id
134
- sessionId
135
- type
136
- isError
137
- totalCostUsd
138
- createdAt
139
- }
140
- }
141
- `,s=this.mapAnalysisTypeToSessionType(t.analysisType),n=this.mapAnalysisTypeToSessionSubtype(t.analysisType),i={sessionId:t.sessionId,type:s,subtype:n,organizationId:process.env.TASK_SHEPHERD_ORGANIZATION_ID||"default-org",isError:!1,durationMs:0,durationApiMs:0,numTurns:1,totalCostUsd:t.cost,usage:{inputTokens:t.inputTokens,outputTokens:t.outputTokens,cacheCreationInputTokens:0,cacheReadInputTokens:0,totalTokens:t.totalTokens},startedAt:t.timestamp,completedAt:t.timestamp},o=await e.mutate({query:r,variables:{input:i},operationName:"CreateClaudeUsageSession"});if(!o.data?.createClaudeUsageSession)throw new Error("Failed to create usage session in backend");c.debug("Usage session persisted to backend",{sessionId:t.sessionId,backendId:o.data.createClaudeUsageSession.id})}catch(e){throw c.warn("Failed to persist usage to backend",{sessionId:t.sessionId,error:e instanceof Error?e.message:String(e)}),e}}mapAnalysisTypeToSessionType(t){switch(t.toLowerCase()){case"project_review":return"PROJECT_REVIEW";case"development_plan":return"DEVELOPMENT_PLAN";case"story_implementation":return"STORY_IMPLEMENTATION";case"task_implementation":return"TASK_IMPLEMENTATION";case"code_review":return"CODE_REVIEW";default:return"OTHER"}}mapAnalysisTypeToSessionSubtype(t){switch(t.toLowerCase()){case"project_review":return"ANALYSIS";case"development_plan":return"PLANNING";case"story_implementation":case"task_implementation":return"IMPLEMENTATION";case"code_review":return"REVIEW";default:return"OTHER"}}};var J=h(require("path")),je=h(require("fs")),F=new Ft.Command;F.name("task-shepherd-agent").description("Task Shepherd AI Agent CLI").version(process.env.npm_package_version||"1.0.0");F.command("init").description("Initialize agent configuration with interactive wizard").option("-f, --force","Force re-initialization even if agent is already configured").action(async a=>{try{let t=new oe;a.force&&console.log(d.default.yellow("\u26A0\uFE0F Force mode enabled - existing configuration will be overwritten")),await t.run()}catch(t){console.error(d.default.red("\u274C Initialization failed:"),t instanceof Error?t.message:t),process.exit(1)}});F.command("status").description("Show current agent configuration and status").option("-j, --json","Output in JSON format").action(async a=>{try{let t=new N,e=t.getCurrentIdentity();if(!e){console.log(d.default.yellow('\u26A0\uFE0F No agent identity found. Run "init" to set up the agent.'));return}if(a.json)console.log(JSON.stringify({identity:e,configPath:t.getIdentityFilePath(),envPath:J.default.join(process.cwd(),".env")},null,2));else{console.log(d.default.blue.bold(`
142
- \u{1F916} Agent Status`)),console.log(d.default.gray("\u2550".repeat(40))),console.log(d.default.cyan("Identity:")),console.log(` ID: ${d.default.white(e.agentId)}`),console.log(` Name: ${d.default.white(e.agentName)}`),console.log(` Hostname: ${d.default.white(e.hostname)}`),console.log(` Platform: ${d.default.white(e.platform)}`),console.log(` Environment: ${d.default.white(e.environment)}`),console.log(d.default.cyan(`
143
- Timing:`)),console.log(` Created: ${d.default.white(new Date(e.createdAt).toLocaleString())}`),console.log(` Last Used: ${d.default.white(new Date(e.lastUsed).toLocaleString())}`),console.log(d.default.cyan(`
144
- Configuration:`)),console.log(` Identity File: ${d.default.gray(t.getIdentityFilePath())}`),console.log(` Environment File: ${d.default.gray(J.default.join(process.cwd(),".env"))}`);let r=je.default.existsSync(".env");console.log(` Environment Status: ${r?d.default.green("\u2713 Found"):d.default.red("\u2717 Missing")}`)}}catch(t){console.error(d.default.red("\u274C Failed to get agent status:"),t instanceof Error?t.message:t),process.exit(1)}});var rt=F.command("identity").description("Manage agent identity");rt.command("show").description("Show current agent identity").action(async()=>{try{let t=new N().getCurrentIdentity();if(!t){console.log(d.default.yellow("\u26A0\uFE0F No agent identity found."));return}console.log(d.default.blue.bold(`
145
- \u{1F4CB} Agent Identity`)),console.log(d.default.gray("\u2550".repeat(30))),console.log(JSON.stringify(t,null,2))}catch(a){console.error(d.default.red("\u274C Failed to show identity:"),a instanceof Error?a.message:a),process.exit(1)}});rt.command("reset").description("Reset agent identity (will require re-initialization)").option("-y, --yes","Skip confirmation prompt").action(async a=>{try{if(!a.yes){let r=require("readline").createInterface({input:process.stdin,output:process.stdout}),s=await new Promise(n=>{r.question(d.default.yellow("\u26A0\uFE0F This will delete your agent identity. Continue? (y/N): "),n)});if(r.close(),s.toLowerCase()!=="y"&&s.toLowerCase()!=="yes"){console.log(d.default.gray("Operation cancelled."));return}}await new N().resetIdentity(),console.log(d.default.green("\u2705 Agent identity reset successfully")),console.log(d.default.gray('Run "init" to create a new identity'))}catch(t){console.error(d.default.red("\u274C Failed to reset identity:"),t instanceof Error?t.message:t),process.exit(1)}});rt.command("strategies").description("List available identity generation strategies").action(()=>{let t=new N().getAvailableStrategies();console.log(d.default.blue.bold(`
146
- \u{1F527} Available Identity Strategies`)),console.log(d.default.gray("\u2550".repeat(50))),t.forEach((e,r)=>{console.log(d.default.cyan(`${r+1}. ${e.strategy}`)),console.log(d.default.gray(` ${e.description}`)),console.log(d.default.gray(` Example: ${e.example}
147
- `))})});var Mt=F.command("heartbeat").description("Heartbeat and health monitoring commands");Mt.command("test").description("Test heartbeat connection to backend").option("-u, --url <url>","Backend GraphQL URL").option("-k, --api-key <key>","API key for authentication").action(async a=>{try{console.log(d.default.blue("\u{1F504} Testing heartbeat connection..."));let t=a.apiKey||process.env.TASK_SHEPHERD_API_KEY;t||(console.error(d.default.red("\u274C No API key provided. Use --api-key or set TASK_SHEPHERD_API_KEY")),process.exit(1));let e=new ce({baseUrl:a.url,apiKey:t}),r=new be,s=new N;await s.initializeIdentity({strategy:"hostname",persistent:!1}),await new ve(e,r,s).forceHeartbeat()?console.log(d.default.green("\u2705 Heartbeat test successful")):(console.log(d.default.red("\u274C Heartbeat test failed")),process.exit(1))}catch(t){console.error(d.default.red("\u274C Heartbeat test failed:"),t instanceof Error?t.message:t),process.exit(1)}});Mt.command("metrics").description("Show current heartbeat metrics").action(async()=>{try{console.log(d.default.yellow("\u26A0\uFE0F Heartbeat metrics are only available when the agent is running")),console.log(d.default.gray("Use the web dashboard at http://localhost:8548 to view live metrics"))}catch(a){console.error(d.default.red("\u274C Failed to get heartbeat metrics:"),a instanceof Error?a.message:a),process.exit(1)}});var de=F.command("workspace").description("Workspace discovery and management commands");de.command("register").description("Register current directory as a Task Shepherd workspace").option("-p, --path <path>","Path to register as workspace",process.cwd()).action(async a=>{try{console.log(d.default.blue("\u{1F4DD} Registering workspace..."));let{WorkspaceRegistrationWizard:t}=await Promise.resolve().then(()=>(Dt(),Rt));await new t().run(a.path)}catch(t){console.error(d.default.red("\u274C Workspace registration failed:"),t instanceof Error?t.message:t),process.exit(1)}});de.command("list").description("List workspaces from local registry").option("-j, --json","Output in JSON format").option("-s, --sync-status","Show sync status for each workspace").action(async a=>{try{console.log(d.default.blue("\u{1F4CB} Listing local workspace registry..."));let{getWorkspaceRegistry:t}=await Promise.resolve().then(()=>(B(),pe)),e=t();await e.initialize();let r=e.getAllWorkspaces();if(a.json)console.log(JSON.stringify(r,null,2));else if(r.length===0)console.log(d.default.yellow("\u26A0\uFE0F No workspaces in local registry")),console.log(d.default.gray('Run "workspace discover" to find and register workspaces'));else{let s=e.getSyncStats();console.log(d.default.green(`\u2705 Found ${r.length} workspace(s) in local registry:`)),a.syncStatus&&console.log(d.default.gray(` Synced: ${s.synced}, Pending: ${s.pending}, Failed: ${s.failed}`)),console.log();for(let n of r){let i=n.workspace;if(console.log(d.default.white.bold(`${i.name} (${i.workspaceId})`)),console.log(d.default.gray(` Path: ${i.path}`)),console.log(d.default.gray(` Pattern: ${i.pattern}`)),console.log(d.default.gray(` Discovered: ${new Date(n.discoveredAt).toLocaleString()}`)),a.syncStatus){let o={synced:"\u2705",pending:"\u23F3",failed:"\u274C"}[n.syncStatus];console.log(d.default.gray(` Sync Status: ${o} ${n.syncStatus}`)),n.lastSyncedAt&&console.log(d.default.gray(` Last Synced: ${new Date(n.lastSyncedAt).toLocaleString()}`)),n.syncError&&console.log(d.default.red(` Sync Error: ${n.syncError}`))}i.services&&i.services.length>0&&console.log(d.default.gray(` Services: ${i.services.map(o=>`${o.name} (${o.technology})`).join(", ")}`)),console.log()}}process.exit(0)}catch(t){console.error(d.default.red("\u274C Failed to list workspaces:"),t instanceof Error?t.message:t),process.exit(1)}});de.command("remove").description("Remove workspace from local registry").option("-i, --id <id>","Workspace ID to remove").option("-p, --path <path>","Remove workspace by path").option("-y, --yes","Skip confirmation prompt").action(async a=>{try{!a.id&&!a.path&&(console.error(d.default.red("\u274C Must specify either --id or --path")),process.exit(1));let{getWorkspaceRegistry:t}=await Promise.resolve().then(()=>(B(),pe)),e=t();await e.initialize();let r=e.getAllWorkspaces(),s=null;if(a.id)s=r.find(n=>n.workspace.workspaceId===a.id);else if(a.path){let n=J.default.resolve(a.path);s=r.find(i=>J.default.resolve(i.workspace.path)===n)}if(s||(console.error(d.default.red(`\u274C Workspace not found: ${a.id||a.path}`)),process.exit(1)),!a.yes){let i=require("readline").createInterface({input:process.stdin,output:process.stdout}),o=await new Promise(l=>{i.question(d.default.yellow(`\u26A0\uFE0F Remove workspace "${s.workspace.name}" (${s.workspace.workspaceId})? (y/N): `),l)});if(i.close(),o.toLowerCase()!=="y"&&o.toLowerCase()!=="yes"){console.log(d.default.gray("Operation cancelled."));return}}await e.removeWorkspace(s.workspace.workspaceId),console.log(d.default.green(`\u2705 Workspace "${s.workspace.name}" removed from local registry`)),console.log(d.default.gray(` ID: ${s.workspace.workspaceId}`)),console.log(d.default.gray(` Path: ${s.workspace.path}`)),process.exit(0)}catch(t){console.error(d.default.red("\u274C Failed to remove workspace:"),t instanceof Error?t.message:t),process.exit(1)}});de.command("sync").description("Sync local workspace registry with backend").option("-w, --workspace <id>","Sync specific workspace by ID").action(async a=>{try{console.log(d.default.blue("\u{1F504} Syncing workspaces with backend..."));let{getWorkspaceSyncService:t}=await Promise.resolve().then(()=>(et(),Ze)),{getWorkspaceRegistry:e}=await Promise.resolve().then(()=>(B(),pe)),r=t(),s=e();if(await s.initialize(),process.env.TASK_SHEPHERD_API_KEY||(console.error(d.default.red("\u274C No API key found. Set TASK_SHEPHERD_API_KEY environment variable.")),process.exit(1)),r.setConnectionStatus(!0,!1),a.workspace)try{await r.syncWorkspace(a.workspace),console.log(d.default.green(`\u2705 Successfully synced workspace: ${a.workspace}`))}catch(i){console.error(d.default.red(`\u274C Failed to sync workspace: ${i instanceof Error?i.message:i}`)),process.exit(1)}else{let i=s.getSyncStats();console.log(d.default.gray(`Found ${i.total} workspace(s): ${i.pending} pending, ${i.failed} failed`)),await r.syncWorkspaces();let o=s.getSyncStats();console.log(d.default.green(`\u2705 Sync complete: ${o.synced} synced, ${o.failed} failed`))}process.exit(0)}catch(t){console.error(d.default.red("\u274C Workspace sync failed:"),t instanceof Error?t.message:t),process.exit(1)}});de.command("status").description("Show workspace registry and sync status").action(async()=>{try{let{getWorkspaceRegistry:a}=await Promise.resolve().then(()=>(B(),pe)),{getWorkspaceSyncService:t}=await Promise.resolve().then(()=>(et(),Ze)),e=a();await e.initialize();let s=t().getSyncStatus(),n=e.getSyncStats();console.log(d.default.blue.bold(`
148
- \u{1F4CA} Workspace Registry Status`)),console.log(d.default.gray("\u2550".repeat(40))),console.log(d.default.cyan("Registry Statistics:")),console.log(` Total Workspaces: ${d.default.white(n.total)}`),console.log(` Synced: ${d.default.green(n.synced)}`),console.log(` Pending: ${d.default.yellow(n.pending)}`),console.log(` Failed: ${d.default.red(n.failed)}`),console.log(d.default.cyan(`
149
- Sync Status:`)),console.log(` Backend Connected: ${s.isConnected?d.default.green("\u2713"):d.default.red("\u2717")}`),console.log(` Sync In Progress: ${s.syncInProgress?d.default.yellow("Yes"):d.default.gray("No")}`);let i=J.default.join(process.env.HOME||process.env.USERPROFILE||"",".task-shepherd-agent","workspace-registry.json");console.log(d.default.cyan(`
150
- Registry Location:`)),console.log(` ${d.default.gray(i)}`),process.exit(0)}catch(a){console.error(d.default.red("\u274C Failed to get status:"),a instanceof Error?a.message:a),process.exit(1)}});var Ht=F.command("config").description("Configuration management commands");Ht.command("validate").description("Validate current configuration").action(async()=>{try{console.log(d.default.blue("\u{1F50D} Validating configuration..."));let a=[],t=[],e=new N,r=e.getCurrentIdentity();if(!r)a.push("No agent identity found");else{let s=e.validateAgentId(r.agentId);s.valid||a.push(`Invalid agent ID: ${s.errors.join(", ")}`)}if(!je.default.existsSync(".env"))t.push(".env file not found");else{let s=je.default.readFileSync(".env","utf8"),n=["TASK_SHEPHERD_API_URL","AGENT_ID"],i=["TASK_SHEPHERD_API_KEY","AGENT_NAME"];for(let o of n)s.includes(o)||a.push(`Missing required environment variable: ${o}`);for(let o of i)s.includes(o)||t.push(`Missing optional environment variable: ${o}`)}console.log(d.default.blue.bold(`
151
- \u{1F4CB} Configuration Validation`)),console.log(d.default.gray("\u2550".repeat(40))),a.length===0?console.log(d.default.green("\u2705 Configuration is valid")):(console.log(d.default.red(`\u274C Found ${a.length} error(s):`)),a.forEach(s=>{console.log(d.default.red(` \u2022 ${s}`))})),t.length>0&&(console.log(d.default.yellow(`\u26A0\uFE0F Found ${t.length} warning(s):`)),t.forEach(s=>{console.log(d.default.yellow(` \u2022 ${s}`))})),a.length>0&&(console.log(d.default.gray(`
152
- Run "init" to fix configuration issues`)),process.exit(1))}catch(a){console.error(d.default.red("\u274C Configuration validation failed:"),a instanceof Error?a.message:a),process.exit(1)}});Ht.command("show").description("Show current configuration").action(()=>{try{console.log(d.default.blue.bold(`
153
- \u2699\uFE0F Current Configuration`)),console.log(d.default.gray("\u2550".repeat(40)));let a=["AGENT_ID","AGENT_NAME","PORT","NODE_ENV","TASK_SHEPHERD_API_URL","TASK_SHEPHERD_API_KEY","ENABLE_HEARTBEAT","ENABLE_METRICS","ENABLE_WEB_UI","HEARTBEAT_INTERVAL","LOG_LEVEL","WEB_PORT"];console.log(d.default.cyan("Environment Variables:")),a.forEach(e=>{let r=process.env[e];if(r){let s=e.includes("KEY")?"***HIDDEN***":r;console.log(` ${e}: ${d.default.white(s)}`)}else console.log(` ${e}: ${d.default.gray("(not set)")}`)});let t=new N;console.log(d.default.cyan(`
154
- File Locations:`)),console.log(` Identity: ${d.default.gray(t.getIdentityFilePath())}`),console.log(` Environment: ${d.default.gray(J.default.join(process.cwd(),".env"))}`),console.log(` Working Directory: ${d.default.gray(process.cwd())}`)}catch(a){console.error(d.default.red("\u274C Failed to show configuration:"),a instanceof Error?a.message:a),process.exit(1)}});var st=F.command("debug").description("Debug work items and analyze error patterns");st.command("work-item <workItemId>").description("Debug specific work item by ID").option("-v, --verbose","Show detailed information").option("--timeline","Show execution timeline").option("--suggestions","Show fix suggestions").option("--export <format>","Export debug data (json|csv)").action(async(a,t)=>{try{let{createDebugWorkItemCommand:e}=await Promise.resolve().then(()=>(Ne(),_e));await e().parseAsync(["node","debug","--work-item-id",a,...process.argv.slice(4)])}catch(e){console.error(d.default.red("\u274C Debug command failed:"),e instanceof Error?e.message:e),process.exit(1)}});st.command("work-type <workType>").description("Analyze error patterns for work type").option("--export <format>","Export pattern data (json)").action(async(a,t)=>{try{let{createDebugWorkItemCommand:e}=await Promise.resolve().then(()=>(Ne(),_e));await e().parseAsync(["node","debug","--work-type",a,...process.argv.slice(4)])}catch(e){console.error(d.default.red("\u274C Debug command failed:"),e instanceof Error?e.message:e),process.exit(1)}});st.command("health").description("Show work item health overview").option("--export <format>","Export health data (json)").action(async a=>{try{let{createDebugWorkItemCommand:t}=await Promise.resolve().then(()=>(Ne(),_e));await t().parseAsync(["node","debug",...process.argv.slice(3)])}catch(t){console.error(d.default.red("\u274C Debug command failed:"),t instanceof Error?t.message:t),process.exit(1)}});F.configureHelp({sortSubcommands:!0});F.on("command:*",a=>{console.error(d.default.red(`\u274C Unknown command: ${a[0]}`)),console.log(d.default.gray("Run --help to see available commands")),process.exit(1)});require.main===module&&F.parse();0&&(module.exports={program});
1109
+ `,i={input:{workerId:this.currentIdentity.agentId,isHealthy:!0,workProgress:[{workItemId:e,percentage:t.percentage,currentStep:t.currentStep,completedSteps:t.completedSteps||[],estimatedTimeRemaining:t.estimatedTimeRemaining,lastError:t.lastError}]}};try{(await this.httpClient.mutate({query:a,variables:i})).data?.updateWorkerHeartbeat?s.debug("Work progress updated successfully",{workItemId:e,percentage:t.percentage,currentStep:t.currentStep,workerId:this.currentIdentity.agentId}):s.warn("Work progress update failed",{workItemId:e,message:"Work progress update failed",workerId:this.currentIdentity.agentId})}catch(n){s.error("Error updating work progress",{workItemId:e,error:n instanceof Error?n.message:String(n),workerId:this.currentIdentity.agentId,service:"worker-registration"})}}connectSubscriptionHandler(e){this.heartbeatService?(this.heartbeatService.setSubscriptionHandler(e),s.info("Subscription handler connected to heartbeat service",{workerId:this.currentIdentity?.agentId,service:"worker-registration"})):s.warn("Cannot connect subscription handler - heartbeat service not initialized",{service:"worker-registration"})}connectCompletedWorkService(e){this.heartbeatService?(this.heartbeatService.setCompletedWorkService(e),s.info("Completed work service connected to heartbeat service",{workerId:this.currentIdentity?.agentId,service:"worker-registration"})):s.warn("Cannot connect completed work service - heartbeat service not initialized",{service:"worker-registration"})}getHeartbeatService(){return this.heartbeatService}destroy(){this.heartbeatService&&(this.heartbeatService.stop(),this.heartbeatService=void 0),this.removeAllListeners(),this.registered=!1,this.currentIdentity=void 0}};Ue();br();var De=A(require("path")),pt=A(require("fs")),ce=new xi.Command,Dn=()=>{try{let l=De.default.join(__dirname,"../../package.json");return JSON.parse(pt.default.readFileSync(l,"utf-8")).version||"1.0.0"}catch{return"1.0.0"}};ce.name("task-shepherd-agent").description("Task Shepherd AI Agent CLI").version(Dn());ce.command("start").description("Start the AI agent service").action(async()=>{try{console.log(S.default.blue("\u{1F680} Starting Task Shepherd AI Agent...")),await Promise.resolve().then(()=>(ki(),fi))}catch(l){console.error(S.default.red("\u274C Failed to start agent:"),l instanceof Error?l.message:l),process.exit(1)}});ce.command("init").description("Initialize agent configuration with interactive wizard").option("-f, --force","Force re-initialization even if agent is already configured").action(async l=>{try{let r=new et;l.force&&console.log(S.default.yellow("\u26A0\uFE0F Force mode enabled - existing configuration will be overwritten")),await r.run()}catch(r){console.error(S.default.red("\u274C Initialization failed:"),r instanceof Error?r.message:r),process.exit(1)}});ce.command("status").description("Show current agent configuration and status").option("-j, --json","Output in JSON format").action(async l=>{try{let r=new Z,e=r.getCurrentIdentity();if(!e){console.log(S.default.yellow('\u26A0\uFE0F No agent identity found. Run "init" to set up the agent.'));return}if(l.json)console.log(JSON.stringify({identity:e,configPath:r.getIdentityFilePath(),envPath:De.default.join(process.cwd(),".env")},null,2));else{console.log(S.default.blue.bold(`
1110
+ \u{1F916} Agent Status`)),console.log(S.default.gray("\u2550".repeat(40))),console.log(S.default.cyan("Identity:")),console.log(` ID: ${S.default.white(e.agentId)}`),console.log(` Name: ${S.default.white(e.agentName)}`),console.log(` Hostname: ${S.default.white(e.hostname)}`),console.log(` Platform: ${S.default.white(e.platform)}`),console.log(` Environment: ${S.default.white(e.environment)}`),console.log(S.default.cyan(`
1111
+ Timing:`)),console.log(` Created: ${S.default.white(new Date(e.createdAt).toLocaleString())}`),console.log(` Last Used: ${S.default.white(new Date(e.lastUsed).toLocaleString())}`),console.log(S.default.cyan(`
1112
+ Configuration:`)),console.log(` Identity File: ${S.default.gray(r.getIdentityFilePath())}`),console.log(` Environment File: ${S.default.gray(De.default.join(process.cwd(),".env"))}`);let t=pt.default.existsSync(".env");console.log(` Environment Status: ${t?S.default.green("\u2713 Found"):S.default.red("\u2717 Missing")}`)}}catch(r){console.error(S.default.red("\u274C Failed to get agent status:"),r instanceof Error?r.message:r),process.exit(1)}});var Qr=ce.command("identity").description("Manage agent identity");Qr.command("show").description("Show current agent identity").action(async()=>{try{let r=new Z().getCurrentIdentity();if(!r){console.log(S.default.yellow("\u26A0\uFE0F No agent identity found."));return}console.log(S.default.blue.bold(`
1113
+ \u{1F4CB} Agent Identity`)),console.log(S.default.gray("\u2550".repeat(30))),console.log(JSON.stringify(r,null,2))}catch(l){console.error(S.default.red("\u274C Failed to show identity:"),l instanceof Error?l.message:l),process.exit(1)}});Qr.command("reset").description("Reset agent identity (will require re-initialization)").option("-y, --yes","Skip confirmation prompt").action(async l=>{try{if(!l.yes){let t=require("readline").createInterface({input:process.stdin,output:process.stdout}),a=await new Promise(i=>{t.question(S.default.yellow("\u26A0\uFE0F This will delete your agent identity. Continue? (y/N): "),i)});if(t.close(),a.toLowerCase()!=="y"&&a.toLowerCase()!=="yes"){console.log(S.default.gray("Operation cancelled."));return}}await new Z().resetIdentity(),console.log(S.default.green("\u2705 Agent identity reset successfully")),console.log(S.default.gray('Run "init" to create a new identity'))}catch(r){console.error(S.default.red("\u274C Failed to reset identity:"),r instanceof Error?r.message:r),process.exit(1)}});Qr.command("strategies").description("List available identity generation strategies").action(()=>{let r=new Z().getAvailableStrategies();console.log(S.default.blue.bold(`
1114
+ \u{1F527} Available Identity Strategies`)),console.log(S.default.gray("\u2550".repeat(50))),r.forEach((e,t)=>{console.log(S.default.cyan(`${t+1}. ${e.strategy}`)),console.log(S.default.gray(` ${e.description}`)),console.log(S.default.gray(` Example: ${e.example}
1115
+ `))})});var Wi=ce.command("heartbeat").description("Heartbeat and health monitoring commands");Wi.command("test").description("Test heartbeat connection to backend").option("-u, --url <url>","Backend GraphQL URL").option("-k, --api-key <key>","API key for authentication").action(async l=>{try{console.log(S.default.blue("\u{1F504} Testing heartbeat connection..."));let r=l.apiKey||process.env.TASK_SHEPHERD_API_KEY;r||(console.error(S.default.red("\u274C No API key provided. Use --api-key or set TASK_SHEPHERD_API_KEY")),process.exit(1));let e=new me({baseUrl:l.url,apiKey:r}),t=new ze,a=new Z;await a.initializeIdentity({strategy:"hostname",persistent:!1}),await new vt(e,t,a).forceHeartbeat()?console.log(S.default.green("\u2705 Heartbeat test successful")):(console.log(S.default.red("\u274C Heartbeat test failed")),process.exit(1))}catch(r){console.error(S.default.red("\u274C Heartbeat test failed:"),r instanceof Error?r.message:r),process.exit(1)}});Wi.command("metrics").description("Show current heartbeat metrics").action(async()=>{try{console.log(S.default.yellow("\u26A0\uFE0F Heartbeat metrics are only available when the agent is running")),console.log(S.default.gray("Use the web dashboard at http://localhost:8548 to view live metrics"))}catch(l){console.error(S.default.red("\u274C Failed to get heartbeat metrics:"),l instanceof Error?l.message:l),process.exit(1)}});var ut=ce.command("workspace").description("Workspace discovery and management commands");ut.command("register").description("Register current directory as a Task Shepherd workspace").option("-p, --path <path>","Path to register as workspace",process.cwd()).action(async l=>{try{console.log(S.default.blue("\u{1F4DD} Registering workspace..."));let{WorkspaceRegistrationWizard:r}=await Promise.resolve().then(()=>(Ri(),Pi));await new r().run(l.path)}catch(r){console.error(S.default.red("\u274C Workspace registration failed:"),r instanceof Error?r.message:r),process.exit(1)}});ut.command("list").description("List workspaces from local registry").option("-j, --json","Output in JSON format").option("-s, --sync-status","Show sync status for each workspace").action(async l=>{try{console.log(S.default.blue("\u{1F4CB} Listing local workspace registry..."));let{getWorkspaceRegistry:r}=await Promise.resolve().then(()=>(Ce(),it)),e=r();await e.initialize();let t=e.getAllWorkspaces();if(l.json)console.log(JSON.stringify(t,null,2));else if(t.length===0)console.log(S.default.yellow("\u26A0\uFE0F No workspaces in local registry")),console.log(S.default.gray('Run "workspace discover" to find and register workspaces'));else{let a=e.getSyncStats();console.log(S.default.green(`\u2705 Found ${t.length} workspace(s) in local registry:`)),l.syncStatus&&console.log(S.default.gray(` Synced: ${a.synced}, Pending: ${a.pending}, Failed: ${a.failed}`)),console.log();for(let i of t){let n=i.workspace;if(console.log(S.default.white.bold(`${n.name} (${n.workspaceId})`)),console.log(S.default.gray(` Path: ${n.path}`)),console.log(S.default.gray(` Pattern: ${n.pattern}`)),console.log(S.default.gray(` Discovered: ${new Date(i.discoveredAt).toLocaleString()}`)),l.syncStatus){let o={synced:"\u2705",pending:"\u23F3",failed:"\u274C"}[i.syncStatus];console.log(S.default.gray(` Sync Status: ${o} ${i.syncStatus}`)),i.lastSyncedAt&&console.log(S.default.gray(` Last Synced: ${new Date(i.lastSyncedAt).toLocaleString()}`)),i.syncError&&console.log(S.default.red(` Sync Error: ${i.syncError}`))}n.services&&n.services.length>0&&console.log(S.default.gray(` Services: ${n.services.map(o=>`${o.name} (${o.technology})`).join(", ")}`)),console.log()}}process.exit(0)}catch(r){console.error(S.default.red("\u274C Failed to list workspaces:"),r instanceof Error?r.message:r),process.exit(1)}});ut.command("remove").description("Remove workspace from local registry").option("-i, --id <id>","Workspace ID to remove").option("-p, --path <path>","Remove workspace by path").option("-y, --yes","Skip confirmation prompt").action(async l=>{try{!l.id&&!l.path&&(console.error(S.default.red("\u274C Must specify either --id or --path")),process.exit(1));let{getWorkspaceRegistry:r}=await Promise.resolve().then(()=>(Ce(),it)),e=r();await e.initialize();let t=e.getAllWorkspaces(),a=null;if(l.id)a=t.find(i=>i.workspace.workspaceId===l.id);else if(l.path){let i=De.default.resolve(l.path);a=t.find(n=>De.default.resolve(n.workspace.path)===i)}if(a||(console.error(S.default.red(`\u274C Workspace not found: ${l.id||l.path}`)),process.exit(1)),!l.yes){let n=require("readline").createInterface({input:process.stdin,output:process.stdout}),o=await new Promise(c=>{n.question(S.default.yellow(`\u26A0\uFE0F Remove workspace "${a.workspace.name}" (${a.workspace.workspaceId})? (y/N): `),c)});if(n.close(),o.toLowerCase()!=="y"&&o.toLowerCase()!=="yes"){console.log(S.default.gray("Operation cancelled."));return}}await e.removeWorkspace(a.workspace.workspaceId),console.log(S.default.green(`\u2705 Workspace "${a.workspace.name}" removed from local registry`)),console.log(S.default.gray(` ID: ${a.workspace.workspaceId}`)),console.log(S.default.gray(` Path: ${a.workspace.path}`)),process.exit(0)}catch(r){console.error(S.default.red("\u274C Failed to remove workspace:"),r instanceof Error?r.message:r),process.exit(1)}});ut.command("sync").description("Sync local workspace registry with backend").option("-w, --workspace <id>","Sync specific workspace by ID").action(async l=>{try{console.log(S.default.blue("\u{1F504} Syncing workspaces with backend..."));let{getWorkspaceSyncService:r}=await Promise.resolve().then(()=>(nt(),zr)),{getWorkspaceRegistry:e}=await Promise.resolve().then(()=>(Ce(),it)),t=r(),a=e();if(await a.initialize(),process.env.TASK_SHEPHERD_API_KEY||(console.error(S.default.red("\u274C No API key found. Set TASK_SHEPHERD_API_KEY environment variable.")),process.exit(1)),t.setConnectionStatus(!0,!1),l.workspace)try{await t.syncWorkspace(l.workspace),console.log(S.default.green(`\u2705 Successfully synced workspace: ${l.workspace}`))}catch(n){console.error(S.default.red(`\u274C Failed to sync workspace: ${n instanceof Error?n.message:n}`)),process.exit(1)}else{let n=a.getSyncStats();console.log(S.default.gray(`Found ${n.total} workspace(s): ${n.pending} pending, ${n.failed} failed`)),await t.syncWorkspaces();let o=a.getSyncStats();console.log(S.default.green(`\u2705 Sync complete: ${o.synced} synced, ${o.failed} failed`))}process.exit(0)}catch(r){console.error(S.default.red("\u274C Workspace sync failed:"),r instanceof Error?r.message:r),process.exit(1)}});ut.command("status").description("Show workspace registry and sync status").action(async()=>{try{let{getWorkspaceRegistry:l}=await Promise.resolve().then(()=>(Ce(),it)),{getWorkspaceSyncService:r}=await Promise.resolve().then(()=>(nt(),zr)),e=l();await e.initialize();let a=r().getSyncStatus(),i=e.getSyncStats();console.log(S.default.blue.bold(`
1116
+ \u{1F4CA} Workspace Registry Status`)),console.log(S.default.gray("\u2550".repeat(40))),console.log(S.default.cyan("Registry Statistics:")),console.log(` Total Workspaces: ${S.default.white(i.total)}`),console.log(` Synced: ${S.default.green(i.synced)}`),console.log(` Pending: ${S.default.yellow(i.pending)}`),console.log(` Failed: ${S.default.red(i.failed)}`),console.log(S.default.cyan(`
1117
+ Sync Status:`)),console.log(` Backend Connected: ${a.isConnected?S.default.green("\u2713"):S.default.red("\u2717")}`),console.log(` Sync In Progress: ${a.syncInProgress?S.default.yellow("Yes"):S.default.gray("No")}`);let n=De.default.join(process.env.HOME||process.env.USERPROFILE||"",".task-shepherd-agent","workspace-registry.json");console.log(S.default.cyan(`
1118
+ Registry Location:`)),console.log(` ${S.default.gray(n)}`),process.exit(0)}catch(l){console.error(S.default.red("\u274C Failed to get status:"),l instanceof Error?l.message:l),process.exit(1)}});var Oi=ce.command("config").description("Configuration management commands");Oi.command("validate").description("Validate current configuration").action(async()=>{try{console.log(S.default.blue("\u{1F50D} Validating configuration..."));let l=[],r=[],e=new Z,t=e.getCurrentIdentity();if(!t)l.push("No agent identity found");else{let a=e.validateAgentId(t.agentId);a.valid||l.push(`Invalid agent ID: ${a.errors.join(", ")}`)}if(!pt.default.existsSync(".env"))r.push(".env file not found");else{let a=pt.default.readFileSync(".env","utf8"),i=["TASK_SHEPHERD_API_URL","AGENT_ID"],n=["TASK_SHEPHERD_API_KEY","AGENT_NAME"];for(let o of i)a.includes(o)||l.push(`Missing required environment variable: ${o}`);for(let o of n)a.includes(o)||r.push(`Missing optional environment variable: ${o}`)}console.log(S.default.blue.bold(`
1119
+ \u{1F4CB} Configuration Validation`)),console.log(S.default.gray("\u2550".repeat(40))),l.length===0?console.log(S.default.green("\u2705 Configuration is valid")):(console.log(S.default.red(`\u274C Found ${l.length} error(s):`)),l.forEach(a=>{console.log(S.default.red(` \u2022 ${a}`))})),r.length>0&&(console.log(S.default.yellow(`\u26A0\uFE0F Found ${r.length} warning(s):`)),r.forEach(a=>{console.log(S.default.yellow(` \u2022 ${a}`))})),l.length>0&&(console.log(S.default.gray(`
1120
+ Run "init" to fix configuration issues`)),process.exit(1))}catch(l){console.error(S.default.red("\u274C Configuration validation failed:"),l instanceof Error?l.message:l),process.exit(1)}});Oi.command("show").description("Show current configuration").action(()=>{try{console.log(S.default.blue.bold(`
1121
+ \u2699\uFE0F Current Configuration`)),console.log(S.default.gray("\u2550".repeat(40)));let l=["AGENT_ID","AGENT_NAME","PORT","NODE_ENV","TASK_SHEPHERD_API_URL","TASK_SHEPHERD_API_KEY","ENABLE_HEARTBEAT","ENABLE_METRICS","ENABLE_WEB_UI","HEARTBEAT_INTERVAL","LOG_LEVEL","WEB_PORT"];console.log(S.default.cyan("Environment Variables:")),l.forEach(e=>{let t=process.env[e];if(t){let a=e.includes("KEY")?"***HIDDEN***":t;console.log(` ${e}: ${S.default.white(a)}`)}else console.log(` ${e}: ${S.default.gray("(not set)")}`)});let r=new Z;console.log(S.default.cyan(`
1122
+ File Locations:`)),console.log(` Identity: ${S.default.gray(r.getIdentityFilePath())}`),console.log(` Environment: ${S.default.gray(De.default.join(process.cwd(),".env"))}`),console.log(` Working Directory: ${S.default.gray(process.cwd())}`)}catch(l){console.error(S.default.red("\u274C Failed to show configuration:"),l instanceof Error?l.message:l),process.exit(1)}});var Jr=ce.command("debug").description("Debug work items and analyze error patterns");Jr.command("work-item <workItemId>").description("Debug specific work item by ID").option("-v, --verbose","Show detailed information").option("--timeline","Show execution timeline").option("--suggestions","Show fix suggestions").option("--export <format>","Export debug data (json|csv)").action(async(l,r)=>{try{let{createDebugWorkItemCommand:e}=await Promise.resolve().then(()=>(nr(),ir));await e().parseAsync(["node","debug","--work-item-id",l,...process.argv.slice(4)])}catch(e){console.error(S.default.red("\u274C Debug command failed:"),e instanceof Error?e.message:e),process.exit(1)}});Jr.command("work-type <workType>").description("Analyze error patterns for work type").option("--export <format>","Export pattern data (json)").action(async(l,r)=>{try{let{createDebugWorkItemCommand:e}=await Promise.resolve().then(()=>(nr(),ir));await e().parseAsync(["node","debug","--work-type",l,...process.argv.slice(4)])}catch(e){console.error(S.default.red("\u274C Debug command failed:"),e instanceof Error?e.message:e),process.exit(1)}});Jr.command("health").description("Show work item health overview").option("--export <format>","Export health data (json)").action(async l=>{try{let{createDebugWorkItemCommand:r}=await Promise.resolve().then(()=>(nr(),ir));await r().parseAsync(["node","debug",...process.argv.slice(3)])}catch(r){console.error(S.default.red("\u274C Debug command failed:"),r instanceof Error?r.message:r),process.exit(1)}});ce.configureHelp({sortSubcommands:!0});ce.on("command:*",l=>{console.error(S.default.red(`\u274C Unknown command: ${l[0]}`)),console.log(S.default.gray("Run --help to see available commands")),process.exit(1)});require.main===module&&ce.parse();0&&(module.exports={program});