@task-shepherd/agent 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
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.2",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","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","@task-shepherd/shared":"*",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:`
|
|
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.4",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","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","@task-shepherd/shared":"*",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:`
|
|
4
4
|
mutation RegisterWorkspace($input: WorkspaceRegistrationInput!) {
|
|
5
5
|
registerWorkspace(input: $input) {
|
|
6
6
|
id
|