@decaf-ts/mcp-server 1.11.0 → 1.14.0
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/assets/code/patterns/builder.enc +0 -0
- package/dist/assets/prompts/agent/agent.enc +0 -0
- package/dist/assets/prompts/agent/architect.enc +0 -0
- package/dist/assets/prompts/agent/documentation.enc +3 -0
- package/dist/assets/prompts/agent/implementation.enc +0 -0
- package/dist/assets/prompts/agent/init.enc +0 -0
- package/dist/assets/prompts/agent/main.enc +0 -0
- package/dist/assets/prompts/agent/manager.enc +0 -0
- package/dist/assets/prompts/agent/orchestrator.enc +0 -0
- package/dist/assets/prompts/agent/reviewer.enc +0 -0
- package/dist/assets/prompts/constitution_commands.enc +0 -0
- package/dist/assets/prompts/documentation/class.enc +0 -0
- package/dist/assets/prompts/documentation/constant.enc +0 -0
- package/dist/assets/prompts/documentation/decorator.enc +0 -0
- package/dist/assets/prompts/documentation/file.enc +0 -0
- package/dist/assets/prompts/documentation/function.enc +0 -0
- package/dist/assets/prompts/documentation/interface.enc +0 -0
- package/dist/assets/prompts/documentation/iterate.enc +0 -0
- package/dist/assets/prompts/documentation/module.enc +0 -0
- package/dist/assets/prompts/documentation/prefix.enc +0 -0
- package/dist/assets/prompts/documentation/repo.enc +0 -0
- package/dist/assets/prompts/documentation/suffix.enc +0 -0
- package/dist/assets/prompts/git_commands.enc +0 -0
- package/dist/assets/prompts/jira/operational_prompts.enc +0 -0
- package/dist/assets/prompts/jira/system_prompt.enc +0 -0
- package/dist/assets/prompts/mode_commands.enc +0 -0
- package/dist/assets/prompts/plan_commands.enc +0 -0
- package/dist/assets/prompts/repository/readme.enc +0 -0
- package/dist/assets/prompts/repository/release_notes.enc +0 -0
- package/dist/assets/prompts/repository/setup.enc +0 -0
- package/dist/assets/prompts/specification_commands.enc +0 -0
- package/dist/assets/prompts/startup_command.enc +0 -0
- package/dist/assets/prompts/task_commands.enc +0 -0
- package/dist/assets/prompts/tests/coverage.enc +0 -0
- package/dist/assets/resources/agent/architect.enc +0 -0
- package/dist/assets/resources/agent/catalog.enc +0 -0
- package/dist/assets/resources/agent/documentation.enc +4 -0
- package/dist/assets/resources/agent/implementation.enc +0 -0
- package/dist/assets/resources/agent/main.enc +0 -0
- package/dist/assets/resources/agent/manager.enc +0 -0
- package/dist/assets/resources/agent/orchestrator.enc +0 -0
- package/dist/assets/resources/agent/reviewer.enc +0 -0
- package/dist/assets/resources/decoration/builder.enc +0 -0
- package/dist/assets/resources/decoration/metadata.enc +0 -0
- package/dist/assets/resources/decoration/validation.enc +0 -0
- package/dist/assets/resources/golden/model-builder.enc +1 -1
- package/dist/assets/resources/golden/validation-errors.enc +2 -1
- package/dist/assets/resources/golden/xray-step-template.enc +0 -0
- package/dist/assets/resources/jira/ticket-templates/bug.enc +0 -0
- package/dist/assets/resources/jira/ticket-templates/catalog.enc +0 -0
- package/dist/assets/resources/jira/ticket-templates/feature.enc +0 -0
- package/dist/assets/resources/jira/ticket-templates/incident.enc +0 -0
- package/dist/assets/resources/jira/ticket-templates/release.enc +0 -0
- package/dist/assets/resources/jira/ticket-templates/test.enc +0 -0
- package/dist/assets/resources/repo-metadata.enc +0 -0
- package/dist/assets/templates/AGENTS.enc +0 -0
- package/dist/assets/templates/agents_template.enc +0 -0
- package/dist/assets/templates/constitution_template.enc +0 -0
- package/dist/assets/templates/decaf/context/logCtx.enc +0 -0
- package/dist/assets/templates/decaf/services/client_based_service.enc +0 -0
- package/dist/assets/templates/decaf/services/model_service.enc +1 -3
- package/dist/assets/templates/decaf/services/service.enc +2 -4
- package/dist/assets/templates/decaf_guidelines.enc +0 -0
- package/dist/assets/templates/instructions_template.enc +0 -0
- package/dist/assets/templates/jira/bug.enc +4 -0
- package/dist/assets/templates/jira/feature.enc +0 -0
- package/dist/assets/templates/jira/incident.enc +0 -0
- package/dist/assets/templates/jira/release.enc +0 -0
- package/dist/assets/templates/jira/test.enc +0 -0
- package/dist/assets/templates/jira_templates.enc +0 -0
- package/dist/assets/templates/plan_template.enc +0 -0
- package/dist/assets/templates/specification_template.enc +0 -0
- package/dist/assets/templates/task_template.enc +0 -0
- package/dist/mcp-server.cjs +1 -1
- package/dist/mcp-server.cjs.map +1 -1
- package/dist/mcp-server.js +1 -1
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp-server.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var e,t;e=this,t=function(e,t,r,i,n,s,a,o,c,l,d,u,p,m,h,g,f,y,b,w,v,z,j,k,I,S){"use strict";function x(e){var t=Object.create(null);return e&&Object.keys(e).forEach(r=>{if("default"!==r){var i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:()=>e[r]})}}),t.default=e,Object.freeze(t)}var T=x(t),A=x(o);class E extends r.MiniLogger{constructor(e,t,r){super(e,t,r)}log(e,t,i,n){const s=this.config("level");r.NumericLogLevels[s],r.NumericLogLevels[e]}}const O=(e,t,...r)=>{const i=(e=>{if("string"==typeof e)return e;if(!e)return"unknown";if("function"==typeof e)return e.name||"unknown";if("object"==typeof e&&"constructor"in e){const t=e.constructor;if(t&&t.name)return t.name}return"unknown"})(e);return new E(i,t)};function C(e,t,r,i){var n,s=arguments.length,a=3>s?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,i);else for(var o=e.length-1;o>=0;o--)(n=e[o])&&(a=(3>s?n(a):s>3?n(t,r,a):n(t,r))||a);return s>3&&a&&Object.defineProperty(t,r,a),a}function J(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}var D,N,R,P,H;"function"==typeof SuppressedError&&SuppressedError,(e=>{e[e.NONE=0]="NONE",e[e.BASIC=1]="BASIC",e[e.ADVANCED=2]="ADVANCED",e[e.HIGH=3]="HIGH"})(D||(D={})),(e=>{e[e.NONE=0]="NONE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(N||(N={})),(e=>{e[e.FREE=0]="FREE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(R||(R={}));class q extends i.Model{get log(){return this._log||(this._log=r.Logging.for(this)),this._log}constructor(e){super(e)}logFor(e){const{sessionId:t,requestId:r,authInfo:i}=e||{};let n="string"==typeof t&&t.length>0?this.log.for(t):this.log;return i&&i.clientId&&(n=n.for(i.clientId)),r&&(n=n.for(r.toString())),n}setDescription(e){return this.description=e,this}getDescription(){return this.description}setName(e){return this.name=e,this}getName(){return this.name}setTitle(e){return this.title=e,this}}C([i.required(),J("design:type",String)],q.prototype,"description",void 0),C([i.required(),J("design:type",String)],q.prototype,"name",void 0),C([i.required(),J("design:type",String)],q.prototype,"title",void 0);class _ extends q{constructor(e){super(e),this.reasoning=D.NONE,this.effort=N.NONE,this.cost=R.FREE}setReasoning(e){return this.reasoning=e,this}setEffort(e){return this.effort=e,this}setCost(e){return this.cost=e,this}}function L(e){if(!e)return;let t=e,r=t&&t._def;for(;r&&"ZodObject"!==r.typeName;){if("ZodEffects"===r.typeName&&r.schema)t=r.schema;else if("ZodOptional"===r.typeName&&r.innerType)t=r.innerType;else if("ZodDefault"===r.typeName&&r.innerType)t=r.innerType;else if("ZodNullable"===r.typeName&&r.innerType)t=r.innerType;else{if(!r.schema)return;t=r.schema}r=t&&t._def}return r&&"ZodObject"===r.typeName?r:void 0}function M(e){return!(!e||"object"!=typeof e||!e._def)}C([i.required(),J("design:type",Number)],_.prototype,"reasoning",void 0),C([i.required(),J("design:type",Number)],_.prototype,"effort",void 0),C([i.required(),J("design:type",Number)],_.prototype,"cost",void 0),(e=>{e.ASSETS="assets"})(P||(P={})),(e=>{e.PROMPT="prompts",e.DOCUMENTATION="documentation",e.CODE="code"})(H||(H={}));const $=Buffer.from("DCAF1","ascii");function F(e){if(e.length<$.length+16+12+16)throw Error("Invalid prompt payload (too short)");if(!e.subarray(0,$.length).equals($))throw Error("Invalid prompt payload (bad magic)");const t=process.env.ENCRYPTION_KEY||"";if(!t)throw Error("Missing encryption key. Set ENCRYPTION_KEY to load obfuscated assets.");let r=$.length;const i=e.subarray(r,r+16);r+=16;const n=e.subarray(r,r+12);r+=12;const s=e.subarray(r,r+16);r+=16;const a=e.subarray(r),o=((e,t)=>l.scryptSync(e,t,32))(t,i),c=l.createDecipheriv("aes-256-gcm",o,n);c.setAuthTag(s);const u=Buffer.concat([c.update(a),c.final()]);return d.gunzipSync(u)}function W(e){let r=o.resolve(e);for(;;){if(t.existsSync(o.join(r,"package.json")))return r;const e=o.dirname(r);if(e===r)break;r=e}}const U=process.argv?.[1]?W(o.dirname(o.resolve(process.argv[1]))):void 0,K=(()=>{const e=Error().stack;if(!e)return;const t=e.split(/\r?\n/).slice(1);for(const e of t){const t=e.match(/\(?([^()]+?):\d+:\d+\)?/);if(!t)continue;let r=t[1];if(r.startsWith("file://"))try{r=u.fileURLToPath(r)}catch{continue}if(!r.includes("node:internal"))return o.dirname(r)}})(),B=K?W(K):void 0,X=U??B??process.cwd();function Y(...e){return o.join(X,...e)}function G(e){let t=e;for(;;){const e=A.join(t,"lib","assets");if(T.existsSync(e))return e;const r=A.join(t,"src","assets");if(T.existsSync(r))return r;const i=A.join(t,"assets");if(T.existsSync(i))return i;const n=A.dirname(t);if(n===t)break;t=n}}function V(){const e=process.env.DECAF_ASSET_DIR||process.env.MCP_ASSET_DIR||process.env.ASSET_DIR||"";if(e&&T.existsSync(e))return e;const t=G(__dirname);if(t)return t;const r=process.argv?.[1];if(r){const e=G(A.dirname(r));if(e)return e}const i=[X,process.env.INIT_CWD].filter(Boolean);for(const e of i){const t=G(e);if(t)return t}return Y("assets")}let Z=class extends r.LoggedClass{constructor(e){super(),this.basePath=e||V()}listAssets(...e){const t=A.join(this.basePath,...e);return T.readdirSync(t)}listPrompts(){return this.listAssets(H.PROMPT)}getAsset(e,t="md",...r){const i=A.join(this.basePath,...r),n=(e,t=!1)=>{try{return t?F(T.readFileSync(e)).toString("utf-8"):T.readFileSync(e,"utf-8")}catch(e){if("ENOENT"===e.code)return null;throw e}},s=n(A.join(i,`${e}.${t}`),"enc"===t);if(null!==s)return s;const a=n(A.join(i,e+".enc"),!0);if(null!==a)return a;throw Error("Asset not found: "+A.join(i,`${e}.${t}`))}getAllAssets(e,...t){return this.listAssets(e,...t).reduce((r,i)=>{const n=A.extname(i),s=A.basename(i,n),a=n.replace(/^\./,"")||void 0;return r[s]=this.getAsset(s,a??void 0,e,...t),r},{})}toPromptDef(e){const t=e=>"number"==typeof e?e:"string"==typeof e?(e=>{switch(e){case"none":return D.NONE;case"basic":return D.BASIC;case"advanced":return D.ADVANCED;case"high":return D.HIGH;case"medium":return N.MEDIUM;case"low":return R.LOW;case"free":return R.FREE;default:throw new c.InternalError("Cannon convert unknown level "+e)}})(e.toLowerCase()):D.NONE;return e.effort=t(e.effort),e.reasoning=t(e.reasoning),e.cost=t(e.cost),e}getPrompt(e,...t){const i=this.getAsset(r.toSnakeCase(e),"json",H.PROMPT,...t);let n;try{n=JSON.parse(i)}catch(r){throw new c.SerializationError(`Failed to parse prompt ${e} in categories ${t}: ${r}`)}return this.toPromptDef(n)}getAllPrompts(...e){const t=this.getAllAssets(H.PROMPT,...e);return Object.entries(t).reduce((t,[r,i])=>{try{t[r]=JSON.parse(i)}catch(t){throw new c.SerializationError(`Failed to parse prompt ${r} in categories ${e}: ${t}`)}return t},t)}};Z=C([s.injectable(),J("design:paramtypes",[String])],Z);class Q extends _{constructor(e){super(e)}setCb(e){return this.cb=e,this}setArgsSchema(e){return this.argsSchema=e,this}static get builder(){return new Q}static patchPrompt(e,t,i,n){const s=(t=Array.isArray(t)?t:Object.keys(t)).filter(e=>!Object.prototype.hasOwnProperty.call(i,e));if(s.length)throw new c.ValidationError("Missing replacements for placeholders: "+s.join(", "));n&&(n.verbose("Patching prompt with placeholders: "+JSON.stringify(t)),n.debug("Values: "+JSON.stringify(i)));const a=t.reduce((e,t)=>(e[t]=i[t],e),{});return r.sf(e,a)}patchPrompt(e,t,r,i){return Q.patchPrompt(e,t,r,i||this.log.for(this.patchPrompt))}build(e,t){const r=this.log.for(this.build),i=this.hasErrors();if(i)throw new c.ValidationError(i.toString());try{this.argsSchema&&((e,t="schema")=>{if(L(e))return e;if(e&&"object"==typeof e){const t=e.def&&"object"==typeof e.def?e.def:void 0,r=t&&(t.shape||"object"===t.type)&&t.shape||("object"===e.type?e.shape:void 0)||(t&&"object"===t.type?{}:void 0);if(t||"object"===e.type||r){const e={};if(r&&"object"==typeof r)for(const[t,i]of Object.entries(r))e[t]=M(i)?i:n.z.any();return n.z.object(e)}}throw Error(`Registration error: provided a non-canonical ${t}. Export a ZodObject (z.object(...)).`)})(this.argsSchema,"argsSchema");const r=(e=>{if(!e)return;if(e&&"object"==typeof e&&!e._def)return e.def&&"object"==typeof e.def&&e.def.shape?e.def.shape:e;const t=L(e);return t?"function"==typeof t.shape?t.shape():t.shape||void 0:void 0})(this.argsSchema);return e.registerPrompt(this.name,{title:this.title,description:this.description,argsSchema:r},async(e,r)=>{const i=this.logFor(r);e=Object.assign({},t,e||{}),i.verbose(`Executing prompt ${this.name} with args: ${JSON.stringify(e)}`),e._meta=Object.assign(e._meta||{},{usage:{reasoning:this.reasoning,effort:this.effort,cost:this.cost}});const n=await Promise.resolve(this.cb(e,r));return i.verbose(`Prompt ${this.name} executed successfully.`),i.debug("Prompt execution meta: "+JSON.stringify(n._meta)),n})}catch(e){throw r.error("Failed to register prompt "+(this.name||this.constructor.name),e),e}}}C([s.inject(Z),J("design:type",Z)],Q.prototype,"assets",void 0),C([i.required(),J("design:type",Object)],Q.prototype,"cb",void 0),C([i.required(),J("design:type",n.ZodObject)],Q.prototype,"argsSchema",void 0),C([a.prop(),J("design:type",Object)],Q.prototype,"placeholders",void 0);class ee extends Q{setCategory(e){return this.promptCategory=e,this}addPrefix(e){return this.prefixes=this.prefixes||[],this.prefixes.push(e),this}addSuffix(e){return this.suffixes=this.suffixes||[],this.suffixes.push(e),this}constructor(e){super(e)}build(e){const t=this.assets.getPrompt(this.name,this.promptCategory);i.Model.fromObject(this,t);const r=new Set((a.Metadata.properties(ee)||[]).filter(e=>!["assets","promptCategory","prefixes","suffixes"].includes(e)));["cb","argsSchema"].forEach(e=>r.add(e));const s=this.hasErrors(...Array.from(r));if(s)throw new c.ValidationError(s.toString());const o=(this.prefixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),l=(this.suffixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),d=[...new Set([...t.placeholders,...o.map(e=>e.placeholders||[]),...l.map(e=>e.placeholders||[])].flat())].reduce((e,t)=>(e[t]=n.z.string().describe("The description for "+t),e),{});return this.setArgsSchema(n.z.object(d)),this.setCb((e,t)=>{const r=this.logFor(t).for(ee).for(this.promptCategory).for(this.name);function i(e=[]){return Array.isArray(e)?e:Object.keys(e)}const n=(this.prefixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),s=(this.suffixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),a=this.assets.getPrompt(this.name,this.promptCategory),o=[...new Set([...n.map(e=>i(e.placeholders)).flat(),...s.map(e=>i(e.placeholders)).flat(),...i(a.placeholders).flat()])];return{messages:[{role:"user",content:{type:"text",text:this.patchPrompt([...n.map(e=>e.prompt),a.prompt,...s.map(e=>e.prompt)].join("\n\n"),o,e,r)}}],_meta:{}}}),super.build(e)}setReasoning(e){throw new c.InternalError("Named prompt builders don't require callback")}setEffort(e){throw new c.InternalError("Named prompt builders don't require callback")}setCost(e){throw new c.InternalError("Named prompt builders don't require callback")}setDescription(e){throw new c.InternalError("Named prompt builders don't require callback")}setTitle(e){throw new c.InternalError("Named prompt builders don't require callback")}static get builder(){return new ee}}C([i.required(),J("design:type",String)],ee.prototype,"promptCategory",void 0),C([i.list(String),i.minlength(1),J("design:type",Array)],ee.prototype,"prefixes",void 0),C([i.minlength(1),i.list(String),J("design:type",Array)],ee.prototype,"suffixes",void 0);const te=Q.builder.setName("interactive-jsdoc").setTitle("Interactive JSDoc helper prompt").setDescription("Interactive JSDoc helper that mirrors common doc-health prompts; provide a gist to steer the assistant.").setArgsSchema(n.z.object({gist:n.z.string().optional()})).setCb(async e=>{const t=e.gist??"interactive jsdoc response";return{messages:[{role:"assistant",content:{type:"text",text:t}}],content:[],structuredContent:{message:t},result:{message:t}}}),re=Object.assign(te,{name:te.getName()});var ie;function ne(e,t=[],r=[]){const i=ee.builder.setCategory(ie.DOCS).setName(e);return["prefix",...t].forEach(e=>i.addPrefix(e)),["suffix",...r].forEach(e=>i.addSuffix(e)),i}(e=>{e.DOCS="documentation",e.CODE="code"})(ie||(ie={}));const se=[ne("class"),ne("constant"),ne("decorator"),ne("function"),ne("module"),ne("file"),ne("repo",[],["iterate"])],ae=n.z.object({className:n.z.string().describe("the class name to turn into a builder")}),oe=Q.builder.setName("ts-code-dp-builder").setTitle("Typescript builder design pattern prompt").setDescription("Generate a builder pattern implementation for a class so the assistant knows to emit chained setters plus Model validation.").setArgsSchema(ae).setReasoning(D.BASIC).setCb((e,t)=>(e.className=r.toPascalCase(e.className),{messages:[{role:"user",content:{type:"text",text:`You're a senior TypeScript developer writing typescript code.You're a senior TypeScript developer writing typescript code.\nTransform the selected class into a builder design pattern implementation in Typescript.\nuse @decaf-ts validation decorators to enforce the validation of your builder.\n\n- must extend the Model Class from @decaf-ts/decorator-validation;\n- each property must be marked as protected;\n- each property must have a setter method that returns 'this' for chaining;\n- the build() method must validate the properties using hasErrors() method from Model class;\n- if validation fails, throw an error with the validation errors;\n- if validation passes, return an instance of the original class with the set properties;\n- optionally (but do so by default) add the static builder and from methods from the example;\n- if the clasee already follows the pattern but has properties without decoration or without setters, simple add them;\n\nexample:\n\noriginal class:\n\`\`\`typescript\nexport class ${e.className} {\n description!: string;\n name!: string = "default name";\n title!: string;\n age?: string;\n dateOfBirth!: Date;\n}}\n\`\`\` \n\nresulting builder pattern implementation:\n\`\`\`typescript\nexport class ${e.className}Builder extends Model {\n\n @minlength(10\n @required()\n protected description!: string;\n \n @required()\n protected name!: string = "default value;\n \n @required()\n protected title!: string;\n \n @min(18)\n protected age?: string;\n \n @date()\n protected dateOfBirth!: Date;\n\n protected constructor(arg?: ModelArg<${e.className}Builder>>) {\n super(arg);\n Model.fromModel(this, arg);\n }\n\n setDescription(value: string) {\n this.description = value;\n return this;\n }\n\n setName(value: string) {\n this.name = value;\n return this;\n }\n\n setTitle(value: string) {\n this.title = value;\n return this;\n }\n setAge(value: number) {\n this.age = value;\n return this;\n }\n setDate(value: Date) {\n this.age = value;\n return this;\n }\n \n build(...args: any[]): ${e.className}Builder | Promise<${e.className}Builder> {\n const errs = this.hasErrors();\n if (errs) throw new Error(errs.toString());\n \n return // code that builds OBJ here\n }\n \n static get builder(): ${e.className}Builder {\n return new ${e.className}Builder(); // static method to get a new builder instance\n }\n \n static from<K extends keyof ${e.className}Builder>(obj: K, ${e.className}Builder[K]): ${e.className}Builder {\n return new ${e.className}Builder(); // static method to create a builder from an object\n }\n}\n\`\`\` \n\n`}}],_meta:{}})),ce=e=>{const t=Object.entries(e||{}).filter(([,e])=>null!=e);return t.length?t.map(([e,t])=>`- ${e}: ${JSON.stringify(t)}`).join("\n"):"- no input provided; ask a clarifying question if necessary."},le=(e,t)=>{const r=e.resources.length?e.resources.join(", "):"none";return[e.description,"","Scenario:\n"+e.scenario,"","Resources: "+r,"\nProvided inputs:",ce(t),"\nCall specification:",e.callTemplate,"\nGuidance:",(i=e.guidance,i.map((e,t)=>`${t+1}. ${e}`).join("\n"))].join("\n");var i},de=[re,...se,oe,...[{name:"guide-file-summarizer-tool",title:"MCP guide: file summarizer",description:"Explain how to obtain a concise preview of a file before discussing its contents or instructing other tools.",toolName:"file-summarizer",scenario:"Before referencing or editing a file, invoke this tool to gather a short summary of the opening lines.",resources:["resource://repo.metadata"],guidance:["Default to README.md when the user does not specify a path and call out that the summary is truncated to the first ten meaningful lines.","Trace any hiccups (file not found / permission issues) through the tool\u2019s structured result so the agent can resolve the path before editing."],argsSchema:n.z.object({filePath:n.z.string().optional()}),callTemplate:'{\n "name": "file-summarizer",\n "arguments": {\n "filePath": "<optional-path>"\n }\n}'},{name:"guide-server-info-tool",title:"MCP guide: server info",description:"Show how to use the server diagnostics tool to list registered prompts, versions, and capabilities without side effects.",toolName:"decaf-server-info",scenario:"When you need to confirm what prompts and metadata the MCP server currently exposes.",resources:["resource://repo.metadata"],guidance:["Treat the server info response as read-only configuration data that helps you decide which prompts to invoke next.","Do not rely on stale memory; re-run this tool if the environment might have changed."],argsSchema:n.z.object({}),callTemplate:'{\n "name": "decaf-server-info",\n "arguments": {}\n}'},{name:"jira-guide-issue-create-tool",title:"Jira guide: issue create",description:"Turn user requests into the structured fields that `jira-issue-create` expects, then call the tool.",toolName:"jira-issue-create",scenario:"Whenever a new ticket, task, or story must be created from requirements or spec notes.",resources:["resource://repo.metadata","resource://decoration.schematic.metadata"],guidance:["Confirm the project key from metadata when it is not in the inputs and prefer the canonical repo name.","Gather summary, description, issueType, and any extra `fields` before calling the tool; do not call within the prompt itself.","Present an action preview that lists the fields and mentions attachments or links that might also be created."],argsSchema:n.z.object({project:n.z.string().optional(),issueType:n.z.string().optional(),summary:n.z.string().optional(),description:n.z.string().optional(),assignee:n.z.string().optional(),fields:n.z.record(n.z.string(),n.z.any()).optional()}).partial(),callTemplate:'{\n "name": "jira-issue-create",\n "arguments": {\n "project": { "key": "<project>" },\n "issuetype": { "name": "<issueType>" },\n "summary": "<summary>",\n "description": "<description>",\n "assignee": "<assignee>",\n "fields": { ... }\n }\n}'},{name:"jira-guide-issue-read-tool",title:"Jira guide: issue read",description:"Explain when and how to fetch live issue data with `jira-issue-read` before referencing it.",toolName:"jira-issue-read",scenario:"Before reporting the state of a Jira ticket or quoting field values.",resources:["resource://repo.metadata"],guidance:["Always prefer the issue ID or key provided in the argument; ask clarifying questions if missing.","Mention which fields you need (description, status, comments) so the tool can optimize the call, then rely on the fresh payload instead of memory."],argsSchema:n.z.object({issueId:n.z.string().optional(),issueKey:n.z.string().optional(),fields:n.z.array(n.z.string()).optional()}).partial(),callTemplate:'{\n "name": "jira-issue-read",\n "arguments": {\n "issueId": "<id>",\n "fields": ["summary", "status", "description"]\n }\n}'},{name:"jira-guide-issue-list-tool",title:"Jira guide: issue list",description:"Map exploratory or filtering requests into safe calls to `jira-issue-list`.",toolName:"jira-issue-list",scenario:"When the user wants to discover tickets that match a summary, project, or JQL filter.",resources:["resource://repo.metadata"],guidance:["Translate the requirements into explicit filters or JQL before invoking the tool.","Respect pagination hints and summarize how many tickets the tool should return in the action preview."],argsSchema:n.z.object({jql:n.z.string().optional(),filters:n.z.record(n.z.string(),n.z.any()).optional(),limit:n.z.number().optional(),order:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-list",\n "arguments": {\n "jql": "<JQL>",\n "filters": { ... },\n "startAt": 0,\n "maxResults": <limit>\n }\n}'},{name:"jira-guide-issue-update-tool",title:"Jira guide: issue update",description:"Document how to gather updates before calling `jira-issue-update` so the user\u2019s request is satisfied.",toolName:"jira-issue-update",scenario:"When a ticket needs field changes, transitions, or property toggles.",resources:["resource://repo.metadata","resource://decoration.schematic.builder"],guidance:["Call `jira-issue-read` first if you need the latest state before updating.","Describe the delta (fields being changed) in the action preview and encode them under the `fields` argument.","Include a comment or transition info if the change ought to be annotated."],argsSchema:n.z.object({issueId:n.z.string().optional(),fields:n.z.record(n.z.string(),n.z.any()).optional(),comment:n.z.string().optional(),transition:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-update",\n "arguments": {\n "issueId": "<id>",\n "fields": { ... },\n "comment": "<comment>",\n "transition": "<transition>"\n }\n}'},{name:"jira-guide-issue-delete-tool",title:"Jira guide: issue delete",description:"Warn when to permanently delete an issue via `jira-issue-delete` and how to confirm it.",toolName:"jira-issue-delete",scenario:"When a ticket must be removed or cleaned up after duplication.",resources:["resource://repo.metadata"],guidance:["Double-check permissions and confirm the issue ID; do not delete unless the user explicitly accepts data loss.","Call out whether subtasks should be removed via `deleteSubtasks`."],argsSchema:n.z.object({issueId:n.z.string().optional(),deleteSubtasks:n.z.boolean().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-delete",\n "arguments": {\n "issueId": "<id>",\n "deleteSubtasks": <true|false>\n }\n}'},{name:"jira-guide-issue-transition-tool",title:"Jira guide: issue transition",description:"Define the process for transitioning a Jira issue and invoking `jira-issue-transition`.",toolName:"jira-issue-transition",scenario:"When a ticket needs a workflow change such as To Do \u2192 In Progress \u2192 Done.",resources:["resource://repo.metadata","resource://decoration.schematic.validation"],guidance:["Check available transitions with `jira-transition-list` before deciding which one to run.","Document the business reason in the comment argument to aid reviewers."],argsSchema:n.z.object({issueId:n.z.string().optional(),transition:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-transition",\n "arguments": {\n "issueId": "<id>",\n "transition": "<transition>",\n "comment": "<comment>"\n }\n}'},{name:"jira-guide-transition-list-tool",title:"Jira guide: transition list",description:"Explain how to use `jira-transition-list` to inspect available workflow steps before triggering one.",toolName:"jira-transition-list",scenario:"When you need to know which transitions are possible for a ticket before calling the transition tool.",resources:["resource://repo.metadata"],guidance:["Always capture the transition names and IDs to reference in the action preview.","Only call `jira-issue-transition` after confirming the desired transition exists."],argsSchema:n.z.object({issueId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-transition-list",\n "arguments": {\n "issueId": "<id>"\n }\n}'},{name:"jira-guide-assign-issue-tool",title:"Jira guide: assign issue",description:"Describe how to safely assign or reassign ownership via `jira-assign-issue`.",toolName:"jira-assign-issue",scenario:"When a ticket should be assigned or moved between assignees.",resources:["resource://repo.metadata"],guidance:["Translate user mentions or names into account IDs and include them in the call.","Mention why the reassignment is happening in your action preview to keep the workflow transparent."],argsSchema:n.z.object({issueId:n.z.string().optional(),assignee:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-assign-issue",\n "arguments": {\n "issueId": "<id>",\n "assignee": { "accountId": "<id>" }\n }\n}'},{name:"jira-guide-unassign-issue-tool",title:"Jira guide: unassign issue",description:"Explain the steps for removing an assignee using `jira-unassign-issue`.",toolName:"jira-unassign-issue",scenario:"When the user wants to unassign an owner to make the ticket available.",resources:["resource://repo.metadata"],guidance:["Document whether the ticket should remain unassigned or be moved immediately to someone else.","Confirm there is no auto-assignment policy that will conflict with the unassign action."],argsSchema:n.z.object({issueId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-unassign-issue",\n "arguments": {\n "issueId": "<id>"\n }\n}'},{name:"jira-guide-comment-add-tool",title:"Jira guide: comment add",description:"Clarify how to craft a structured comment (tiered sections, mentions) and call `jira-comment-add`.",toolName:"jira-comment-add",scenario:"When you need to capture findings, reviews, or blockers on a ticket.",resources:["resource://repo.metadata"],guidance:["Use panels, mentions, and sections when describing blockers or decisions.","Reference the relevant attachments or links and mention next steps."],argsSchema:n.z.object({issueId:n.z.string().optional(),comment:n.z.string().optional(),visibility:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-comment-add",\n "arguments": {\n "issueId": "<id>",\n "comment": "<markdown comment>",\n "visibility": "<role>"\n }\n}'},{name:"jira-guide-comment-list-tool",title:"Jira guide: comment list",description:"Indicate when to fetch the comment trail via `jira-comment-list`.",toolName:"jira-comment-list",scenario:"When decisions or conversations need to be reviewed before adding new comments.",resources:["resource://repo.metadata"],guidance:["Specify pagination or filters so you only pull the required batch of comments.","Summarize the key threads in the action preview before calling the tool again to append."],argsSchema:n.z.object({issueId:n.z.string().optional(),page:n.z.number().optional()}).partial(),callTemplate:'{\n "name": "jira-comment-list",\n "arguments": {\n "issueId": "<id>",\n "page": 0,\n "maxResults": 25\n }\n}'},{name:"jira-guide-link-create-tool",title:"Jira guide: link create",description:"Describe how to link issues (e.g., tests to specs) and call `jira-link-create`.",toolName:"jira-link-create",scenario:"When a ticket must be related to another via tested-by, duplicates, or dependees.",resources:["resource://repo.metadata"],guidance:["Include a short note on why the link exists so reviewers can trace the intent.","Verify that both issue keys exist before calling the tool; fetch via `jira-issue-read` if necessary."],argsSchema:n.z.object({inwardIssue:n.z.string().optional(),outwardIssue:n.z.string().optional(),linkType:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-link-create",\n "arguments": {\n "inwardIssue": "<inward>",\n "outwardIssue": "<outward>",\n "linkType": "<relation>",\n "comment": "<note>"\n }\n}'},{name:"jira-guide-link-update-tool",title:"Jira guide: link update",description:"Detail how to change an existing link type with `jira-link-update`.",toolName:"jira-link-update",scenario:"When the relationship between two issues needs to change (e.g., blocks \u2192 relates to).",resources:["resource://repo.metadata"],guidance:["Document the desired new relationship and why the previous one no longer applies.","List the link ID you are targeting so the tool updates precisely that connection."],argsSchema:n.z.object({linkId:n.z.string().optional(),linkType:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-link-update",\n "arguments": {\n "linkId": "<id>",\n "linkType": "<new relation>"\n }\n}'},{name:"jira-guide-link-delete-tool",title:"Jira guide: link delete",description:"Explain how to remove an incorrect or outdated link with `jira-link-delete`.",toolName:"jira-link-delete",scenario:"When a previously created link must be removed or replaced.",resources:["resource://repo.metadata"],guidance:["Ensure you reference the correct link ID and confirm both issues still exist.","Mention why the link is no longer valid to keep the audit trail clear."],argsSchema:n.z.object({linkId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-link-delete",\n "arguments": {\n "linkId": "<id>"\n }\n}'},{name:"jira-guide-attach-issue-tool",title:"Jira guide: attach file",description:"Describe when to upload artifacts with `jira-attach-issue` and how to include comments.",toolName:"jira-attach-issue",scenario:"When the user references logs, screenshots, or generated files that should be attached.",resources:["resource://repo.metadata"],guidance:["State which files are being attached and describe their purpose in the preview comment.","Ensure the file path is accessible and safe for the tool to read before calling it."],argsSchema:n.z.object({issueId:n.z.string().optional(),filePath:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-attach-issue",\n "arguments": {\n "issueId": "<id>",\n "filePath": "<path>",\n "comment": "<note>"\n }\n}'},{name:"jira-guide-attachment-list-tool",title:"Jira guide: attachment list",description:"Explain when to list attachments before adding or deleting files.",toolName:"jira-attachment-list",scenario:"When you need to verify existing attachments prior to uploading or removing files.",resources:["resource://repo.metadata"],guidance:["Capture the attached file names so you can reference the correct ID for deletion.","Use pagination hints if the ticket has many attachments."],argsSchema:n.z.object({issueId:n.z.string().optional(),page:n.z.number().optional()}).partial(),callTemplate:'{\n "name": "jira-attachment-list",\n "arguments": {\n "issueId": "<id>",\n "page": 0\n }\n}'},{name:"jira-guide-attachment-delete-tool",title:"Jira guide: attachment delete",description:"Describe how to delete a specific attachment with `jira-attachment-delete`.",toolName:"jira-attachment-delete",scenario:"When an attachment is obsolete, sensitive, or incorrect.",resources:["resource://repo.metadata"],guidance:["Confirm you have the attachment ID from the listing step to avoid removing the wrong file.","Summarize why the attachment is being removed in the action preview."],argsSchema:n.z.object({issueId:n.z.string().optional(),attachmentId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-attachment-delete",\n "arguments": {\n "issueId": "<id>",\n "attachmentId": "<attachment>"\n }\n}'},{name:"jira-guide-worklog-add-tool",title:"Jira guide: worklog add",description:"Clarify how to log time against an issue with `jira-worklog-add`.",toolName:"jira-worklog-add",scenario:"When the user reports effort spent on a ticket and needs to record it.",resources:["resource://repo.metadata"],guidance:["Convert natural language durations into Jira-friendly strings and include the context of the work.","Mention whether the log should be visible to everyone or restricted."],argsSchema:n.z.object({issueId:n.z.string().optional(),timeSpent:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-worklog-add",\n "arguments": {\n "issueId": "<id>",\n "timeSpent": "<duration>",\n "comment": "<details>"\n }\n}'},{name:"jira-guide-markdown-to-adf-tool",title:"Jira guide: markdown to ADF",description:"Summarize when to pre-process Markdown into Jira ADF before calling other tools.",toolName:"jira-markdown-to-adf",scenario:"When you need to send Markdown content into Jira fields (descriptions, comments) through other tools.",resources:["resource://repo.metadata","resource://golden.override.model-builder"],guidance:["Use this conversion whenever you cannot guarantee that Jira will accept raw Markdown.","Keep the resulting ADF document handy for downstream calls (issue-update, comment-add, etc.)."],argsSchema:n.z.object({markdown:n.z.string().optional(),context:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-markdown-to-adf",\n "arguments": {\n "markdown": "<text>",\n "context": "<purpose>"\n }\n}'},{name:"jira-guide-adf-to-markdown-tool",title:"Jira guide: ADF to Markdown",description:"Describe why to convert Jira ADF back into Markdown for editing.",toolName:"jira-adf-to-markdown",scenario:"When a user needs to edit a field that already contains ADF (comments/descriptions).",resources:["resource://repo.metadata"],guidance:["Convert the ADF, revise it, then re-run markdown-to-adf if you plan to push it back through Jira.","Keep the Markdown summary in the action preview for reviewers."],argsSchema:n.z.object({adf:n.z.any().optional()}).partial(),callTemplate:'{\n "name": "jira-adf-to-markdown",\n "arguments": {\n "adf": <ADF payload>\n }\n}'},{name:"jira-guide-xray-step-add-tool",title:"Jira guide: Xray step add",description:"Explain how to add a test step from the golden template to a test case via `jira-xray-step-add`.",toolName:"jira-xray-step-add",scenario:"When you document new verification steps for an automated or manual test case.",resources:["resource://repo.metadata","resource://golden.override.xray-step-template"],guidance:["Reference the golden step template before composing the new instruction.","Include both the action and verification so reviewers immediately know the expected result."],argsSchema:n.z.object({testCaseKey:n.z.string().optional(),step:n.z.string().optional(),status:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-add",\n "arguments": {\n "testCaseKey": "<key>",\n "step": "<description>",\n "status": "<PASS|FAIL|TODO>"\n }\n}'},{name:"jira-guide-xray-step-update-tool",title:"Jira guide: Xray step update",description:"Document how to update an existing Xray step via `jira-xray-step-update`.",toolName:"jira-xray-step-update",scenario:"When a test step needs corrections to instructions or expected results.",resources:["resource://repo.metadata","resource://golden.override.xray-step-template"],guidance:["Summarize the delta (what\u2019s changing) before calling the tool so the reviewer knows the context.","Be precise with the `stepId` to avoid editing the wrong step."],argsSchema:n.z.object({testCaseKey:n.z.string().optional(),stepId:n.z.string().optional(),update:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-update",\n "arguments": {\n "testCaseKey": "<key>",\n "stepId": "<id>",\n "update": "<new text>"\n }\n}'},{name:"jira-guide-xray-step-delete-tool",title:"Jira guide: Xray step delete",description:"Explain why you would remove a test step and how to use `jira-xray-step-delete`.",toolName:"jira-xray-step-delete",scenario:"When a chore is no longer relevant and its step should be removed.",resources:["resource://repo.metadata"],guidance:["Confirm the step ID and test case key using the list or read tools before deleting.","Document the reason for removal so auditors understand the change."],argsSchema:n.z.object({testCaseKey:n.z.string().optional(),stepId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-delete",\n "arguments": {\n "testCaseKey": "<key>",\n "stepId": "<id>"\n }\n}'},{name:"jira-guide-xray-step-list-tool",title:"Jira guide: Xray step list",description:"Describe how to inspect the existing Xray steps before editing or deleting them.",toolName:"jira-xray-step-list",scenario:"When you should view the existing test steps to confirm numbering or status.",resources:["resource://repo.metadata"],guidance:["Report the step IDs and descriptions in your preview so you can reference them later.","Use the list data instead of memory to keep numbering accurate."],argsSchema:n.z.object({testCaseKey:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-list",\n "arguments": {\n "testCaseKey": "<key>"\n }\n}'}].map(e=>Q.builder.setName(e.name).setTitle(e.title).setDescription(e.description).setArgsSchema(e.argsSchema).setCb(async(t={},r)=>({messages:[{role:"user",content:{type:"text",text:le(e,t)}}],structuredContent:{tool:e.toolName,args:t},result:{tool:e.toolName,args:t},_meta:{}})))],ue=o.resolve(process.cwd(),"README.md"),pe=n.z.object({filePath:n.z.string().optional()}),me="##VERSION##",he="##PACKAGE##";function ge(){try{let e=process.argv[1]?o.dirname(o.resolve(process.argv[1])):process.cwd();for(;;){const r=o.join(e,"package.json");if(t.existsSync(r))return JSON.parse(t.readFileSync(r,"utf-8"));const i=o.dirname(e);if(i===e)break;e=i}}catch{}return{}}const fe=me.startsWith("##")?ge().version??"0.0.0":me,ye=he.startsWith("##")?ge().name??"unknown":he;a.Metadata.registerLibrary(ye,fe);const be={mcpId:"decaf",name:"decaf-ts mcp server",title:"Decaf-TS MCP Server",description:"Provides precise coding assistance for the decaf-ts framework",version:fe,websiteUrl:"https://decaf-ts.github.io",repositoryUrl:"https://github.com/decaf-ts/mcp-server",license:"AGPL-3.0",workingDir:X,assetDir:V(),contacts:[{name:"Decaf-TS",url:"https://decaf-ts.github.io"}],tags:"server,official,decaf-ts",metadata:{},icons:[{src:"workdocs/assets/favicon.svg",mimeType:"image/svg+xml",sizes:"any"}],jira:{host:process.env.JIRA__HOST||"decaf-ts.atlassian.net",email:process.env.JIRA__EMAIL||"",apiKey:process.env.JIRA__API_KEY||process.env.JIRA__APIKEY||"",projectKey:process.env.JIRA__PROJECT_KEY||void 0,issueType:process.env.JIRA__ISSUE_TYPE||void 0,parentIssue:process.env.JIRA__PARENT_ISSUE||void 0,timeout:process.env.JIRA__TIMEOUT?parseInt(process.env.JIRA__TIMEOUT):1e3,rateLimitRetryDelayMs:process.env.JIRA__RATE_LIMIT_RETRY_DELAY_MS?parseInt(process.env.JIRA__RATE_LIMIT_RETRY_DELAY_MS):3e3},xray:{host:process.env.XRAY__HOST||process.env.XRAY__API_HOST||"https://xray.cloud.getxray.app",apiUser:process.env.XRAY__API_USER||"",apiSecret:process.env.XRAY__API_SECRET||""},level:r.LogLevel.error},we=r.LoggedEnvironment.accumulate(be);function ve(){const{host:e,email:t,apiKey:r,projectKey:i,issueType:n}=we.jira;return{host:e?.trim(),email:t?.trim(),apiKey:r?.trim(),projectKey:i?.trim(),issueType:n?.trim(),parentIssue:we.jira.parentIssue?.trim()}}function ze(){const e=ve();return[{name:"JIRA__HOST",required:!0,description:"Atlassian host (e.g. decaf-ts.atlassian.net) where your Jira instance is hosted.",value:e.host},{name:"JIRA__EMAIL",required:!0,description:"Email address of the Jira account that has API access.",value:e.email},{name:"JIRA__API_KEY",required:!0,description:"API token created in your Atlassian profile (a.k.a. APIKEY alias) for authenticating requests.",sensitive:!0,value:e.apiKey},{name:"JIRA__PROJECT_KEY",required:!1,description:"Default Jira project key (e.g. DECAF) used when an issue creation request omits a project.",value:e.projectKey},{name:"JIRA__ISSUE_TYPE",required:!1,description:"Default Jira issue type (e.g. Task, Bug) used when creating issues without an explicit type.",value:e.issueType},{name:"JIRA__PARENT_ISSUE",required:!1,description:"Default parent issue key (e.g. DECAF-123) applied when a child issue is created without an explicit parent.",value:e.parentIssue}]}function je(e){const t=e.value?((e,t)=>{if(e)return t?"<configured>":e})(e.value,e.sensitive):"not set",r=e.required?"(required)":"(optional)";return`\u2022 ${e.name} ${r}: ${e.description} Current state: ${t}.`}r.Logging.setConfig(we);class ke extends Error{constructor(e){const t=ze(),r=(e=>{const t=ze();return`${e.length?`Missing Jira credentials: ${e.map(e=>e.name).join(", ")}.`:"Jira credentials are configured."}\n\nThis setup uses the following environment variables:\n${t.map(je).join("\n")}`})(e);super(r),this.name="MissingJiraEnvironmentError",this.descriptors=t,this.missing=e,"function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,ke)}}const Ie=r.Logging.for("jira.client"),Se=/(authorization|cookie)/i;function xe(e){if(!e)return;const t=e.baseURL??"",r=e.url??"";return t&&r?`${t.endsWith("/")?t.slice(0,-1):t}/${r.startsWith("/")?r.slice(1):r}`:r||t||void 0}function Te(e){if(void 0!==e){if("string"==typeof e)return e;try{return JSON.stringify(e,null,2)}catch(t){return h.inspect(e,{depth:null})}}}function Ae(e){if(!e)return;const t={};return Object.entries(e).forEach(([e,r])=>{t[e]=Se.test(e)&&r?"[REDACTED]":r}),t}const Ee=(()=>{try{return g.createRequire(process.cwd())}catch(e){return}})();async function Oe(){let e;try{const t=await(async e=>{try{return await import(e)}catch(t){if(!Ee)throw t;try{return Ee(e)}catch(e){throw e.cause??=t,e}}})("jira.js"),r=t.default,i=t.Version3Client??r?.Version3Client??t.default;if("function"!=typeof i)throw Error("jira.js did not export a Version3Client constructor");e=i}catch(e){throw Error("Unable to load 'jira.js' \u2014 ensure it is installed as a dependency: "+e)}const{host:t,email:r,apiKey:i}=(()=>{const e=ve(),t=ze().filter(e=>e.required&&!e.value);if(t.length>0)throw new ke(t);return{host:e.host,email:e.email,apiKey:e.apiKey}})(),n=new e({host:t.startsWith("http://")||t.startsWith("https://")?t:"https://"+t,authentication:{basic:{email:r,apiToken:i}},baseRequestConfig:{headers:{Accept:"application/json","Content-Type":"application/json"}}});return(e=>{if(!e)return;const t="__jiraLoggingAttached";e[t]||(e[t]=!0,e.interceptors.request.use(e=>{e.headers=(e=>{const t={...e||{}};return Object.keys(t).some(e=>"accept"===e.toLowerCase())||(t.Accept="application/json"),Object.keys(t).some(e=>"content-type"===e.toLowerCase())||(t["Content-Type"]="application/json"),t})(e.headers);const t=(e.method??"GET").toString().toUpperCase(),r=xe(e);return Ie.info("jira.request",{method:t,url:r,headers:Ae(e.headers),params:e.params,data:Te(e.data)}),e},e=>(Ie.error("jira.request.error",{message:e.message}),Promise.reject(e))),e.interceptors.response.use(e=>{const t=(e.config?.method??"GET").toString().toUpperCase(),r=xe(e.config);return Ie.info("jira.response",{method:t,url:r,status:e.status,headers:Ae(e.headers),data:Te(e.data)}),e},e=>{const t=e.config,r=e.response,i=(t?.method??"GET").toString().toUpperCase(),n=xe(t);return Ie.error("jira.response.error",{method:i,url:n,status:r?.status,headers:Ae(r?.headers),data:Te(r?.data),message:e.message}),Promise.reject(e)}))})(n.instance),n}const Ce=n.z.object({name:n.z.string().min(1).optional().describe("Optional template name that pre-populates additional fields"),content:n.z.string().min(1).describe("Markdown template content to apply when constructing the description"),placeholders:n.z.record(n.z.string(),n.z.string()).optional().describe("Map of placeholder replacements used by the template")}).describe("Template metadata used to adjust the created description"),Je=n.z.object({template:Ce.optional().describe("Optional template settings for this create request")}).describe("Additional template controls available when creating an issue"),De=n.z.union([n.z.object({fields:n.z.record(n.z.string(),n.z.any()).describe("Full raw field map that gets delivered to Jira")}).merge(Je).describe("Create argument that supplies every field explicitly"),n.z.object({summary:n.z.string().min(1).describe("Title or summary of the new issue"),projectKey:n.z.string().min(1).describe("Project key where the issue is created"),issueType:n.z.string().min(1).describe("Type name for the new issue (story, task, etc.)"),description:n.z.string().optional().describe("Optional textual description for the issue")}).merge(Je).describe("Create argument with minimal required identifiers plus optional description")]).describe("Union describing how to create an issue either via raw fields or shorthand properties");function Ne(e,t,r){const i=((e.url??"")+"").match(/^(attachment|jira-attachment):(.+)$/i);if(!i)return null;const n=i[2],s=r.resolveAttachment?.(n);return s?{type:"block",node:{type:"mediaSingle",attrs:{layout:"center"},content:[{type:"media",attrs:{type:"file",id:s.id,collection:s.collection??"attachments"}}]}}:null}function Re(e,t){if(!e)return[];if(!t.enableAtMentions&&!t.enableEmojiShortcodes)return[{type:"text",text:e}];let r=0;const i=[],n=/(^|[^A-Za-z0-9_])@([A-Za-z0-9._-]{1,64})/g,s=/:([a-z0-9_+-]{1,64}):/gi;for(;r<e.length;){const a=He(t.enableAtMentions?Pe(n,e,r):null,t.enableEmojiShortcodes?Pe(s,e,r):null);if(!a){i.push({type:"text",text:e.slice(r)});break}if(a.index>r&&i.push({type:"text",text:e.slice(r,a.index)}),"mention"===a.kind){const{full:e,groups:n}=a,s=n[0]??"",o=n[1]??"";s&&i.push({type:"text",text:s});const c=t.resolveMention?.(o);c?i.push({type:"mention",attrs:{id:c.id,text:c.text}}):i.push({type:"text",text:"@"+o}),r=a.index+e.length;continue}if("emoji"===a.kind){const{full:e,groups:n}=a,s=`:${n[0]}:`,o=t.resolveEmoji?.(s);i.push({type:"emoji",attrs:o?{shortName:o.shortName,text:o.text}:{shortName:s}}),r=a.index+e.length;continue}}return(e=>{const t=[];for(const r of e){const e=t[t.length-1];"text"!==r.type||"text"!==e?.type||e.marks||r.marks?t.push(r):e.text=(e.text??"")+(r.text??"")}return t})(i)}function Pe(e,t,r){e.lastIndex=r;const i=e.exec(t);if(!i)return null;const n=e.source.includes("@")?"mention":"emoji";return{index:i.index,full:i[0],groups:i.slice(1),kind:n}}function He(e,t){return e?t&&e.index>t.index?t:e:t}function qe(e){const t=(e.children??[])[0];return"text"===t?.type?(t.value??"")+"":"paragraph"===t?.type?((t.children??[]).map(e=>"text"===e.type?(e.value??"")+"":"").join("")||"")+"":""}function _e(e){const t=((e??"")+"").toLowerCase().trim();return t?"info"===t||"note"===t||"success"===t||"warning"===t||"error"===t?t:"danger"===t?"error":null:null}function Le(e){const t=((e??"")+"").toLowerCase().trim();return!t||"neutral"!==t&&"green"!==t&&"yellow"!==t&&"red"!==t&&"blue"!==t&&"purple"!==t?null:t}function Me(e,t){const r=[];for(const i of e??[])if(i?.type)if("text"!==i.type)if("strong"!==i.type)if("emphasis"!==i.type)if("delete"!==i.type)if("inlineCode"!==i.type)if("break"!==i.type){if("link"===i.type){const e=(i.url??"")+"",n=Fe(i.children??[],e),s=Ne(i,0,t);if(s){"inline"===s.type?r.push(s.node):r.push({type:"text",text:n,marks:[{type:"link",attrs:{href:e}}]});continue}if(t.enableSmartCards&&We(n,e)){r.push({type:"inlineCard",attrs:{url:e}});continue}r.push({type:"text",text:n,marks:[{type:"link",attrs:{href:e}}]});continue}if("textDirective"===i.type&&"status"===i.name){const e=qe(i)||"Status",t=Le(i.attributes?.color)??"neutral";r.push({type:"status",attrs:{text:e,color:t}});continue}if("textDirective"===i.type&&"emoji"===i.name){const e=Ue(i);r.push(Ke(e,t));continue}}else r.push({type:"hardBreak"});else r.push({type:"text",text:(i.value??"")+"",marks:[{type:"code"}]});else r.push(...$e(Me(i.children??[],t),{type:"strike"}));else r.push(...$e(Me(i.children??[],t),{type:"em"}));else r.push(...$e(Me(i.children??[],t),{type:"strong"}));else r.push(...Re((i.value??"")+"",t));return r.filter(e=>!("text"===e.type&&""===(e.text??"")))}function $e(e,t){return e.map(e=>{if("text"!==e.type)return e;if(e.marks?.some(e=>"code"===e.type))return e;const r=e.marks?[...e.marks,t]:[t];return{...e,marks:r}})}function Fe(e,t){const r=[];for(const t of e??[])"text"===t.type||"inlineCode"===t.type?r.push((t.value??"")+""):"emphasis"!==t.type&&"strong"!==t.type&&"delete"!==t.type||r.push(Fe(t.children??[],""));return r.join("")||t}function We(e,t){const r=(e??"").trim(),i=(t??"").trim();return r===i&&/^https?:\/\//i.test(i)}function Ue(e){return(e.children??[]).map(e=>"text"===e.type?(e.value??"")+"":"").join("").trim()||""}function Ke(e,t){const r=e.startsWith(":")?e:`:${e}:`,i=t.resolveEmoji?.(r);return i?{type:"emoji",attrs:{shortName:i.shortName,text:i.text}}:{type:"emoji",attrs:{shortName:r}}}function Be(e){return e?"string"==typeof e?e:"text"===e.type||"inlineCode"===e.type?(e.value??"")+"":Array.isArray(e.children)?e.children.map(Be).join(""):"":""}function Xe(e,t){if(!e?.type)return null;if((e=>"containerDirective"===e?.type&&"panel"===e?.name)(e))return((e,t)=>{const r=e.attributes??{},i=_e(r.type)??"info",n="string"==typeof r.title?r.title:void 0,s=(e.children??[]).map(e=>Xe(e,t)).flat().filter(Boolean);return{type:"panel",attrs:{panelType:i,...n?{panelType:i,title:n}:{panelType:i}},content:s.length?s:[{type:"paragraph",content:[]}]}})(e,t);switch(e.type){case"heading":return{type:"heading",attrs:{level:Ge(e.depth??1,1,6)},content:Me(e.children??[],t)};case"paragraph":{const r=(e=>{const t=e.children??[];if(1!==t.length)return null;const r=t[0];if("image"!==r?.type)return null;const i=(r.url??"")+"";return i?{type:"mediaSingle",attrs:{layout:"center"},content:[{type:"media",attrs:{type:"external",url:i}}]}:null})(e);return r||{type:"paragraph",content:Me(e.children??[],t)}}case"blockquote":return{type:"blockquote",content:(e.children??[]).map(e=>Xe(e,t)).flat().filter(Boolean)};case"list":return((e,t)=>t.enableTaskLists&&(e.children??[]).some(e=>"boolean"==typeof e.checked)?((e,t)=>{const r=[];let i=0;for(const n of e.children??[]){if("boolean"!=typeof n.checked)continue;i+=1;const e=(n.children??[]).map(e=>Xe(e,t)).flat().filter(Boolean);r.push({type:"taskItem",attrs:{localId:"task-"+i,state:n.checked?"DONE":"TODO"},content:e.length?e:[{type:"paragraph",content:[]}]})}return{type:"taskList",content:r}})(e,t):{type:e.ordered?"orderedList":"bulletList",content:(e.children??[]).map(e=>((e,t)=>{const r=(e.children??[]).map(e=>Xe(e,t)).flat().filter(Boolean);return{type:"listItem",content:r.length?r:[{type:"paragraph",content:[]}]}})(e,t))})(e,t);case"code":{const r=((e,t)=>{const r=(e??"").toString().trim().toLowerCase();return r?t.enableMermaid&&r.includes("mermaid")?"mermaid":(e=>{const t=e.trim().toLowerCase();return{js:"javascript",javascript:"javascript",jsx:"javascript",ts:"typescript",typescript:"typescript",tsx:"typescript",py:"python",python:"python",rb:"ruby",ruby:"ruby",sh:"bash",bash:"bash",zsh:"bash",shell:"bash",yml:"yaml",yaml:"yaml",json:"json",toml:"toml",xml:"xml",html:"html",css:"css",scss:"scss",sql:"sql",go:"go",rust:"rust",java:"java",c:"c",cpp:"cpp","c++":"cpp",cs:"csharp",csharp:"csharp",php:"php",kotlin:"kotlin",swift:"swift",md:"markdown",markdown:"markdown",graphql:"graphql",gql:"graphql",dockerfile:"docker",makefile:"make",ini:"ini"}[t]??t})(r):null})(e.lang,t);return{type:"codeBlock",attrs:{language:r},content:[{type:"text",text:(e.value??"")+""}]}}case"thematicBreak":return{type:"rule"};case"table":return((e,t)=>({type:"table",content:(e.children??[]).map((e,r)=>({type:"tableRow",content:(e.children??[]).map(e=>({type:0===r?"tableHeader":"tableCell",content:[{type:"paragraph",content:Me(e.children??[],t)}]}))}))}))(e,t);case"leafDirective":return"status"===e.name?(e=>{const t=Le((e.attributes??{}).color)??"neutral";return{type:"paragraph",content:[{type:"status",attrs:{text:qe(e)||"Status",color:t}}]}})(e):"panel"===e.name?((e,t)=>{const r=e.attributes??{},i=_e(r.type)??"info",n="string"==typeof r.title?r.title:void 0;return{type:"panel",attrs:{panelType:i,...n?{title:n}:{}},content:[{type:"paragraph",content:Me([{type:"text",value:qe(e)}],t)}]}})(e,t):Ye(e,t);default:return Ye(e,t)}}function Ye(e,t){if("drop"===t.unknownNodeStrategy)return null;const r=Be(e);return r?{type:"paragraph",content:[{type:"text",text:r}]}:null}function Ge(e,t,r){const i=Number.isFinite(e)?Math.trunc(e):t;return Math.max(t,Math.min(r,i))}const Ve={resolveMention:void 0,resolveAttachment:void 0,resolveEmoji:void 0,enableSmartCards:!0,enableMermaid:!0,enableEmojiShortcodes:!0,enableAtMentions:!0,enableTaskLists:!0,unknownNodeStrategy:"text"};function Ze(e,t={}){const r={...Ve,...t},i=e??"",n=f.unified().use(w.default||w).use(y.default||y).use(b.default||w),s=n.parse(i),a=n.runSync(s);return Qe(a),((e,t)=>{const r=[];for(const i of e.children??[]){const e=Xe(i,t);e&&(Array.isArray(e)?r.push(...e):r.push(e))}return((e,t)=>{if(!t.enableSmartCards)return e;const r=e.content.map(e=>(e=>{if("paragraph"!==e.type)return e;const t=e.content??[];if(1!==t.length)return e;const r=t[0];if("inlineCard"!==r?.type)return e;const i=r.attrs?.url;return i?[{type:"blockCard",attrs:{url:i}}]:e})(e)).flat();return{...e,content:r}})({version:1,type:"doc",content:r},t)})(a,r)}function Qe(e){if(!e||!Array.isArray(e.children))return;const t=[];for(const r of e.children)"definition"!==r?.type&&("html"!==r?.type?(Qe(r),t.push(r)):t.push({type:"text",value:(r.value??"")+""}));e.children=t}function et(e){return{...e,content:tt(e.content??[])}}function tt(e){return e.flatMap(e=>"panel"===e.type?tt(e.content??[]):[rt(e)])}function rt(e){return e.content?{...e,content:tt(e.content)}:{...e}}const it=/\{\{\s*([^\}]+)\s*\}\}/g;function nt(e){if(!e||0>=Object.keys(e).length)return[];const t=(e=>{if(null==e)return"";try{return JSON.stringify(e,null,2)}catch{return h.inspect(e,{depth:null})}})(e);return t?[{type:"text",text:t}]:[]}function st(e={},t=[]){const r=(e=>e&&"object"==typeof e?Array.isArray(e)?{items:e}:e:"string"==typeof e?{message:e}:null==e?{}:{value:e})(e);return{content:t.length?t:nt(r),result:r,structuredContent:r}}const at={name:"jira-issue-create",inputSchema:De,runTool:async(e,t)=>st(await(async(e,t)=>{const r=e=>e&&e.trim()?e.trim():void 0,i=((e,t,r)=>{const i=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return Object.prototype.hasOwnProperty.call(i,"fields")?i:{...i,projectKey:"string"==typeof i.projectKey?i.projectKey:t,issueType:"string"==typeof i.issueType?i.issueType:r}})(t,r(we.jira.projectKey),r(we.jira.issueType));let n,s;try{n=De.parse(i)}catch(e){const t=Error("validation error");throw t.code="validation_error",t}if((e=>"object"==typeof e&&null!==e&&"fields"in e&&!!e.fields)(n))s={...n.fields};else{const e=n;s={summary:e.summary,project:{key:e.projectKey},issuetype:{name:e.issueType},...e.description?{description:e.description}:{}}}if(s=((e,t)=>{if(!t||!t.content)return e;const r=(i=t.content,n=t.placeholders,i?i.replace(it,(e,t)=>{const r=t.trim();if(!r)return"";if(n&&Object.prototype.hasOwnProperty.call(n,r)){const e=n[r];return null==e?"":e+""}return e}):"");var i,n;if(!r.trim())return e;const s=Ze(r),a=(o=e.description)?"object"==typeof o&&"doc"===o.type&&Array.isArray(o.content)?o.content:"string"==typeof o?Ze(o).content:[]:[];var o;return e.description={type:"doc",version:1,content:[...a,...s.content]},e})(s,n.template),!e?.issues||"function"!=typeof e.issues.createIssue)throw Error("Jira client missing create function");return await e.issues.createIssue({fields:s})})(e,t))};class ot extends Error{constructor({code:e,message:t,details:r}){super(t),Object.setPrototypeOf(this,new.target.prototype),this.name="NormalizedJiraError",this.code=e,this.details=r}}const ct=r.Logging.for("jira.errors");function lt(e){if(!e)return new ot({code:"jira_error",message:"Unknown Jira error",details:{raw:e}});const t=e?.status??e?.statusCode??e?.response?.status??e?.response?.statusCode,r="number"==typeof t?t:Number(t)||void 0,i=e?.response?.data??e?.data??e?.response?.body??e?.body,n=e?.response?.statusText??(r?""+r:void 0),s=e?.response?.headers?Ae(e.response.headers):void 0,a=[];"string"==typeof e?.message&&a.push(e.message),((e,t)=>{e&&(Array.isArray(e.errorMessages)&&e.errorMessages.forEach(e=>"string"==typeof e&&t.push(e)),"string"==typeof e.errorMessage&&t.push(e.errorMessage),e.errorCollection&&Array.isArray(e.errorCollection.errors)&&e.errorCollection.errors.forEach(e=>{"string"==typeof e?t.push(e):e&&"string"==typeof e.message&&t.push(e.message)}),e?.errors&&"object"==typeof e.errors&&Object.values(e.errors).forEach(e=>{"string"==typeof e?t.push(e):"string"==typeof e?.message&&t.push(e.message)}))})(i,a);const o=r?`Jira API error (${r})`:"Jira API error",c=a.length>0?a.join(" | "):o,l=r?"jira_"+r:e?.code??"jira_error",d=e?.config,u=d?{method:d.method?d.method.toString().toUpperCase():void 0,url:d.url,headers:Ae(d.headers),data:Te(d.data)}:void 0,p={httpStatus:r,body:i,request:u,response:s?{statusText:n,headers:s}:n?{statusText:n}:void 0,raw:e};return ct.error("jira.error",{code:l,message:c,httpStatus:r,statusText:n,responseHeaders:s,request:u,body:Te(i)??i}),new ot({code:l,message:c,details:p})}const dt=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID to delete"),deleteSubtasks:n.z.boolean().optional().default(!0).describe("Whether to delete the subtasks alongside this issue")}).describe("Arguments used to delete a Jira issue (with optional subtasks)"),ut={name:"jira-issue-delete",inputSchema:dt,runTool:async(e,t)=>{try{const r=dt.parse(t),i={issueIdOrKey:r.issueId,deleteSubtasks:r.deleteSubtasks};return await e.issues.deleteIssue(i),st({success:!0,message:`Issue ${r.issueId} deleted successfully`})}catch(e){throw lt(e)}}},pt=n.z.object({projectKey:n.z.string().trim().min(1).optional().describe("Project key used to scope the issue search"),issueType:n.z.string().trim().min(1).optional().describe("Issue type name used to filter the results"),parentIssueId:n.z.string().trim().min(1).optional().describe("Optional parent issue key/ID to limit results to a subtree"),name:n.z.string().trim().min(1).optional().describe("Issue summary to match exactly"),reference:n.z.string().trim().min(1).optional().describe("External reference or custom identifier to filter by"),jql:n.z.string().trim().min(1).optional().describe("Free-form JQL query to drive the search"),nextPageToken:n.z.string().trim().min(1).optional().describe("Opaque pagination token returned by Jira enhanced search"),maxResults:n.z.number().int().min(1).optional().describe("Maximum number of issues to return"),fields:n.z.array(n.z.string()).optional().describe("List of issue fields to include in the response"),expand:n.z.string().optional().describe("Optional expansion clause for the results"),orderBy:n.z.string().trim().min(1).optional().describe("Field or clause used to order the returned issues")}).describe("Parameters describing how to search for Jira issues");function mt(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}const ht={name:"jira-issue-list",inputSchema:pt,runTool:async(e,t)=>{try{const r=pt.parse(t),i=r.maxResults??50;let n=r.jql?.trim();if(n){if(r.orderBy){const e=r.orderBy.trim();e&&(n=/\border\s+by\b/i.test(n)?`${n}, ${e}`:`${n} ORDER BY ${e}`)}}else n=(e=>{const t=[];if(e.projectKey&&t.push(`project = "${mt(e.projectKey)}"`),e.issueType&&t.push(`issuetype = "${mt(e.issueType)}"`),e.parentIssueId&&t.push(`parent = "${mt(e.parentIssueId)}"`),e.name&&t.push(`summary ~ "${mt(e.name)}"`),e.reference){const r=mt(e.reference);t.push(`(key ~ "${r}" OR summary ~ "${r}" OR text ~ "${r}")`)}if(0===t.length){const e=Error("Provide a jql query or at least one filter (project, name, reference, parent, issue type, etc.).");throw e.code="validation_error",e}let r=t.join(" AND ");if(e.orderBy){const t=e.orderBy.trim();t&&(r=/\border\s+by\b/i.test(r)?`${r}, ${t}`:`${r} ORDER BY ${t}`)}return r})(r);const s={jql:n,nextPageToken:r.nextPageToken,maxResults:i,fields:r.fields,expand:r.expand},a=e.issueSearch;if(!a||"function"!=typeof a.searchForIssuesUsingJqlEnhancedSearchPost)throw Error("Jira search API is unavailable on the client");const o=await a.searchForIssuesUsingJqlEnhancedSearchPost(s);return st({...o,startAt:o?.startAt??0,maxResults:o?.maxResults??i})}catch(e){throw lt(e)}}},gt=n.z.object({issueId:n.z.string().min(1).describe("Jira issue key or numeric ID to read"),expand:n.z.string().optional().describe("Optional expand clause for nested fields or changelog"),fields:n.z.array(n.z.string()).optional().describe("Explicit list of issue fields to return"),properties:n.z.array(n.z.string()).optional().describe("Specific issue properties to include in the response")}).describe("Arguments required to read a Jira issue"),ft={name:"jira-issue-read",inputSchema:gt,runTool:async(e,t)=>{try{const r=gt.parse(t),i={issueIdOrKey:r.issueId,expand:r.expand,fields:r.fields,properties:r.properties};return st(await e.issues.getIssue(i))}catch(e){throw lt(e)}}},yt=n.z.object({issueId:n.z.string().min(1).describe("Target issue key or ID to transition"),transitionId:n.z.union([n.z.string(),n.z.number()]).describe("Identifier for the transition to execute"),fields:n.z.record(n.z.string(),n.z.any()).optional().describe("Optional field updates to apply during the transition"),update:n.z.record(n.z.string(),n.z.array(n.z.object({set:n.z.any().optional().describe("Set operation for the transition update"),add:n.z.any().optional().describe("Add operation for the transition update"),remove:n.z.any().optional().describe("Remove operation for the transition update")}))).optional().describe("Structured update operations to send alongside the transition"),comment:n.z.string().optional().describe("Optional comment to attach during the transition")}).describe("Inputs needed to transition a Jira issue"),bt={name:"jira-issue-transition",inputSchema:yt,runTool:async(e,t)=>{try{const r=yt.parse(t),i={issueIdOrKey:r.issueId,transition:{id:r.transitionId+""}};if(r.fields&&(i.fields=r.fields),r.update&&(i.update=r.update),await e.issues.doTransition(i),r.comment){const t=e.issueComments;if(!t||"function"!=typeof t.addComment)throw Error("Jira issueComments API is unavailable on the client");await t.addComment({issueIdOrKey:r.issueId,comment:Ze(r.comment)})}return st({success:!0,message:"Issue transitioned to "+r.transitionId})}catch(e){throw lt(e)}}},wt=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID for which to list transitions"),expand:n.z.string().optional().describe("Optional expand parameter for the transition response")}).describe("Inputs used to fetch available transitions for an issue"),vt={name:"jira-transition-list",inputSchema:wt,runTool:async(e,t)=>{try{const r=wt.parse(t),i=e.issues;if(!i||"function"!=typeof i.getTransitions)throw Error("Jira transitions API is unavailable on the client");const n={issueIdOrKey:r.issueId,expand:r.expand};return st(await i.getTransitions(n))}catch(e){throw lt(e)}}},zt=n.z.object({key:n.z.string().min(1).describe("The key of the issue property"),value:n.z.any().describe("The value of the issue property")}).describe("Details of issue properties to be add or update."),jt=n.z.object({description:n.z.string().optional().describe("Markdown description that is converted to Jira ADF (use jira-md-to-adf if you need raw ADF input)")}).catchall(n.z.any()).describe("Field map that gets delivered to Jira (labels, components, etc.)"),kt=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID to update"),fields:jt.optional(),update:n.z.record(n.z.string(),n.z.array(n.z.object({set:n.z.any().optional().describe("Set operation alongside the update key"),add:n.z.any().optional().describe("Add operation alongside the update key"),remove:n.z.any().optional().describe("Remove operation alongside the update key"),edit:n.z.any().optional().describe("Edit operation alongside the update key")}))).optional().describe("Structured update operations for array/set fields"),properties:n.z.array(zt).optional().describe("Property payloads to attach to the issue"),notifyUsers:n.z.boolean().optional().default(!0).describe("Whether to notify watchers when the issue is updated"),issueTemplateId:n.z.string().optional().describe("Optional template ID to render issue descriptions"),overrideScreenSecurity:n.z.boolean().optional().default(!1).describe("Temporarily bypass screen security restrictions"),overrideEditableFlag:n.z.boolean().optional().default(!1).describe("Temporarily bypass the editable flag on the screen")}).describe("Arguments used to update existing Jira issues"),It=n.z.record(n.z.string(),n.z.any()).optional(),St=n.z.object({type:n.z.string().describe("Mark name, such as strong, emphasis, code, or link"),attrs:It}).describe("Inline formatting or link marks applied to text nodes"),xt=n.z.object({type:n.z.literal("text"),text:n.z.string().describe("Rendered string content for the text node"),marks:n.z.array(St).optional()}).describe("Plain text node that carries optional formatting marks"),Tt=n.z.object({type:n.z.literal("mention"),attrs:n.z.object({id:n.z.string().describe("Jira internal identifier for the mention"),text:n.z.string().describe("Human readable mention text"),userType:n.z.string().optional(),accessLevel:n.z.string().optional(),localizedAccessLevel:n.z.string().optional()}).describe("Metadata describing the mentioned user")}).describe("Represents a user or team mention in a block or inline context"),At=n.z.object({type:n.z.literal("emoji"),attrs:n.z.object({shortName:n.z.string().describe("Emoji shortcode such as smiling_face"),id:n.z.string().optional(),text:n.z.string().optional()}).describe("Emoji metadata")}).describe("Emoji inline node"),Et=n.z.object({type:n.z.literal("inlineCard"),attrs:n.z.object({url:n.z.string().url().describe("Target URL that backs the inline card")}).describe("Inline card attributes")}).describe("Inline card that represents a linked resource"),Ot=n.z.object({type:n.z.literal("status"),attrs:n.z.object({text:n.z.string().describe("Status label text"),color:n.z.string().describe("Color code applied by Jira"),localId:n.z.string().optional(),style:n.z.string().optional()}).describe("Status metadata published by Jira")}).describe("Status node used for Jira workflow or custom fields"),Ct=n.z.object({type:n.z.literal("date"),attrs:n.z.object({representation:n.z.string().optional(),timestamp:n.z.number().optional()}).describe("Date metadata, usually RFC3339 or timestamp")}).describe("Date node that embeds a Jira date reference"),Jt=n.z.object({type:n.z.literal("hardBreak")}).describe("Inline hard break that forces a newline"),Dt=n.z.object({type:n.z.literal("rule")}).describe("Horizontal rule dividing sections of the document");let Nt,Rt;const Pt=n.z.lazy(()=>n.z.union([xt,Tt,At,Et,Ot,Ct,Jt])),Ht=n.z.lazy(()=>n.z.object({type:n.z.literal("paragraph"),content:n.z.array(Pt).describe("Inline nodes contained by the paragraph")})),qt=n.z.lazy(()=>n.z.object({type:n.z.literal("heading"),attrs:n.z.object({level:n.z.number().int().min(1).max(6).describe("Heading level, 1-6")}).optional(),content:n.z.array(Pt).describe("Inline nodes composing the heading")})),_t=n.z.lazy(()=>n.z.object({type:n.z.literal("listItem"),attrs:n.z.object({localId:n.z.string().optional()}).optional(),content:n.z.array(n.z.lazy(()=>Nt)).describe("Block level nodes nested inside the list item")})),Lt=n.z.lazy(()=>n.z.object({type:n.z.literal("bulletList"),content:n.z.array(_t).describe("List items within the bullet list")})),Mt=n.z.lazy(()=>n.z.object({type:n.z.literal("orderedList"),attrs:n.z.object({order:n.z.number().int().min(1).optional()}).optional(),content:n.z.array(_t)})),$t=n.z.lazy(()=>n.z.object({type:n.z.literal("taskItem"),attrs:n.z.object({localId:n.z.string().optional(),state:n.z.enum(["TODO","IN_PROGRESS","DONE"]).optional()}).optional(),content:n.z.array(n.z.lazy(()=>Nt)).describe("Blocks living inside the task item")})),Ft=n.z.lazy(()=>n.z.object({type:n.z.literal("taskList"),content:n.z.array($t).describe("Task items inside the list")})),Wt=n.z.lazy(()=>n.z.object({type:n.z.literal("codeBlock"),attrs:n.z.object({language:n.z.string().optional()}).optional(),content:n.z.array(xt).optional()})),Ut=n.z.lazy(()=>n.z.object({type:n.z.literal("panel"),attrs:n.z.object({panelType:n.z.enum(["info","note","tip","warning","success"]).optional(),title:n.z.string().optional()}).optional(),content:n.z.array(n.z.lazy(()=>Nt)).describe("Panels may nest paragraphs, lists, or other blocks")})),Kt=n.z.lazy(()=>n.z.object({type:n.z.literal("blockquote"),content:n.z.array(n.z.lazy(()=>Nt)).describe("Quoted block content")})),Bt=n.z.lazy(()=>n.z.object({type:n.z.literal("blockCard"),attrs:n.z.object({url:n.z.string().url().describe("URL for the card")})})),Xt=n.z.lazy(()=>n.z.object({type:n.z.literal("media"),attrs:n.z.object({id:n.z.string().describe("Media identifier in Jira storage"),type:n.z.string().describe("Media type, e.g., file or link"),collection:n.z.string().optional(),width:n.z.number().optional(),height:n.z.number().optional()}).describe("Metadata describing the embedded media")})),Yt=n.z.lazy(()=>n.z.object({type:n.z.literal("mediaSingle"),content:n.z.array(Xt).describe("Single media block content")})),Gt=n.z.lazy(()=>n.z.object({type:n.z.literal("mediaGroup"),content:n.z.array(Xt).describe("Gallery-style media grouping")})),Vt=n.z.object({type:n.z.literal("tableCell"),attrs:n.z.object({colspan:n.z.number().int().min(1).optional(),rowspan:n.z.number().int().min(1).optional()}).optional(),content:n.z.array(n.z.lazy(()=>Nt)).describe("Content inside the table cell")}).describe("A regular table cell container"),Zt=n.z.lazy(()=>Vt),Qt=n.z.lazy(()=>Vt.extend({type:n.z.literal("tableHeader")})),er=n.z.lazy(()=>n.z.object({type:n.z.literal("tableRow"),content:n.z.array(n.z.union([Zt,Qt]))})),tr=n.z.lazy(()=>n.z.object({type:n.z.literal("table"),content:n.z.array(er)})),rr=n.z.lazy(()=>n.z.object({type:n.z.literal("decisionItem"),attrs:n.z.object({localId:n.z.string().optional(),state:n.z.enum(["DECIDED","DECIDING"]).optional()}).optional(),content:n.z.array(n.z.lazy(()=>Nt))})),ir=n.z.lazy(()=>n.z.object({type:n.z.literal("decisionList"),content:n.z.array(rr)})),nr=n.z.lazy(()=>n.z.object({type:n.z.string(),attrs:n.z.record(n.z.string(),n.z.any()).optional(),content:n.z.array(n.z.lazy(()=>Rt)).optional(),marks:n.z.array(St).optional(),text:n.z.string().optional()}).describe("Unknown or extended Jira node"));Nt=n.z.lazy(()=>n.z.union([Ht,qt,Lt,Mt,_t,Ft,$t,Wt,Ut,Kt,Bt,Yt,Gt,tr,er,Zt,Qt,ir,rr,Dt,nr])),Rt=n.z.lazy(()=>n.z.union([Nt,Pt]));const sr=n.z.object({type:n.z.literal("doc"),version:n.z.literal(1),content:n.z.array(Nt).describe("Top-level block nodes in the document")}).describe("Jira ADF document structure; run jira-md-to-adf when converting markdown"),ar=r.Logging.for("jira.rate-limit"),or=we.jira.rateLimitRetryDelayMs??3e3;let cr=!1;const lr="jira-issue-update",dr=kt,ur={name:lr,inputSchema:dr,runTool:async(e,t)=>{try{const r=dr.parse(t),i={issueIdOrKey:r.issueId};if(r.fields&&(i.fields=(e=>{const t={...e},r=t.description;if("string"==typeof r){const e=et(Ze(r));t.description=sr.parse(e)}else if(r&&"object"==typeof r){const e=et(sr.parse(r));t.description=e}return t})(r.fields)),r.update&&(i.update=r.update),r.properties||r.issueTemplateId){const e=[...r.properties??[]];r.issueTemplateId&&e.push({key:"issueTemplateId",value:r.issueTemplateId}),i.properties=e}return void 0!==r.notifyUsers&&(i.notifyUsers=r.notifyUsers),void 0!==r.overrideScreenSecurity&&(i.overrideScreenSecurity=r.overrideScreenSecurity),void 0!==r.overrideEditableFlag&&(i.overrideEditableFlag=r.overrideEditableFlag),st(await(async(e,t)=>{try{return await t()}catch(i){if((e=>{const t=(e=>e?.status??e?.statusCode??e?.response?.status??e?.response?.statusCode??void 0)(e);if(403!==t)return!1;const r=(e=>{const t=e?.response?.data??e?.data??e?.response?.body??e,r=[];return"string"==typeof t&&r.push(t),"string"==typeof t?.message&&r.push(t.message),"string"==typeof t?.errorMessage&&r.push(t.errorMessage),Array.isArray(t?.errorMessages)&&r.push(...t.errorMessages.filter(e=>"string"==typeof e)),"string"==typeof t?.details?.message&&r.push(t.details.message),r.join(" ")||""})(e);return/rate\s?limit/i.test(r)})(i))return cr||(ar.warn(`Jira rate limit detected for ${e}; waiting ${or}ms before retrying.`,{retryDelayMs:or}),cr=!0),or>0&&await(r=or,new Promise(e=>setTimeout(e,r))),t();throw i}var r})(lr,()=>e.issues.editIssue(i)))}catch(e){throw lt(e)}}},pr=n.z.object({markdown:n.z.string().describe("Markdown source that will be converted into Jira ADF"),options:n.z.record(n.z.string(),n.z.any()).optional().describe("Optional MarkdownToAdfOptions passed to the converter")}).describe("Convert markdown into a sanitized Jira ADF document"),mr={name:"jira-md-to-adf",inputSchema:pr,runTool:async(e,t)=>{const r=pr.parse(t),i=et(Ze(r.markdown,r.options));return st(sr.parse(i))}},hr=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID for the assignment change"),assignee:n.z.union([n.z.string().describe("Account ID of the new assignee"),n.z.object({accountId:n.z.string().min(1).describe("Account ID of the assignee")})]).describe("How the new assignee is specified")}).describe("Arguments required to assign a Jira issue to someone"),gr={name:"jira-assign-issue",inputSchema:hr,runTool:async(e,t)=>{try{const r=hr.parse(t);let i=null;"string"==typeof r.assignee?i=r.assignee:"accountId"in r.assignee&&(i=r.assignee.accountId);const n={issueIdOrKey:r.issueId,accountId:i};return await e.issues.assignIssue(n),st({success:!0,message:"Issue assigned to "+(i??"unassigned")})}catch(e){throw lt(e)}}},fr=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID to remove the assignee from")}).describe("Inputs required to unassign a Jira issue"),yr={name:"jira-unassign-issue",inputSchema:fr,runTool:async(e,t)=>{try{const r=fr.parse(t),i={issueIdOrKey:r.issueId,accountId:null};return await e.issues.assignIssue(i),st({success:!0,message:`Issue ${r.issueId} unassigned successfully`})}catch(e){throw lt(e)}}},br=n.z.object({issueId:n.z.string().min(1).describe("The Jira issue key or numeric ID receiving the comment"),body:n.z.string().min(1).describe("The markdown-compatible text of the comment"),visibility:n.z.object({type:n.z.enum(["role","group"]).describe("Visibility type that restricts the comment to a role or group"),value:n.z.string().min(1).describe("The name of the role or group granted visibility")}).optional().describe("Optional visibility override controlling who can read the comment")}).describe("Arguments for adding a comment to a Jira issue"),wr={name:"jira-comment-add",inputSchema:br,runTool:async(e,t)=>{try{const r=br.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.addComment)throw Error("Jira issueComments API is unavailable on the client");const n={issueIdOrKey:r.issueId,comment:r.body,visibility:r.visibility};return st(await i.addComment(n))}catch(e){throw lt(e)}}},vr=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID whose comments should be retrieved"),start:n.z.number().optional().default(0).describe("Zero-based index to start pagination from"),maxResults:n.z.number().optional().default(50).describe("Maximum number of comments to return"),orderBy:n.z.string().optional().describe("Field name to order the returned comments by"),expand:n.z.string().optional().describe("Optional expansion clause for the comment response")}).describe("Parameters for fetching comments on a Jira issue"),zr={name:"jira-comment-list",inputSchema:vr,runTool:async(e,t)=>{try{const r=vr.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.getComments)throw Error("Jira issueComments API is unavailable on the client");const n={issueIdOrKey:r.issueId,startAt:r.start,maxResults:r.maxResults,orderBy:r.orderBy,expand:r.expand};return st(await i.getComments(n))}catch(e){throw lt(e)}}},jr=n.z.enum(["Blocks","Relates to","Duplicates","Is blocked by","Is related to","is tested by","tests","Is covered by","covered by","Is duplicated by","Causes","Is caused by","Clone","Required","Work on","Split","Roll up"]).describe("The named relationship (Blocks, Relates to, etc.) that describes the link type"),kr=n.z.object({id:n.z.string().optional().describe("Numeric Jira ID used when referencing an issue"),key:n.z.string().optional().describe("Human-readable key of the linked issue")}).describe("An issue reference (ID or key) used when building a link payload"),Ir=n.z.object({type:n.z.enum(["role","group"]).describe("Visibility scope type attached to the comment"),value:n.z.string().min(1).describe("Name of the role or group granted visibility to the comment")}).describe("Optional visibility settings applied to the comment"),Sr=n.z.object({body:n.z.string().optional().describe("Markdown text to include as a linked-comment"),visibility:Ir.optional().describe("Optional ACL for the comment")}).describe("Optional comment applied at the time the link is created or updated"),xr=n.z.object({link:n.z.object({relationship:jr,inwardIssue:kr,outwardIssue:kr,comment:Sr.optional()}).describe("Definition of the link that should be created between two issues")}).describe("Arguments required to create a Jira issue link");let Tr=[];function Ar(e){return(e||"").trim().toLowerCase()}async function Er(e,t){if(!t)throw Error("Link relationship is required");0===Tr.length&&(Tr=await(async e=>{const t=e?.issueLinkTypes;if(!t||"function"!=typeof t.getIssueLinkTypes)throw Error("Jira issueLinkTypes API is unavailable on the client");const r=await t.getIssueLinkTypes();return r?.issueLinkTypes??[]})(e));const r=Ar(t),i=Tr.find(e=>[e.name,e.inward,e.outward].some(e=>Ar(e)===r));if(!i)throw Error(`No issue link type matching '${t}' found.`);return i}function Or(e){if(!e)throw Error("Linked issue must include an id or key");if(e.id)return{id:e.id};if(e.key)return{key:e.key};throw Error("Linked issue must include an id or key")}function Cr(e){if(!e)return;const t={};return e.body&&(t.body=Ze(e.body)),e.visibility&&(t.visibility=e.visibility),Object.keys(t).length>0?t:void 0}const Jr=xr,Dr={name:"jira-link-create",inputSchema:Jr,runTool:async(e,t)=>{try{const r=Jr.parse(t).link,i=Cr(r.comment),n=e.issueLinks;if(!n||"function"!=typeof n.linkIssues)throw Error("Jira issueLinks API is unavailable on the client");const s=await Er(e,r.relationship),a={inwardIssue:Or(r.inwardIssue),outwardIssue:Or(r.outwardIssue),type:Nr(s),...i?{comment:i}:{}};return await n.linkIssues(a),st({success:!0,message:"Issue link created with relationship "+r.relationship})}catch(e){throw lt(e)}}};function Nr(e){if(e.id)return{id:e.id};if(e.name)return{name:e.name};throw Error("Resolved issue link type is missing both id and name")}const Rr=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID receiving the attachment"),file:n.z.string().min(1).describe("Base64 or path to the file contents to upload"),mimeType:n.z.string().optional().describe("Optional MIME type override for the attachment"),comment:n.z.string().optional().describe("Optional comment to associate with the attachment")}).describe("Inputs needed to attach a file to a Jira issue"),Pr={name:"jira-attach",inputSchema:Rr,runTool:async(e,r)=>{try{const i=Rr.parse(r),n=o.resolve(i.file);let s=i.file,a="attachment",c=!1;try{await t.promises.access(n),c=!0}catch{s=i.file,a="attachment"}c&&(s=await t.promises.readFile(n),a=o.basename(n));const l=e.issueAttachments;if(!l||"function"!=typeof l.addAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const d={filename:a,file:s,mimeType:i.mimeType},u=await l.addAttachment({issueIdOrKey:i.issueId,attachment:d});if(i.comment){const t=e?.issueComments;if(!t||"function"!=typeof t.addComment)throw Error("Jira issueComments API is unavailable on the client");await t.addComment({issueIdOrKey:i.issueId,comment:Ze(i.comment)})}return st(u)}catch(e){if(e&&"object"==typeof e&&"code"in e&&"string"==typeof e.code&&["ENOENT","EACCES"].includes(e.code))throw Error("Attachment file error: "+(e.message??"Unknown error"));throw lt(e)}}},Hr=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID whose attachments should be listed")}).describe("Arguments used to fetch attachments for a Jira issue"),qr={name:"jira-attachment-list",inputSchema:Hr,runTool:async(e,t)=>{try{const r=Hr.parse(t),i=e.issues;if(!i||"function"!=typeof i.getIssue)throw Error("Jira issues API is unavailable on the client");const n={issueIdOrKey:r.issueId,fields:["attachment"]},s=await i.getIssue(n);return st({attachments:Array.isArray(s.fields?.attachment)?s.fields.attachment:[]})}catch(e){throw lt(e)}}},_r=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID owning the attachment"),attachmentId:n.z.string().min(1).describe("ID of the attachment to delete")}).describe("Arguments required to remove an attachment from Jira"),Lr={name:"jira-attachment-delete",inputSchema:_r,runTool:async(e,t)=>{try{const r=_r.parse(t),i=e.issueAttachments;if(!i||"function"!=typeof i.removeAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const n={id:r.attachmentId};return await i.removeAttachment(n),st({success:!0,message:`Attachment ${r.attachmentId} deleted successfully`})}catch(e){throw lt(e)}}},Mr=n.z.object({issueId:n.z.string().min(1).describe("Target issue key or ID for the worklog entry"),timeSpent:n.z.string().min(1).describe('Time spent text (e.g., "1h 30m")'),comment:n.z.string().optional().describe("Optional worklog comment in markdown"),author:n.z.object({accountId:n.z.string().min(1).describe("Account ID of the user logging the work")}).optional().describe("Optional author override for the worklog entry"),startingOn:n.z.string().optional().describe("Optional timestamp for when the work started (ISO)"),artifact:n.z.string().optional().describe("Optional identifier linking the worklog to another artifact")}).describe("Arguments required to add a worklog entry to a Jira issue"),$r={name:"jira-worklog-add",inputSchema:Mr,runTool:async(e,t)=>{try{const r=Mr.parse(t),i={timeSpent:r.timeSpent,issueIdOrKey:r.issueId};if(r.comment&&(i.comment=r.comment),r.author&&(i.author=r.author),r.startingOn&&(i.started=r.startingOn),r.artifact){const e=[...i.properties??[]];e.push({key:"artifact",value:r.artifact}),i.properties=e}const n=e.issueWorklogs;if(!n||"function"!=typeof n.addWorklog)throw Error("Jira issueWorklogs API is unavailable on the client");return st(await n.addWorklog(i))}catch(e){throw lt(e)}}},Fr=r.Logging.for("jira.xray");class Wr{constructor(){this.clientId=we.orThrow().xray.apiUser,this.clientSecret=we.orThrow().xray.apiSecret,this.baseUrl=we.orThrow().xray.host||"https://eu.xray.cloud.getxray.app"}async authenticate(){if(!this.clientId||!this.clientSecret)throw Error("Xray API credentials are missing (XRAY__API_USER, XRAY__API_SECRET).");const e=await fetch(this.baseUrl+"/api/v2/authenticate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:this.clientId,client_secret:this.clientSecret})}),t=await e.text();return this.token=t.replace(/"/g,""),this.token}async graphql(e,t){this.token||await this.authenticate();const r={query:e,variables:t};Fr.info("xray.graphql.request",{payload:Te(r)});try{const e=await fetch(this.baseUrl+"/api/v2/graphql",{method:"POST",headers:{Authorization:"Bearer "+this.token,"Content-Type":"application/json"},body:JSON.stringify(r)}),t=await e.json();if(Fr.info("xray.graphql.response",{status:e.status,headers:e.headers?.get?e.headers.get("content-type"):void 0,body:Te(t)}),t.errors)throw Fr.error("xray.graphql.errors",{errors:Te(t.errors)}),Error(JSON.stringify(t.errors,null,2));return t.data}catch(e){throw Fr.error("xray.graphql.failure",{error:e+""}),e}}async getTest(e){return(await this.graphql('\n query GetTest($issueId: String!) {\n getTest(issueId: $issueId) {\n issueId\n jira(fields:["key"])\n steps {\n id\n action\n data\n result\n }\n }\n }\n ',{issueId:e})).getTest}async addStep(e,t){return(await this.graphql("\n mutation AddTestStep($issueId: String!, $step: CreateStepInput!) {\n addTestStep(issueId: $issueId, step: $step) {\n id\n action\n data\n result\n }\n }\n ",{issueId:e,step:t})).addTestStep}async updateStep(e,t){return(await this.graphql("\n mutation UpdateTestStep($stepId: String!, $step: UpdateStepInput!) {\n updateTestStep(stepId: $stepId, step: $step) {\n id\n action\n data\n result\n }\n }\n ",{stepId:e,step:t})).updateTestStep}async deleteStep(e){return(await this.graphql("\n mutation RemoveTestStep($stepId: String!) {\n removeTestStep(stepId: $stepId)\n }\n ",{stepId:e})).removeTestStep}async addSteps(e,t){return Promise.all(t.map(t=>this.addStep(e,t)))}async updateSteps(e){return Promise.all(e.map(e=>this.updateStep(e.stepId,e.step)))}async deleteSteps(e){return Promise.all(e.map(e=>this.deleteStep(e)))}async syncSteps(e,t){const r=(await this.getTest(e)).steps||[],i=[],n=[],s=[];for(let e=0;e<t.length;e++){const s=t[e],a=r[e];a?a.action===s.action&&a.data===s.data&&a.result===s.result||i.push({stepId:a.id,step:s}):n.push(s)}if(r.length>t.length)for(let e=t.length;e<r.length;e++)s.push(r[e].id);await this.addSteps(e,n),await this.updateSteps(i),await this.deleteSteps(s)}}let Ur=null;const Kr=new Map;function Br(e){const t=e?.fields,r=e?.action??t?.Action??t?.action;if(!r||"string"!=typeof r)throw Error("Xray step action is required");const i=e.data??e.fields?.Data??e.fields?.data??void 0,n=e.result??e.fields?.Result??e.fields?.result??void 0;return{action:r.toString(),data:"string"==typeof i?i:void 0,result:"string"==typeof n?n:void 0}}async function Xr(e,t){if(!t)throw Error("Issue reference is required when interacting with Xray steps");if(Kr.has(t))return Kr.get(t);if(/^[0-9]+$/.test(t))return Kr.set(t,t),t;const r=e?.issues;if(!r?.getIssue)throw Error("Jira client does not expose issue lookup functionality");const i=await r.getIssue({issueIdOrKey:t,fields:["id"]}),n=i?.id;if(!n)throw Error("Unable to resolve Jira issue ID for "+t);return Kr.set(t,n),n}async function Yr(e){if(e?.test?.step)return e.test.step;const t=await(async()=>{if(Ur)return Ur;const e=we.orThrow().xray.apiUser?.trim(),t=we.orThrow().xray.apiSecret?.trim();if(!e||!t)throw Error("Xray credentials are missing (XRAY__API_USER, XRAY__API_SECRET). Please configure them before using Xray tools.");const r=await Oe(),i=new Wr,n={async createStep(e,t){const n=await Xr(r,e),s=await i.addStep(n,Br(t));return{step:s,id:s?.id}},async updateStep(e,t,n){await Xr(r,e);const s=Br(n),a=await i.updateStep(t.toString(),s);return{step:a,id:a?.id}},deleteStep:async(e,t)=>(await Xr(r,e),{success:!0===await i.deleteStep(t.toString())}),async getSteps(e){const t=await Xr(r,e),n=await i.getTest(t);return{steps:n?.steps??[]}}};return Ur={test:{step:n}},Ur})();if(!t?.test?.step)throw Error("Xray step API is unavailable on the client");return t.test.step}const Gr=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID that owns the step"),action:n.z.string().min(1).describe("Action description for the new Xray step"),data:n.z.string().optional().describe("Optional data or context used by this step"),result:n.z.string().optional().describe("Optional expected result for the step")}).describe("Inputs for adding a step to an Xray test case"),Vr={name:"jira-xray-step-add",inputSchema:Gr,runTool:async(e,t)=>{try{const r=Gr.parse(t),i=await Yr(e),n={action:r.action,data:r.data,result:r.result};return st(await i.createStep(r.issueId,n))}catch(e){throw lt(e)}}},Zr=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID that owns the step"),stepId:n.z.union([n.z.string(),n.z.number()]).describe("Identifier for the step that should be updated"),action:n.z.string().min(1).describe("New action text for the step"),data:n.z.string().optional().describe("Updated data/context for the step"),result:n.z.string().optional().describe("Updated expected result for the step")}).describe("Inputs required to modify an Xray test step"),Qr={name:"jira-xray-step-update",inputSchema:Zr,runTool:async(e,t)=>{try{const r=Zr.parse(t),i=await Yr(e),n=r.stepId+"",s={action:r.action,data:r.data,result:r.result};return st(await i.updateStep(r.issueId,n,s))}catch(e){throw lt(e)}}},ei=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID owning the step"),stepId:n.z.union([n.z.string(),n.z.number()]).describe("Identifier of the step to delete")}).describe("Arguments used to remove an Xray test step"),ti={name:"jira-xray-step-delete",inputSchema:ei,runTool:async(e,t)=>{try{const r=ei.parse(t),i=await Yr(e);return await i.deleteStep(r.issueId,r.stepId.toString()),st({success:!0})}catch(e){throw lt(e)}}},ri=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID whose steps should be returned")}).describe("Inputs required to list steps on an Xray test case"),ii={name:"jira-xray-step-list",inputSchema:ri,runTool:async(e,t)=>{try{const r=ri.parse(t),i=await Yr(e);return st(await i.getSteps(r.issueId))}catch(e){throw lt(e)}}},ni=n.z.object({linkId:n.z.string().min(1).describe("Identifier for the Jira issue link to remove")}).describe("Inputs required to delete an existing Jira issue link"),si={name:"jira-link-delete",inputSchema:ni,runTool:async(e,t)=>{try{const r=ni.parse(t),i=e.issueLinks;if(!i||"function"!=typeof i.deleteIssueLink)throw Error("Jira issueLinks API is unavailable on the client");const n={linkId:r.linkId};return await i.deleteIssueLink(n),st({success:!0,message:`Issue link ${r.linkId} deleted successfully`})}catch(e){throw lt(e)}}},ai=n.z.object({linkId:n.z.string().min(1).describe("ID of the existing issue link to change"),relationship:jr,comment:Sr.optional().describe("Optional comment to attach while recreating the link")}).describe("Inputs required to update (recreate) a Jira issue link"),oi={name:"jira-link-update",inputSchema:ai,runTool:async(e,t)=>{try{const r=ai.parse(t),i=e.issueLinks;if(!i||"function"!=typeof i.getIssueLink||"function"!=typeof i.deleteIssueLink||"function"!=typeof i.linkIssues)throw Error("Jira issueLinks API is unavailable on the client");const n=await i.getIssueLink({linkId:r.linkId});if(!n)throw Error(`Issue link ${r.linkId} not found`);const s=n.inwardIssue,a=n.outwardIssue;if(!s||!a)throw Error("Issue link payload is missing linked issues");const o=await Er(e,r.relationship);await i.deleteIssueLink({linkId:r.linkId});const c=Cr(r.comment),l={inwardIssue:Or(s),outwardIssue:Or(a),type:ci(o),...c?{comment:c}:{}};return await i.linkIssues(l),st({success:!0,message:`Issue link ${r.linkId} updated to ${r.relationship}`})}catch(e){throw lt(e)}}};function ci(e){if(e.id)return{id:e.id};if(e.name)return{name:e.name};throw Error("Resolved issue link type is missing both id and name")}function li(e=[]){return e.map(di).join("")}function di(e){switch(e.type){case"text":return(e=>{let t=e.text||"";for(const r of e.marks||[])switch(r.type){case"strong":t=`**${t}**`;break;case"em":t=`*${t}*`;break;case"strike":t=`~~${t}~~`;break;case"code":t="`"+t+"`";break;case"link":t=`[${t}](${r.attrs.href})`}return t})(e);case"mention":return e.attrs.text||"@"+e.attrs.id;case"emoji":return e.attrs.shortName||"";case"inlineCard":return e.attrs.url;case"status":return`:status{color="${e.attrs.color}"}[${e.attrs.text}]`;case"hardBreak":return" \n"}return""}function ui(e){switch(e.type){case"heading":return"#".repeat(e.attrs?.level)+" "+li(e.content);case"paragraph":return li(e.content);case"blockquote":return e.content.map(ui).map(e=>"> "+e).join("\n");case"bulletList":case"orderedList":case"taskList":return(e=>{const t=[];let r=1;for(const i of e.content){let n="- ";"orderedList"===e.type&&(n=r+++". "),"taskList"===e.type&&(n="- "+("DONE"===i.attrs?.state?"[x] ":"[ ] "));const s=i.content.map(ui).join(" ");t.push(n+s)}return t.join("\n")})(e);case"table":return(e=>{const t=e.content||[];return t.length?["| "+t[0].content.map(e=>li(e.content[0].content)).join(" | ")+" |","| "+t[0].content.map(()=>"---").join(" | ")+" |",...t.slice(1).map(e=>e.content.map(e=>li(e.content[0].content)).join(" | ")).map(e=>"| "+e+" |")].join("\n"):""})(e);case"codeBlock":return"```"+(e.attrs?.language||"")+"\n"+e.content?.map(e=>e.text).join("")+"\n```";case"panel":return(e=>`::panel{type="${e.attrs?.panelType||"info"}"}\n${e.content.map(ui).join("\n")}\n::`)(e);case"rule":return"---";case"mediaSingle":return(e=>{const t=e.content?.[0];return t?"external"===t.attrs?.type?``:"file"===t.attrs?.type?`[attachment](attachment:${t.attrs.id})`:"":""})(e);case"blockCard":return e.attrs?.url}return""}const pi=n.z.object({document:sr.describe("Jira ADF document you want to translate into Markdown (use jira-md-to-adf to go the other way).")}).describe("Convert Jira ADF documents back to Markdown text for editing or review"),mi={name:"jira-adf-to-markdown",inputSchema:pi,runTool:async(e,t)=>{return st({markdown:(r=pi.parse(t).document,(e=>{if(!e||"doc"!==e.type)return"";const t=[];for(const r of e.content||[])t.push(ui(r));return t.join("\n\n")})(r))});var r}},hi={[at.name]:{title:"Jira Issue Create",description:"Create a Jira issue (optionally applying a markdown template)",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[ft.name]:{title:"Jira Issue Read",description:"Read a Jira issue with expandable fields and properties",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[ht.name]:{title:"Jira Issue List",description:"Search issues by summary, reference, parent, or JQL and list the matching tickets",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[ur.name]:{title:"Jira Issue Update",description:"Update a Jira issue using fields, update ops, and property toggles",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[mr.name]:{title:"Jira Markdown to ADF",description:"Convert Markdown into a sanitized Jira ADF document so fields.description can be supplied to jira-issue-update and other tools that expect Jira documents",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[mi.name]:{title:"Jira ADF to Markdown",description:"Translate Jira ADF documents back into Markdown text so you can edit them before sending them through tooling or LLM prompts (use jira-md-to-adf to get valid ADF inputs).",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[ut.name]:{title:"Jira Issue Delete",description:"Delete a Jira issue and optionally remove its subtasks",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[bt.name]:{title:"Jira Issue Transition",description:"Transition a Jira issue while optionally adding a comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[vt.name]:{title:"Jira Transition List",description:"List available transitions for a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[gr.name]:{title:"Jira Issue Assign",description:"Assign a Jira issue to a user or account",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[yr.name]:{title:"Jira Issue Unassign",description:"Unassign the current owner from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[wr.name]:{title:"Jira Comment Add",description:"Add a comment to a Jira issue with optional visibility",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[zr.name]:{title:"Jira Comment List",description:"List comments on a Jira issue with pagination support",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Dr.name]:{title:"Jira Link Create",description:"Create an issue link relationship with optional comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[oi.name]:{title:"Jira Link Update",description:"Change the relationship type for an existing issue link",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[si.name]:{title:"Jira Link Delete",description:"Delete an issue link from Jira",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Pr.name]:{title:"Jira Attachment Add",description:"Attach a local file to a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[qr.name]:{title:"Jira Attachment List",description:"List attachments on a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Lr.name]:{title:"Jira Attachment Delete",description:"Delete an attachment from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[$r.name]:{title:"Jira Worklog Add",description:"Log time spent on a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Vr.name]:{title:"Jira Xray Step Add",description:"Add a step to an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Qr.name]:{title:"Jira Xray Step Update",description:"Update a step on an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[ti.name]:{title:"Jira Xray Step Delete",description:"Delete a step from an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[ii.name]:{title:"Jira Xray Step List",description:"List steps for an Xray test case",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}}};async function gi(e){const t=r.Logging.for(gi);let i,n=null;try{i=await Oe()}catch(e){if(!(e instanceof ke))return void t.warn("Skipping Jira tool registration; unable to create Jira client",{error:e});n=e,t.warn("Registering Jira tools without credentials; each tool will report configuration requirements.",{error:e})}const s=[at,ft,ht,ur,mr,mi,ut,bt,vt,gr,yr,wr,zr,Dr,oi,si,Pr,qr,Lr,$r,Vr,Qr,ti,ii];for(const r of s){const s=hi[r.name];if(s)try{await e.registerTool(r.name,{title:s.title,description:s.description,inputSchema:r.inputSchema,annotations:s.annotations},async e=>{if(!i)throw n??Error("Jira client unavailable because credentials could not be loaded.");return await r.runTool(i,e)}),t.info("Registered Jira tool "+r.name)}catch(e){t.error("Failed to register Jira tool "+r.name,{error:e})}}}const fi=e=>{try{p.appendFileSync("/tmp/register-tools.log",e+"\n")}catch{}};async function yi(e){const t=r.Logging.for(yi);fi("registerTools start");try{await(async e=>{await e.registerTool("file-summarizer",{title:"File summarizer",description:"Summarizes a file so the model knows the gist before making decisions; defaults to README.md when no path is supplied.",inputSchema:pe.shape,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},async e=>(async e=>{const t=e?.filePath?o.resolve(process.cwd(),e.filePath):ue;let r,i="ok";try{r=(await m.readFile(t,"utf8")).split(/\r?\n/).filter(e=>e.trim().length>0).slice(0,10).join(" ").slice(0,800),r=r||"(file contained no readable content)"}catch(t){i="error";const n=t instanceof Error?t.message:"unknown error reading file";r=`Unable to summarize ${e?.filePath??"README.md"}: ${n}`}const n={filePath:t,status:i,summary:r};return{content:[{type:"text",text:r}],structuredContent:n,result:n}})(e))})(e),t.verbose("Registered file summarizer tool"),fi("file summarizer registered")}catch(e){t.error("Failed to register file summarizer tool",e),fi("file summarizer failed: "+e.message)}try{await(async e=>{e.registerTool("decaf-server-info",{title:"Decaf MCP Server Info",description:"Return read-only server metadata, version, and registered prompt lists so callers can discover what exposures are available without side effects.",inputSchema:{},outputSchema:void 0,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},async()=>{const e=de.map(e=>e.getName()).sort();return{content:[{type:"text",text:["Name: "+we.name,"Title: "+we.title,"Version: "+we.version,"Prompts: "+(e.join(", ")||"<none>")].join("\n")}]}})})(e),fi("server info registered")}catch(e){t.error("Failed to register server info tool",e),fi("server info failed: "+e.message)}try{await gi(e)}catch(e){t.error("Failed to register Jira tools",e)}}class bi extends q{setCb(e){return this.cb=e,this}setConfig(e){return this.config=e,this}setUriOtTemplate(e){return this.uriOrTemplate=e,this}constructor(e){super(e)}static get builder(){return new bi}build(e){const t=this.hasErrors();if(t)throw Error(t.toString());try{const t="string"==typeof this.uriOrTemplate&&this.uriOrTemplate.includes("{")?new v.ResourceTemplate(new z.UriTemplate(this.uriOrTemplate),{list:void 0}):this.uriOrTemplate,r=Object.assign(this.config,{_meta:{}}),i=async(e,t)=>{const r=this.logFor(t);r.verbose(`Requesting resource ${this.name} from ${e.toString()}`);const i=await Promise.resolve(this.cb(e,t));return r.verbose(`Resource ${this.name} retrieved successfully.`),r.debug("Resource retrieval meta: "+JSON.stringify(i._meta)),i};return e.resource(this.name,t,r,i)}catch(e){throw r.Logging.for(this).error("Error registering resource "+this.name,e),e}}}C([i.required(),J("design:type",Object)],bi.prototype,"uriOrTemplate",void 0),C([i.required(),J("design:type",Function)],bi.prototype,"cb",void 0),C([i.required(),J("design:type",Object)],bi.prototype,"config",void 0);const wi=V()??A.join(__dirname,"..","assets"),vi=A.join(wi,"templates"),zi=A.join(wi,"prompts");function ji(e,t){const r=T.readdirSync(e,{withFileTypes:!0}).filter(e=>e.isFile()).map(e=>e.name).sort(),i=new Set(t),n=new Map;for(const t of r){const r=A.join(e,t),s=A.extname(t);if(!i.has(s))continue;const a=A.basename(t,s),o=n.get(a);if(o){if(".md"===A.extname(o)){if(".md"===s)continue;continue}if(".md"===s){n.set(a,r);continue}}else n.set(a,r)}return n}function ki(e){if(e.endsWith(".enc"))return F(T.readFileSync(e)).toString("utf-8");try{return T.readFileSync(e,"utf8")}catch(e){if("ENOENT"!==e.code)throw e}const t=(e=>e.endsWith(".enc")?e:A.extname(e)?e.slice(0,-A.extname(e).length)+".enc":e+".enc")(e);if(!T.existsSync(t))throw Error("Asset not found: "+e);return F(T.readFileSync(t)).toString("utf-8")}const Ii=A.join(__dirname,"..","assets"),Si=V()||Ii,xi=A.join(Si,"resources");function Ti(e){const t=A.join(xi,e);try{return T.readFileSync(t,"utf-8")}catch(e){if("ENOENT"!==e.code)throw e}const r=(e=>{const t=A.extname(e);return t?e.slice(0,-t.length)+".enc":e+".enc"})(t);if(!T.existsSync(r))throw Error("Asset not found: "+e);return F(T.readFileSync(r)).toString("utf-8")}const Ai="resource://repo.metadata",Ei=(()=>{const e=Ti("repo-metadata.json");return JSON.parse(e)})(),Oi=bi.builder.setName("repo.metadata").setTitle("Repository metadata snapshot").setDescription("Deterministic metadata about the decaf-ts MCP server, Jira defaults, and the canonical project key.").setUriOtTemplate(Ai).setConfig({mimeType:"application/json",description:"Static repository metadata that documents the MCP surface."}).setCb(async()=>{const e=we.version,t=we.jira.projectKey??Ei.jira?.projectKey??"DECAF",r={...Ei,version:e,projectKey:t};return{contents:[{uri:Ai,mimeType:"application/json",text:JSON.stringify(r,null,2)}],_meta:{source:"assets/repo-metadata.json"}}}),Ci="resource://decoration.schematic.metadata",Ji=Ti("decoration/metadata.json"),Di=bi.builder.setName("decoration.schematic.metadata").setTitle("Decoration metadata schematic").setDescription("Outlines the annotation and field metadata contracts that decorators expose.").setUriOtTemplate(Ci).setConfig({mimeType:"application/json",description:"Annotation metadata definitions for decorator tooling."}).setCb(async()=>({contents:[{uri:Ci,mimeType:"application/json",text:Ji}],_meta:{schematic:"metadata"}})),Ni="resource://decoration.schematic.builder",Ri=Ti("decoration/builder.json"),Pi=bi.builder.setName("decoration.schematic.builder").setTitle("Decoration builder pattern schematic").setDescription("Describes how decorated models spawn builder classes with fluent setters and validation.").setUriOtTemplate(Ni).setConfig({mimeType:"application/json",description:"Builder conventions for decorated models."}).setCb(async()=>({contents:[{uri:Ni,mimeType:"application/json",text:Ri}],_meta:{schematic:"builder"}})),Hi="resource://decoration.schematic.validation",qi=Ti("decoration/validation.json"),_i=bi.builder.setName("decoration.schematic.validation").setTitle("Decoration validation schematic").setDescription("Tracks how decorator metadata flows through validation routines and error serialization.").setUriOtTemplate(Hi).setConfig({mimeType:"application/json",description:"Validation lifecycle and error contract for decorated models."}).setCb(async()=>({contents:[{uri:Hi,mimeType:"application/json",text:qi}],_meta:{schematic:"validation"}})),Li="resource://golden.override.model-builder",Mi=Ti("golden/model-builder.txt"),$i=bi.builder.setName("golden.override.model-builder").setTitle("Golden override: model builder snippet").setDescription("A coding template that shows how a Model builder keeps setters fluent and enforces validation.").setUriOtTemplate(Li).setConfig({mimeType:"text/plain",description:"Model builder golden snippet for copy/paste reference."}).setCb(async()=>({contents:[{uri:Li,mimeType:"text/plain",text:Mi}],_meta:{override:"model-builder"}})),Fi="resource://golden.override.validation-errors",Wi=Ti("golden/validation-errors.json"),Ui=bi.builder.setName("golden.override.validation-errors").setTitle("Golden override: validation error report").setDescription("Shows the structure returned when decorator validation fails, including error arrays and metadata.").setUriOtTemplate(Fi).setConfig({mimeType:"application/json",description:"Example validation error payload emitted by decorated models."}).setCb(async()=>({contents:[{uri:Fi,mimeType:"application/json",text:Wi}],_meta:{override:"validation-errors"}})),Ki="resource://golden.override.xray-step-template",Bi=Ti("golden/xray-step-template.txt"),Xi=[Oi,Di,Pi,_i,$i,Ui,bi.builder.setName("golden.override.xray-step-template").setTitle("Golden override: Xray step template").setDescription("A compliant Xray test-step template that lists the precondition, action, and verification.").setUriOtTemplate(Ki).setConfig({mimeType:"text/plain",description:"Template for documenting Xray steps."}).setCb(async()=>({contents:[{uri:Ki,mimeType:"text/plain",text:Bi}],_meta:{override:"xray-step-template"}}))];async function Yi(e){const t=r.Logging.for(Yi);for(const r of Xi)try{await r.build(e),t.info("Registered resource "+r.getName())}catch(e){t.error("Failed to register resource "+r.getName(),e)}}const Gi=new WeakMap;function Vi(e){try{p.appendFileSync("/tmp/mcp-debug.log",`${(new Date).toISOString()} ${e}\n`)}catch{}}class Zi extends r.LoggedClass{get client(){const e=Gi.get(this);if(!e)throw Error("Mcp server requires Mcp client");return e}constructor(){super()}async load(){const e=this.log.for(this.load);for(const t of de)try{e.info("loading prompt "+t.getName());const r=t.build(this.client);e.verbose(`Loaded prompt ${r.title} from ${t.getName()} definition`)}catch(r){e.error("Failed to load prompt "+t.getName(),r)}try{await yi(this.client),e.verbose("Registered built-in tools")}catch(e){}try{await Yi(this.client),e.verbose("Registered built-in resources")}catch(e){}try{await(async(e,t)=>{t.info("Registering agent templates as resources...");const r=ji(vi,[".md",".enc"]);for(const[i,n]of r){const r=bi.builder.setName(i).setTitle("Template: "+i).setDescription("Resource template for "+i).setUriOtTemplate(new v.ResourceTemplate(new z.UriTemplate("resource://template."+i),{list:void 0})).setConfig({mimeType:"text/markdown",description:"Template for "+i}).setCb(async e=>{const t=ki(n);return{contents:[{uri:e.toString(),text:t,mimeType:"text/markdown"}],_meta:{source:n}}});try{r.build(e),t.info("Registered template: "+i)}catch(e){t.error(`Failed to register template ${i}:`,e)}}t.info("Registering agent prompts...");const i=ji(zi,[".md",".enc"]);for(const[r,s]of i){const i=ki(s),a=Q.builder.setName(r).setTitle("Prompt: "+r).setDescription("Dynamic prompt for "+r).setArgsSchema(n.z.object({})).setCb(async e=>({messages:[{role:"user",content:{type:"text",text:i}}],_meta:{}}));try{a.build(e),t.info("Registered prompt: "+r)}catch(e){t.error(`Failed to register prompt ${r}:`,e)}}})(this.client,e)}catch(e){}}async boot(e="stdio"){"stdio"===e&&r.Logging.setFactory(O),r.Logging.for(this.constructor.name);const t=((Array.isArray(we.icons)?we.icons:[we.icons])||[]).map(e=>{const t="string"==typeof e?.src?e.src:(e?.src??"")+"",r="string"==typeof e?.mimeType?e.mimeType:(e?.mimeType??"")+"";let i=[];return Array.isArray(e?.sizes)?i=e.sizes.map(e=>e+""):"string"==typeof e?.sizes&&(i=(e.sizes+"").split(",").map(e=>e.trim())),{src:t,mimeType:r,sizes:i}}),i={name:we.name,title:we.title,websiteUrl:we.websiteUrl,version:we.version,icons:t},n=new v.McpServer(i,{instructions:"You are an AI assistant designed to help users with programming tasks related to the Decaf-TS framework. \nProvide clear, concise, and accurate information.\nIf you don't know the answer, admit it rather than making up information.\nAlways prioritize the user's intent and provide helpful suggestions when appropriate.\n",capabilities:{logging:{},tools:{},prompts:{}}});switch((e=>{const t=e,r=t.server?.setRequestHandler?.bind(t.server);r&&(t.server.setRequestHandler=(e,t)=>{let i=t;return k.ListToolsRequestSchema&&e===k.ListToolsRequestSchema&&(i=async(...e)=>{Vi("ListTools handler invoked");const r=await t(...e);return Vi("ListTools result: "+(r?.tools?.map(e=>e.name).filter(Boolean).join(", ")||"<none>")),r}),r(e,i)});const i=t.server?.registerCapabilities?.bind(t.server);i&&(t.server.registerCapabilities=e=>(e?.tools?.listChanged&&Vi("Server registering tools.listChanged capability"),i(e)));const n=t.setToolRequestHandlers?.bind(t);n&&(t.setToolRequestHandlers=()=>{Vi("client.setToolRequestHandlers start");const e=n();return Vi("client.setToolRequestHandlers done"),e})})(n),((e,t)=>{Gi.set(e,t)})(this,n),n.onerror=e=>{this.log.error("MCP instance onerror",e)},e){case"stdio":e=new I.StdioServerTransport;break;case"http":e=new S.StreamableHTTPServerTransport({sessionIdGenerator:()=>j.v4(),onsessioninitialized:e=>{},onsessionclosed:e=>{},enableJsonResponse:!0,eventStore:void 0});break;default:if(!(s=e)||"object"!=typeof s||"function"!=typeof s.send&&"function"!=typeof s.close&&"function"!=typeof s.on)throw new c.InternalError("Invalid transport type: "+e)}var s;try{await this.load()}catch(e){throw e}if(await this.client.connect(e),"1"===process.env.MCP_DEBUG_TOOLS)try{const e=this.client;"function"==typeof e.listTools&&((await e.listTools({})).tools||[]).map(e=>e.name).join(", ")}catch(e){}}}const Qi=new e.Command("start").option("--transport [String]","transport mode","stdio").description("starts decaf's mcp server").action(async e=>{const r=Y("package.json"),i=JSON.parse(t.readFileSync(r,"utf-8")),{transport:n}=e,s=(new E).for("mcp-server");if("stdio"!==n)throw Error("Unsupported transport mode: "+n);s.info("Transport stdio"),s.debug(`running with options: ${JSON.stringify(e)} for ${i.name} version ${i.version}`);const a=new Zi;await a.boot(n),s.info("Decaf MCP server is now running. Press CTRL+C to stop."),await(async e=>{const t=["SIGINT","SIGTERM"];await new Promise(r=>{let i=!1;const n=setInterval(()=>{},1e6),s=async()=>{if(!i){i=!0,clearInterval(n);try{const t=e.client;t?.close&&await t.close()}catch{}finally{r()}}};for(const e of t)process.once(e,s)})})(a)}),en=new e.Command("md-to-ast").description("pipes markdown to jira ast: `cat file.md` | npx decaf-mcp md-to-ast > ast.json").action(async e=>{const i=Y("package.json"),n=JSON.parse(t.readFileSync(i,"utf-8")),s=n.version;r.Logging.for("md-to-ast").debug(`running with options: ${JSON.stringify(e)} for ${n.name} version ${s}`);const a=Ze(await(async()=>{const e=[];for await(const t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")})(),{resolveMention:e=>({id:e,text:"@"+e}),resolveAttachment:e=>({id:e,collection:"attachments"})});process.stdout.write(JSON.stringify(a,null,2)+"\n")}),tn=(new e.Command).name("decaf-mcp").description("decaf mcp server and agentic functionality").addCommand(Qi).addCommand(en);"undefined"!=typeof require&&require.main===module&&tn.parseAsync(process.argv).catch(e=>{process.exit(1)})},"object"==typeof exports&&"undefined"!=typeof module?t(require("commander"),require("fs"),require("@decaf-ts/logging"),require("@decaf-ts/decorator-validation"),require("zod"),require("@decaf-ts/injectable-decorators"),require("@decaf-ts/decoration"),require("path"),require("@decaf-ts/db-decorators"),require("crypto"),require("zlib"),require("url"),require("node:fs"),require("fs/promises"),require("node:util"),require("node:module"),require("unified"),require("remark-directive"),require("remark-gfm"),require("remark-parse"),require("@modelcontextprotocol/sdk/server/mcp.js"),require("@modelcontextprotocol/sdk/shared/uriTemplate.js"),require("uuid"),require("@modelcontextprotocol/sdk/types.js"),require("@modelcontextprotocol/sdk/server/stdio.js"),require("@modelcontextprotocol/sdk/server/streamableHttp.js")):"function"==typeof define&&define.amd?define(["commander","fs","@decaf-ts/logging","@decaf-ts/decorator-validation","zod","@decaf-ts/injectable-decorators","@decaf-ts/decoration","path","@decaf-ts/db-decorators","crypto","zlib","url","node:fs","fs/promises","node:util","node:module","unified","remark-directive","remark-gfm","remark-parse","@modelcontextprotocol/sdk/server/mcp.js","@modelcontextprotocol/sdk/shared/uriTemplate.js","uuid","@modelcontextprotocol/sdk/types.js","@modelcontextprotocol/sdk/server/stdio.js","@modelcontextprotocol/sdk/server/streamableHttp.js"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).commander,e.fs,e.logging,e.decoratorValidation,e.zod,e.injectableDecorators,e.decoration,e.path,e.dbDecorators,e.crypto,e.zlib,e.url,e.node_fs,e.fsPromises,e.node_util,e.node_module,e.unified,e.remarkDirective,e.remarkGfm,e.remarkParse,e.mcp_js,e.uriTemplate_js,e.uuid,e.types_js,e.stdio_js,e.streamableHttp_js);
|
|
2
|
+
var e,t;e=this,t=function(e,t,r,i,n,o,s,a,c,p,d,l,u,m,h,g,f,y,b,w,v,k,j,z,T,x,S,I,E,A){"use strict";function R(e){var t=Object.create(null);return e&&Object.keys(e).forEach(r=>{if("default"!==r){var i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:()=>e[r]})}}),t.default=e,Object.freeze(t)}var O=R(t),P=R(a);class C extends r.MiniLogger{constructor(e,t,r){super(e,t,r)}log(e,t,i,n){const o=this.config("level");r.NumericLogLevels[o],r.NumericLogLevels[e]}}const N=(e,t,...r)=>{const i=(e=>{if("string"==typeof e)return e;if(!e)return"unknown";if("function"==typeof e)return e.name||"unknown";if("object"==typeof e&&"constructor"in e){const t=e.constructor;if(t&&t.name)return t.name}return"unknown"})(e);return new C(i,t)};function J(e,t,r,i){var n,o=arguments.length,s=3>o?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,r,i);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(s=(3>o?n(s):o>3?n(t,r,s):n(t,r))||s);return o>3&&s&&Object.defineProperty(t,r,s),s}function D(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}var _,F,$,M,q;"function"==typeof SuppressedError&&SuppressedError,(e=>{e[e.NONE=0]="NONE",e[e.BASIC=1]="BASIC",e[e.ADVANCED=2]="ADVANCED",e[e.HIGH=3]="HIGH"})(_||(_={})),(e=>{e[e.NONE=0]="NONE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(F||(F={})),(e=>{e[e.FREE=0]="FREE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})($||($={}));class L extends i.Model{get log(){return this._log||(this._log=r.Logging.for(this)),this._log}constructor(e){super(e)}logFor(e){const{sessionId:t,requestId:r,authInfo:i}=e||{};let n="string"==typeof t&&t.length>0?this.log.for(t):this.log;return i&&i.clientId&&(n=n.for(i.clientId)),r&&(n=n.for(r.toString())),n}setDescription(e){return this.description=e,this}getDescription(){return this.description}setName(e){return this.name=e,this}getName(){return this.name}setTitle(e){return this.title=e,this}}J([i.required(),D("design:type",String)],L.prototype,"description",void 0),J([i.required(),D("design:type",String)],L.prototype,"name",void 0),J([i.required(),D("design:type",String)],L.prototype,"title",void 0);class H extends L{constructor(e){super(e),this.reasoning=_.NONE,this.effort=F.NONE,this.cost=$.FREE}setReasoning(e){return this.reasoning=e,this}setEffort(e){return this.effort=e,this}setCost(e){return this.cost=e,this}}function G(e){if(!e)return;let t=e,r=t&&t._def;for(;r&&"ZodObject"!==r.typeName;){if("ZodEffects"===r.typeName&&r.schema)t=r.schema;else if("ZodOptional"===r.typeName&&r.innerType)t=r.innerType;else if("ZodDefault"===r.typeName&&r.innerType)t=r.innerType;else if("ZodNullable"===r.typeName&&r.innerType)t=r.innerType;else{if(!r.schema)return;t=r.schema}r=t&&t._def}return r&&"ZodObject"===r.typeName?r:void 0}function U(e){return!(!e||"object"!=typeof e||!e._def)}J([i.required(),D("design:type",Number)],H.prototype,"reasoning",void 0),J([i.required(),D("design:type",Number)],H.prototype,"effort",void 0),J([i.required(),D("design:type",Number)],H.prototype,"cost",void 0),(e=>{e.ASSETS="assets"})(M||(M={})),(e=>{e.PROMPT="prompts",e.DOCUMENTATION="documentation",e.CODE="code"})(q||(q={}));const W=Buffer.from("DCAF1","ascii");function K(e){if(e.length<W.length+16+12+16)throw Error("Invalid prompt payload (too short)");if(!e.subarray(0,W.length).equals(W))throw Error("Invalid prompt payload (bad magic)");const t=process.env.ENCRYPTION_KEY||"";if(!t)throw Error("Missing encryption key. Set ENCRYPTION_KEY to load obfuscated assets.");let r=W.length;const i=e.subarray(r,r+16);r+=16;const n=e.subarray(r,r+12);r+=12;const o=e.subarray(r,r+16);r+=16;const s=e.subarray(r),a=((e,t)=>p.scryptSync(e,t,32))(t,i),c=p.createDecipheriv("aes-256-gcm",a,n);c.setAuthTag(o);const l=Buffer.concat([c.update(s),c.final()]);return d.gunzipSync(l)}function B(e){let r=a.resolve(e);for(;;){if(t.existsSync(a.join(r,"package.json")))return r;const e=a.dirname(r);if(e===r)break;r=e}}const Y=process.argv?.[1]?B(a.dirname(a.resolve(process.argv[1]))):void 0,X=(()=>{const e=Error().stack;if(!e)return;const t=e.split(/\r?\n/).slice(1);for(const e of t){const t=e.match(/\(?([^()]+?):\d+:\d+\)?/);if(!t)continue;let r=t[1];if(r.startsWith("file://"))try{r=l.fileURLToPath(r)}catch{continue}if(!r.includes("node:internal"))return a.dirname(r)}})(),V=X?B(X):void 0,Z=Y??V??process.cwd();function Q(...e){return a.join(Z,...e)}function ee(e){let t=e;for(;;){const e=P.join(t,"lib","assets");if(O.existsSync(e))return e;const r=P.join(t,"src","assets");if(O.existsSync(r))return r;const i=P.join(t,"assets");if(O.existsSync(i))return i;const n=P.dirname(t);if(n===t)break;t=n}}function te(){const e=process.env.DECAF_ASSET_DIR||process.env.MCP_ASSET_DIR||process.env.ASSET_DIR||"";if(e&&O.existsSync(e))return e;const t=ee(__dirname);if(t)return t;const r=process.argv?.[1];if(r){const e=ee(P.dirname(r));if(e)return e}const i=[Z,process.env.INIT_CWD].filter(Boolean);for(const e of i){const t=ee(e);if(t)return t}return Q("assets")}let re=class extends r.LoggedClass{constructor(e){super(),this.basePath=e||te()}listAssets(...e){const t=P.join(this.basePath,...e);return O.readdirSync(t)}listPrompts(){return this.listAssets(q.PROMPT)}getAsset(e,t="md",...r){const i=P.join(this.basePath,...r),n=(e,t=!1)=>{try{return t?K(O.readFileSync(e)).toString("utf-8"):O.readFileSync(e,"utf-8")}catch(e){if("ENOENT"===e.code)return null;throw e}},o=n(P.join(i,`${e}.${t}`),"enc"===t);if(null!==o)return o;const s=n(P.join(i,e+".enc"),!0);if(null!==s)return s;throw Error("Asset not found: "+P.join(i,`${e}.${t}`))}getAllAssets(e,...t){return this.listAssets(e,...t).reduce((r,i)=>{const n=P.extname(i),o=P.basename(i,n),s=n.replace(/^\./,"")||void 0;return r[o]=this.getAsset(o,s??void 0,e,...t),r},{})}toPromptDef(e){const t=e=>"number"==typeof e?e:"string"==typeof e?(e=>{switch(e){case"none":return _.NONE;case"basic":return _.BASIC;case"advanced":return _.ADVANCED;case"high":return _.HIGH;case"medium":return F.MEDIUM;case"low":return $.LOW;case"free":return $.FREE;default:throw new c.InternalError("Cannon convert unknown level "+e)}})(e.toLowerCase()):_.NONE;return e.effort=t(e.effort),e.reasoning=t(e.reasoning),e.cost=t(e.cost),e}getPrompt(e,...t){const i=this.getAsset(r.toSnakeCase(e),"json",q.PROMPT,...t);let n;try{n=JSON.parse(i)}catch(r){throw new c.SerializationError(`Failed to parse prompt ${e} in categories ${t}: ${r}`)}return this.toPromptDef(n)}getAllPrompts(...e){const t=this.getAllAssets(q.PROMPT,...e);return Object.entries(t).reduce((t,[r,i])=>{try{t[r]=JSON.parse(i)}catch(t){throw new c.SerializationError(`Failed to parse prompt ${r} in categories ${e}: ${t}`)}return t},t)}};re=J([o.injectable(),D("design:paramtypes",[String])],re);class ie extends H{constructor(e){super(e)}setCb(e){return this.cb=e,this}setArgsSchema(e){return this.argsSchema=e,this}static get builder(){return new ie}static patchPrompt(e,t,i,n){const o=(t=Array.isArray(t)?t:Object.keys(t)).filter(e=>!Object.prototype.hasOwnProperty.call(i,e));if(o.length)throw new c.ValidationError("Missing replacements for placeholders: "+o.join(", "));n&&(n.verbose("Patching prompt with placeholders: "+JSON.stringify(t)),n.debug("Values: "+JSON.stringify(i)));const s=t.reduce((e,t)=>(e[t]=i[t],e),{});return r.sf(e,s)}patchPrompt(e,t,r,i){return ie.patchPrompt(e,t,r,i||this.log.for(this.patchPrompt))}build(e,t){const r=this.log.for(this.build),i=this.hasErrors();if(i)throw new c.ValidationError(i.toString());try{this.argsSchema&&((e,t="schema")=>{if(G(e))return e;if(e&&"object"==typeof e){const t=e.def&&"object"==typeof e.def?e.def:void 0,r=t&&(t.shape||"object"===t.type)&&t.shape||("object"===e.type?e.shape:void 0)||(t&&"object"===t.type?{}:void 0);if(t||"object"===e.type||r){const e={};if(r&&"object"==typeof r)for(const[t,i]of Object.entries(r))e[t]=U(i)?i:n.z.any();return n.z.object(e)}}throw Error(`Registration error: provided a non-canonical ${t}. Export a ZodObject (z.object(...)).`)})(this.argsSchema,"argsSchema");const r=(e=>{if(!e)return;if(e&&"object"==typeof e&&!e._def)return e.def&&"object"==typeof e.def&&e.def.shape?e.def.shape:e;const t=G(e);return t?"function"==typeof t.shape?t.shape():t.shape||void 0:void 0})(this.argsSchema);return e.registerPrompt(this.name,{title:this.title,description:this.description,argsSchema:r},async(e,r)=>{const i=this.logFor(r);e=Object.assign({},t,e||{}),i.verbose(`Executing prompt ${this.name} with args: ${JSON.stringify(e)}`),e._meta=Object.assign(e._meta||{},{usage:{reasoning:this.reasoning,effort:this.effort,cost:this.cost}});const n=await Promise.resolve(this.cb(e,r));return i.verbose(`Prompt ${this.name} executed successfully.`),i.debug("Prompt execution meta: "+JSON.stringify(n._meta)),n})}catch(e){throw r.error("Failed to register prompt "+(this.name||this.constructor.name),e),e}}}J([o.inject(re),D("design:type",re)],ie.prototype,"assets",void 0),J([i.required(),D("design:type",Object)],ie.prototype,"cb",void 0),J([i.required(),D("design:type",n.ZodObject)],ie.prototype,"argsSchema",void 0),J([s.prop(),D("design:type",Object)],ie.prototype,"placeholders",void 0);class ne extends ie{setCategory(e){return this.promptCategory=e,this}addPrefix(e){return this.prefixes=this.prefixes||[],this.prefixes.push(e),this}addSuffix(e){return this.suffixes=this.suffixes||[],this.suffixes.push(e),this}constructor(e){super(e)}build(e){const t=this.assets.getPrompt(this.name,this.promptCategory);i.Model.fromObject(this,t);const r=new Set((s.Metadata.properties(ne)||[]).filter(e=>!["assets","promptCategory","prefixes","suffixes"].includes(e)));["cb","argsSchema"].forEach(e=>r.add(e));const o=this.hasErrors(...Array.from(r));if(o)throw new c.ValidationError(o.toString());const a=(this.prefixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),p=(this.suffixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),d=[...new Set([...t.placeholders,...a.map(e=>e.placeholders||[]),...p.map(e=>e.placeholders||[])].flat())].reduce((e,t)=>(e[t]=n.z.string().describe("The description for "+t),e),{});return this.setArgsSchema(n.z.object(d)),this.setCb((e,t)=>{const r=this.logFor(t).for(ne).for(this.promptCategory).for(this.name);function i(e=[]){return Array.isArray(e)?e:Object.keys(e)}const n=(this.prefixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),o=(this.suffixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),s=this.assets.getPrompt(this.name,this.promptCategory),a=[...new Set([...n.map(e=>i(e.placeholders)).flat(),...o.map(e=>i(e.placeholders)).flat(),...i(s.placeholders).flat()])];return{messages:[{role:"user",content:{type:"text",text:this.patchPrompt([...n.map(e=>e.prompt),s.prompt,...o.map(e=>e.prompt)].join("\n\n"),a,e,r)}}],_meta:{}}}),super.build(e)}setReasoning(e){throw new c.InternalError("Named prompt builders don't require callback")}setEffort(e){throw new c.InternalError("Named prompt builders don't require callback")}setCost(e){throw new c.InternalError("Named prompt builders don't require callback")}setDescription(e){throw new c.InternalError("Named prompt builders don't require callback")}setTitle(e){throw new c.InternalError("Named prompt builders don't require callback")}static get builder(){return new ne}}J([i.required(),D("design:type",String)],ne.prototype,"promptCategory",void 0),J([i.list(String),i.minlength(1),D("design:type",Array)],ne.prototype,"prefixes",void 0),J([i.minlength(1),i.list(String),D("design:type",Array)],ne.prototype,"suffixes",void 0);const oe=ie.builder.setName("interactive-jsdoc").setTitle("Interactive JSDoc helper prompt").setDescription("Interactive JSDoc helper that mirrors common doc-health prompts; provide a gist to steer the assistant.").setArgsSchema(n.z.object({gist:n.z.string().optional()})).setCb(async e=>{const t=e.gist??"interactive jsdoc response";return{messages:[{role:"assistant",content:{type:"text",text:t}}],content:[],structuredContent:{message:t},result:{message:t}}}),se=Object.assign(oe,{name:oe.getName()});var ae;function ce(e,t=[],r=[]){const i=ne.builder.setCategory(ae.DOCS).setName(e);return["prefix",...t].forEach(e=>i.addPrefix(e)),["suffix",...r].forEach(e=>i.addSuffix(e)),i}(e=>{e.DOCS="documentation",e.CODE="code"})(ae||(ae={}));const pe=[ce("class"),ce("constant"),ce("decorator"),ce("function"),ce("module"),ce("file"),ce("repo",[],["iterate"])],de=n.z.object({className:n.z.string().describe("the class name to turn into a builder")}),le=ie.builder.setName("ts-code-dp-builder").setTitle("Typescript builder design pattern prompt").setDescription("Generate a builder pattern implementation for a class so the assistant knows to emit chained setters plus Model validation.").setArgsSchema(de).setReasoning(_.BASIC).setCb((e,t)=>(e.className=r.toPascalCase(e.className),{messages:[{role:"user",content:{type:"text",text:`You're a senior TypeScript developer writing typescript code.You're a senior TypeScript developer writing typescript code.\nTransform the selected class into a builder design pattern implementation in Typescript.\nuse @decaf-ts validation decorators to enforce the validation of your builder.\n\n- must extend the Model Class from @decaf-ts/decorator-validation;\n- each property must be marked as protected;\n- each property must have a setter method that returns 'this' for chaining;\n- the build() method must validate the properties using hasErrors() method from Model class;\n- if validation fails, throw an error with the validation errors;\n- if validation passes, return an instance of the original class with the set properties;\n- optionally (but do so by default) add the static builder and from methods from the example;\n- if the clasee already follows the pattern but has properties without decoration or without setters, simple add them;\n\nexample:\n\noriginal class:\n\`\`\`typescript\nexport class ${e.className} {\n description!: string;\n name!: string = "default name";\n title!: string;\n age?: string;\n dateOfBirth!: Date;\n}}\n\`\`\` \n\nresulting builder pattern implementation:\n\`\`\`typescript\nexport class ${e.className}Builder extends Model {\n\n @minlength(10\n @required()\n protected description!: string;\n \n @required()\n protected name!: string = "default value;\n \n @required()\n protected title!: string;\n \n @min(18)\n protected age?: string;\n \n @date()\n protected dateOfBirth!: Date;\n\n protected constructor(arg?: ModelArg<${e.className}Builder>>) {\n super(arg);\n Model.fromModel(this, arg);\n }\n\n setDescription(value: string) {\n this.description = value;\n return this;\n }\n\n setName(value: string) {\n this.name = value;\n return this;\n }\n\n setTitle(value: string) {\n this.title = value;\n return this;\n }\n setAge(value: number) {\n this.age = value;\n return this;\n }\n setDate(value: Date) {\n this.age = value;\n return this;\n }\n \n build(...args: any[]): ${e.className}Builder | Promise<${e.className}Builder> {\n const errs = this.hasErrors();\n if (errs) throw new Error(errs.toString());\n \n return // code that builds OBJ here\n }\n \n static get builder(): ${e.className}Builder {\n return new ${e.className}Builder(); // static method to get a new builder instance\n }\n \n static from<K extends keyof ${e.className}Builder>(obj: K, ${e.className}Builder[K]): ${e.className}Builder {\n return new ${e.className}Builder(); // static method to create a builder from an object\n }\n}\n\`\`\` \n\n`}}],_meta:{}})),ue=n.z.object({project:n.z.string().optional(),issueType:n.z.string().optional(),summary:n.z.string().optional(),description:n.z.string().optional(),assignee:n.z.string().optional(),fields:n.z.record(n.z.string(),n.z.any()).optional()}),me=ie.builder.setName("jira-issue-create").setTitle("Jira: Create Issue Prompt").setDescription("Produce the structured fields required to create a Jira issue. This prompt MUST be text-only and must NOT call runtime tools or server APIs.").setArgsSchema(ue).setCb((e,t)=>{const r=e?.project??"<project-key>",i=e?.issueType??"Task",n=e?.summary??"<summary>",o=e?.description??"<description>";return{messages:[{role:"user",content:{type:"text",text:`You are an assistant that prepares a Jira issue payload. Do NOT call any server or runtime APIs. Output ONLY valid JSON (no explanatory text) with a top-level object named "fields" containing the canonical fields to create the issue. Use the following guidance and the provided inputs when present:\n\n- project: use the project key (${r})\n- issuetype: use the issue type (${i})\n- summary: use the summary (${n})\n- description: use the description (${o})\n- assignee: include assignee if provided (${e?.assignee??null})\n- include any extra \`fields\` object keys provided by the user input if present\n\nExample output:\n{\n "fields": {\n "project": { "key": "${r}" },\n "issuetype": { "name": "${i}" },\n "summary": "${n}",\n "description": "${o}"\n }\n}\n`}}],_meta:{}}}),he=P.join(__dirname,"..","assets"),ge=te()||he,fe=P.join(ge,"resources");function ye(e){const t=P.join(fe,e);try{return O.readFileSync(t,"utf-8")}catch(e){if("ENOENT"!==e.code)throw e}const r=(e=>{const t=P.extname(e);return t?e.slice(0,-t.length)+".enc":e+".enc"})(t);if(!O.existsSync(r))throw Error("Asset not found: "+e);return K(O.readFileSync(r)).toString("utf-8")}function be(e){const t=ye(e);return JSON.parse(t)}const we=be("jira/ticket-templates/catalog.json"),ve=we.templates,ke=new Map;function je(e,t){const r=xe(e);r&&ke.set(r,t)}for(const e of Object.values(ve))je(e.type,e),je(e.name,e),je(e.uri,e),je(e.assetPath,e),je(e.assetPath.replace(/^jira\/ticket-templates\//,""),e),je(e.assetPath.replace(/\.md$/,""),e);function ze(e){const t=xe(e);if(!t)return ve[we.defaultType];const r=ke.get(t);if(r)return r;throw Error("Unknown Jira ticket template reference: "+e)}function Te(e){return ye(ze(e).assetPath)}function xe(e){if(!e)return"";let t=e.trim();return t?(t=t.replace(/^resource:\/\//i,""),t=t.replace(/[?#].*$/,""),t=t.replace(/\\/g,"/"),t=t.toLowerCase(),t.endsWith(".md")&&(t=t.slice(0,-3)),t.includes("/")&&(t=t.slice(t.lastIndexOf("/")+1)),t):""}const Se=n.z.object({ticketType:n.z.enum(["bug","incident","release","feature","test"]).optional(),template_path:n.z.string().optional(),project:n.z.string().optional(),projectKey:n.z.string().optional(),issueType:n.z.string().optional(),summary:n.z.string().optional(),description:n.z.string().optional(),customFields:n.z.record(n.z.string(),n.z.union([n.z.string(),n.z.number(),n.z.boolean()])).optional(),fields:n.z.record(n.z.string(),n.z.any()).optional()}).partial();function Ie(e){try{return ze(e)}catch{return}}function Ee(e){const t=(e=>e.template_path?e.template_path:"resource://jira.ticket.template."+(e.ticketType??"bug"))(e),r=Ie(t),i=!!r,n=r?.uri??t,o=e.projectKey??e.project??"<project-key>",s=e.issueType??r?.issueType??"<issue-type>",a=e.summary??"<summary>",c=e.description??"<description>",p=i?(e=>{const t=Ie(e);return t?(e=>{const t=(e=>e.customFields??[])(ze(e));return t.length?t.map(e=>{const t=e.required?" (required)":" (optional)",r=e.example?" e.g. "+e.example:"";return`- ${e.key}${t}: ${e.label} \u2014 ${e.description}${r}`}).join("\n"):"- no additional template-specific inputs."})(t.uri):"- no additional template-specific inputs."})(t):"- custom template_path supplied; ask the user for the template-specific fields required by that external resource before invoking the tool.\n- do not rewrite or replace the provided template_path value.";return`You are preparing a Jira ticket using the template-backed creation flow.\n\nPreferred tool: jira-ticket-create\nFallback tool: jira-issue-create only when the user explicitly wants a raw, non-template issue payload.\n\nRules:\n1. If the user says "open a bug ticket", "open an incident ticket", or "open a release/change request", choose the matching template resource unless an explicit template_path is provided.\n2. If template_path is provided, use it verbatim and do not replace it with the default template for the ticket type.\n3. If template_path points at a non-bundled template resource, fetch its content and pass that content through 'template.content' while keeping the provided path intact.\n4. Ask for missing project key, summary, and every required template-specific field before executing the tool.\n5. Use customFields for template-specific values that should be tracked and rendered into the template content. Use fields only for raw Jira field maps or actual Jira custom field IDs.\n6. Present a short action preview before the tool call so the user can confirm the template and the tracked custom fields.\n\nSelected template:\n- ticketType: ${JSON.stringify(e.ticketType??"bug")}\n- template_path: ${JSON.stringify(t)}\n- template_uri: ${JSON.stringify(n)}\n- issueType: ${JSON.stringify(s)}\n\nRequired template-specific fields:\n${p}\n\nProvided inputs:\n- project: ${JSON.stringify(o)}\n- summary: ${JSON.stringify(a)}\n- description: ${JSON.stringify(c)}\n- customFields: ${JSON.stringify(e.customFields??{})}\n\nUse the resource-backed template to produce a Jira ticket payload.`}const Ae=ie.builder.setName("jira-guide-ticket-template-create-tool").setTitle("Jira: Template-backed Ticket Prompt").setDescription("Guide ticket creation through resource-backed bug, incident, release, feature, and test templates instead of the generic issue creator.").setArgsSchema(Se).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:Ee(e)}}],_meta:{}})),Re=e=>{const t=Object.entries(e||{}).filter(([,e])=>null!=e);return t.length?t.map(([e,t])=>`- ${e}: ${JSON.stringify(t)}`).join("\n"):"- no input provided; ask a clarifying question if necessary."},Oe=(e,t)=>{const r=e.resources.length?e.resources.join(", "):"none";return[e.description,"","Scenario:\n"+e.scenario,"","Resources: "+r,"\nProvided inputs:",Re(t),"\nCall specification:",e.callTemplate,"\nGuidance:",(i=e.guidance,i.map((e,t)=>`${t+1}. ${e}`).join("\n"))].join("\n");var i},Pe=[{name:"guide-server-info-tool",title:"MCP guide: server info",description:"Show how to use the server diagnostics tool to list registered prompts, versions, and capabilities without side effects.",toolName:"decaf-server-info",scenario:"When you need to confirm what prompts and metadata the MCP server currently exposes.",resources:["resource://repo.metadata"],guidance:["Treat the server info response as read-only configuration data that helps you decide which prompts to invoke next.","Do not rely on stale memory; re-run this tool if the environment might have changed."],argsSchema:n.z.object({}),callTemplate:'{\n "name": "decaf-server-info",\n "arguments": {}\n}'},{name:"jira-guide-issue-create-tool",title:"Jira guide: issue create",description:"Turn user requests into the structured fields that `jira-issue-create` expects, then call the tool.",toolName:"jira-issue-create",scenario:"Whenever a new ticket, task, or story must be created from requirements or spec notes.",resources:["resource://repo.metadata","resource://decoration.schematic.metadata"],guidance:["Confirm the project key from metadata when it is not in the inputs and prefer the canonical repo name.","Gather summary, description, issueType, and any extra `fields` before calling the tool; do not call within the prompt itself.","Present an action preview that lists the fields and mentions attachments or links that might also be created."],argsSchema:n.z.object({project:n.z.string().optional(),issueType:n.z.string().optional(),summary:n.z.string().optional(),description:n.z.string().optional(),assignee:n.z.string().optional(),fields:n.z.record(n.z.string(),n.z.any()).optional()}).partial(),callTemplate:'{\n "name": "jira-issue-create",\n "arguments": {\n "project": { "key": "<project>" },\n "issuetype": { "name": "<issueType>" },\n "summary": "<summary>",\n "description": "<description>",\n "assignee": "<assignee>",\n "fields": { ... }\n }\n}'},{name:"jira-guide-issue-read-tool",title:"Jira guide: issue read",description:"Explain when and how to fetch live issue data with `jira-issue-read` before referencing it.",toolName:"jira-issue-read",scenario:"Before reporting the state of a Jira ticket or quoting field values.",resources:["resource://repo.metadata"],guidance:["Always prefer the issue ID or key provided in the argument; ask clarifying questions if missing.","Mention which fields you need (description, status, comments) so the tool can optimize the call, then rely on the fresh payload instead of memory."],argsSchema:n.z.object({issueId:n.z.string().optional(),issueKey:n.z.string().optional(),fields:n.z.array(n.z.string()).optional()}).partial(),callTemplate:'{\n "name": "jira-issue-read",\n "arguments": {\n "issueId": "<id>",\n "fields": ["summary", "status", "description"]\n }\n}'},{name:"jira-guide-issue-list-tool",title:"Jira guide: issue list",description:"Map exploratory or filtering requests into safe calls to `jira-issue-list`.",toolName:"jira-issue-list",scenario:"When the user wants to discover tickets that match a summary, project, or JQL filter.",resources:["resource://repo.metadata"],guidance:["Translate the requirements into explicit filters or JQL before invoking the tool.","Respect pagination hints and summarize how many tickets the tool should return in the action preview."],argsSchema:n.z.object({jql:n.z.string().optional(),filters:n.z.record(n.z.string(),n.z.any()).optional(),limit:n.z.number().optional(),order:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-list",\n "arguments": {\n "jql": "<JQL>",\n "filters": { ... },\n "startAt": 0,\n "maxResults": <limit>\n }\n}'},{name:"jira-guide-issue-update-tool",title:"Jira guide: issue update",description:"Document how to gather updates before calling `jira-issue-update` so the user\u2019s request is satisfied.",toolName:"jira-issue-update",scenario:"When a ticket needs field changes, transitions, or property toggles.",resources:["resource://repo.metadata","resource://decoration.schematic.builder"],guidance:["Call `jira-issue-read` first if you need the latest state before updating.","Describe the delta (fields being changed) in the action preview and encode them under the `fields` argument.","Include a comment or transition info if the change ought to be annotated."],argsSchema:n.z.object({issueId:n.z.string().optional(),fields:n.z.record(n.z.string(),n.z.any()).optional(),comment:n.z.string().optional(),transition:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-update",\n "arguments": {\n "issueId": "<id>",\n "fields": { ... },\n "comment": "<comment>",\n "transition": "<transition>"\n }\n}'},{name:"jira-guide-issue-delete-tool",title:"Jira guide: issue delete",description:"Warn when to permanently delete an issue via `jira-issue-delete` and how to confirm it.",toolName:"jira-issue-delete",scenario:"When a ticket must be removed or cleaned up after duplication.",resources:["resource://repo.metadata"],guidance:["Double-check permissions and confirm the issue ID; do not delete unless the user explicitly accepts data loss.","Call out whether subtasks should be removed via `deleteSubtasks`."],argsSchema:n.z.object({issueId:n.z.string().optional(),deleteSubtasks:n.z.boolean().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-delete",\n "arguments": {\n "issueId": "<id>",\n "deleteSubtasks": <true|false>\n }\n}'},{name:"jira-guide-issue-transition-tool",title:"Jira guide: issue transition",description:"Define the process for transitioning a Jira issue and invoking `jira-issue-transition`.",toolName:"jira-issue-transition",scenario:"When a ticket needs a workflow change such as To Do \u2192 In Progress \u2192 Done.",resources:["resource://repo.metadata","resource://decoration.schematic.validation"],guidance:["Check available transitions with `jira-transition-list` before deciding which one to run.","Document the business reason in the comment argument to aid reviewers."],argsSchema:n.z.object({issueId:n.z.string().optional(),transition:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-issue-transition",\n "arguments": {\n "issueId": "<id>",\n "transition": "<transition>",\n "comment": "<comment>"\n }\n}'},{name:"jira-guide-transition-list-tool",title:"Jira guide: transition list",description:"Explain how to use `jira-transition-list` to inspect available workflow steps before triggering one.",toolName:"jira-transition-list",scenario:"When you need to know which transitions are possible for a ticket before calling the transition tool.",resources:["resource://repo.metadata"],guidance:["Always capture the transition names and IDs to reference in the action preview.","Only call `jira-issue-transition` after confirming the desired transition exists."],argsSchema:n.z.object({issueId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-transition-list",\n "arguments": {\n "issueId": "<id>"\n }\n}'},{name:"jira-guide-assign-issue-tool",title:"Jira guide: assign issue",description:"Describe how to safely assign or reassign ownership via `jira-assign-issue`.",toolName:"jira-assign-issue",scenario:"When a ticket should be assigned or moved between assignees.",resources:["resource://repo.metadata"],guidance:["Translate user mentions or names into account IDs and include them in the call.","Mention why the reassignment is happening in your action preview to keep the workflow transparent."],argsSchema:n.z.object({issueId:n.z.string().optional(),assignee:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-assign-issue",\n "arguments": {\n "issueId": "<id>",\n "assignee": { "accountId": "<id>" }\n }\n}'},{name:"jira-guide-unassign-issue-tool",title:"Jira guide: unassign issue",description:"Explain the steps for removing an assignee using `jira-unassign-issue`.",toolName:"jira-unassign-issue",scenario:"When the user wants to unassign an owner to make the ticket available.",resources:["resource://repo.metadata"],guidance:["Document whether the ticket should remain unassigned or be moved immediately to someone else.","Confirm there is no auto-assignment policy that will conflict with the unassign action."],argsSchema:n.z.object({issueId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-unassign-issue",\n "arguments": {\n "issueId": "<id>"\n }\n}'},{name:"jira-guide-comment-add-tool",title:"Jira guide: comment add",description:"Clarify how to craft a structured comment (tiered sections, mentions) and call `jira-comment-add`.",toolName:"jira-comment-add",scenario:"When you need to capture findings, reviews, or blockers on a ticket.",resources:["resource://repo.metadata"],guidance:["Use panels, mentions, and sections when describing blockers or decisions.","Reference the relevant attachments or links and mention next steps."],argsSchema:n.z.object({issueId:n.z.string().optional(),comment:n.z.string().optional(),visibility:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-comment-add",\n "arguments": {\n "issueId": "<id>",\n "comment": "<markdown comment>",\n "visibility": "<role>"\n }\n}'},{name:"jira-guide-comment-list-tool",title:"Jira guide: comment list",description:"Indicate when to fetch the comment trail via `jira-comment-list`.",toolName:"jira-comment-list",scenario:"When decisions or conversations need to be reviewed before adding new comments.",resources:["resource://repo.metadata"],guidance:["Specify pagination or filters so you only pull the required batch of comments.","Summarize the key threads in the action preview before calling the tool again to append."],argsSchema:n.z.object({issueId:n.z.string().optional(),page:n.z.number().optional()}).partial(),callTemplate:'{\n "name": "jira-comment-list",\n "arguments": {\n "issueId": "<id>",\n "page": 0,\n "maxResults": 25\n }\n}'},{name:"jira-guide-link-create-tool",title:"Jira guide: link create",description:"Describe how to link issues (e.g., tests to specs) and call `jira-link-create`.",toolName:"jira-link-create",scenario:"When a ticket must be related to another via tested-by, duplicates, or dependees.",resources:["resource://repo.metadata"],guidance:["Include a short note on why the link exists so reviewers can trace the intent.","Verify that both issue keys exist before calling the tool; fetch via `jira-issue-read` if necessary."],argsSchema:n.z.object({inwardIssue:n.z.string().optional(),outwardIssue:n.z.string().optional(),linkType:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-link-create",\n "arguments": {\n "inwardIssue": "<inward>",\n "outwardIssue": "<outward>",\n "linkType": "<relation>",\n "comment": "<note>"\n }\n}'},{name:"jira-guide-link-update-tool",title:"Jira guide: link update",description:"Detail how to change an existing link type with `jira-link-update`.",toolName:"jira-link-update",scenario:"When the relationship between two issues needs to change (e.g., blocks \u2192 relates to).",resources:["resource://repo.metadata"],guidance:["Document the desired new relationship and why the previous one no longer applies.","List the link ID you are targeting so the tool updates precisely that connection."],argsSchema:n.z.object({linkId:n.z.string().optional(),linkType:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-link-update",\n "arguments": {\n "linkId": "<id>",\n "linkType": "<new relation>"\n }\n}'},{name:"jira-guide-link-delete-tool",title:"Jira guide: link delete",description:"Explain how to remove an incorrect or outdated link with `jira-link-delete`.",toolName:"jira-link-delete",scenario:"When a previously created link must be removed or replaced.",resources:["resource://repo.metadata"],guidance:["Ensure you reference the correct link ID and confirm both issues still exist.","Mention why the link is no longer valid to keep the audit trail clear."],argsSchema:n.z.object({linkId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-link-delete",\n "arguments": {\n "linkId": "<id>"\n }\n}'},{name:"jira-guide-attach-issue-tool",title:"Jira guide: attach file",description:"Describe when to upload artifacts with `jira-attach-issue` and how to include comments.",toolName:"jira-attach-issue",scenario:"When the user references logs, screenshots, or generated files that should be attached.",resources:["resource://repo.metadata"],guidance:["State which files are being attached and describe their purpose in the preview comment.","Ensure the file path is accessible and safe for the tool to read before calling it."],argsSchema:n.z.object({issueId:n.z.string().optional(),filePath:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-attach-issue",\n "arguments": {\n "issueId": "<id>",\n "filePath": "<path>",\n "comment": "<note>"\n }\n}'},{name:"jira-guide-attachment-list-tool",title:"Jira guide: attachment list",description:"Explain when to list attachments before adding or deleting files.",toolName:"jira-attachment-list",scenario:"When you need to verify existing attachments prior to uploading or removing files.",resources:["resource://repo.metadata"],guidance:["Capture the attached file names so you can reference the correct ID for deletion.","Use pagination hints if the ticket has many attachments."],argsSchema:n.z.object({issueId:n.z.string().optional(),page:n.z.number().optional()}).partial(),callTemplate:'{\n "name": "jira-attachment-list",\n "arguments": {\n "issueId": "<id>",\n "page": 0\n }\n}'},{name:"jira-guide-attachment-delete-tool",title:"Jira guide: attachment delete",description:"Describe how to delete a specific attachment with `jira-attachment-delete`.",toolName:"jira-attachment-delete",scenario:"When an attachment is obsolete, sensitive, or incorrect.",resources:["resource://repo.metadata"],guidance:["Confirm you have the attachment ID from the listing step to avoid removing the wrong file.","Summarize why the attachment is being removed in the action preview."],argsSchema:n.z.object({issueId:n.z.string().optional(),attachmentId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-attachment-delete",\n "arguments": {\n "issueId": "<id>",\n "attachmentId": "<attachment>"\n }\n}'},{name:"jira-guide-worklog-add-tool",title:"Jira guide: worklog add",description:"Clarify how to log time against an issue with `jira-worklog-add`.",toolName:"jira-worklog-add",scenario:"When the user reports effort spent on a ticket and needs to record it.",resources:["resource://repo.metadata"],guidance:["Convert natural language durations into Jira-friendly strings and include the context of the work.","Mention whether the log should be visible to everyone or restricted."],argsSchema:n.z.object({issueId:n.z.string().optional(),timeSpent:n.z.string().optional(),comment:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-worklog-add",\n "arguments": {\n "issueId": "<id>",\n "timeSpent": "<duration>",\n "comment": "<details>"\n }\n}'},{name:"jira-guide-markdown-to-adf-tool",title:"Jira guide: markdown to ADF",description:"Summarize when to pre-process Markdown into Jira ADF before calling other tools.",toolName:"jira-markdown-to-adf",scenario:"When you need to send Markdown content into Jira fields (descriptions, comments) through other tools.",resources:["resource://repo.metadata","resource://golden.override.model-builder"],guidance:["Use this conversion whenever you cannot guarantee that Jira will accept raw Markdown.","Keep the resulting ADF document handy for downstream calls (issue-update, comment-add, etc.)."],argsSchema:n.z.object({markdown:n.z.string().optional(),context:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-markdown-to-adf",\n "arguments": {\n "markdown": "<text>",\n "context": "<purpose>"\n }\n}'},{name:"jira-guide-adf-to-markdown-tool",title:"Jira guide: ADF to Markdown",description:"Describe why to convert Jira ADF back into Markdown for editing.",toolName:"jira-adf-to-markdown",scenario:"When a user needs to edit a field that already contains ADF (comments/descriptions).",resources:["resource://repo.metadata"],guidance:["Convert the ADF, revise it, then re-run markdown-to-adf if you plan to push it back through Jira.","Keep the Markdown summary in the action preview for reviewers."],argsSchema:n.z.object({adf:n.z.any().optional()}).partial(),callTemplate:'{\n "name": "jira-adf-to-markdown",\n "arguments": {\n "adf": <ADF payload>\n }\n}'},{name:"jira-guide-xray-step-add-tool",title:"Jira guide: Xray step add",description:"Explain how to add a test step from the golden template to a test case via `jira-xray-step-add`.",toolName:"jira-xray-step-add",scenario:"When you document new verification steps for an automated or manual test case.",resources:["resource://repo.metadata","resource://golden.override.xray-step-template"],guidance:["Reference the golden step template before composing the new instruction.","Include both the action and verification so reviewers immediately know the expected result."],argsSchema:n.z.object({testCaseKey:n.z.string().optional(),step:n.z.string().optional(),status:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-add",\n "arguments": {\n "testCaseKey": "<key>",\n "step": "<description>",\n "status": "<PASS|FAIL|TODO>"\n }\n}'},{name:"jira-guide-xray-step-update-tool",title:"Jira guide: Xray step update",description:"Document how to update an existing Xray step via `jira-xray-step-update`.",toolName:"jira-xray-step-update",scenario:"When a test step needs corrections to instructions or expected results.",resources:["resource://repo.metadata","resource://golden.override.xray-step-template"],guidance:["Summarize the delta (what\u2019s changing) before calling the tool so the reviewer knows the context.","Be precise with the `stepId` to avoid editing the wrong step."],argsSchema:n.z.object({testCaseKey:n.z.string().optional(),stepId:n.z.string().optional(),update:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-update",\n "arguments": {\n "testCaseKey": "<key>",\n "stepId": "<id>",\n "update": "<new text>"\n }\n}'},{name:"jira-guide-xray-step-delete-tool",title:"Jira guide: Xray step delete",description:"Explain why you would remove a test step and how to use `jira-xray-step-delete`.",toolName:"jira-xray-step-delete",scenario:"When a chore is no longer relevant and its step should be removed.",resources:["resource://repo.metadata"],guidance:["Confirm the step ID and test case key using the list or read tools before deleting.","Document the reason for removal so auditors understand the change."],argsSchema:n.z.object({testCaseKey:n.z.string().optional(),stepId:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-delete",\n "arguments": {\n "testCaseKey": "<key>",\n "stepId": "<id>"\n }\n}'},{name:"jira-guide-xray-step-list-tool",title:"Jira guide: Xray step list",description:"Describe how to inspect the existing Xray steps before editing or deleting them.",toolName:"jira-xray-step-list",scenario:"When you should view the existing test steps to confirm numbering or status.",resources:["resource://repo.metadata"],guidance:["Report the step IDs and descriptions in your preview so you can reference them later.","Use the list data instead of memory to keep numbering accurate."],argsSchema:n.z.object({testCaseKey:n.z.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-list",\n "arguments": {\n "testCaseKey": "<key>"\n }\n}'}].map(e=>ie.builder.setName(e.name).setTitle(e.title).setDescription(e.description).setArgsSchema(e.argsSchema).setCb(async(t={},r)=>({messages:[{role:"user",content:{type:"text",text:Oe(e,t)}}],structuredContent:{tool:e.toolName,args:t},result:{tool:e.toolName,args:t},_meta:{}}))),Ce=n.z.object({filePath:n.z.string().optional(),textType:n.z.enum(["text","code"]).optional(),context:n.z.string().optional()}).partial();function Ne(e,t){const r=e.textType??"text",i=e.context?.trim()?`Context:\n${e.context.trim()}\n`:"",n=t?.trim()?"Source content:\n"+t.trim():"";return o={filePath:e.filePath??"README.md",textType:r,contextSection:i,contentSection:n},"You are a professional summarization assistant.\n\nGoal:\nCreate a comprehensive summary for a {{textType}} file. Preserve all important details, relevant context, implementation facts, structure, dependencies, assumptions, edge cases, and caveats. Do not impose an artificial size limit.\n\n{{contextSection}}\nFile metadata:\n- path: {{filePath}}\n- type: {{textType}}\n\n{{contentSection}}\nRules:\n- If textType is 'text', summarize the document structure, claims, decisions, entities, and actionable details.\n- If textType is 'code', summarize architecture, exported symbols, control flow, dependencies, side effects, error handling, and testing implications.\n- Keep technical names intact.\n- If the file is empty or trivial, say so explicitly.\n- Return a comprehensive summary; include extra detail when it materially helps understanding or later editing.".replace(/\{\{([a-zA-Z0-9_]+)\}\}/g,(e,t)=>Object.prototype.hasOwnProperty.call(o,t)?o[t]??"":"").replace(/\n{3,}/g,"\n\n").trim();var o}const Je=ie.builder.setName("guide-file-summarizer-tool").setTitle("MCP guide: file summarizer").setDescription("Professional prompt for summarizing text and code files with optional context.").setArgsSchema(Ce).setCb(e=>({messages:[{role:"user",content:{type:"text",text:Ne(e)}}],_meta:{}}));function De(e){switch(e){case"codex":return{executable:"codex",args:["-s","workspace-write","exec"]};case"claude":return{executable:"claude",args:[]};case"copilot":return{executable:"copilot",args:[]};default:return(e=>{throw Error("Unsupported provider: "+e)})(e)}}async function _e(e){const t=De(e.provider),r=m.spawn(t.executable,t.args,{cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:{...process.env,DECAF_AGENT_TOOLING:JSON.stringify(e.toolMetadata??{})}});let i="",n="";return r.stdout.on("data",e=>{i+=e.toString()}),r.stderr.on("data",e=>{n+=e.toString()}),r.stdin.write(e.prompt),r.stdin.end(),{exitCode:await new Promise((e,t)=>{r.once("error",t),r.once("close",t=>e(t??0))}),stdout:i,stderr:n,command:t}}const Fe=n.z.object({filePath:n.z.string().optional(),textType:n.z.enum(["text","code"]).optional(),context:n.z.string().optional()}).partial(),$e=a.resolve(process.cwd(),"README.md"),Me=[Je,se,...pe,le,me,...Pe,Ae],qe="##VERSION##",Le="##PACKAGE##";function He(){try{let e=process.argv[1]?a.dirname(a.resolve(process.argv[1])):process.cwd();for(;;){const r=a.join(e,"package.json");if(t.existsSync(r))return JSON.parse(t.readFileSync(r,"utf-8"));const i=a.dirname(e);if(i===e)break;e=i}}catch{}return{}}const Ge=qe.startsWith("##")?He().version??"0.0.0":qe,Ue=Le.startsWith("##")?He().name??"unknown":Le;s.Metadata.registerLibrary(Ue,Ge);const We={mcpId:"decaf",name:"decaf-ts mcp server",title:"Decaf-TS MCP Server",description:"Provides precise coding assistance for the decaf-ts framework",version:Ge,websiteUrl:"https://decaf-ts.github.io",repositoryUrl:"https://github.com/decaf-ts/mcp-server",license:"AGPL-3.0",workingDir:Z,assetDir:te(),contacts:[{name:"Decaf-TS",url:"https://decaf-ts.github.io"}],tags:"server,official,decaf-ts",metadata:{},icons:[{src:"workdocs/assets/favicon.svg",mimeType:"image/svg+xml",sizes:"any"}],jira:{host:process.env.JIRA__HOST||"decaf-ts.atlassian.net",email:process.env.JIRA__EMAIL||"",apiKey:process.env.JIRA__API_KEY||process.env.JIRA__APIKEY||"",projectKey:process.env.JIRA__PROJECT_KEY||void 0,issueType:process.env.JIRA__ISSUE_TYPE||void 0,parentIssue:process.env.JIRA__PARENT_ISSUE||void 0,timeout:process.env.JIRA__TIMEOUT?parseInt(process.env.JIRA__TIMEOUT):1e3,rateLimitRetryDelayMs:process.env.JIRA__RATE_LIMIT_RETRY_DELAY_MS?parseInt(process.env.JIRA__RATE_LIMIT_RETRY_DELAY_MS):3e3},xray:{host:process.env.XRAY__HOST||process.env.XRAY__API_HOST||"https://xray.cloud.getxray.app",apiUser:process.env.XRAY__API_USER||"",apiSecret:process.env.XRAY__API_SECRET||""},level:r.LogLevel.error},Ke=r.LoggedEnvironment.accumulate(We);function Be(){const{host:e,email:t,apiKey:r,projectKey:i,issueType:n}=Ke.jira;return{host:e?.trim(),email:t?.trim(),apiKey:r?.trim(),projectKey:i?.trim(),issueType:n?.trim(),parentIssue:Ke.jira.parentIssue?.trim()}}function Ye(){const e=Be();return[{name:"JIRA__HOST",required:!0,description:"Atlassian host (e.g. decaf-ts.atlassian.net) where your Jira instance is hosted.",value:e.host},{name:"JIRA__EMAIL",required:!0,description:"Email address of the Jira account that has API access.",value:e.email},{name:"JIRA__API_KEY",required:!0,description:"API token created in your Atlassian profile (a.k.a. APIKEY alias) for authenticating requests.",sensitive:!0,value:e.apiKey},{name:"JIRA__PROJECT_KEY",required:!1,description:"Default Jira project key (e.g. DECAF) used when an issue creation request omits a project.",value:e.projectKey},{name:"JIRA__ISSUE_TYPE",required:!1,description:"Default Jira issue type (e.g. Task, Bug) used when creating issues without an explicit type.",value:e.issueType},{name:"JIRA__PARENT_ISSUE",required:!1,description:"Default parent issue key (e.g. DECAF-123) applied when a child issue is created without an explicit parent.",value:e.parentIssue}]}function Xe(e){const t=e.value?((e,t)=>{if(e)return t?"<configured>":e})(e.value,e.sensitive):"not set",r=e.required?"(required)":"(optional)";return`\u2022 ${e.name} ${r}: ${e.description} Current state: ${t}.`}r.Logging.setConfig(Ke);class Ve extends Error{constructor(e){const t=Ye(),r=(e=>{const t=Ye();return`${e.length?`Missing Jira credentials: ${e.map(e=>e.name).join(", ")}.`:"Jira credentials are configured."}\n\nThis setup uses the following environment variables:\n${t.map(Xe).join("\n")}`})(e);super(r),this.name="MissingJiraEnvironmentError",this.descriptors=t,this.missing=e,"function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,Ve)}}const Ze=r.Logging.for("jira.client"),Qe=/(authorization|cookie)/i;function et(e){if(!e)return;const t=e.baseURL??"",r=e.url??"";return t&&r?`${t.endsWith("/")?t.slice(0,-1):t}/${r.startsWith("/")?r.slice(1):r}`:r||t||void 0}function tt(e){if(void 0!==e){if("string"==typeof e)return e;try{return JSON.stringify(e,null,2)}catch(t){return h.inspect(e,{depth:null})}}}function rt(e){if(!e)return;const t={};return Object.entries(e).forEach(([e,r])=>{t[e]=Qe.test(e)&&r?"[REDACTED]":r}),t}const it=(()=>{try{return g.createRequire(process.cwd())}catch(e){return}})();async function nt(){let e;try{const t=await(async e=>{try{return await import(e)}catch(t){if(!it)throw t;try{return it(e)}catch(e){throw e.cause??=t,e}}})("jira.js"),r=t.default,i=t.Version3Client??r?.Version3Client??t.default;if("function"!=typeof i)throw Error("jira.js did not export a Version3Client constructor");e=i}catch(e){throw Error("Unable to load 'jira.js' \u2014 ensure it is installed as a dependency: "+e)}const{host:t,email:r,apiKey:i}=(()=>{const e=Be(),t=Ye().filter(e=>e.required&&!e.value);if(t.length>0)throw new Ve(t);return{host:e.host,email:e.email,apiKey:e.apiKey}})(),n=new e({host:t.startsWith("http://")||t.startsWith("https://")?t:"https://"+t,authentication:{basic:{email:r,apiToken:i}},baseRequestConfig:{headers:{Accept:"application/json","Content-Type":"application/json"}}});return(e=>{if(!e)return;const t="__jiraLoggingAttached";e[t]||(e[t]=!0,e.interceptors.request.use(e=>{e.headers=(e=>{const t={...e||{}};return Object.keys(t).some(e=>"accept"===e.toLowerCase())||(t.Accept="application/json"),Object.keys(t).some(e=>"content-type"===e.toLowerCase())||(t["Content-Type"]="application/json"),t})(e.headers);const t=(e.method??"GET").toString().toUpperCase(),r=et(e);return Ze.info("jira.request",{method:t,url:r,headers:rt(e.headers),params:e.params,data:tt(e.data)}),e},e=>(Ze.error("jira.request.error",{message:e.message}),Promise.reject(e))),e.interceptors.response.use(e=>{const t=(e.config?.method??"GET").toString().toUpperCase(),r=et(e.config);return Ze.info("jira.response",{method:t,url:r,status:e.status,headers:rt(e.headers),data:tt(e.data)}),e},e=>{const t=e.config,r=e.response,i=(t?.method??"GET").toString().toUpperCase(),n=et(t);return Ze.error("jira.response.error",{method:i,url:n,status:r?.status,headers:rt(r?.headers),data:tt(r?.data),message:e.message}),Promise.reject(e)}))})(n.instance),n}function ot(e){if(!e||0>=Object.keys(e).length)return[];const t=(e=>{if(null==e)return"";try{return JSON.stringify(e,null,2)}catch{return h.inspect(e,{depth:null})}})(e);return t?[{type:"text",text:t}]:[]}function st(e={},t=[]){const r=(e=>e&&"object"==typeof e?Array.isArray(e)?{items:e}:e:"string"==typeof e?{message:e}:null==e?{}:{value:e})(e);return{content:t.length?t:ot(r),result:r,structuredContent:r}}const at=n.z.object({name:n.z.string().min(1).optional().describe("Optional template name that pre-populates additional fields"),content:n.z.string().min(1).describe("Markdown template content to apply when constructing the description"),placeholders:n.z.record(n.z.string(),n.z.union([n.z.string(),n.z.number(),n.z.boolean()])).optional().describe("Map of placeholder replacements used by the template")}).describe("Template metadata used to adjust the created description"),ct=n.z.object({template:at.optional().describe("Optional template settings for this create request"),customFields:n.z.record(n.z.string(),n.z.union([n.z.string(),n.z.number(),n.z.boolean()])).optional().describe("Template-specific field values that can be merged into the rendered description")}).describe("Additional template controls available when creating an issue"),pt=n.z.union([n.z.object({fields:n.z.record(n.z.string(),n.z.any()).describe("Full raw field map that gets delivered to Jira")}).merge(ct).describe("Create argument that supplies every field explicitly"),n.z.object({summary:n.z.string().min(1).describe("Title or summary of the new issue"),projectKey:n.z.string().min(1).describe("Project key where the issue is created"),issueType:n.z.string().min(1).describe("Type name for the new issue (story, task, etc.)"),description:n.z.string().optional().describe("Optional textual description for the issue")}).merge(ct).describe("Create argument with minimal required identifiers plus optional description")]).describe("Union describing how to create an issue either via raw fields or shorthand properties");function dt(e,t,r){const i=((e.url??"")+"").match(/^(attachment|jira-attachment):(.+)$/i);if(!i)return null;const n=i[2],o=r.resolveAttachment?.(n);return o?{type:"block",node:{type:"mediaSingle",attrs:{layout:"center"},content:[{type:"media",attrs:{type:"file",id:o.id,collection:o.collection??"attachments"}}]}}:null}function lt(e,t){if(!e)return[];if(!t.enableAtMentions&&!t.enableEmojiShortcodes)return[{type:"text",text:e}];let r=0;const i=[],n=/(^|[^A-Za-z0-9_])@([A-Za-z0-9._-]{1,64})/g,o=/:([a-z0-9_+-]{1,64}):/gi;for(;r<e.length;){const s=mt(t.enableAtMentions?ut(n,e,r):null,t.enableEmojiShortcodes?ut(o,e,r):null);if(!s){i.push({type:"text",text:e.slice(r)});break}if(s.index>r&&i.push({type:"text",text:e.slice(r,s.index)}),"mention"===s.kind){const{full:e,groups:n}=s,o=n[0]??"",a=n[1]??"";o&&i.push({type:"text",text:o});const c=t.resolveMention?.(a);c?i.push({type:"mention",attrs:{id:c.id,text:c.text}}):i.push({type:"text",text:"@"+a}),r=s.index+e.length;continue}if("emoji"===s.kind){const{full:e,groups:n}=s,o=`:${n[0]}:`,a=t.resolveEmoji?.(o);i.push({type:"emoji",attrs:a?{shortName:a.shortName,text:a.text}:{shortName:o}}),r=s.index+e.length;continue}}return(e=>{const t=[];for(const r of e){const e=t[t.length-1];"text"!==r.type||"text"!==e?.type||e.marks||r.marks?t.push(r):e.text=(e.text??"")+(r.text??"")}return t})(i)}function ut(e,t,r){e.lastIndex=r;const i=e.exec(t);if(!i)return null;const n=e.source.includes("@")?"mention":"emoji";return{index:i.index,full:i[0],groups:i.slice(1),kind:n}}function mt(e,t){return e?t&&e.index>t.index?t:e:t}function ht(e){const t=(e.children??[])[0];return"text"===t?.type?(t.value??"")+"":"paragraph"===t?.type?((t.children??[]).map(e=>"text"===e.type?(e.value??"")+"":"").join("")||"")+"":""}function gt(e){const t=((e??"")+"").toLowerCase().trim();return t?"info"===t||"note"===t||"success"===t||"warning"===t||"error"===t?t:"danger"===t?"error":null:null}function ft(e){const t=((e??"")+"").toLowerCase().trim();return!t||"neutral"!==t&&"green"!==t&&"yellow"!==t&&"red"!==t&&"blue"!==t&&"purple"!==t?null:t}function yt(e,t){const r=[];for(const i of e??[])if(i?.type)if("text"!==i.type)if("strong"!==i.type)if("emphasis"!==i.type)if("delete"!==i.type)if("inlineCode"!==i.type)if("break"!==i.type){if("link"===i.type){const e=(i.url??"")+"",n=wt(i.children??[],e),o=dt(i,0,t);if(o){"inline"===o.type?r.push(o.node):r.push({type:"text",text:n,marks:[{type:"link",attrs:{href:e}}]});continue}if(t.enableSmartCards&&vt(n,e)){r.push({type:"inlineCard",attrs:{url:e}});continue}r.push({type:"text",text:n,marks:[{type:"link",attrs:{href:e}}]});continue}if("textDirective"===i.type&&"status"===i.name){const e=ht(i)||"Status",t=ft(i.attributes?.color)??"neutral";r.push({type:"status",attrs:{text:e,color:t}});continue}if("textDirective"===i.type&&"emoji"===i.name){const e=kt(i);r.push(jt(e,t));continue}}else r.push({type:"hardBreak"});else r.push({type:"text",text:(i.value??"")+"",marks:[{type:"code"}]});else r.push(...bt(yt(i.children??[],t),{type:"strike"}));else r.push(...bt(yt(i.children??[],t),{type:"em"}));else r.push(...bt(yt(i.children??[],t),{type:"strong"}));else r.push(...lt((i.value??"")+"",t));return r.filter(e=>!("text"===e.type&&""===(e.text??"")))}function bt(e,t){return e.map(e=>{if("text"!==e.type)return e;if(e.marks?.some(e=>"code"===e.type))return e;const r=e.marks?[...e.marks,t]:[t];return{...e,marks:r}})}function wt(e,t){const r=[];for(const t of e??[])"text"===t.type||"inlineCode"===t.type?r.push((t.value??"")+""):"emphasis"!==t.type&&"strong"!==t.type&&"delete"!==t.type||r.push(wt(t.children??[],""));return r.join("")||t}function vt(e,t){const r=(e??"").trim(),i=(t??"").trim();return r===i&&/^https?:\/\//i.test(i)}function kt(e){return(e.children??[]).map(e=>"text"===e.type?(e.value??"")+"":"").join("").trim()||""}function jt(e,t){const r=e.startsWith(":")?e:`:${e}:`,i=t.resolveEmoji?.(r);return i?{type:"emoji",attrs:{shortName:i.shortName,text:i.text}}:{type:"emoji",attrs:{shortName:r}}}function zt(e){return e?"string"==typeof e?e:"text"===e.type||"inlineCode"===e.type?(e.value??"")+"":Array.isArray(e.children)?e.children.map(zt).join(""):"":""}function Tt(e,t){if(!e?.type)return null;if((e=>"containerDirective"===e?.type&&"panel"===e?.name)(e))return((e,t)=>{const r=e.attributes??{},i=gt(r.type)??"info",n="string"==typeof r.title?r.title:void 0,o=(e.children??[]).map(e=>Tt(e,t)).flat().filter(Boolean);return{type:"panel",attrs:{panelType:i,...n?{panelType:i,title:n}:{panelType:i}},content:o.length?o:[{type:"paragraph",content:[]}]}})(e,t);switch(e.type){case"heading":return{type:"heading",attrs:{level:St(e.depth??1,1,6)},content:yt(e.children??[],t)};case"paragraph":{const r=(e=>{const t=e.children??[];if(1!==t.length)return null;const r=t[0];if("image"!==r?.type)return null;const i=(r.url??"")+"";return i?{type:"mediaSingle",attrs:{layout:"center"},content:[{type:"media",attrs:{type:"external",url:i}}]}:null})(e);return r||{type:"paragraph",content:yt(e.children??[],t)}}case"blockquote":return{type:"blockquote",content:(e.children??[]).map(e=>Tt(e,t)).flat().filter(Boolean)};case"list":return((e,t)=>t.enableTaskLists&&(e.children??[]).some(e=>"boolean"==typeof e.checked)?((e,t)=>{const r=[];let i=0;for(const n of e.children??[]){if("boolean"!=typeof n.checked)continue;i+=1;const e=(n.children??[]).map(e=>Tt(e,t)).flat().filter(Boolean);r.push({type:"taskItem",attrs:{localId:"task-"+i,state:n.checked?"DONE":"TODO"},content:e.length?e:[{type:"paragraph",content:[]}]})}return{type:"taskList",content:r}})(e,t):{type:e.ordered?"orderedList":"bulletList",content:(e.children??[]).map(e=>((e,t)=>{const r=(e.children??[]).map(e=>Tt(e,t)).flat().filter(Boolean);return{type:"listItem",content:r.length?r:[{type:"paragraph",content:[]}]}})(e,t))})(e,t);case"code":{const r=((e,t)=>{const r=(e??"").toString().trim().toLowerCase();return r?t.enableMermaid&&r.includes("mermaid")?"mermaid":(e=>{const t=e.trim().toLowerCase();return{js:"javascript",javascript:"javascript",jsx:"javascript",ts:"typescript",typescript:"typescript",tsx:"typescript",py:"python",python:"python",rb:"ruby",ruby:"ruby",sh:"bash",bash:"bash",zsh:"bash",shell:"bash",yml:"yaml",yaml:"yaml",json:"json",toml:"toml",xml:"xml",html:"html",css:"css",scss:"scss",sql:"sql",go:"go",rust:"rust",java:"java",c:"c",cpp:"cpp","c++":"cpp",cs:"csharp",csharp:"csharp",php:"php",kotlin:"kotlin",swift:"swift",md:"markdown",markdown:"markdown",graphql:"graphql",gql:"graphql",dockerfile:"docker",makefile:"make",ini:"ini"}[t]??t})(r):null})(e.lang,t);return{type:"codeBlock",attrs:{language:r},content:[{type:"text",text:(e.value??"")+""}]}}case"thematicBreak":return{type:"rule"};case"table":return((e,t)=>({type:"table",content:(e.children??[]).map((e,r)=>({type:"tableRow",content:(e.children??[]).map(e=>({type:0===r?"tableHeader":"tableCell",content:[{type:"paragraph",content:yt(e.children??[],t)}]}))}))}))(e,t);case"leafDirective":return"status"===e.name?(e=>{const t=ft((e.attributes??{}).color)??"neutral";return{type:"paragraph",content:[{type:"status",attrs:{text:ht(e)||"Status",color:t}}]}})(e):"panel"===e.name?((e,t)=>{const r=e.attributes??{},i=gt(r.type)??"info",n="string"==typeof r.title?r.title:void 0;return{type:"panel",attrs:{panelType:i,...n?{title:n}:{}},content:[{type:"paragraph",content:yt([{type:"text",value:ht(e)}],t)}]}})(e,t):xt(e,t);default:return xt(e,t)}}function xt(e,t){if("drop"===t.unknownNodeStrategy)return null;const r=zt(e);return r?{type:"paragraph",content:[{type:"text",text:r}]}:null}function St(e,t,r){const i=Number.isFinite(e)?Math.trunc(e):t;return Math.max(t,Math.min(r,i))}const It={resolveMention:void 0,resolveAttachment:void 0,resolveEmoji:void 0,enableSmartCards:!0,enableMermaid:!0,enableEmojiShortcodes:!0,enableAtMentions:!0,enableTaskLists:!0,unknownNodeStrategy:"text"};function Et(e,t={}){const r={...It,...t},i=e??"",n=f.unified().use(w.default||w).use(y.default||y).use(b.default||w),o=n.parse(i),s=n.runSync(o);return At(s),((e,t)=>{const r=[];for(const i of e.children??[]){const e=Tt(i,t);e&&(Array.isArray(e)?r.push(...e):r.push(e))}return((e,t)=>{if(!t.enableSmartCards)return e;const r=e.content.map(e=>(e=>{if("paragraph"!==e.type)return e;const t=e.content??[];if(1!==t.length)return e;const r=t[0];if("inlineCard"!==r?.type)return e;const i=r.attrs?.url;return i?[{type:"blockCard",attrs:{url:i}}]:e})(e)).flat();return{...e,content:r}})({version:1,type:"doc",content:r},t)})(s,r)}function At(e){if(!e||!Array.isArray(e.children))return;const t=[];for(const r of e.children)"definition"!==r?.type&&("html"!==r?.type?(At(r),t.push(r)):t.push({type:"text",value:(r.value??"")+""}));e.children=t}function Rt(e){return{...e,content:Ot(e.content??[])}}function Ot(e){return e.flatMap(e=>"panel"===e.type?Ot(e.content??[]):[Pt(e)])}function Pt(e){return e.content?{...e,content:Ot(e.content)}:{...e}}const Ct=/\{\{\s*([^}]+)\s*\}\}/g;async function Nt(e,t){const r=e=>e&&e.trim()?e.trim():void 0,i=((e,t,r)=>{const i=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return Object.prototype.hasOwnProperty.call(i,"fields")?i:{...i,projectKey:"string"==typeof i.projectKey?i.projectKey:t,issueType:"string"==typeof i.issueType?i.issueType:r}})(t,r(Ke.jira.projectKey),r(Ke.jira.issueType));let n,o;try{n=pt.parse(i)}catch(e){const t=Error("validation error");throw t.code="validation_error",t}if((e=>"object"==typeof e&&null!==e&&"fields"in e&&!!e.fields)(n))o={...n.fields};else{const e=n;o={summary:e.summary,project:{key:e.projectKey},issuetype:{name:e.issueType},...e.description?{description:e.description}:{}}}o=((e,t)=>{if(!t||!t.content)return e;const r=(i=t.content,n=t.placeholders,i?i.replace(Ct,(e,t)=>{const r=t.trim();if(!r)return"";if(n&&Object.prototype.hasOwnProperty.call(n,r)){const e=n[r];return null==e?"":e+""}return e}):"");var i,n;if(!r.trim())return e;const o=Et(r),s=(a=e.description)?"object"==typeof a&&"doc"===a.type&&Array.isArray(a.content)?a.content:"string"==typeof a?Et(a).content:[]:[];var a;return e.description={type:"doc",version:1,content:[...s,...o.content]},e})(o,(e=>e.template?.content?{...e.template,placeholders:{...e.customFields??{},...e.template.placeholders??{}}}:e.template)(n));const s=(e=>{if(e?.issues&&"function"==typeof e.issues.createIssue)return e.issues.createIssue.bind(e.issues);const t=e?.issues&&e.issues.create;return"function"==typeof t?e=>Promise.resolve(t(e)):void 0})(e);if(!s)throw Error("Jira client missing create function");return(a=await s({fields:o}))&&"object"==typeof a&&"data"in a&&a.data&&"object"==typeof a.data?a.data:a;var a}const Jt={name:"jira-issue-create",inputSchema:pt,runTool:async(e,t)=>st(await Nt(e,t))};class Dt extends Error{constructor({code:e,message:t,details:r}){super(t),Object.setPrototypeOf(this,new.target.prototype),this.name="NormalizedJiraError",this.code=e,this.details=r}}const _t=r.Logging.for("jira.errors");function Ft(e){if(!e)return new Dt({code:"jira_error",message:"Unknown Jira error",details:{raw:e}});const t=e?.status??e?.statusCode??e?.response?.status??e?.response?.statusCode,r="number"==typeof t?t:Number(t)||void 0,i=e?.response?.data??e?.data??e?.response?.body??e?.body,n=e?.response?.statusText??(r?""+r:void 0),o=e?.response?.headers?rt(e.response.headers):void 0,s=[];"string"==typeof e?.message&&s.push(e.message),((e,t)=>{e&&(Array.isArray(e.errorMessages)&&e.errorMessages.forEach(e=>"string"==typeof e&&t.push(e)),"string"==typeof e.errorMessage&&t.push(e.errorMessage),e.errorCollection&&Array.isArray(e.errorCollection.errors)&&e.errorCollection.errors.forEach(e=>{"string"==typeof e?t.push(e):e&&"string"==typeof e.message&&t.push(e.message)}),e?.errors&&"object"==typeof e.errors&&Object.values(e.errors).forEach(e=>{"string"==typeof e?t.push(e):"string"==typeof e?.message&&t.push(e.message)}))})(i,s);const a=r?`Jira API error (${r})`:"Jira API error",c=s.length>0?s.join(" | "):a,p=r?"jira_"+r:e?.code??"jira_error",d=e?.config,l=d?{method:d.method?d.method.toString().toUpperCase():void 0,url:d.url,headers:rt(d.headers),data:tt(d.data)}:void 0,u={httpStatus:r,body:i,request:l,response:o?{statusText:n,headers:o}:n?{statusText:n}:void 0,raw:e};return _t.error("jira.error",{code:p,message:c,httpStatus:r,statusText:n,responseHeaders:o,request:l,body:tt(i)??i}),new Dt({code:p,message:c,details:u})}const $t=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID to delete"),deleteSubtasks:n.z.boolean().optional().default(!0).describe("Whether to delete the subtasks alongside this issue")}).describe("Arguments used to delete a Jira issue (with optional subtasks)"),Mt={name:"jira-issue-delete",inputSchema:$t,runTool:async(e,t)=>{try{const r=$t.parse(t),i={issueIdOrKey:r.issueId,deleteSubtasks:r.deleteSubtasks};return await e.issues.deleteIssue(i),st({success:!0,message:`Issue ${r.issueId} deleted successfully`})}catch(e){throw Ft(e)}}},qt=n.z.object({projectKey:n.z.string().trim().min(1).optional().describe("Project key used to scope the issue search"),issueType:n.z.string().trim().min(1).optional().describe("Issue type name used to filter the results"),parentIssueId:n.z.string().trim().min(1).optional().describe("Optional parent issue key/ID to limit results to a subtree"),name:n.z.string().trim().min(1).optional().describe("Issue summary to match exactly"),reference:n.z.string().trim().min(1).optional().describe("External reference or custom identifier to filter by"),jql:n.z.string().trim().min(1).optional().describe("Free-form JQL query to drive the search"),nextPageToken:n.z.string().trim().min(1).optional().describe("Opaque pagination token returned by Jira enhanced search"),maxResults:n.z.number().int().min(1).optional().describe("Maximum number of issues to return"),fields:n.z.array(n.z.string()).optional().describe("List of issue fields to include in the response"),expand:n.z.string().optional().describe("Optional expansion clause for the results"),orderBy:n.z.string().trim().min(1).optional().describe("Field or clause used to order the returned issues")}).describe("Parameters describing how to search for Jira issues");function Lt(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}const Ht={name:"jira-issue-list",inputSchema:qt,runTool:async(e,t)=>{try{const r=qt.parse(t),i=r.maxResults??50;let n=r.jql?.trim();if(n){if(r.orderBy){const e=r.orderBy.trim();e&&(n=/\border\s+by\b/i.test(n)?`${n}, ${e}`:`${n} ORDER BY ${e}`)}}else n=(e=>{const t=[];if(e.projectKey&&t.push(`project = "${Lt(e.projectKey)}"`),e.issueType&&t.push(`issuetype = "${Lt(e.issueType)}"`),e.parentIssueId&&t.push(`parent = "${Lt(e.parentIssueId)}"`),e.name&&t.push(`summary ~ "${Lt(e.name)}"`),e.reference){const r=Lt(e.reference);t.push(`(key ~ "${r}" OR summary ~ "${r}" OR text ~ "${r}")`)}if(0===t.length){const e=Error("Provide a jql query or at least one filter (project, name, reference, parent, issue type, etc.).");throw e.code="validation_error",e}let r=t.join(" AND ");if(e.orderBy){const t=e.orderBy.trim();t&&(r=/\border\s+by\b/i.test(r)?`${r}, ${t}`:`${r} ORDER BY ${t}`)}return r})(r);const o={jql:n,nextPageToken:r.nextPageToken,maxResults:i,fields:r.fields,expand:r.expand},s=e.issueSearch;if(!s||"function"!=typeof s.searchForIssuesUsingJqlEnhancedSearchPost)throw Error("Jira search API is unavailable on the client");const a=await s.searchForIssuesUsingJqlEnhancedSearchPost(o);return st({...a,startAt:a?.startAt??0,maxResults:a?.maxResults??i})}catch(e){throw Ft(e)}}},Gt=n.z.object({issueId:n.z.string().min(1).describe("Jira issue key or numeric ID to read"),expand:n.z.string().optional().describe("Optional expand clause for nested fields or changelog"),fields:n.z.array(n.z.string()).optional().describe("Explicit list of issue fields to return"),properties:n.z.array(n.z.string()).optional().describe("Specific issue properties to include in the response")}).describe("Arguments required to read a Jira issue"),Ut={name:"jira-issue-read",inputSchema:Gt,runTool:async(e,t)=>{try{const r=Gt.parse(t),i={issueIdOrKey:r.issueId,expand:r.expand,fields:r.fields,properties:r.properties};return st(await e.issues.getIssue(i))}catch(e){throw Ft(e)}}},Wt=n.z.object({issueId:n.z.string().min(1).describe("Target issue key or ID to transition"),transitionId:n.z.union([n.z.string(),n.z.number()]).describe("Identifier for the transition to execute"),fields:n.z.record(n.z.string(),n.z.any()).optional().describe("Optional field updates to apply during the transition"),update:n.z.record(n.z.string(),n.z.array(n.z.object({set:n.z.any().optional().describe("Set operation for the transition update"),add:n.z.any().optional().describe("Add operation for the transition update"),remove:n.z.any().optional().describe("Remove operation for the transition update")}))).optional().describe("Structured update operations to send alongside the transition"),comment:n.z.string().optional().describe("Optional comment to attach during the transition")}).describe("Inputs needed to transition a Jira issue"),Kt={name:"jira-issue-transition",inputSchema:Wt,runTool:async(e,t)=>{try{const r=Wt.parse(t),i={issueIdOrKey:r.issueId,transition:{id:r.transitionId+""}};if(r.fields&&(i.fields=r.fields),r.update&&(i.update=r.update),await e.issues.doTransition(i),r.comment){const t=e.issueComments;if(!t||"function"!=typeof t.addComment)throw Error("Jira issueComments API is unavailable on the client");await t.addComment({issueIdOrKey:r.issueId,comment:Et(r.comment)})}return st({success:!0,message:"Issue transitioned to "+r.transitionId})}catch(e){throw Ft(e)}}},Bt=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID for which to list transitions"),expand:n.z.string().optional().describe("Optional expand parameter for the transition response")}).describe("Inputs used to fetch available transitions for an issue"),Yt={name:"jira-transition-list",inputSchema:Bt,runTool:async(e,t)=>{try{const r=Bt.parse(t),i=e.issues;if(!i||"function"!=typeof i.getTransitions)throw Error("Jira transitions API is unavailable on the client");const n={issueIdOrKey:r.issueId,expand:r.expand};return st(await i.getTransitions(n))}catch(e){throw Ft(e)}}},Xt=n.z.object({key:n.z.string().min(1).describe("The key of the issue property"),value:n.z.any().describe("The value of the issue property")}).describe("Details of issue properties to be add or update."),Vt=n.z.object({description:n.z.string().optional().describe("Markdown description that is converted to Jira ADF (use jira-md-to-adf if you need raw ADF input)")}).catchall(n.z.any()).describe("Field map that gets delivered to Jira (labels, components, etc.)"),Zt=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID to update"),fields:Vt.optional(),update:n.z.record(n.z.string(),n.z.array(n.z.object({set:n.z.any().optional().describe("Set operation alongside the update key"),add:n.z.any().optional().describe("Add operation alongside the update key"),remove:n.z.any().optional().describe("Remove operation alongside the update key"),edit:n.z.any().optional().describe("Edit operation alongside the update key")}))).optional().describe("Structured update operations for array/set fields"),properties:n.z.array(Xt).optional().describe("Property payloads to attach to the issue"),notifyUsers:n.z.boolean().optional().default(!0).describe("Whether to notify watchers when the issue is updated"),issueTemplateId:n.z.string().optional().describe("Optional template ID to render issue descriptions"),overrideScreenSecurity:n.z.boolean().optional().default(!1).describe("Temporarily bypass screen security restrictions"),overrideEditableFlag:n.z.boolean().optional().default(!1).describe("Temporarily bypass the editable flag on the screen")}).describe("Arguments used to update existing Jira issues"),Qt=n.z.record(n.z.string(),n.z.any()).optional(),er=n.z.object({type:n.z.string().describe("Mark name, such as strong, emphasis, code, or link"),attrs:Qt}).describe("Inline formatting or link marks applied to text nodes"),tr=n.z.object({type:n.z.literal("text"),text:n.z.string().describe("Rendered string content for the text node"),marks:n.z.array(er).optional()}).describe("Plain text node that carries optional formatting marks"),rr=n.z.object({type:n.z.literal("mention"),attrs:n.z.object({id:n.z.string().describe("Jira internal identifier for the mention"),text:n.z.string().describe("Human readable mention text"),userType:n.z.string().optional(),accessLevel:n.z.string().optional(),localizedAccessLevel:n.z.string().optional()}).describe("Metadata describing the mentioned user")}).describe("Represents a user or team mention in a block or inline context"),ir=n.z.object({type:n.z.literal("emoji"),attrs:n.z.object({shortName:n.z.string().describe("Emoji shortcode such as smiling_face"),id:n.z.string().optional(),text:n.z.string().optional()}).describe("Emoji metadata")}).describe("Emoji inline node"),nr=n.z.object({type:n.z.literal("inlineCard"),attrs:n.z.object({url:n.z.string().url().describe("Target URL that backs the inline card")}).describe("Inline card attributes")}).describe("Inline card that represents a linked resource"),or=n.z.object({type:n.z.literal("status"),attrs:n.z.object({text:n.z.string().describe("Status label text"),color:n.z.string().describe("Color code applied by Jira"),localId:n.z.string().optional(),style:n.z.string().optional()}).describe("Status metadata published by Jira")}).describe("Status node used for Jira workflow or custom fields"),sr=n.z.object({type:n.z.literal("date"),attrs:n.z.object({representation:n.z.string().optional(),timestamp:n.z.number().optional()}).describe("Date metadata, usually RFC3339 or timestamp")}).describe("Date node that embeds a Jira date reference"),ar=n.z.object({type:n.z.literal("hardBreak")}).describe("Inline hard break that forces a newline"),cr=n.z.object({type:n.z.literal("rule")}).describe("Horizontal rule dividing sections of the document");let pr,dr;const lr=n.z.lazy(()=>n.z.union([tr,rr,ir,nr,or,sr,ar])),ur=n.z.lazy(()=>n.z.object({type:n.z.literal("paragraph"),content:n.z.array(lr).describe("Inline nodes contained by the paragraph")})),mr=n.z.lazy(()=>n.z.object({type:n.z.literal("heading"),attrs:n.z.object({level:n.z.number().int().min(1).max(6).describe("Heading level, 1-6")}).optional(),content:n.z.array(lr).describe("Inline nodes composing the heading")})),hr=n.z.lazy(()=>n.z.object({type:n.z.literal("listItem"),attrs:n.z.object({localId:n.z.string().optional()}).optional(),content:n.z.array(n.z.lazy(()=>pr)).describe("Block level nodes nested inside the list item")})),gr=n.z.lazy(()=>n.z.object({type:n.z.literal("bulletList"),content:n.z.array(hr).describe("List items within the bullet list")})),fr=n.z.lazy(()=>n.z.object({type:n.z.literal("orderedList"),attrs:n.z.object({order:n.z.number().int().min(1).optional()}).optional(),content:n.z.array(hr)})),yr=n.z.lazy(()=>n.z.object({type:n.z.literal("taskItem"),attrs:n.z.object({localId:n.z.string().optional(),state:n.z.enum(["TODO","IN_PROGRESS","DONE"]).optional()}).optional(),content:n.z.array(n.z.lazy(()=>pr)).describe("Blocks living inside the task item")})),br=n.z.lazy(()=>n.z.object({type:n.z.literal("taskList"),content:n.z.array(yr).describe("Task items inside the list")})),wr=n.z.lazy(()=>n.z.object({type:n.z.literal("codeBlock"),attrs:n.z.object({language:n.z.string().optional()}).optional(),content:n.z.array(tr).optional()})),vr=n.z.lazy(()=>n.z.object({type:n.z.literal("panel"),attrs:n.z.object({panelType:n.z.enum(["info","note","tip","warning","success"]).optional(),title:n.z.string().optional()}).optional(),content:n.z.array(n.z.lazy(()=>pr)).describe("Panels may nest paragraphs, lists, or other blocks")})),kr=n.z.lazy(()=>n.z.object({type:n.z.literal("blockquote"),content:n.z.array(n.z.lazy(()=>pr)).describe("Quoted block content")})),jr=n.z.lazy(()=>n.z.object({type:n.z.literal("blockCard"),attrs:n.z.object({url:n.z.string().url().describe("URL for the card")})})),zr=n.z.lazy(()=>n.z.object({type:n.z.literal("media"),attrs:n.z.object({id:n.z.string().describe("Media identifier in Jira storage"),type:n.z.string().describe("Media type, e.g., file or link"),collection:n.z.string().optional(),width:n.z.number().optional(),height:n.z.number().optional()}).describe("Metadata describing the embedded media")})),Tr=n.z.lazy(()=>n.z.object({type:n.z.literal("mediaSingle"),content:n.z.array(zr).describe("Single media block content")})),xr=n.z.lazy(()=>n.z.object({type:n.z.literal("mediaGroup"),content:n.z.array(zr).describe("Gallery-style media grouping")})),Sr=n.z.object({type:n.z.literal("tableCell"),attrs:n.z.object({colspan:n.z.number().int().min(1).optional(),rowspan:n.z.number().int().min(1).optional()}).optional(),content:n.z.array(n.z.lazy(()=>pr)).describe("Content inside the table cell")}).describe("A regular table cell container"),Ir=n.z.lazy(()=>Sr),Er=n.z.lazy(()=>Sr.extend({type:n.z.literal("tableHeader")})),Ar=n.z.lazy(()=>n.z.object({type:n.z.literal("tableRow"),content:n.z.array(n.z.union([Ir,Er]))})),Rr=n.z.lazy(()=>n.z.object({type:n.z.literal("table"),content:n.z.array(Ar)})),Or=n.z.lazy(()=>n.z.object({type:n.z.literal("decisionItem"),attrs:n.z.object({localId:n.z.string().optional(),state:n.z.enum(["DECIDED","DECIDING"]).optional()}).optional(),content:n.z.array(n.z.lazy(()=>pr))})),Pr=n.z.lazy(()=>n.z.object({type:n.z.literal("decisionList"),content:n.z.array(Or)})),Cr=n.z.lazy(()=>n.z.object({type:n.z.string(),attrs:n.z.record(n.z.string(),n.z.any()).optional(),content:n.z.array(n.z.lazy(()=>dr)).optional(),marks:n.z.array(er).optional(),text:n.z.string().optional()}).describe("Unknown or extended Jira node"));pr=n.z.lazy(()=>n.z.union([ur,mr,gr,fr,hr,br,yr,wr,vr,kr,jr,Tr,xr,Rr,Ar,Ir,Er,Pr,Or,cr,Cr])),dr=n.z.lazy(()=>n.z.union([pr,lr]));const Nr=n.z.object({type:n.z.literal("doc"),version:n.z.literal(1),content:n.z.array(pr).describe("Top-level block nodes in the document")}).describe("Jira ADF document structure; run jira-md-to-adf when converting markdown"),Jr=r.Logging.for("jira.rate-limit"),Dr=Ke.jira.rateLimitRetryDelayMs??3e3;let _r=!1;const Fr="jira-issue-update",$r=Zt,Mr={name:Fr,inputSchema:$r,runTool:async(e,t)=>{try{const r=$r.parse(t),i={issueIdOrKey:r.issueId};if(r.fields&&(i.fields=(e=>{const t={...e},r=t.description;if("string"==typeof r){const e=Rt(Et(r));t.description=Nr.parse(e)}else if(r&&"object"==typeof r){const e=Rt(Nr.parse(r));t.description=e}return t})(r.fields)),r.update&&(i.update=r.update),r.properties||r.issueTemplateId){const e=[...r.properties??[]];r.issueTemplateId&&e.push({key:"issueTemplateId",value:r.issueTemplateId}),i.properties=e}return void 0!==r.notifyUsers&&(i.notifyUsers=r.notifyUsers),void 0!==r.overrideScreenSecurity&&(i.overrideScreenSecurity=r.overrideScreenSecurity),void 0!==r.overrideEditableFlag&&(i.overrideEditableFlag=r.overrideEditableFlag),st(await(async(e,t)=>{try{return await t()}catch(i){if((e=>{const t=(e=>e?.status??e?.statusCode??e?.response?.status??e?.response?.statusCode??void 0)(e);if(403!==t)return!1;const r=(e=>{const t=e?.response?.data??e?.data??e?.response?.body??e,r=[];return"string"==typeof t&&r.push(t),"string"==typeof t?.message&&r.push(t.message),"string"==typeof t?.errorMessage&&r.push(t.errorMessage),Array.isArray(t?.errorMessages)&&r.push(...t.errorMessages.filter(e=>"string"==typeof e)),"string"==typeof t?.details?.message&&r.push(t.details.message),r.join(" ")||""})(e);return/rate\s?limit/i.test(r)})(i))return _r||(Jr.warn(`Jira rate limit detected for ${e}; waiting ${Dr}ms before retrying.`,{retryDelayMs:Dr}),_r=!0),Dr>0&&await(r=Dr,new Promise(e=>setTimeout(e,r))),t();throw i}var r})(Fr,()=>e.issues.editIssue(i)))}catch(e){throw Ft(e)}}},qr=n.z.object({markdown:n.z.string().describe("Markdown source that will be converted into Jira ADF"),options:n.z.record(n.z.string(),n.z.any()).optional().describe("Optional MarkdownToAdfOptions passed to the converter")}).describe("Convert markdown into a sanitized Jira ADF document"),Lr={name:"jira-md-to-adf",inputSchema:qr,runTool:async(e,t)=>{const r=qr.parse(t),i=Rt(Et(r.markdown,r.options));return st(Nr.parse(i))}},Hr=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID for the assignment change"),assignee:n.z.union([n.z.string().describe("Account ID of the new assignee"),n.z.object({accountId:n.z.string().min(1).describe("Account ID of the assignee")})]).describe("How the new assignee is specified")}).describe("Arguments required to assign a Jira issue to someone"),Gr={name:"jira-assign-issue",inputSchema:Hr,runTool:async(e,t)=>{try{const r=Hr.parse(t);let i=null;"string"==typeof r.assignee?i=r.assignee:"accountId"in r.assignee&&(i=r.assignee.accountId);const n={issueIdOrKey:r.issueId,accountId:i};return await e.issues.assignIssue(n),st({success:!0,message:"Issue assigned to "+(i??"unassigned")})}catch(e){throw Ft(e)}}},Ur=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID to remove the assignee from")}).describe("Inputs required to unassign a Jira issue"),Wr={name:"jira-unassign-issue",inputSchema:Ur,runTool:async(e,t)=>{try{const r=Ur.parse(t),i={issueIdOrKey:r.issueId,accountId:null};return await e.issues.assignIssue(i),st({success:!0,message:`Issue ${r.issueId} unassigned successfully`})}catch(e){throw Ft(e)}}},Kr=n.z.object({issueId:n.z.string().min(1).describe("The Jira issue key or numeric ID receiving the comment"),body:n.z.string().min(1).describe("The markdown-compatible text of the comment"),visibility:n.z.object({type:n.z.enum(["role","group"]).describe("Visibility type that restricts the comment to a role or group"),value:n.z.string().min(1).describe("The name of the role or group granted visibility")}).optional().describe("Optional visibility override controlling who can read the comment")}).describe("Arguments for adding a comment to a Jira issue"),Br={name:"jira-comment-add",inputSchema:Kr,runTool:async(e,t)=>{try{const r=Kr.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.addComment)throw Error("Jira issueComments API is unavailable on the client");const n={issueIdOrKey:r.issueId,comment:r.body,visibility:r.visibility};return st(await i.addComment(n))}catch(e){throw Ft(e)}}},Yr=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID whose comments should be retrieved"),start:n.z.number().optional().default(0).describe("Zero-based index to start pagination from"),maxResults:n.z.number().optional().default(50).describe("Maximum number of comments to return"),orderBy:n.z.string().optional().describe("Field name to order the returned comments by"),expand:n.z.string().optional().describe("Optional expansion clause for the comment response")}).describe("Parameters for fetching comments on a Jira issue"),Xr={name:"jira-comment-list",inputSchema:Yr,runTool:async(e,t)=>{try{const r=Yr.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.getComments)throw Error("Jira issueComments API is unavailable on the client");const n={issueIdOrKey:r.issueId,startAt:r.start,maxResults:r.maxResults,orderBy:r.orderBy,expand:r.expand};return st(await i.getComments(n))}catch(e){throw Ft(e)}}},Vr=n.z.enum(["Blocks","Relates to","Duplicates","Is blocked by","Is related to","is tested by","tests","Is covered by","covered by","Is duplicated by","Causes","Is caused by","Clone","Required","Work on","Split","Roll up"]).describe("The named relationship (Blocks, Relates to, etc.) that describes the link type"),Zr=n.z.object({id:n.z.string().optional().describe("Numeric Jira ID used when referencing an issue"),key:n.z.string().optional().describe("Human-readable key of the linked issue")}).describe("An issue reference (ID or key) used when building a link payload"),Qr=n.z.object({type:n.z.enum(["role","group"]).describe("Visibility scope type attached to the comment"),value:n.z.string().min(1).describe("Name of the role or group granted visibility to the comment")}).describe("Optional visibility settings applied to the comment"),ei=n.z.object({body:n.z.string().optional().describe("Markdown text to include as a linked-comment"),visibility:Qr.optional().describe("Optional ACL for the comment")}).describe("Optional comment applied at the time the link is created or updated"),ti=n.z.object({link:n.z.object({relationship:Vr,inwardIssue:Zr,outwardIssue:Zr,comment:ei.optional()}).describe("Definition of the link that should be created between two issues")}).describe("Arguments required to create a Jira issue link");let ri=[];function ii(e){return(e||"").trim().toLowerCase()}async function ni(e,t){if(!t)throw Error("Link relationship is required");0===ri.length&&(ri=await(async e=>{const t=e?.issueLinkTypes;if(!t||"function"!=typeof t.getIssueLinkTypes)throw Error("Jira issueLinkTypes API is unavailable on the client");const r=await t.getIssueLinkTypes();return r?.issueLinkTypes??[]})(e));const r=ii(t),i=ri.find(e=>[e.name,e.inward,e.outward].some(e=>ii(e)===r));if(!i)throw Error(`No issue link type matching '${t}' found.`);return i}function oi(e){if(!e)throw Error("Linked issue must include an id or key");if(e.id)return{id:e.id};if(e.key)return{key:e.key};throw Error("Linked issue must include an id or key")}function si(e){if(!e)return;const t={};return e.body&&(t.body=Et(e.body)),e.visibility&&(t.visibility=e.visibility),Object.keys(t).length>0?t:void 0}const ai=ti,ci={name:"jira-link-create",inputSchema:ai,runTool:async(e,t)=>{try{const r=ai.parse(t).link,i=si(r.comment),n=e.issueLinks;if(!n||"function"!=typeof n.linkIssues)throw Error("Jira issueLinks API is unavailable on the client");const o=await ni(e,r.relationship),s={inwardIssue:oi(r.inwardIssue),outwardIssue:oi(r.outwardIssue),type:pi(o),...i?{comment:i}:{}};return await n.linkIssues(s),st({success:!0,message:"Issue link created with relationship "+r.relationship})}catch(e){throw Ft(e)}}};function pi(e){if(e.id)return{id:e.id};if(e.name)return{name:e.name};throw Error("Resolved issue link type is missing both id and name")}const di=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID receiving the attachment"),file:n.z.string().min(1).describe("Base64 or path to the file contents to upload"),mimeType:n.z.string().optional().describe("Optional MIME type override for the attachment"),comment:n.z.string().optional().describe("Optional comment to associate with the attachment")}).describe("Inputs needed to attach a file to a Jira issue"),li={name:"jira-attach",inputSchema:di,runTool:async(e,r)=>{try{const i=di.parse(r),n=a.resolve(i.file);let o=i.file,s="attachment",c=!1;try{await t.promises.access(n),c=!0}catch{o=i.file,s="attachment"}c&&(o=await t.promises.readFile(n),s=a.basename(n));const p=e.issueAttachments;if(!p||"function"!=typeof p.addAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const d={filename:s,file:o,mimeType:i.mimeType},l=await p.addAttachment({issueIdOrKey:i.issueId,attachment:d});if(i.comment){const t=e?.issueComments;if(!t||"function"!=typeof t.addComment)throw Error("Jira issueComments API is unavailable on the client");await t.addComment({issueIdOrKey:i.issueId,comment:Et(i.comment)})}return st(l)}catch(e){if(e&&"object"==typeof e&&"code"in e&&"string"==typeof e.code&&["ENOENT","EACCES"].includes(e.code))throw Error("Attachment file error: "+(e.message??"Unknown error"));throw Ft(e)}}},ui=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID whose attachments should be listed")}).describe("Arguments used to fetch attachments for a Jira issue"),mi={name:"jira-attachment-list",inputSchema:ui,runTool:async(e,t)=>{try{const r=ui.parse(t),i=e.issues;if(!i||"function"!=typeof i.getIssue)throw Error("Jira issues API is unavailable on the client");const n={issueIdOrKey:r.issueId,fields:["attachment"]},o=await i.getIssue(n);return st({attachments:Array.isArray(o.fields?.attachment)?o.fields.attachment:[]})}catch(e){throw Ft(e)}}},hi=n.z.object({issueId:n.z.string().min(1).describe("Issue key or ID owning the attachment"),attachmentId:n.z.string().min(1).describe("ID of the attachment to delete")}).describe("Arguments required to remove an attachment from Jira"),gi={name:"jira-attachment-delete",inputSchema:hi,runTool:async(e,t)=>{try{const r=hi.parse(t),i=e.issueAttachments;if(!i||"function"!=typeof i.removeAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const n={id:r.attachmentId};return await i.removeAttachment(n),st({success:!0,message:`Attachment ${r.attachmentId} deleted successfully`})}catch(e){throw Ft(e)}}},fi=n.z.object({issueId:n.z.string().min(1).describe("Target issue key or ID for the worklog entry"),timeSpent:n.z.string().min(1).describe('Time spent text (e.g., "1h 30m")'),comment:n.z.string().optional().describe("Optional worklog comment in markdown"),author:n.z.object({accountId:n.z.string().min(1).describe("Account ID of the user logging the work")}).optional().describe("Optional author override for the worklog entry"),startingOn:n.z.string().optional().describe("Optional timestamp for when the work started (ISO)"),artifact:n.z.string().optional().describe("Optional identifier linking the worklog to another artifact")}).describe("Arguments required to add a worklog entry to a Jira issue"),yi={name:"jira-worklog-add",inputSchema:fi,runTool:async(e,t)=>{try{const r=fi.parse(t),i={timeSpent:r.timeSpent,issueIdOrKey:r.issueId};if(r.comment&&(i.comment=r.comment),r.author&&(i.author=r.author),r.startingOn&&(i.started=r.startingOn),r.artifact){const e=[...i.properties??[]];e.push({key:"artifact",value:r.artifact}),i.properties=e}const n=e.issueWorklogs;if(!n||"function"!=typeof n.addWorklog)throw Error("Jira issueWorklogs API is unavailable on the client");return st(await n.addWorklog(i))}catch(e){throw Ft(e)}}},bi=r.Logging.for("jira.xray");class wi{constructor(){this.clientId=Ke.orThrow().xray.apiUser,this.clientSecret=Ke.orThrow().xray.apiSecret,this.baseUrl=Ke.orThrow().xray.host||"https://eu.xray.cloud.getxray.app"}async authenticate(){if(!this.clientId||!this.clientSecret)throw Error("Xray API credentials are missing (XRAY__API_USER, XRAY__API_SECRET).");const e=await fetch(this.baseUrl+"/api/v2/authenticate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:this.clientId,client_secret:this.clientSecret})}),t=await e.text();return this.token=t.replace(/"/g,""),this.token}async graphql(e,t){this.token||await this.authenticate();const r={query:e,variables:t};bi.info("xray.graphql.request",{payload:tt(r)});try{const e=await fetch(this.baseUrl+"/api/v2/graphql",{method:"POST",headers:{Authorization:"Bearer "+this.token,"Content-Type":"application/json"},body:JSON.stringify(r)}),t=await e.json();if(bi.info("xray.graphql.response",{status:e.status,headers:e.headers?.get?e.headers.get("content-type"):void 0,body:tt(t)}),t.errors)throw bi.error("xray.graphql.errors",{errors:tt(t.errors)}),Error(JSON.stringify(t.errors,null,2));return t.data}catch(e){throw bi.error("xray.graphql.failure",{error:e+""}),e}}async getTest(e){return(await this.graphql('\n query GetTest($issueId: String!) {\n getTest(issueId: $issueId) {\n issueId\n jira(fields:["key"])\n steps {\n id\n action\n data\n result\n }\n }\n }\n ',{issueId:e})).getTest}async addStep(e,t){return(await this.graphql("\n mutation AddTestStep($issueId: String!, $step: CreateStepInput!) {\n addTestStep(issueId: $issueId, step: $step) {\n id\n action\n data\n result\n }\n }\n ",{issueId:e,step:t})).addTestStep}async updateStep(e,t){return(await this.graphql("\n mutation UpdateTestStep($stepId: String!, $step: UpdateStepInput!) {\n updateTestStep(stepId: $stepId, step: $step) {\n id\n action\n data\n result\n }\n }\n ",{stepId:e,step:t})).updateTestStep}async deleteStep(e){return(await this.graphql("\n mutation RemoveTestStep($stepId: String!) {\n removeTestStep(stepId: $stepId)\n }\n ",{stepId:e})).removeTestStep}async addSteps(e,t){return Promise.all(t.map(t=>this.addStep(e,t)))}async updateSteps(e){return Promise.all(e.map(e=>this.updateStep(e.stepId,e.step)))}async deleteSteps(e){return Promise.all(e.map(e=>this.deleteStep(e)))}async syncSteps(e,t){const r=(await this.getTest(e)).steps||[],i=[],n=[],o=[];for(let e=0;e<t.length;e++){const o=t[e],s=r[e];s?s.action===o.action&&s.data===o.data&&s.result===o.result||i.push({stepId:s.id,step:o}):n.push(o)}if(r.length>t.length)for(let e=t.length;e<r.length;e++)o.push(r[e].id);await this.addSteps(e,n),await this.updateSteps(i),await this.deleteSteps(o)}}let vi=null;const ki=new Map;function ji(e){const t=e?.fields,r=e?.action??t?.Action??t?.action;if(!r||"string"!=typeof r)throw Error("Xray step action is required");const i=e.data??e.fields?.Data??e.fields?.data??void 0,n=e.result??e.fields?.Result??e.fields?.result??void 0;return{action:r.toString(),data:"string"==typeof i?i:void 0,result:"string"==typeof n?n:void 0}}async function zi(e,t){if(!t)throw Error("Issue reference is required when interacting with Xray steps");if(ki.has(t))return ki.get(t);if(/^[0-9]+$/.test(t))return ki.set(t,t),t;const r=e?.issues;if(!r?.getIssue)throw Error("Jira client does not expose issue lookup functionality");const i=await r.getIssue({issueIdOrKey:t,fields:["id"]}),n=i?.id;if(!n)throw Error("Unable to resolve Jira issue ID for "+t);return ki.set(t,n),n}async function Ti(e){if(e?.test?.step)return e.test.step;const t=await(async()=>{if(vi)return vi;const e=Ke.orThrow().xray.apiUser?.trim(),t=Ke.orThrow().xray.apiSecret?.trim();if(!e||!t)throw Error("Xray credentials are missing (XRAY__API_USER, XRAY__API_SECRET). Please configure them before using Xray tools.");const r=await nt(),i=new wi,n={async createStep(e,t){const n=await zi(r,e),o=await i.addStep(n,ji(t));return{step:o,id:o?.id}},async updateStep(e,t,n){await zi(r,e);const o=ji(n),s=await i.updateStep(t.toString(),o);return{step:s,id:s?.id}},deleteStep:async(e,t)=>(await zi(r,e),{success:!0===await i.deleteStep(t.toString())}),async getSteps(e){const t=await zi(r,e),n=await i.getTest(t);return{steps:n?.steps??[]}}};return vi={test:{step:n}},vi})();if(!t?.test?.step)throw Error("Xray step API is unavailable on the client");return t.test.step}const xi=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID that owns the step"),action:n.z.string().min(1).describe("Action description for the new Xray step"),data:n.z.string().optional().describe("Optional data or context used by this step"),result:n.z.string().optional().describe("Optional expected result for the step")}).describe("Inputs for adding a step to an Xray test case"),Si={name:"jira-xray-step-add",inputSchema:xi,runTool:async(e,t)=>{try{const r=xi.parse(t),i=await Ti(e),n={action:r.action,data:r.data,result:r.result};return st(await i.createStep(r.issueId,n))}catch(e){throw Ft(e)}}},Ii=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID that owns the step"),stepId:n.z.union([n.z.string(),n.z.number()]).describe("Identifier for the step that should be updated"),action:n.z.string().min(1).describe("New action text for the step"),data:n.z.string().optional().describe("Updated data/context for the step"),result:n.z.string().optional().describe("Updated expected result for the step")}).describe("Inputs required to modify an Xray test step"),Ei={name:"jira-xray-step-update",inputSchema:Ii,runTool:async(e,t)=>{try{const r=Ii.parse(t),i=await Ti(e),n=r.stepId+"",o={action:r.action,data:r.data,result:r.result};return st(await i.updateStep(r.issueId,n,o))}catch(e){throw Ft(e)}}},Ai=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID owning the step"),stepId:n.z.union([n.z.string(),n.z.number()]).describe("Identifier of the step to delete")}).describe("Arguments used to remove an Xray test step"),Ri={name:"jira-xray-step-delete",inputSchema:Ai,runTool:async(e,t)=>{try{const r=Ai.parse(t),i=await Ti(e);return await i.deleteStep(r.issueId,r.stepId.toString()),st({success:!0})}catch(e){throw Ft(e)}}},Oi=n.z.object({issueId:n.z.string().min(1).describe("Xray test case key or ID whose steps should be returned")}).describe("Inputs required to list steps on an Xray test case"),Pi={name:"jira-xray-step-list",inputSchema:Oi,runTool:async(e,t)=>{try{const r=Oi.parse(t),i=await Ti(e);return st(await i.getSteps(r.issueId))}catch(e){throw Ft(e)}}},Ci=n.z.object({linkId:n.z.string().min(1).describe("Identifier for the Jira issue link to remove")}).describe("Inputs required to delete an existing Jira issue link"),Ni={name:"jira-link-delete",inputSchema:Ci,runTool:async(e,t)=>{try{const r=Ci.parse(t),i=e.issueLinks;if(!i||"function"!=typeof i.deleteIssueLink)throw Error("Jira issueLinks API is unavailable on the client");const n={linkId:r.linkId};return await i.deleteIssueLink(n),st({success:!0,message:`Issue link ${r.linkId} deleted successfully`})}catch(e){throw Ft(e)}}},Ji=n.z.object({linkId:n.z.string().min(1).describe("ID of the existing issue link to change"),relationship:Vr,comment:ei.optional().describe("Optional comment to attach while recreating the link")}).describe("Inputs required to update (recreate) a Jira issue link"),Di={name:"jira-link-update",inputSchema:Ji,runTool:async(e,t)=>{try{const r=Ji.parse(t),i=e.issueLinks;if(!i||"function"!=typeof i.getIssueLink||"function"!=typeof i.deleteIssueLink||"function"!=typeof i.linkIssues)throw Error("Jira issueLinks API is unavailable on the client");const n=await i.getIssueLink({linkId:r.linkId});if(!n)throw Error(`Issue link ${r.linkId} not found`);const o=n.inwardIssue,s=n.outwardIssue;if(!o||!s)throw Error("Issue link payload is missing linked issues");const a=await ni(e,r.relationship);await i.deleteIssueLink({linkId:r.linkId});const c=si(r.comment),p={inwardIssue:oi(o),outwardIssue:oi(s),type:_i(a),...c?{comment:c}:{}};return await i.linkIssues(p),st({success:!0,message:`Issue link ${r.linkId} updated to ${r.relationship}`})}catch(e){throw Ft(e)}}};function _i(e){if(e.id)return{id:e.id};if(e.name)return{name:e.name};throw Error("Resolved issue link type is missing both id and name")}function Fi(e=[]){return e.map($i).join("")}function $i(e){switch(e.type){case"text":return(e=>{let t=e.text||"";for(const r of e.marks||[])switch(r.type){case"strong":t=`**${t}**`;break;case"em":t=`*${t}*`;break;case"strike":t=`~~${t}~~`;break;case"code":t="`"+t+"`";break;case"link":t=`[${t}](${r.attrs.href})`}return t})(e);case"mention":return e.attrs.text||"@"+e.attrs.id;case"emoji":return e.attrs.shortName||"";case"inlineCard":return e.attrs.url;case"status":return`:status{color="${e.attrs.color}"}[${e.attrs.text}]`;case"hardBreak":return" \n"}return""}function Mi(e){switch(e.type){case"heading":return"#".repeat(e.attrs?.level)+" "+Fi(e.content);case"paragraph":return Fi(e.content);case"blockquote":return e.content.map(Mi).map(e=>"> "+e).join("\n");case"bulletList":case"orderedList":case"taskList":return(e=>{const t=[];let r=1;for(const i of e.content){let n="- ";"orderedList"===e.type&&(n=r+++". "),"taskList"===e.type&&(n="- "+("DONE"===i.attrs?.state?"[x] ":"[ ] "));const o=i.content.map(Mi).join(" ");t.push(n+o)}return t.join("\n")})(e);case"table":return(e=>{const t=e.content||[];return t.length?["| "+t[0].content.map(e=>Fi(e.content[0].content)).join(" | ")+" |","| "+t[0].content.map(()=>"---").join(" | ")+" |",...t.slice(1).map(e=>e.content.map(e=>Fi(e.content[0].content)).join(" | ")).map(e=>"| "+e+" |")].join("\n"):""})(e);case"codeBlock":return"```"+(e.attrs?.language||"")+"\n"+e.content?.map(e=>e.text).join("")+"\n```";case"panel":return(e=>`::panel{type="${e.attrs?.panelType||"info"}"}\n${e.content.map(Mi).join("\n")}\n::`)(e);case"rule":return"---";case"mediaSingle":return(e=>{const t=e.content?.[0];return t?"external"===t.attrs?.type?``:"file"===t.attrs?.type?`[attachment](attachment:${t.attrs.id})`:"":""})(e);case"blockCard":return e.attrs?.url}return""}const qi=n.z.object({document:Nr.describe("Jira ADF document you want to translate into Markdown (use jira-md-to-adf to go the other way).")}).describe("Convert Jira ADF documents back to Markdown text for editing or review"),Li={name:"jira-adf-to-markdown",inputSchema:qi,runTool:async(e,t)=>{return st({markdown:(r=qi.parse(t).document,(e=>{if(!e||"doc"!==e.type)return"";const t=[];for(const r of e.content||[])t.push(Mi(r));return t.join("\n\n")})(r))});var r}},Hi=n.z.enum(["bug","incident","release","feature","test"]),Gi=n.z.object({ticketType:Hi.optional(),template_path:n.z.string().min(1).optional(),project:n.z.string().min(1).optional(),projectKey:n.z.string().min(1).optional(),issueType:n.z.string().min(1).optional(),summary:n.z.string().min(1).optional(),description:n.z.string().optional(),assignee:n.z.string().optional(),customFields:n.z.record(n.z.string(),n.z.union([n.z.string(),n.z.number(),n.z.boolean()])).optional(),fields:n.z.record(n.z.string(),n.z.any()).optional(),template:n.z.object({content:n.z.string().min(1),placeholders:n.z.record(n.z.string(),n.z.union([n.z.string(),n.z.number(),n.z.boolean()])).optional()}).optional()}).refine(e=>!!(e.ticketType||e.template_path||e.template?.content||e.fields),{message:"ticketType, template_path, template.content, or fields must be provided",path:["ticketType"]});function Ui(e){return e&&e.trim()?e.trim():void 0}const Wi={name:"jira-ticket-create",inputSchema:Gi,runTool:async(e,t)=>st(await(async(e,t)=>{const r=Gi.parse(t),i=r.template_path??r.ticketType,n=(e=>{if(e)try{return ze(e)}catch{return}})(i),o=r.template?.content??(n?Te(i):void 0),s=r.projectKey??r.project??(e=>{const t=e?.project;if(t&&"object"==typeof t){const e=t.key;if("string"==typeof e&&e.trim())return e.trim()}const r=e?.projectKey;return"string"==typeof r&&r.trim()?r.trim():void 0})(r.fields)??Ui(Ke.jira.projectKey)??"",a=r.issueType??(e=>{const t=e?.issuetype;if(t&&"object"==typeof t){const e=t.name;if("string"==typeof e&&e.trim())return e.trim()}const r=e?.issueType;return"string"==typeof r&&r.trim()?r.trim():void 0})(r.fields)??n?.issueType??Ui(Ke.jira.issueType)??"Task",c=r.summary??(e=>{const t=e?.summary;return"string"==typeof t&&t.trim()?t.trim():void 0})(r.fields)??"",p=o||r.template?{content:o??r.template.content,placeholders:{...r.customFields??{},summary:c,projectKey:s??"",issueType:a,ticketType:n?.type??r.ticketType??"",templatePath:n?.uri??r.template_path??"",templateName:n?.name??"",templateTitle:n?.title??"",...r.template?.placeholders??{}}}:void 0;return await Nt(e,r.fields?{fields:r.fields,...p?{template:p}:{}}:{summary:c,projectKey:s,issueType:a,...r.description?{description:r.description}:{},...r.assignee?{assignee:r.assignee}:{},...p?{template:p}:{}})})(e,t))},Ki={[Jt.name]:{title:"Jira Issue Create",description:"Create a Jira issue (optionally applying a markdown template)",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Wi.name]:{title:"Jira Ticket Create",description:"Create a Jira ticket from a resource-backed bug, incident, release, feature, or test template with tracked custom fields",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Ut.name]:{title:"Jira Issue Read",description:"Read a Jira issue with expandable fields and properties",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Ht.name]:{title:"Jira Issue List",description:"Search issues by summary, reference, parent, or JQL and list the matching tickets",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Mr.name]:{title:"Jira Issue Update",description:"Update a Jira issue using fields, update ops, and property toggles",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Lr.name]:{title:"Jira Markdown to ADF",description:"Convert Markdown into a sanitized Jira ADF document so fields.description can be supplied to jira-issue-update and other tools that expect Jira documents",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Li.name]:{title:"Jira ADF to Markdown",description:"Translate Jira ADF documents back into Markdown text so you can edit them before sending them through tooling or LLM prompts (use jira-md-to-adf to get valid ADF inputs).",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Mt.name]:{title:"Jira Issue Delete",description:"Delete a Jira issue and optionally remove its subtasks",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Kt.name]:{title:"Jira Issue Transition",description:"Transition a Jira issue while optionally adding a comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Yt.name]:{title:"Jira Transition List",description:"List available transitions for a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Gr.name]:{title:"Jira Issue Assign",description:"Assign a Jira issue to a user or account",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Wr.name]:{title:"Jira Issue Unassign",description:"Unassign the current owner from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Br.name]:{title:"Jira Comment Add",description:"Add a comment to a Jira issue with optional visibility",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Xr.name]:{title:"Jira Comment List",description:"List comments on a Jira issue with pagination support",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[ci.name]:{title:"Jira Link Create",description:"Create an issue link relationship with optional comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Di.name]:{title:"Jira Link Update",description:"Change the relationship type for an existing issue link",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Ni.name]:{title:"Jira Link Delete",description:"Delete an issue link from Jira",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[li.name]:{title:"Jira Attachment Add",description:"Attach a local file to a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[mi.name]:{title:"Jira Attachment List",description:"List attachments on a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[gi.name]:{title:"Jira Attachment Delete",description:"Delete an attachment from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[yi.name]:{title:"Jira Worklog Add",description:"Log time spent on a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Si.name]:{title:"Jira Xray Step Add",description:"Add a step to an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Ei.name]:{title:"Jira Xray Step Update",description:"Update a step on an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Ri.name]:{title:"Jira Xray Step Delete",description:"Delete a step from an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Pi.name]:{title:"Jira Xray Step List",description:"List steps for an Xray test case",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}}};async function Bi(e){const t=r.Logging.for(Bi);let i,n=null;try{i=await nt()}catch(e){if(!(e instanceof Ve))return void t.warn("Skipping Jira tool registration; unable to create Jira client",{error:e});n=e,t.warn("Registering Jira tools without credentials; each tool will report configuration requirements.",{error:e})}const o=[Jt,Wi,Ut,Ht,Mr,Lr,Li,Mt,Kt,Yt,Gr,Wr,Br,Xr,ci,Di,Ni,li,mi,gi,yi,Si,Ei,Ri,Pi];for(const r of o){const o=Ki[r.name];if(o)try{await e.registerTool(r.name,{title:o.title,description:o.description,inputSchema:r.inputSchema,annotations:o.annotations},async e=>{if(!i)throw n??Error("Jira client unavailable because credentials could not be loaded.");return await r.runTool(i,e)}),t.info("Registered Jira tool "+r.name)}catch(e){t.error("Failed to register Jira tool "+r.name,{error:e})}}}async function Yi(e){const t=r.Logging.for(Yi);try{await(async e=>{await e.registerTool("file-summarizer",{title:"File summarizer",description:"Summarizes a file by delegating to the configured provider CLI and returning the model-produced summary. Defaults to README.md when no path is supplied.",inputSchema:Fe.shape,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},async e=>(async e=>{const t=Fe.parse(e??{}),r=t?.filePath?a.resolve(process.cwd(),t.filePath):$e,i=(()=>{const e=(process.env.AGENT_PROVIDER||"codex").toLowerCase();return"claude"===e||"copilot"===e||"codex"===e?e:"codex"})(),n=((e,t)=>{if(t)return t;if(!e)return"text";const r=e.split(".").pop()?.toLowerCase();return r&&new Set(["ts","tsx","js","jsx","mjs","cjs","mts","cts","json","yaml","yml","py","go","rs","java","c","h","cpp","hpp","cs","rb","php","sh","bash","zsh","sql","toml","ini"]).has(r)?"code":"text"})(t.filePath,t.textType);try{const e=await u.readFile(r,"utf8"),o=await _e({provider:i,prompt:Ne({filePath:r,textType:n,context:t.context},e),toolMetadata:{tool:"file-summarizer",filePath:r,textType:n,context:t.context},cwd:process.cwd()});if(0!==o.exitCode)throw Error(o.stderr.trim()||"summarization provider failed");const s=(e=>{const t=e.trim();if(!t)return{summary:"(empty response from summarization provider)"};const r=(e=>{const t=e.trim();if(t.startsWith("{")&&t.endsWith("}"))return t;const r=t.indexOf("{"),i=t.lastIndexOf("}");return-1!==r&&-1!==i&&i>r?t.slice(r,i+1):void 0})(t);if(!r)return{summary:t};try{const e=JSON.parse(r);if("string"==typeof e.summary&&e.summary.trim())return{summary:e.summary,highlights:Array.isArray(e.highlights)?e.highlights.filter(e=>"string"==typeof e):void 0,warnings:Array.isArray(e.warnings)?e.warnings.filter(e=>"string"==typeof e):void 0}}catch{}return{summary:t}})(o.stdout),a=s.summary.trim(),c={filePath:r,status:"ok",provider:i,textType:n,context:t.context,summary:a,highlights:s.highlights??[],warnings:s.warnings??[]};return{content:[{type:"text",text:a}],structuredContent:c,result:c}}catch(e){const o=e instanceof Error?e.message:"unknown summarization failure",s=`Unable to summarize ${t?.filePath??"README.md"}: ${o}`,a={filePath:r,status:"error",provider:i,textType:n,context:t.context,summary:s,highlights:[],warnings:[o]};return{content:[{type:"text",text:s}],structuredContent:a,result:a}}})(e))})(e),t.verbose("Registered file summarizer tool")}catch(e){t.error("Failed to register file summarizer tool",e)}try{await(async e=>{e.registerTool("decaf-server-info",{title:"Decaf MCP Server Info",description:"Return read-only server metadata, version, and registered prompt lists so callers can discover what exposures are available without side effects.",inputSchema:{},outputSchema:void 0,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},async()=>{const e=Me.map(e=>e.getName()).sort();return{content:[{type:"text",text:["Name: "+Ke.name,"Title: "+Ke.title,"Version: "+Ke.version,"Prompts: "+(e.join(", ")||"<none>")].join("\n")}]}})})(e)}catch(e){t.error("Failed to register server info tool",e)}try{await Bi(e)}catch(e){t.error("Failed to register Jira tools",e)}}class Xi extends L{setCb(e){return this.cb=e,this}setConfig(e){return this.config=e,this}setUriOtTemplate(e){return this.uriOrTemplate=e,this}constructor(e){super(e)}static get builder(){return new Xi}build(e){const t=this.hasErrors();if(t)throw Error(t.toString());try{const t="string"==typeof this.uriOrTemplate&&this.uriOrTemplate.includes("{")?new v.ResourceTemplate(new k.UriTemplate(this.uriOrTemplate),{list:void 0}):this.uriOrTemplate,r=Object.assign(this.config,{_meta:{}}),i=async(e,t)=>{const r=this.logFor(t);r.verbose(`Requesting resource ${this.name} from ${e.toString()}`);const i=await Promise.resolve(this.cb(e,t));return r.verbose(`Resource ${this.name} retrieved successfully.`),r.debug("Resource retrieval meta: "+JSON.stringify(i._meta)),i};return e.resource(this.name,t,r,i)}catch(e){throw r.Logging.for(this).error("Error registering resource "+this.name,e),e}}}J([i.required(),D("design:type",Object)],Xi.prototype,"uriOrTemplate",void 0),J([i.required(),D("design:type",Function)],Xi.prototype,"cb",void 0),J([i.required(),D("design:type",Object)],Xi.prototype,"config",void 0);const Vi=z.join("workdocs","ai"),Zi=z.join("project"),Qi=z.join(Zi,"agent"),en=z.join(Qi,"prompts"),tn=z.join(Qi,"behaviors"),rn=te()??Q("src","assets"),nn=z.join(rn,"prompts","agent"),on=z.join(rn,"resources","agent"),sn=z.join(rn,"templates"),an="catalog.json";function cn(e){return z.resolve(e||Q(Vi))}function pn(e){return z.join(e,Zi)}function dn(e){return z.join(e,Qi)}function ln(e){return z.join(e,en)}function un(e){return z.join(e,tn)}function mn(e="./AGENTS.md"){return z.resolve(process.cwd(),e)}function hn(e){return z.join(dn(e),an)}function gn(e={}){const t=cn(e.workspacePath),r=pn(t),i=dn(t),n=[];kn(r),kn(i),kn(ln(t)),kn(un(t)),vn(z.join(sn,"AGENTS.md"),mn(e.entryFile),!1!==e.preserveExisting,n),vn(z.join(sn,"instructions_template.md"),z.join(r,"instructions.md"),!1!==e.preserveExisting,n),vn(z.join(sn,"constitution_template.md"),z.join(r,"constitution.md"),!1!==e.preserveExisting,n),vn(z.join(sn,"plan_template.md"),z.join(r,"plan.md"),!1!==e.preserveExisting,n),vn(z.join(sn,"specification_template.md"),z.join(r,"specifications","specification_template.md"),!1!==e.preserveExisting,n),vn(z.join(sn,"task_template.md"),z.join(r,"specifications","task_template.md"),!1!==e.preserveExisting,n);const o=["constitution_commands.md","git_commands.md","mode_commands.md","plan_commands.md","specification_commands.md","startup_command.md","task_commands.md"];for(const t of o)vn(z.join(rn,"prompts",t),z.join(r,"commands",t),!1!==e.preserveExisting,n);const s=jn(nn,[".md",".json"]);for(const r of s)vn(z.join(nn,r),z.join(ln(t),r),!1!==e.preserveExisting,n);const a=jn(on,[".json"]);for(const r of a)vn(z.join(on,r),z.join(un(t),r),!1!==e.preserveExisting,n);return vn(z.join(on,an),hn(t),!1!==e.preserveExisting,n),{workspaceRoot:t,projectRoot:r,agentRoot:i,entryFile:mn(e.entryFile),copiedFiles:n}}function fn(e={}){const t=cn(e.workspacePath),r=dn(t),i=hn(t),n=mn(e.entryFile);return j.existsSync(r)&&j.existsSync(i)?(j.existsSync(n)||(kn(z.dirname(n)),j.copyFileSync(z.join(sn,"AGENTS.md"),n)),{workspaceRoot:t,projectRoot:pn(t),agentRoot:r,entryFile:n,copiedFiles:[]}):gn({workspacePath:e.workspacePath,entryFile:e.entryFile,preserveExisting:!0})}function yn(e){return zn(hn(e))||Tn(z.join(on,an))}function bn(e,t){return zn(z.join(un(e),t.behaviorFile))||Tn(z.join(on,t.behaviorFile))}function wn(e,t){const r=z.join(ln(e),t.promptFile);if(!j.existsSync(r))throw Error("Missing copied agent prompt file: "+r);return j.readFileSync(r,"utf8")}function vn(e,t,r,i){kn(z.dirname(t)),r&&j.existsSync(t)||(j.copyFileSync(e,t),i.push(t))}function kn(e){j.mkdirSync(e,{recursive:!0})}function jn(e,t){return j.existsSync(e)?j.readdirSync(e,{withFileTypes:!0}).filter(e=>e.isFile()).map(e=>e.name).filter(e=>t.includes(z.extname(e))).sort():[]}function zn(e){if(j.existsSync(e))return Tn(e)}function Tn(e){return JSON.parse(j.readFileSync(e,"utf8"))}const xn=["prompt","goap","workflow"];function Sn(e){return(e=>{const t=(e+"").toLowerCase();if(xn.includes(t))return t;if("default"===t)return"prompt";throw Error("Unsupported agent model type: "+e)})(e||process.env.AGENT_MODEL_TYPE||"prompt")}function In(e){return"goap"===e}function En(e){return"prompt"===e}class An{constructor(){this.store=new Map}set(e,t){return this.store.set(e,t),this}get(e){return this.store.get(e)}has(e){return this.store.has(e)}remove(e){return this.store.delete(e),this}clear(){this.store.clear()}}const Rn={plan:"architect",review:"reviewer","create-specs":"architect",implement:"implementation",execute:"orchestrator",manage:"manager"};class On{constructor(e,t,r={}){this.definition=e,this.options=t,this.blackboard=new An,this.modelType=Sn(t.modelType),this.providerCommand=De(this.options.provider),this.behavior=this.createBehaviourHost(r),In(this.modelType)||(this.tree=new T.BehaviourTree(e.tree,this.behavior))}get log(){return this._log||(this._log=r.Logging.for(this)),this._log}run(){return this.blackboard.set("modelType",this.modelType),this.blackboard.set("provider",this.options.provider),this.blackboard.set("objective",this.options.objective??this.definition.objective),this.blackboard.set("specRef",this.options.specRef),this.blackboard.set("specRefs",this.options.specRefs??[]),this.report("started",this.definition.name+" started",0),In(this.modelType)?this.runGoap():this.runWorkflow()}report(e,t,r){this.options.onProgress&&this.options.onProgress({agentName:this.definition.name,operation:In(this.modelType)?"goap":"workflow",specRef:this.options.specRef,taskRef:this.options.specRefs?.[0],status:e,summary:t,progress:r})}createBehaviourHost(e){const t={blackboard:this.blackboard,log:this.log,report:this.report.bind(this)};for(const e of this.definition.actions)t[e.name]=()=>{const t=this.executeAction(e);return this.blackboard.set("lastActionResult",t.summary),t.blocker&&this.blackboard.set("blocker",t.blocker),this.options.onAction&&this.options.onAction(e,this.blackboard),this.notifyActionProgress(e,void 0,t),t.ok?T.State.SUCCEEDED:T.State.FAILED};return Object.assign(t,e)}runWorkflow(){if(!this.tree)return this.report("blocked","Workflow tree is unavailable for this model type."),{stage:this.definition.name,ok:!1,confidence:35,summary:this.definition.name+" blocked",blocker:"Workflow tree is unavailable for this model type."};this.tree.reset(),this.report("started",this.definition.name+" workflow initialized",.05),this.tree.step();let e=0;for(;this.tree.getState()===T.State.RUNNING&&50>e&&(this.tree.step(),e+=1,this.emitWorkflowStateProgress(e),this.tree.getState()===T.State.RUNNING););this.tree.getState()===T.State.RUNNING&&(this.blackboard.set("blocker","Agent tree did not resolve within the safety bound."),this.report("blocked","Agent tree did not resolve within the safety bound."));const t=this.tree.getState()===T.State.SUCCEEDED,r=t?this.definition.name+" completed":this.definition.name+" failed",i=this.blackboard.get("lastActionResult"),n=this.blackboard.get("blocker");return this.report(t?"completed":"blocked",r,t?1:.85),{stage:this.definition.name,ok:t,confidence:Pn(t,n),summary:r,details:i,blocker:n}}runGoap(){if(!this.definition.goap)return this.report("blocked","GOAP definition is missing from the copied behavior artifacts."),{stage:this.definition.name,ok:!1,confidence:35,summary:this.definition.name+" blocked",blocker:"GOAP definition is missing from the copied behavior artifacts."};const e=x.planner(this.definition.goap.state,this.definition.goap.goal,this.definition.goap.actions);if(this.blackboard.set("goapPlan",e),this.report("started",`GOAP planner produced ${e?.length??0} actions`,.1),!e||0===e.length)return this.report("blocked","GOAP planner could not derive a plan from the copied behavior artifacts."),{stage:this.definition.name,ok:!1,confidence:35,summary:this.definition.name+" blocked",blocker:"GOAP planner could not derive a plan from the copied behavior artifacts."};const t=[];for(const r of e){const i=this.definition.actions.find(e=>e.name===r.name);if(!i)return this.report("blocked","Missing action handler for GOAP action "+r.name),{stage:this.definition.name,ok:!1,confidence:35,summary:this.definition.name+" blocked",blocker:"Missing action handler for GOAP action "+r.name,details:t.join(", ")||void 0};const n=this.executeAction(i);if(t.push(i.name),this.blackboard.set("lastActionResult",n.summary),n.blocker&&this.blackboard.set("blocker",n.blocker),this.notifyActionProgress(i,t.length/e.length,n),!n.ok)return this.report("blocked",n.blocker||"GOAP action failed",t.length/e.length),{stage:this.definition.name,ok:!1,confidence:Pn(!1,n.blocker),summary:this.definition.name+" blocked",blocker:n.blocker||"GOAP action failed",details:t.join(", ")}}return this.report("completed",this.definition.name+" completed via GOAP plan",1),{stage:this.definition.name,ok:!0,confidence:90,summary:this.definition.name+" completed via GOAP plan",details:t.join(", ")}}notifyActionProgress(e,t,r){const i=r?.summary??this.blackboard.get("lastActionResult")??e.kind+" handled",n=!1===r?.ok||r?.blocker?"blocked":"completed";this.report(n,`${e.name}: ${i}`,t)}emitWorkflowStateProgress(e){const t=this.tree?.getState();t!==T.State.RUNNING?t!==T.State.SUCCEEDED?t===T.State.FAILED&&this.report("blocked",this.definition.name+" workflow failed",Math.min(.9,.8+.02*e)):this.report("completed",this.definition.name+" workflow completed",1):this.report("started",this.definition.name+" workflow running",Math.min(.8,.1+.02*e))}executeAction(e){switch(e.kind){case"capture":return this.captureObjective();case"spawn-orchestrators":return this.spawnOrchestrators();case"load-spec":return this.mark("load-spec",!0,"spec loaded");case"load-plan":return this.mark("load-plan",!0,"plan loaded");case"read-context":return this.mark("read-context",!0,"context loaded");case"resolve-blockers":return this.mark("resolve-blockers",!0,"blockers checked");case"produce-plan":return this.mark("produce-plan",!0,"plan produced");case"create-specs":return this.mark("create-specs",!0,"specs produced");case"plan":return this.mark("plan",!0,"plan stage requested");case"implement":return this.mark("implement",!0,"implementation stage requested");case"review":return this.mark("review",!0,"review stage requested");case"document":return this.mark("document",!0,"documentation stage requested");case"build":return this.mark("build",!0,"build requested");case"lint":return this.mark("lint",!0,"lint requested");case"test-individual":return this.mark("test-individual",!0,"focused tests requested");case"test-full":return this.mark("test-full",!0,"full suite requested");case"review-changes":return this.mark("review-changes",!0,"review completed");case"review-outcome":return this.mark("review-outcome",!0,"review outcome produced");case"update-docs":return this.mark("update-docs",!0,"docs updated");case"report":return this.reportProgress();default:return this.mark(e.kind,!0,e.kind+" handled")}}captureObjective(){const e=this.options.objective??this.definition.objective;return this.blackboard.set("objective",e),this.mark("capture",!0,"captured objective: "+e)}spawnOrchestrators(){const e=this.options.specRefs?.length?this.options.specRefs:this.options.specRef?[this.options.specRef]:[];return this.blackboard.set("specRefs",e),this.mark("spawn-orchestrators",!0,e.length?"spawned orchestrators for: "+e.join(", "):"no orchestrators requested")}reportProgress(){const e=(this.options.specRef??"SPEC")+"/"+(this.options.specRef??"TASK").replace(/^[^-]+-/,"TASK-")+": "+this.definition.name+" "+(this.blackboard.get("lastActionResult")??"completed");return this.mark("report",!0,e)}mark(e,t,r,i){return{stage:e,ok:t,confidence:Pn(t,i),summary:r,blocker:i}}}function Pn(e,t){return e?t?55:90:t?35:45}const Cn=new Map;function Nn(e,t){return e+"::"+t}class Jn{constructor(){this.options={},this.behaviours={}}static get builder(){return new Jn}setDefinition(e){return this.definition=e,this}setWorkspaceRoot(e){return this.options.workspaceRoot=e,this}setProvider(e){return this.options.provider=e,this}setModelType(e){return this.options.modelType=e,this}setSpecRef(e){return this.options.specRef=e,this}setSpecRefs(e){return this.options.specRefs=e,this}setObjective(e){return this.options.objective=e,this}setActionHook(e){return this.options.onAction=e,this}setProgressHook(e){return this.options.onProgress=e,this}addBehaviour(e,t){return this.behaviours[e]=t,this}build(){if(!this.definition)throw Error("AgentBuilder requires a definition");if(!this.options.workspaceRoot)throw Error("AgentBuilder requires a workspaceRoot");if(!this.options.provider)throw Error("AgentBuilder requires a provider");const e=this.options.modelType??Sn(),t=new On(this.definition,{workspaceRoot:this.options.workspaceRoot,provider:this.options.provider,modelType:e,objective:this.options.objective,specRef:this.options.specRef,specRefs:this.options.specRefs,onAction:this.options.onAction,onProgress:this.options.onProgress},this.behaviours);var r,i,n;return r=this.options.workspaceRoot,i=this.definition.name,n=t,Cn.set(Nn(r,i),n),t}}function Dn(e){const t=yn(e.workspaceRoot).agents.find(t=>t.name===e.agentName);if(!t)throw Error("Unknown agent: "+e.agentName);const r=(i=e.workspaceRoot,n=e.agentName,Cn.get(Nn(i,n)));var i,n;if(r)return r;const o=bn(e.workspaceRoot,t);return Jn.builder.setDefinition(o).setWorkspaceRoot(e.workspaceRoot).setProvider(e.provider).setModelType(e.modelType??Sn()).setSpecRef(e.specRef??t.name).setSpecRefs(e.specRefs??[]).setObjective(e.objective??o.objective).setProgressHook(e.onProgress).build()}function _n(e){return["SPEC: "+e.specRef,"STAGE: "+e.stageName,"WORKSPACE_ROOT: "+e.workspaceRoot,"PROJECT_ROOT: "+e.projectRoot,"AGENT_ROOT: "+e.agentRoot,"PROMPT_ROOT: "+e.promptRoot,"",`Prompt content from ${e.definition.promptFile}:`,e.prompt,"\nBehavior tree:",JSON.stringify(e.definition,null,2),"\nRequired workflow: update SPEC/TASK files before advancing; stop on blockers or clarifications; add Jira comments if JIRA_ENABLED=true."].join("\n")}function Fn(e,t,r,i){const n=`${t}\n${r}`.trim(),o=(e=>{const t=e.toLowerCase();return t.includes("clarification")?"clarification requested":t.includes("blocker")?"blocker reported":t.includes("needs input")?"input required":void 0})(n),s=0===i&&!o;return{stage:e,ok:s,confidence:$n(s,o),summary:s?e+" completed":e+" blocked",details:n||void 0,blocker:o}}function $n(e,t){return e?t?55:90:t?35:45}function Mn(e,t,r,i,n){const o=z.join(pn(e),"specifications",t+".md"),s=(e=>{if(!j.existsSync(e))return[];const t=j.readFileSync(e,"utf8");return Array.from(new Set(t.match(/TASK-\d+/g)??[]))})(o),a=`- ${(new Date).toISOString()} ${r}: ${i}${n?" - "+n:""}\n`;qn(o,"Agent Progress",a);for(const t of s)qn(z.join(pn(e),"specifications","tasks",t+".md"),"Agent Progress",a)}function qn(e,t,r){if(!j.existsSync(e))return;const i=j.readFileSync(e,"utf8"),n="## "+t;i.includes(n)?j.writeFileSync(e,i.replace(RegExp(n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"\\n([\\s\\S]*?)$","m"),`${n}\n${r}$1`)):j.writeFileSync(e,`${i.trimEnd()}\n\n${n}\n${r}`)}async function Ln(e,t,r,i){if("true"===process.env.JIRA_ENABLED)try{const n=(await nt()).issueComments;if(!n?.addComment)return;await n.addComment({issueIdOrKey:e,comment:Et(`Agent stage **${t}** ${r.ok?"completed":"blocked"}.\n\n${r.summary}${r.blocker?"\n\nBlocker: "+r.blocker:""}\n\nModel type: ${i}.`)})}catch{}}function Hn(e){return Rn[e]}async function Gn(e){const t=fn({workspacePath:e.workspacePath,entryFile:e.entryFile}),r=Sn(e.modelType);if("execute"===e.operation){e.onProgress?.({agentName:"manager",operation:e.operation,specRef:e.specRef||e.executeSpec||"SPEC-UNKNOWN",status:"started",summary:"Execution started",progress:0});const i=await(async e=>{const t=Sn(e.modelType),r=((e,t)=>{const r=j.mkdtempSync(z.join(S.tmpdir(),`decaf-agent-${t.toLowerCase()}-`));try{return m.execFileSync("git",["worktree","add","--detach",r,"HEAD"],{cwd:e,stdio:"pipe"}),{repoRoot:e,path:r,created:!0}}catch{return{repoRoot:e,path:e,created:!1}}})(fn({workspacePath:e.workspacePath,entryFile:e.entryFile}).workspaceRoot,e.specRef),i=z.join(r.path,"workdocs","ai"),n=[];try{fn({workspacePath:i,entryFile:e.entryFile});const r=yn(i),o=["manager","orchestrator","architect","implementation","reviewer","documentation"].map(e=>r.agents.find(t=>t.name===e)).filter(e=>!!e);for(const r of o){const s=bn(i,r);let a,c;if(Mn(i,e.specRef,r.name,"started"),e.onProgress?.({agentName:r.name,operation:"execute",specRef:e.specRef,status:"started",summary:r.name+" stage started",progress:n.length/o.length}),En(t)){const n=wn(i,r);a=await _e({provider:e.provider,prompt:_n({specRef:e.specRef,stageName:r.name,definition:s,prompt:n,workspaceRoot:i,agentRoot:un(i),promptRoot:ln(i),projectRoot:pn(i)}),toolMetadata:{specRef:e.specRef,stage:r.name,modelType:t},cwd:i}).catch(t=>({exitCode:1,stdout:"",stderr:t+"",command:{executable:e.provider,args:[]}})),c=Fn(r.name,a.stdout,a.stderr,a.exitCode)}else c=Dn({workspaceRoot:i,provider:e.provider,modelType:t,specRef:e.specRef,objective:s.objective,agentName:r.name,onProgress:e.onProgress}).run(),a={exitCode:c.ok?0:1,stdout:JSON.stringify(c,null,2)+"\n",stderr:c.blocker?c.blocker+"\n":"",command:{executable:t,args:[r.name]}};if(n.push(c),Mn(i,e.specRef,r.name,c.ok?"completed":"blocked",c.summary),e.onProgress?.({agentName:r.name,operation:"execute",specRef:e.specRef,status:c.ok?"completed":"blocked",summary:c.summary,progress:n.length/o.length}),await Ln(e.specRef,r.name,c,t),!c.ok)return{specRef:e.specRef,workspaceRoot:i,provider:e.provider,modelType:t,stages:n,blocked:!0}}return Mn(i,e.specRef,"documentation","completed","workflow completed"),{specRef:e.specRef,workspaceRoot:i,provider:e.provider,modelType:t,stages:n,blocked:!1}}finally{(e=>{if(e.created){try{m.execFileSync("git",["worktree","remove","--force",e.path],{cwd:e.repoRoot,stdio:"pipe"})}catch{}try{j.rmSync(e.path,{recursive:!0,force:!0})}catch{}}})(r)}})({specRef:e.specRef||e.executeSpec||"SPEC-UNKNOWN",provider:e.provider,modelType:r,workspacePath:t.workspaceRoot,entryFile:e.entryFile,onProgress:e.onProgress});return e.onProgress?.({agentName:"manager",operation:e.operation,specRef:e.specRef||e.executeSpec||"SPEC-UNKNOWN",status:i.blocked?"blocked":"completed",summary:i.blocked?"Execution blocked":"Execution completed",progress:1}),{operation:e.operation,agentName:"manager",provider:e.provider,modelType:r,specRef:e.specRef||e.executeSpec||"SPEC-UNKNOWN",blocked:i.blocked,taskComplete:!i.blocked,status:i.blocked?"blocked":"completed",confidence:i.blocked?40:90,summary:i.blocked?"Execution blocked":"Execution completed",blockers:i.blocked?i.stages.filter(e=>!e.ok).map(e=>e.blocker||e.summary):[],questions:i.blocked?["Please provide the missing input needed to continue."]:[],execution:i}}const i=yn(t.workspaceRoot),n=Hn(e.operation),o=i.agents.find(e=>e.name===n);if(!o)throw Error("Unknown agent for operation: "+e.operation);let s,a;if(En(r)){const i=bn(t.workspaceRoot,o),c=wn(t.workspaceRoot,o);e.onProgress?.({agentName:n,operation:e.operation,specRef:e.specRef??e.executeSpec,status:"started",summary:n+" prompt stage started",progress:0}),s=await _e({provider:e.provider,prompt:Un({operation:e.operation,specRef:e.specRef,workspaceRoot:t.workspaceRoot,agentRoot:un(t.workspaceRoot),promptRoot:ln(t.workspaceRoot),projectRoot:pn(t.workspaceRoot),prompt:c,definition:i}),toolMetadata:{operation:e.operation,specRef:e.specRef,provider:e.provider,modelType:r,workspacePath:t.workspaceRoot},cwd:t.workspaceRoot}).catch(t=>({exitCode:1,stdout:"",stderr:t+"",command:{executable:e.provider,args:[]}})),a=((e,t,r,i)=>{const n=`${t}\n${r}`.trim(),o=Wn(n),s=0===i&&!o;return{stage:e,ok:s,confidence:s?90:o?35:45,summary:s?e+" completed":e+" blocked",details:n||void 0,blocker:o}})(o.name,s.stdout,s.stderr,s.exitCode),e.onProgress?.({agentName:n,operation:e.operation,specRef:e.specRef??e.executeSpec,status:a.ok?"completed":"blocked",summary:a.summary,progress:1})}else{const i=bn(t.workspaceRoot,o);a=Dn({workspaceRoot:t.workspaceRoot,provider:e.provider,modelType:r,specRef:e.specRef??e.executeSpec,objective:e.objective??i.objective,agentName:n,onProgress:e.onProgress}).run(),s={exitCode:0,stdout:JSON.stringify({modelType:r,stage:a,agentName:n},null,2)+"\n",stderr:"",command:{executable:r,args:[e.operation]}}}const c=!1===a.ok||0!==s.exitCode||void 0!==Wn(s.stdout+"\n"+s.stderr),p=Wn(s.stdout+"\n"+s.stderr)??a.blocker,d={operation:e.operation,agentName:n,provider:e.provider,modelType:r,specRef:e.specRef??e.executeSpec,blocked:c,taskComplete:!c,status:c?"blocked":"completed",confidence:c?Math.min(a.confidence,45):Math.max(a.confidence,80),summary:a.summary,blockers:p?[p]:[],questions:p?["Please provide the missing input needed to continue."]:[],stage:a,stdout:s.stdout,stderr:s.stderr,command:s.command};return await(async(e,t,r,i)=>{if("true"===process.env.JIRA_ENABLED)try{const n=(await nt()).issueComments;if(!n?.addComment)return;await n.addComment({issueIdOrKey:e,comment:Et(`Agent stage **${t}** ${r.ok?"completed":"blocked"}.\n\n${r.summary}${r.blocker?"\n\nBlocker: "+r.blocker:""}\n\nModel type: ${i}.`)})}catch{}})(e.specRef||n,e.operation,a,r),d}function Un(e){const t="agent."+e.operation,r=["You are executing the decaf agent workflow.","manage"===e.operation?"Use agent.manage when coordinating multiple agents or relaying user feedback.":"Use the tool "+t+" when you need to continue this operation.","Use agent.notify to emit progress updates while the work is active. Always report progress in SPEC/TASK format. Finish with TASK COMPLETE."].join(" ");return["OPERATION: "+e.operation,e.specRef?"SPEC: "+e.specRef:"","WORKSPACE_ROOT: "+e.workspaceRoot,"PROJECT_ROOT: "+e.projectRoot,"AGENT_ROOT: "+e.agentRoot,"PROMPT_ROOT: "+e.promptRoot,"",r,"","Prompt content from "+e.definition.promptFile+":",e.prompt,"\nBehavior tree:",JSON.stringify(e.definition,null,2),"\nUpdate SPEC/TASK files before advancing.\nTASK COMPLETE"].join("\n")}function Wn(e){const t=e.toLowerCase();return t.includes("clarification")?"clarification requested":t.includes("blocker")?"blocker reported":t.includes("needs input")?"input required":void 0}const Kn=["plan","review","create-specs","implement","execute","manage"];async function Bn(e,t={}){const i=r.Logging.for(Bn),o=fn({workspacePath:t.workspacePath,entryFile:t.entryFile}),s=yn(o.workspaceRoot),a=["resource://agent.catalog"],c=[],p=[];Yn(Xi.builder.setName("agent.catalog").setTitle("Agent catalog").setDescription("Repository-backed catalog of agent prompts, behaviors, and provider metadata.").setUriOtTemplate("resource://agent.catalog").setConfig({mimeType:"application/json",description:"Agent catalog copied into the repository workspace."}).setCb(async()=>({contents:[{uri:"resource://agent.catalog",mimeType:"application/json",text:JSON.stringify(s,null,2)}],_meta:{agentMode:!0}})),e,a);for(const{entry:r,definition:i}of(e=>yn(e).agents.map(t=>({entry:t,definition:bn(e,t)})))(o.workspaceRoot))Dn({workspaceRoot:o.workspaceRoot,provider:s.defaultProvider,modelType:Sn(t.modelType),agentName:r.name}),Yn(Xi.builder.setName("agent.behavior."+r.name).setTitle(i.title+" behavior").setDescription(`Behavior tree and GOAP metadata for ${i.title}.`).setUriOtTemplate("resource://agent.behavior."+r.name).setConfig({mimeType:"application/json",description:`Behavior tree JSON for ${i.title}.`}).setCb(async()=>{return{contents:[{uri:"resource://agent.behavior."+r.name,mimeType:"application/json",text:JSON.stringify(i,null,2)}],_meta:{source:(e=o.workspaceRoot,t=r.behaviorFile,z.join(un(e),t)),agent:r.name}};var e,t}),e,a),Yn(Xi.builder.setName("agent.prompt."+r.name).setTitle(i.title+" prompt").setDescription(`Prompt for ${i.title} loaded from the repo-copied workspace files.`).setUriOtTemplate("resource://agent.prompt."+r.name).setConfig({mimeType:"text/markdown",description:`Prompt text for ${i.title}.`}).setCb(async()=>{return{contents:[{uri:"resource://agent.prompt."+r.name,mimeType:"text/markdown",text:wn(o.workspaceRoot,r)}],_meta:{source:(e=o.workspaceRoot,t=r.promptFile,z.join(ln(e),t)),agent:r.name}};var e,t}),e,a),Xn(ie.builder.setName("agent-"+r.name).setTitle(i.title+" prompt").setDescription(`Repository-backed prompt for ${i.title}.`).setArgsSchema(n.z.object({})).setCb(async()=>({messages:[{role:"user",content:{type:"text",text:wn(o.workspaceRoot,r)}}],_meta:{agent:r.name}})),e,c);const d=n.z.object({operation:n.z.enum(Kn),specRef:n.z.string().optional(),objective:n.z.string().optional(),provider:n.z.enum(s.providers).optional(),modelType:n.z.enum(["prompt","goap","workflow"]).optional()}).shape;Vn({name:"agent.notify",title:"Agent progress notifier",description:"Emit a progress notification for agent mode tooling.",inputSchema:n.z.object({agentName:n.z.string(),operation:n.z.string(),specRef:n.z.string().optional(),taskRef:n.z.string().optional(),status:n.z.enum(["started","completed","blocked"]),summary:n.z.string(),confidence:n.z.number().int().min(1).max(100).optional(),progress:n.z.number().min(0).max(1).optional()}).shape},e,p,async(e,t)=>{const r={operation:"notify",agentName:e.agentName,blocked:"blocked"===e.status,taskComplete:"blocked"!==e.status,status:"blocked"===e.status?"blocked":"completed",confidence:e.confidence??("blocked"===e.status?40:90),summary:e.summary,blockers:"blocked"===e.status?[e.summary]:[],questions:"blocked"===e.status?["Please provide the missing input needed to continue."]:[],progress:e.progress??("started"===e.status?0:1),specRef:e.specRef,taskRef:e.taskRef};return{content:[{type:"text",text:JSON.stringify(r,null,2)+"\nTASK COMPLETE"}],_meta:{confidence:r.confidence,status:r.status}}}),Vn({name:"agent.do",title:"Agent dispatcher",description:"Dispatch an agent operation to the appropriate concrete agent.",inputSchema:d},e,p,async(e,r)=>{const i=Sn(e.modelType);return await Zn(r,{agentName:Hn(e.operation),operation:e.operation,specRef:e.specRef,status:"started",summary:"dispatching "+e.operation,progress:0}),Qn(await Gn({operation:e.operation,provider:e.provider??s.defaultProvider,modelType:i,workspacePath:o.workspaceRoot,entryFile:t.entryFile,specRef:e.specRef,objective:e.objective,onProgress:e=>Zn(r,e)}))});for(const r of Kn)Vn({name:"agent."+r,title:"Agent "+r,description:`Run the ${r} agent workflow via the dispatcher.`,inputSchema:n.z.object({specRef:n.z.string().optional(),objective:n.z.string().optional(),provider:n.z.enum(s.providers).optional(),modelType:n.z.enum(["prompt","goap","workflow"]).optional()}).shape},e,p,async(e,i)=>{const n=Sn(e.modelType);return await Zn(i,{agentName:Hn(r),operation:r,specRef:e.specRef,status:"started",summary:"starting "+r,progress:0}),Qn(await Gn({operation:r,provider:e.provider??s.defaultProvider,modelType:n,workspacePath:o.workspaceRoot,entryFile:t.entryFile,specRef:e.specRef,objective:e.objective,onProgress:e=>Zn(i,e)}))});return i.info(`Registered agent-mode assets for ${s.agents.length} agents`),{resourceUris:a,templateNames:[],promptNames:c,toolNames:p}}function Yn(e,t,r){try{const i=e.getName();e.build(t);const n=i?"resource://"+i:void 0;n&&!r.includes(n)&&r.push(n)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}function Xn(e,t,r){try{const i=e.getName();e.build(t),i&&!r.includes(i)&&r.push(i)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}function Vn(e,t,r,i){try{t.registerTool(e.name,{title:e.title,description:e.description,inputSchema:e.inputSchema,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},i),r.push(e.name)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}async function Zn(e,t){if(!e?.sendNotification||void 0===e._meta?.progressToken)return;const r=[t.agentName,t.operation,t.specRef?"SPEC "+t.specRef:void 0,t.taskRef?"TASK "+t.taskRef:void 0,t.status].filter(Boolean);e.sendNotification({method:"notifications/progress",params:{progressToken:e._meta?.progressToken,progress:t.progress??("started"===t.status?0:1),total:1,message:`${r.join(" ")}: ${t.summary}`}}).catch(()=>{})}function Qn(e){const t={operation:e.operation??"unknown",agentName:e.agentName??"unknown",provider:e.provider??"codex",modelType:e.modelType??"prompt",specRef:e.specRef,blocked:e.blocked??!1,taskComplete:e.taskComplete??!0,status:e.status??(e.blocked?"blocked":"completed"),confidence:e.confidence??(e.blocked?40:90),summary:e.summary??"completed",blockers:e.blockers??[],questions:e.questions??[],stage:e.stage,execution:e.execution,command:e.command,stdout:e.stdout,stderr:e.stderr};return{content:[{type:"text",text:JSON.stringify(t,null,2)+"\nTASK COMPLETE"}],_meta:{exitCode:e.exitCode??(e.blocked?1:0),confidence:t.confidence}}}const eo="resource://repo.metadata",to=be("repo-metadata.json"),ro=Xi.builder.setName("repo.metadata").setTitle("Repository metadata snapshot").setDescription("Deterministic metadata about the decaf-ts MCP server, Jira defaults, and the canonical project key.").setUriOtTemplate(eo).setConfig({mimeType:"application/json",description:"Static repository metadata that documents the MCP surface."}).setCb(async()=>{const e=Ke.version,t=Ke.jira.projectKey??to.jira?.projectKey??"DECAF",r={...to,version:e,projectKey:t};return{contents:[{uri:eo,mimeType:"application/json",text:JSON.stringify(r,null,2)}],_meta:{source:"assets/repo-metadata.json"}}}),io="resource://decoration.schematic.metadata",no=ye("decoration/metadata.json"),oo=Xi.builder.setName("decoration.schematic.metadata").setTitle("Decoration metadata schematic").setDescription("Outlines the annotation and field metadata contracts that decorators expose.").setUriOtTemplate(io).setConfig({mimeType:"application/json",description:"Annotation metadata definitions for decorator tooling."}).setCb(async()=>({contents:[{uri:io,mimeType:"application/json",text:no}],_meta:{schematic:"metadata"}})),so="resource://decoration.schematic.builder",ao=ye("decoration/builder.json"),co=Xi.builder.setName("decoration.schematic.builder").setTitle("Decoration builder pattern schematic").setDescription("Describes how decorated models spawn builder classes with fluent setters and validation.").setUriOtTemplate(so).setConfig({mimeType:"application/json",description:"Builder conventions for decorated models."}).setCb(async()=>({contents:[{uri:so,mimeType:"application/json",text:ao}],_meta:{schematic:"builder"}})),po="resource://decoration.schematic.validation",lo=ye("decoration/validation.json"),uo=Xi.builder.setName("decoration.schematic.validation").setTitle("Decoration validation schematic").setDescription("Tracks how decorator metadata flows through validation routines and error serialization.").setUriOtTemplate(po).setConfig({mimeType:"application/json",description:"Validation lifecycle and error contract for decorated models."}).setCb(async()=>({contents:[{uri:po,mimeType:"application/json",text:lo}],_meta:{schematic:"validation"}})),mo="resource://golden.override.model-builder",ho=ye("golden/model-builder.txt"),go=Xi.builder.setName("golden.override.model-builder").setTitle("Golden override: model builder snippet").setDescription("A coding template that shows how a Model builder keeps setters fluent and enforces validation.").setUriOtTemplate(mo).setConfig({mimeType:"text/plain",description:"Model builder golden snippet for copy/paste reference."}).setCb(async()=>({contents:[{uri:mo,mimeType:"text/plain",text:ho}],_meta:{override:"model-builder"}})),fo="resource://golden.override.validation-errors",yo=ye("golden/validation-errors.json"),bo=Xi.builder.setName("golden.override.validation-errors").setTitle("Golden override: validation error report").setDescription("Shows the structure returned when decorator validation fails, including error arrays and metadata.").setUriOtTemplate(fo).setConfig({mimeType:"application/json",description:"Example validation error payload emitted by decorated models."}).setCb(async()=>({contents:[{uri:fo,mimeType:"application/json",text:yo}],_meta:{override:"validation-errors"}})),wo="resource://golden.override.xray-step-template",vo=ye("golden/xray-step-template.txt"),ko=Xi.builder.setName("golden.override.xray-step-template").setTitle("Golden override: Xray step template").setDescription("A compliant Xray test-step template that lists the precondition, action, and verification.").setUriOtTemplate(wo).setConfig({mimeType:"text/plain",description:"Template for documenting Xray steps."}).setCb(async()=>({contents:[{uri:wo,mimeType:"text/plain",text:vo}],_meta:{override:"xray-step-template"}})),jo="resource://jira.ticket.templates",zo=Xi.builder.setName("jira.ticket.templates").setTitle("Jira ticket template catalog").setDescription("Catalog of default resource-backed Jira ticket templates for bug, incident, release, feature, and test flows.").setUriOtTemplate(jo).setConfig({mimeType:"application/json",description:"Catalog describing the default Jira ticket template resources."}).setCb(async()=>({contents:[{uri:jo,mimeType:"application/json",text:JSON.stringify({defaultType:we.defaultType,templates:Object.fromEntries(Object.entries(ve).map(([e,t])=>[e,{type:t.type,name:t.name,uri:t.uri,title:t.title,description:t.description,issueType:t.issueType,customFields:t.customFields}]))},null,2)}],_meta:{catalog:!0}}));function To(e){const t=ve[e];return Xi.builder.setName(t.name).setTitle(t.title).setDescription(t.description).setUriOtTemplate(t.uri).setConfig({mimeType:"text/markdown",description:t.description}).setCb(async()=>({contents:[{uri:t.uri,mimeType:"text/markdown",text:Te(t.type)}],_meta:{type:t.type}}))}const xo=[ro,oo,co,uo,go,bo,ko,zo,To("bug"),To("incident"),To("release"),To("feature"),To("test")];async function So(e){const t=r.Logging.for(So);for(const r of xo)try{await r.build(e),t.info("Registered resource "+r.getName())}catch(e){t.error("Failed to register resource "+r.getName(),e)}}const Io=new WeakMap;function Eo(e){if("1"===process.env.MCP_DEBUG_BOOT)try{j.appendFileSync("/tmp/mcp-boot.log",`${(new Date).toISOString()} ${e}\n`)}catch{}}class Ao extends r.LoggedClass{get client(){const e=Io.get(this);if(!e)throw Error("Mcp server requires Mcp client");return e}constructor(){super(),this.runtimeOptions={}}async load(){const e=this.log.for(this.load);for(const t of Me)try{e.info("loading prompt "+t.getName());const r=t.build(this.client);e.verbose(`Loaded prompt ${r.title} from ${t.getName()} definition`)}catch(r){e.error("Failed to load prompt "+t.getName(),r)}try{await Yi(this.client),e.verbose("Registered built-in tools")}catch(e){}try{await So(this.client),e.verbose("Registered built-in resources")}catch(e){}if(this.runtimeOptions.agentMode)try{await Bn(this.client,{workspacePath:this.runtimeOptions.workspacePath,entryFile:this.runtimeOptions.entryFile,agentProvider:this.runtimeOptions.agentProvider,modelType:this.runtimeOptions.modelType}),e.verbose("Registered agent-mode assets")}catch(e){}}async boot(e="stdio",t={}){this.runtimeOptions=t,"stdio"===e&&r.Logging.setFactory(N),process.env.ENCRYPTION_KEY,process.env.JIRA_ENABLED,this.runtimeOptions.agentMode,this.runtimeOptions.agentProvider??process.env.AGENT_PROVIDER,this.runtimeOptions.modelType??process.env.AGENT_MODEL_TYPE,this.runtimeOptions.workspacePath??process.env.AGENT_WORKSPACE_PATH,this.runtimeOptions.entryFile??process.env.AGENT_ENTRY_FILE;const i=((Array.isArray(Ke.icons)?Ke.icons:[Ke.icons])||[]).map(e=>{const t="string"==typeof e?.src?e.src:(e?.src??"")+"",r="string"==typeof e?.mimeType?e.mimeType:(e?.mimeType??"")+"";let i=[];return Array.isArray(e?.sizes)?i=e.sizes.map(e=>e+""):"string"==typeof e?.sizes&&(i=(e.sizes+"").split(",").map(e=>e.trim())),{src:t,mimeType:r,sizes:i}}),n={name:Ke.name,title:Ke.title,websiteUrl:Ke.websiteUrl,version:Ke.version,icons:i},o={instructions:this.runtimeOptions.agentMode?(this.runtimeOptions,["Agent mode is active.","Manager agent guide:\n- You are the user-facing entry point for agent mode.\n- Review the plan before delegating any work.\n- Use agent.manage to coordinate multiple agents and agent.do to dispatch a specific sub-agent.\n- Use agent.notify to emit live progress updates while work is active.\n- Available user-facing commands: agent plan, agent review, agent create-specs, agent implement, agent execute, and agent manage.\n- Provide concise progress updates and summarize blockers or questions instead of re-explaining the full spec.\n- Ask the user to start by reviewing the plan.","","Available tools: agent.do, agent.plan, agent.review, agent.create-specs, agent.implement, agent.execute, agent.manage, agent.notify.","Use the agent-prefixed commands and finish responses with TASK COMPLETE."].filter(Boolean).join("\n")):"You are an AI assistant designed to help users with programming tasks related to the Decaf-TS framework. \nProvide clear, concise, and accurate information.\nIf you don't know the answer, admit it rather than making up information.\nAlways prioritize the user's intent and provide helpful suggestions when appropriate.\n",capabilities:{logging:{},tools:{listChanged:!0},prompts:{listChanged:!0},resources:{listChanged:!0}}},s=new v.McpServer(n,o);switch(((e,t)=>{Io.set(e,t)})(this,s),s.onerror=e=>{this.log.error("MCP instance onerror",e)},e){case"stdio":e=new E.StdioServerTransport;break;case"http":e=new A.StreamableHTTPServerTransport({sessionIdGenerator:()=>I.v4(),onsessioninitialized:e=>{},onsessionclosed:e=>{},enableJsonResponse:!0,eventStore:void 0});break;default:if(!(a=e)||"object"!=typeof a||"function"!=typeof a.send&&"function"!=typeof a.close&&"function"!=typeof a.on)throw new c.InternalError("Invalid transport type: "+e)}var a;try{Eo("before load"),await this.load(),Eo("after load")}catch(e){throw Eo("load failed: "+e),e}if(Eo("before connect"),await this.client.connect(e),Eo("after connect"),"1"===process.env.MCP_DEBUG_TOOLS)try{const e=this.client;"function"==typeof e.listTools&&((await e.listTools({})).tools||[]).map(e=>e.name).join(", ")}catch(e){}}}function Ro(e){const t=(e||process.env.AGENT_PROVIDER||"codex").toLowerCase();if("claude"===t||"copilot"===t||"codex"===t)return t;throw Error("Unsupported agent provider: "+e)}function Oo(e,t){return Sn(e??(t?"goap":void 0))}async function Po(e){const t=await Gn({operation:e.operation,specRef:e.specRef,objective:e.objective,provider:Ro(e.provider),modelType:e.modelType?Oo(e.modelType):void 0,workspacePath:e.workspacePath,entryFile:e.entryFile});return process.stdout.write(JSON.stringify(t,null,2)+"\n"),process.stdout.write("TASK COMPLETE\n"),t.blocked&&(process.exitCode=2),t}async function Co(e){"1"===process.env.MCP_DEBUG_BOOT&&process.stderr.write("agent start command invoked\n");const r=Ro(e.agentProvider),i=Oo(e.modelType),n=fn({workspacePath:e.path,entryFile:e.entryFile}),o=yn(n.workspaceRoot);if(e.execute&&(await Po({operation:"execute",specRef:e.execute,provider:r,modelType:i,workspacePath:n.workspaceRoot,entryFile:e.entryFile})).blocked)return;const s=Q("package.json"),a=JSON.parse(t.readFileSync(s,"utf-8")),c=e.transport??"stdio",p=(new C).for("mcp-server-agent");if("stdio"!==c)throw Error("Unsupported transport mode: "+c);p.info("Transport stdio"),p.debug("running agent mode with options: "+JSON.stringify(e)+" for "+a.name+" version "+a.version),p.debug("agent catalog: "+o.agents.map(e=>e.name).join(", "));const d=new Ao;await d.boot(c,{agentMode:!0,workspacePath:n.workspaceRoot,agentProvider:r,modelType:i,executeSpec:e.execute,entryFile:e.entryFile}),p.info("Decaf MCP server is now running in agent mode. Press CTRL+C to stop."),await Wo(d)}const No=new e.Command("start").option("--transport [String]","transport mode","stdio").option("--path <path>","agent workspace path",process.env.AGENT_WORKSPACE_PATH||"workdocs/ai").option("--entryFile <file>","agent entry AGENTS file",process.env.AGENT_ENTRY_FILE||"./AGENTS.md").option("--agent","start in agent mode",!1).option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--execute <specRef>","optionally execute a SPEC before staying in agent mode").description("starts decaf's mcp server").action(async e=>{if(e.agent)return Co({transport:e.transport,path:e.path,entryFile:e.entryFile,agentProvider:e.agentProvider,modelType:e.modelType,execute:e.execute});"1"===process.env.MCP_DEBUG_BOOT&&process.stderr.write("start command invoked\n");const r=Q("package.json"),i=JSON.parse(t.readFileSync(r,"utf-8")),n=e.transport??"stdio",o=(new C).for("mcp-server");if("stdio"!==n)throw Error("Unsupported transport mode: "+n);o.info("Transport stdio"),o.debug("running with options: "+JSON.stringify(e)+" for "+i.name+" version "+i.version);const s=new Ao;await s.boot(n,{workspacePath:e.path,entryFile:e.entryFile}),o.info("Decaf MCP server is now running. Press CTRL+C to stop."),await Wo(s)}),Jo=new e.Command("md-to-ast").description("pipes markdown to jira ast and writes JSON to stdout").action(async e=>{const i=Q("package.json"),n=JSON.parse(t.readFileSync(i,"utf-8")),o=n.version;r.Logging.for("md-to-ast").debug("running with options: "+JSON.stringify(e)+" for "+n.name+" version "+o);const s=Et(await(async()=>{const e=[];for await(const t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")})(),{resolveMention:e=>({id:e,text:"@"+e}),resolveAttachment:e=>({id:e,collection:"attachments"})});process.stdout.write(JSON.stringify(s,null,2)+"\n")}),Do=new e.Command("setup").description("copies the agent workspace files into a target path").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").action(async e=>{const t=gn({workspacePath:e.path,entryFile:e.entryFile,preserveExisting:!0});process.stdout.write(JSON.stringify(t,null,2)+"\n")}),_o=new e.Command("do").description("dispatches an agent operation through agent.do").requiredOption("--operation <operation>","agent operation to execute").option("--specRef <specRef>","SPEC identifier to operate on").option("--objective <objective>","custom objective to use").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).action(async e=>{await Po({operation:e.operation,specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:Oo(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),Fo=new e.Command("manage").description("runs the manager agent").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--specRef <specRef>","SPEC identifier to manage").option("--objective <objective>","custom objective to use").action(async e=>{await Po({operation:"manage",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:Oo(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),$o=new e.Command("plan").description("runs the architect planning agent").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--specRef <specRef>","SPEC identifier to plan").option("--objective <objective>","custom objective to use").action(async e=>{await Po({operation:"plan",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:Oo(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),Mo=new e.Command("review").description("runs the reviewer agent").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--specRef <specRef>","SPEC identifier to review").option("--objective <objective>","custom objective to use").action(async e=>{await Po({operation:"review",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:Oo(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),qo=new e.Command("create-specs").description("runs the spec creation agent").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--specRef <specRef>","SPEC identifier to create or update").option("--objective <objective>","custom objective to use").action(async e=>{await Po({operation:"create-specs",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:Oo(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),Lo=new e.Command("implement").description("runs the implementation agent").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--specRef <specRef>","SPEC identifier to implement").option("--objective <objective>","custom objective to use").action(async e=>{await Po({operation:"implement",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:Oo(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),Ho=new e.Command("execute").description("runs the automated development flow for a SPEC").argument("<specRef>","SPEC identifier to execute").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).action(async(e,t)=>{await Po({operation:"execute",specRef:e,provider:t.agentProvider,modelType:Oo(t.modelType,t.goap),workspacePath:t.path,entryFile:t.entryFile})}),Go=new e.Command("start").description("starts decaf in agent mode").option("--transport [String]","transport mode","stdio").option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--execute <specRef>","optionally execute a SPEC before staying in agent mode").action(Co),Uo=new e.Command("agent").description("agent workspace setup and agent-mode execution").addCommand(Do).addCommand(Go).addCommand(_o).addCommand(Fo).addCommand($o).addCommand(Mo).addCommand(qo).addCommand(Lo).addCommand(Ho).option("--path <path>","workspace path","workdocs/ai").option("--entryFile <file>","entry AGENTS file","./AGENTS.md").option("--agent-provider <provider>","provider CLI to use").option("--model-type <modelType>","agent execution model type",process.env.AGENT_MODEL_TYPE||"prompt").option("--goap","use GOAP mode",!1).option("--execute <specRef>","execute a SPEC using the agent workflow").action(async e=>{e.execute?await Po({operation:"execute",specRef:e.execute,provider:e.agentProvider,modelType:Oo(e.modelType,e.goap),workspacePath:e.path||"workdocs/ai",entryFile:e.entryFile||"./AGENTS.md"}):Uo.help({error:!1})});async function Wo(e){const t=["SIGINT","SIGTERM"];await new Promise(r=>{let i=!1;const n=setInterval(()=>{},1e6),o=async()=>{if(!i){i=!0,clearInterval(n);try{const t=e.client;t?.close&&await t.close()}catch{}finally{r()}}};for(const e of t)process.once(e,o)})}(new e.Command).name("decaf-mcp").description("decaf mcp server and agentic functionality").addCommand(No).addCommand(Uo).addCommand(Jo).parseAsync(process.argv).catch(e=>{process.exit(1)})},"object"==typeof exports&&"undefined"!=typeof module?t(require("commander"),require("fs"),require("@decaf-ts/logging"),require("@decaf-ts/decorator-validation"),require("zod"),require("@decaf-ts/injectable-decorators"),require("@decaf-ts/decoration"),require("path"),require("@decaf-ts/db-decorators"),require("crypto"),require("zlib"),require("url"),require("fs/promises"),require("node:child_process"),require("node:util"),require("node:module"),require("unified"),require("remark-directive"),require("remark-gfm"),require("remark-parse"),require("@modelcontextprotocol/sdk/server/mcp.js"),require("@modelcontextprotocol/sdk/shared/uriTemplate.js"),require("node:fs"),require("node:path"),require("mistreevous"),require("goap-solver"),require("node:os"),require("uuid"),require("@modelcontextprotocol/sdk/server/stdio.js"),require("@modelcontextprotocol/sdk/server/streamableHttp.js")):"function"==typeof define&&define.amd?define(["commander","fs","@decaf-ts/logging","@decaf-ts/decorator-validation","zod","@decaf-ts/injectable-decorators","@decaf-ts/decoration","path","@decaf-ts/db-decorators","crypto","zlib","url","fs/promises","node:child_process","node:util","node:module","unified","remark-directive","remark-gfm","remark-parse","@modelcontextprotocol/sdk/server/mcp.js","@modelcontextprotocol/sdk/shared/uriTemplate.js","node:fs","node:path","mistreevous","goap-solver","node:os","uuid","@modelcontextprotocol/sdk/server/stdio.js","@modelcontextprotocol/sdk/server/streamableHttp.js"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).commander,e.fs,e.logging,e.decoratorValidation,e.zod,e.injectableDecorators,e.decoration,e.path,e.dbDecorators,e.crypto,e.zlib,e.url,e.fsPromises,e.node_child_process,e.node_util,e.node_module,e.unified,e.remarkDirective,e.remarkGfm,e.remarkParse,e.mcp_js,e.uriTemplate_js,e.fs$1,e.path$1,e.mistreevous,e.goapSolver,e.os,e.uuid,e.stdio_js,e.streamableHttp_js);
|
|
3
3
|
//# sourceMappingURL=mcp-server.cjs.map
|