@decaf-ts/mcp-server 1.15.1 → 1.15.7
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 +0 -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 +1 -3
- 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 +0 -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 -2
- package/dist/assets/resources/golden/validation-errors.enc +0 -0
- 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/ados/.ai/agent/fallback-workflow.enc +0 -0
- package/dist/assets/templates/ados/.ai/agent/mcp-setup.enc +0 -0
- package/dist/assets/templates/ados/.ai/agent/pm-instructions.enc +0 -0
- package/dist/assets/templates/ados/.ai/mcp.json.enc +0 -0
- package/dist/assets/templates/ados/.ai/rules/bash.enc +0 -0
- package/dist/assets/templates/ados/.opencode/README.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/architect.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/bootstrapper.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/coder.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/committer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/designer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/doc-syncer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/editor.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/external-researcher.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/fixer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/image-generator.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/image-reviewer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/migrator.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/plan-writer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/pm.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/pr-manager.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/reviewer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/runner.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/spec-writer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/test-plan-writer.enc +0 -0
- package/dist/assets/templates/ados/.opencode/agent/toolsmith.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/apply-review-feedback.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/bootstrap.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/check-fix.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/check.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/commit.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/design.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/migrate-workdocs.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/plan-change.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/plan-decision.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/pr.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/review-deep.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/review-remote.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/review.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/run-plan.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/sync-docs.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/write-decision.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/write-plan.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/write-spec.enc +0 -0
- package/dist/assets/templates/ados/.opencode/command/write-test-plan.enc +0 -0
- package/dist/assets/templates/ados/.opencode/opencode-github-copilot.enc +0 -0
- package/dist/assets/templates/ados/.opencode/opencode.enc +0 -0
- package/dist/assets/templates/ados/AGENTS.enc +0 -0
- package/dist/assets/templates/ados/MIGRATION_GUIDE.enc +0 -0
- package/dist/assets/templates/ados/README.enc +0 -0
- package/dist/assets/templates/ados/doc/00-index.enc +0 -0
- package/dist/assets/templates/ados/doc/documentation-handbook.enc +0 -0
- package/dist/assets/templates/agents_template.enc +0 -0
- package/dist/assets/templates/commands/constitution_commands.enc +0 -0
- package/dist/assets/templates/commands/git_commands.enc +0 -0
- package/dist/assets/templates/commands/mode_commands.enc +0 -0
- package/dist/assets/templates/commands/plan_commands.enc +0 -0
- package/dist/assets/templates/commands/specification_commands.enc +0 -0
- package/dist/assets/templates/commands/startup_command.enc +0 -0
- package/dist/assets/templates/commands/task_commands.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 +0 -0
- package/dist/assets/templates/decaf/services/service.enc +0 -0
- package/dist/assets/templates/decaf_guidelines.enc +1 -1
- package/dist/assets/templates/instructions_template.enc +0 -0
- package/dist/assets/templates/jira/bug.enc +0 -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/plan_template.enc +0 -0
- package/dist/assets/templates/skills/as-zod/SKILL.enc +0 -0
- package/dist/assets/templates/skills/as-zod/model-bridge/SKILL.enc +0 -0
- package/dist/assets/templates/skills/cli/SKILL.enc +0 -0
- package/dist/assets/templates/skills/cli/package-modules/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/adapters/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/auth/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/context/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/fs/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/migrations/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/model-builder/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/model-decoration/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/persistence-service/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/query/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/query/statement-paginator/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/ram-fs-adapters/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/repository/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/services/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/services/client-based-service/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/services/model-service/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/tasks/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/transactions/SKILL.enc +0 -0
- package/dist/assets/templates/skills/core/workers/SKILL.enc +0 -0
- package/dist/assets/templates/skills/crypto/cli/SKILL.enc +0 -0
- package/dist/assets/templates/skills/crypto/security/SKILL.enc +0 -0
- package/dist/assets/templates/skills/db-decorators/SKILL.enc +0 -0
- package/dist/assets/templates/skills/db-decorators/operations/SKILL.enc +0 -0
- package/dist/assets/templates/skills/db-decorators/validation/SKILL.enc +0 -0
- package/dist/assets/templates/skills/decoration/SKILL.enc +0 -0
- package/dist/assets/templates/skills/decoration/metadata-and-flavours/SKILL.enc +0 -0
- package/dist/assets/templates/skills/decorator-validation/SKILL.enc +0 -0
- package/dist/assets/templates/skills/environment/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/cli/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/common/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/components/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/directives/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/engine/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/graph/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/i18n/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/pipes/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/services/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-angular/utils/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-couchdb/adapter-repository/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-couchdb/indexes-views/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-couchdb/query/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-fabric/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-fabric/cli/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-fabric/client/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-fabric/contracts/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-fabric/contracts/bootstrap/SKILL.enc +3 -0
- package/dist/assets/templates/skills/for-fabric/shared/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/axios/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/event/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/rest/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/server/auth/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/server/controllers/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/server/hooks/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-http/server/transformers/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nano/adapter-repository/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/auth/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/bootstrap/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/cli/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/decaf-model/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/events/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/events-webhooks/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/injection/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/request-pipeline/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/server-setup/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-nest/webhooks/SKILL.enc +3 -0
- package/dist/assets/templates/skills/for-pouch/adapter-repository/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-typeorm/adapter-repository/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-typeorm/models-relations/SKILL.enc +0 -0
- package/dist/assets/templates/skills/for-typeorm/query-sequences/SKILL.enc +0 -0
- package/dist/assets/templates/skills/injectable-decorators/SKILL.enc +0 -0
- package/dist/assets/templates/skills/injectable-decorators/injectables/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/blob/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/docker/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/feature-flags/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/graph/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/keycloak/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/kibana/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/loader/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/namespaces/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/nest/SKILL.enc +0 -0
- package/dist/assets/templates/skills/integrations/secrets/SKILL.enc +0 -0
- package/dist/assets/templates/skills/logging/SKILL.enc +0 -0
- package/dist/assets/templates/skills/logging/rendering/SKILL.enc +0 -0
- package/dist/assets/templates/skills/transactional-decorators/SKILL.enc +0 -0
- package/dist/assets/templates/skills/ui-decorators/SKILL.enc +0 -0
- package/dist/assets/templates/skills/ui-decorators/decorators/SKILL.enc +0 -0
- package/dist/assets/templates/skills/ui-decorators/graph/SKILL.enc +0 -0
- package/dist/assets/templates/skills/ui-decorators/list-item/SKILL.enc +0 -0
- package/dist/assets/templates/skills/ui-decorators/rendering-engine/SKILL.enc +0 -0
- package/dist/assets/templates/skills/ui-decorators/rendering-targets/SKILL.enc +0 -0
- package/dist/assets/templates/skills/ui-decorators/ui-models/SKILL.enc +0 -0
- package/dist/assets/templates/skills/utils/SKILL.enc +0 -0
- package/dist/assets/templates/skills/utils/cli/SKILL.enc +0 -0
- package/dist/assets/templates/skills/utils/release-automation/SKILL.enc +0 -0
- package/dist/assets/templates/skills/utils/testing/SKILL.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 +3 -2
package/dist/mcp-server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Command as e}from"commander";import*as t from"fs";import n,{promises as i}from"fs";import{MiniLogger as r,NumericLogLevels as o,Logging as s,LoggedClass as a,toSnakeCase as c,sf as p,toPascalCase as d,LogLevel as l,LoggedEnvironment as u}from"@decaf-ts/logging";import{required as m,Model as h,list as f,minlength as g}from"@decaf-ts/decorator-validation";import{z as y,ZodObject as b}from"zod";import{injectable as w,inject as k}from"@decaf-ts/injectable-decorators";import{prop as v,Metadata as j}from"@decaf-ts/decoration";import*as T from"path";import S,{resolve as x}from"path";import{InternalError as I,SerializationError as E,ValidationError as A}from"@decaf-ts/db-decorators";import R from"crypto";import O from"zlib";import{fileURLToPath as C}from"url";import{readFile as P}from"fs/promises";import{spawn as N,execFileSync as _}from"node:child_process";import{inspect as D}from"node:util";import{createRequire as J}from"node:module";import{unified as F}from"unified";import $ from"remark-directive";import M from"remark-gfm";import H from"remark-parse";import{ResourceTemplate as L,McpServer as G}from"@modelcontextprotocol/sdk/server/mcp.js";import{UriTemplate as q}from"@modelcontextprotocol/sdk/shared/uriTemplate.js";import U,{appendFileSync as W}from"node:fs";import K from"node:path";import{BehaviourTree as z,State as B}from"mistreevous";import{planner as Y}from"goap-solver";import X from"node:os";import{v4 as V}from"uuid";import{StdioServerTransport as Z}from"@modelcontextprotocol/sdk/server/stdio.js";import{StreamableHTTPServerTransport as Q}from"@modelcontextprotocol/sdk/server/streamableHttp.js";class ee extends r{constructor(e,t,n){super(e,t,n)}log(e,t,n,i){const r=this.config("level");o[r],o[e]}}const te=(e,t,...n)=>{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 ee(i,t)};function ne(e,t,n,i){var r,o=arguments.length,s=3>o?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,i);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(s=(3>o?r(s):o>3?r(t,n,s):r(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s}function ie(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}var re,oe,se,ae,ce;"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"})(re||(re={})),(e=>{e[e.NONE=0]="NONE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(oe||(oe={})),(e=>{e[e.FREE=0]="FREE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(se||(se={}));class pe extends h{get log(){return this._log||(this._log=s.for(this)),this._log}constructor(e){super(e)}logFor(e){const{sessionId:t,requestId:n,authInfo:i}=e||{};let r="string"==typeof t&&t.length>0?this.log.for(t):this.log;return i&&i.clientId&&(r=r.for(i.clientId)),n&&(r=r.for(n.toString())),r}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}}ne([m(),ie("design:type",String)],pe.prototype,"description",void 0),ne([m(),ie("design:type",String)],pe.prototype,"name",void 0),ne([m(),ie("design:type",String)],pe.prototype,"title",void 0);class de extends pe{constructor(e){super(e),this.reasoning=re.NONE,this.effort=oe.NONE,this.cost=se.FREE}setReasoning(e){return this.reasoning=e,this}setEffort(e){return this.effort=e,this}setCost(e){return this.cost=e,this}}function le(e){if(!e)return;let t=e,n=t&&t._def;for(;n&&"ZodObject"!==n.typeName;){if("ZodEffects"===n.typeName&&n.schema)t=n.schema;else if("ZodOptional"===n.typeName&&n.innerType)t=n.innerType;else if("ZodDefault"===n.typeName&&n.innerType)t=n.innerType;else if("ZodNullable"===n.typeName&&n.innerType)t=n.innerType;else{if(!n.schema)return;t=n.schema}n=t&&t._def}return n&&"ZodObject"===n.typeName?n:void 0}function ue(e){return!(!e||"object"!=typeof e||!e._def)}ne([m(),ie("design:type",Number)],de.prototype,"reasoning",void 0),ne([m(),ie("design:type",Number)],de.prototype,"effort",void 0),ne([m(),ie("design:type",Number)],de.prototype,"cost",void 0),(e=>{e.ASSETS="assets"})(ae||(ae={})),(e=>{e.PROMPT="prompts",e.DOCUMENTATION="documentation",e.CODE="code"})(ce||(ce={}));const me=Buffer.from("DCAF1","ascii");function he(e){if(e.length<me.length+16+12+16)throw Error("Invalid prompt payload (too short)");if(!e.subarray(0,me.length).equals(me))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 n=me.length;const i=e.subarray(n,n+16);n+=16;const r=e.subarray(n,n+12);n+=12;const o=e.subarray(n,n+16);n+=16;const s=e.subarray(n),a=((e,t)=>R.scryptSync(e,t,32))(t,i),c=R.createDecipheriv("aes-256-gcm",a,r);c.setAuthTag(o);const p=Buffer.concat([c.update(s),c.final()]);return O.gunzipSync(p)}function fe(e){let t=S.resolve(e);for(;;){if(n.existsSync(S.join(t,"package.json")))return t;const e=S.dirname(t);if(e===t)break;t=e}}const ge=process.argv?.[1]?fe(S.dirname(S.resolve(process.argv[1]))):void 0,ye=(()=>{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 n=t[1];if(n.startsWith("file://"))try{n=C(n)}catch{continue}if(!n.includes("node:internal"))return S.dirname(n)}})(),be=ye?fe(ye):void 0,we=ge??be??process.cwd();function ke(...e){return S.join(we,...e)}function ve(e){let n=e;for(;;){const e=T.join(n,"lib","assets");if(t.existsSync(e))return e;const i=T.join(n,"src","assets");if(t.existsSync(i))return i;const r=T.join(n,"assets");if(t.existsSync(r))return r;const o=T.dirname(n);if(o===n)break;n=o}}function je(){const e=process.env.DECAF_ASSET_DIR||process.env.MCP_ASSET_DIR||process.env.ASSET_DIR||"";if(e&&t.existsSync(e))return e;const n=ve(__dirname);if(n)return n;const i=process.argv?.[1];if(i){const e=ve(T.dirname(i));if(e)return e}const r=[we,process.env.INIT_CWD].filter(Boolean);for(const e of r){const t=ve(e);if(t)return t}return ke("assets")}let Te=class extends a{constructor(e){super(),this.basePath=e||je()}listAssets(...e){const n=T.join(this.basePath,...e);return t.readdirSync(n)}listPrompts(){return this.listAssets(ce.PROMPT)}getAsset(e,n="md",...i){const r=T.join(this.basePath,...i),o=(e,n=!1)=>{try{return n?he(t.readFileSync(e)).toString("utf-8"):t.readFileSync(e,"utf-8")}catch(e){if("ENOENT"===e.code)return null;throw e}},s=o(T.join(r,`${e}.${n}`),"enc"===n);if(null!==s)return s;const a=o(T.join(r,e+".enc"),!0);if(null!==a)return a;throw Error("Asset not found: "+T.join(r,`${e}.${n}`))}getAllAssets(e,...t){return this.listAssets(e,...t).reduce((n,i)=>{const r=T.extname(i),o=T.basename(i,r),s=r.replace(/^\./,"")||void 0;return n[o]=this.getAsset(o,s??void 0,e,...t),n},{})}toPromptDef(e){const t=e=>"number"==typeof e?e:"string"==typeof e?(e=>{switch(e){case"none":return re.NONE;case"basic":return re.BASIC;case"advanced":return re.ADVANCED;case"high":return re.HIGH;case"medium":return oe.MEDIUM;case"low":return se.LOW;case"free":return se.FREE;default:throw new I("Cannon convert unknown level "+e)}})(e.toLowerCase()):re.NONE;return e.effort=t(e.effort),e.reasoning=t(e.reasoning),e.cost=t(e.cost),e}getPrompt(e,...t){const n=this.getAsset(c(e),"json",ce.PROMPT,...t);let i;try{i=JSON.parse(n)}catch(n){throw new E(`Failed to parse prompt ${e} in categories ${t}: ${n}`)}return this.toPromptDef(i)}getAllPrompts(...e){const t=this.getAllAssets(ce.PROMPT,...e);return Object.entries(t).reduce((t,[n,i])=>{try{t[n]=JSON.parse(i)}catch(t){throw new E(`Failed to parse prompt ${n} in categories ${e}: ${t}`)}return t},t)}};Te=ne([w(),ie("design:paramtypes",[String])],Te);class Se extends de{constructor(e){super(e)}setCb(e){return this.cb=e,this}setArgsSchema(e){return this.argsSchema=e,this}static get builder(){return new Se}static patchPrompt(e,t,n,i){const r=(t=Array.isArray(t)?t:Object.keys(t)).filter(e=>!Object.prototype.hasOwnProperty.call(n,e));if(r.length)throw new A("Missing replacements for placeholders: "+r.join(", "));i&&(i.verbose("Patching prompt with placeholders: "+JSON.stringify(t)),i.debug("Values: "+JSON.stringify(n)));const o=t.reduce((e,t)=>(e[t]=n[t],e),{});return p(e,o)}patchPrompt(e,t,n,i){return Se.patchPrompt(e,t,n,i||this.log.for(this.patchPrompt))}build(e,t){const n=this.log.for(this.build),i=this.hasErrors();if(i)throw new A(i.toString());try{this.argsSchema&&((e,t="schema")=>{if(le(e))return e;if(e&&"object"==typeof e){const t=e.def&&"object"==typeof e.def?e.def:void 0,n=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||n){const e={};if(n&&"object"==typeof n)for(const[t,i]of Object.entries(n))e[t]=ue(i)?i:y.any();return y.object(e)}}throw Error(`Registration error: provided a non-canonical ${t}. Export a ZodObject (z.object(...)).`)})(this.argsSchema,"argsSchema");const n=(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=le(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:n},async(e,n)=>{const i=this.logFor(n);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 r=await Promise.resolve(this.cb(e,n));return i.verbose(`Prompt ${this.name} executed successfully.`),i.debug("Prompt execution meta: "+JSON.stringify(r._meta)),r})}catch(e){throw n.error("Failed to register prompt "+(this.name||this.constructor.name),e),e}}}ne([k(Te),ie("design:type",Te)],Se.prototype,"assets",void 0),ne([m(),ie("design:type",Object)],Se.prototype,"cb",void 0),ne([m(),ie("design:type",b)],Se.prototype,"argsSchema",void 0),ne([v(),ie("design:type",Object)],Se.prototype,"placeholders",void 0);class xe extends Se{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);h.fromObject(this,t);const n=new Set((j.properties(xe)||[]).filter(e=>!["assets","promptCategory","prefixes","suffixes"].includes(e)));["cb","argsSchema"].forEach(e=>n.add(e));const i=this.hasErrors(...Array.from(n));if(i)throw new A(i.toString());const r=(this.prefixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),o=(this.suffixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),s=[...new Set([...t.placeholders,...r.map(e=>e.placeholders||[]),...o.map(e=>e.placeholders||[])].flat())].reduce((e,t)=>(e[t]=y.string().describe("The description for "+t),e),{});return this.setArgsSchema(y.object(s)),this.setCb((e,t)=>{const n=this.logFor(t).for(xe).for(this.promptCategory).for(this.name);function i(e=[]){return Array.isArray(e)?e:Object.keys(e)}const r=(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([...r.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([...r.map(e=>e.prompt),s.prompt,...o.map(e=>e.prompt)].join("\n\n"),a,e,n)}}],_meta:{}}}),super.build(e)}setReasoning(e){throw new I("Named prompt builders don't require callback")}setEffort(e){throw new I("Named prompt builders don't require callback")}setCost(e){throw new I("Named prompt builders don't require callback")}setDescription(e){throw new I("Named prompt builders don't require callback")}setTitle(e){throw new I("Named prompt builders don't require callback")}static get builder(){return new xe}}ne([m(),ie("design:type",String)],xe.prototype,"promptCategory",void 0),ne([f(String),g(1),ie("design:type",Array)],xe.prototype,"prefixes",void 0),ne([g(1),f(String),ie("design:type",Array)],xe.prototype,"suffixes",void 0);const Ie=Se.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(y.object({gist:y.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}}}),Ee=Object.assign(Ie,{name:Ie.getName()});var Ae;function Re(e,t=[],n=[]){const i=xe.builder.setCategory(Ae.DOCS).setName(e);return["prefix",...t].forEach(e=>i.addPrefix(e)),["suffix",...n].forEach(e=>i.addSuffix(e)),i}(e=>{e.DOCS="documentation",e.CODE="code"})(Ae||(Ae={}));const Oe=[Re("class"),Re("constant"),Re("decorator"),Re("function"),Re("module"),Re("file"),Re("repo",[],["iterate"])],Ce=y.object({className:y.string().describe("the class name to turn into a builder")}),Pe=Se.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(Ce).setReasoning(re.BASIC).setCb((e,t)=>(e.className=d(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:{}})),Ne=y.object({project:y.string().optional(),issueType:y.string().optional(),summary:y.string().optional(),description:y.string().optional(),assignee:y.string().optional(),fields:y.record(y.string(),y.any()).optional()}),_e=Se.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(Ne).setCb((e,t)=>{const n=e?.project??"<project-key>",i=e?.issueType??"Task",r=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 (${n})\n- issuetype: use the issue type (${i})\n- summary: use the summary (${r})\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": "${n}" },\n "issuetype": { "name": "${i}" },\n "summary": "${r}",\n "description": "${o}"\n }\n}\n`}}],_meta:{}}}),De=T.join(__dirname,"..","assets"),Je=je()||De,Fe=T.join(Je,"resources");function $e(e){const n=T.join(Fe,e);try{return t.readFileSync(n,"utf-8")}catch(e){if("ENOENT"!==e.code)throw e}const i=(e=>{const t=T.extname(e);return t?e.slice(0,-t.length)+".enc":e+".enc"})(n);if(!t.existsSync(i))throw Error("Asset not found: "+e);return he(t.readFileSync(i)).toString("utf-8")}function Me(e){const t=$e(e);return JSON.parse(t)}const He=Me("jira/ticket-templates/catalog.json"),Le=He.templates,Ge=new Map;function qe(e,t){const n=Ke(e);n&&Ge.set(n,t)}for(const e of Object.values(Le))qe(e.type,e),qe(e.name,e),qe(e.uri,e),qe(e.assetPath,e),qe(e.assetPath.replace(/^jira\/ticket-templates\//,""),e),qe(e.assetPath.replace(/\.md$/,""),e);function Ue(e){const t=Ke(e);if(!t)return Le[He.defaultType];const n=Ge.get(t);if(n)return n;throw Error("Unknown Jira ticket template reference: "+e)}function We(e){return $e(Ue(e).assetPath)}function Ke(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 ze=y.object({ticketType:y.enum(["bug","incident","release","feature","test"]).optional(),template_path:y.string().optional(),project:y.string().optional(),projectKey:y.string().optional(),issueType:y.string().optional(),summary:y.string().optional(),description:y.string().optional(),customFields:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional(),fields:y.record(y.string(),y.any()).optional()}).partial();function Be(e){try{return Ue(e)}catch{return}}function Ye(e){const t=(e=>e.template_path?e.template_path:"resource://jira.ticket.template."+(e.ticketType??"bug"))(e),n=Be(t),i=!!n,r=n?.uri??t,o=e.projectKey??e.project??"<project-key>",s=e.issueType??n?.issueType??"<issue-type>",a=e.summary??"<summary>",c=e.description??"<description>",p=i?(e=>{const t=Be(e);return t?(e=>{const t=(e=>e.customFields??[])(Ue(e));return t.length?t.map(e=>{const t=e.required?" (required)":" (optional)",n=e.example?" e.g. "+e.example:"";return`- ${e.key}${t}: ${e.label} \u2014 ${e.description}${n}`}).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(r)}\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 Xe=Se.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(ze).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:Ye(e)}}],_meta:{}})),Ve=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."},Ze=(e,t)=>{const n=e.resources.length?e.resources.join(", "):"none";return[e.description,"","Scenario:\n"+e.scenario,"","Resources: "+n,"\nProvided inputs:",Ve(t),"\nCall specification:",e.callTemplate,"\nGuidance:",(i=e.guidance,i.map((e,t)=>`${t+1}. ${e}`).join("\n"))].join("\n");var i},Qe=[{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:y.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:y.object({project:y.string().optional(),issueType:y.string().optional(),summary:y.string().optional(),description:y.string().optional(),assignee:y.string().optional(),fields:y.record(y.string(),y.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:y.object({issueId:y.string().optional(),issueKey:y.string().optional(),fields:y.array(y.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:y.object({jql:y.string().optional(),filters:y.record(y.string(),y.any()).optional(),limit:y.number().optional(),order:y.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:y.object({issueId:y.string().optional(),fields:y.record(y.string(),y.any()).optional(),comment:y.string().optional(),transition:y.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:y.object({issueId:y.string().optional(),deleteSubtasks:y.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:y.object({issueId:y.string().optional(),transition:y.string().optional(),comment:y.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:y.object({issueId:y.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:y.object({issueId:y.string().optional(),assignee:y.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:y.object({issueId:y.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:y.object({issueId:y.string().optional(),comment:y.string().optional(),visibility:y.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:y.object({issueId:y.string().optional(),page:y.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:y.object({inwardIssue:y.string().optional(),outwardIssue:y.string().optional(),linkType:y.string().optional(),comment:y.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:y.object({linkId:y.string().optional(),linkType:y.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:y.object({linkId:y.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:y.object({issueId:y.string().optional(),filePath:y.string().optional(),comment:y.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:y.object({issueId:y.string().optional(),page:y.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:y.object({issueId:y.string().optional(),attachmentId:y.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:y.object({issueId:y.string().optional(),timeSpent:y.string().optional(),comment:y.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:y.object({markdown:y.string().optional(),context:y.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:y.object({adf:y.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:y.object({testCaseKey:y.string().optional(),step:y.string().optional(),status:y.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:y.object({testCaseKey:y.string().optional(),stepId:y.string().optional(),update:y.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:y.object({testCaseKey:y.string().optional(),stepId:y.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:y.object({testCaseKey:y.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-list",\n "arguments": {\n "testCaseKey": "<key>"\n }\n}'}].map(e=>Se.builder.setName(e.name).setTitle(e.title).setDescription(e.description).setArgsSchema(e.argsSchema).setCb(async(t={},n)=>({messages:[{role:"user",content:{type:"text",text:Ze(e,t)}}],structuredContent:{tool:e.toolName,args:t},result:{tool:e.toolName,args:t},_meta:{}}))),et=y.object({filePath:y.string().optional(),textType:y.enum(["text","code"]).optional(),context:y.string().optional()}).partial();function tt(e,t){const n=e.textType??"text",i=e.context?.trim()?`Context:\n${e.context.trim()}\n`:"",r=t?.trim()?"Source content:\n"+t.trim():"";return o={filePath:e.filePath??"README.md",textType:n,contextSection:i,contentSection:r},"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 nt=Se.builder.setName("guide-file-summarizer-tool").setTitle("MCP guide: file summarizer").setDescription("Professional prompt for summarizing text and code files with optional context.").setArgsSchema(et).setCb(e=>({messages:[{role:"user",content:{type:"text",text:tt(e)}}],_meta:{}}));function it(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 rt(e){const t=it(e.provider),n=N(t.executable,t.args,{cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:{...process.env,DECAF_AGENT_TOOLING:JSON.stringify(e.toolMetadata??{})}});let i="",r="";n.stdout.on("data",e=>{i+=e.toString()}),n.stderr.on("data",e=>{r+=e.toString()}),n.stdin.write(e.prompt),n.stdin.end();const o=await new Promise((e,t)=>{n.once("error",t),n.once("close",t=>e(t??0))});return{exitCode:o,stdout:i,stderr:r,command:t}}const ot=y.object({filePath:y.string().optional(),textType:y.enum(["text","code"]).optional(),context:y.string().optional()}).partial(),st=x(process.cwd(),"README.md"),at=[nt,Ee,...Oe,Pe,_e,...Qe,Xe],ct="##VERSION##",pt="##PACKAGE##";function dt(){try{let e=process.argv[1]?S.dirname(S.resolve(process.argv[1])):process.cwd();for(;;){const t=S.join(e,"package.json");if(n.existsSync(t))return JSON.parse(n.readFileSync(t,"utf-8"));const i=S.dirname(e);if(i===e)break;e=i}}catch{}return{}}const lt=ct.startsWith("##")?dt().version??"0.0.0":ct,ut=pt.startsWith("##")?dt().name??"unknown":pt;j.registerLibrary(ut,lt);const mt={mcpId:"decaf",name:"decaf-ts mcp server",title:"Decaf-TS MCP Server",description:"Provides precise coding assistance for the decaf-ts framework",version:lt,websiteUrl:"https://decaf-ts.github.io",repositoryUrl:"https://github.com/decaf-ts/mcp-server",license:"AGPL-3.0",workingDir:we,assetDir:je(),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:l.error},ht=u.accumulate(mt);function ft(){const{host:e,email:t,apiKey:n,projectKey:i,issueType:r}=ht.jira;return{host:e?.trim(),email:t?.trim(),apiKey:n?.trim(),projectKey:i?.trim(),issueType:r?.trim(),parentIssue:ht.jira.parentIssue?.trim()}}function gt(){const e=ft();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 yt(e){const t=e.value?((e,t)=>{if(e)return t?"<configured>":e})(e.value,e.sensitive):"not set",n=e.required?"(required)":"(optional)";return`\u2022 ${e.name} ${n}: ${e.description} Current state: ${t}.`}s.setConfig(ht);class bt extends Error{constructor(e){const t=gt(),n=(e=>{const t=gt();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(yt).join("\n")}`})(e);super(n),this.name="MissingJiraEnvironmentError",this.descriptors=t,this.missing=e,"function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,bt)}}const wt=s.for("jira.client"),kt=/(authorization|cookie)/i;function vt(e){if(!e)return;const t=e.baseURL??"",n=e.url??"";return t&&n?`${t.endsWith("/")?t.slice(0,-1):t}/${n.startsWith("/")?n.slice(1):n}`:n||t||void 0}function jt(e){if(void 0!==e){if("string"==typeof e)return e;try{return JSON.stringify(e,null,2)}catch(t){return D(e,{depth:null})}}}function Tt(e){if(!e)return;const t={};return Object.entries(e).forEach(([e,n])=>{t[e]=kt.test(e)&&n?"[REDACTED]":n}),t}const St=(()=>{try{return J(process.cwd())}catch(e){return}})();async function xt(){let e;try{const t=await(async e=>{try{return await import(e)}catch(t){if(!St)throw t;try{return St(e)}catch(e){throw e.cause??=t,e}}})("jira.js"),n=t.default,i=t.Version3Client??n?.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:n,apiKey:i}=(()=>{const e=ft(),t=gt().filter(e=>e.required&&!e.value);if(t.length>0)throw new bt(t);return{host:e.host,email:e.email,apiKey:e.apiKey}})(),r=new e({host:t.startsWith("http://")||t.startsWith("https://")?t:"https://"+t,authentication:{basic:{email:n,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(),n=vt(e);return wt.info("jira.request",{method:t,url:n,headers:Tt(e.headers),params:e.params,data:jt(e.data)}),e},e=>(wt.error("jira.request.error",{message:e.message}),Promise.reject(e))),e.interceptors.response.use(e=>{const t=(e.config?.method??"GET").toString().toUpperCase(),n=vt(e.config);return wt.info("jira.response",{method:t,url:n,status:e.status,headers:Tt(e.headers),data:jt(e.data)}),e},e=>{const t=e.config,n=e.response,i=(t?.method??"GET").toString().toUpperCase(),r=vt(t);return wt.error("jira.response.error",{method:i,url:r,status:n?.status,headers:Tt(n?.headers),data:jt(n?.data),message:e.message}),Promise.reject(e)}))})(r.instance),r}function It(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 D(e,{depth:null})}})(e);return t?[{type:"text",text:t}]:[]}function Et(e={},t=[]){const n=(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:It(n),result:n,structuredContent:n}}const At=y.object({name:y.string().min(1).optional().describe("Optional template name that pre-populates additional fields"),content:y.string().min(1).describe("Markdown template content to apply when constructing the description"),placeholders:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional().describe("Map of placeholder replacements used by the template")}).describe("Template metadata used to adjust the created description"),Rt=y.object({template:At.optional().describe("Optional template settings for this create request"),customFields:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional().describe("Template-specific field values that can be merged into the rendered description")}).describe("Additional template controls available when creating an issue"),Ot=y.union([y.object({fields:y.record(y.string(),y.any()).describe("Full raw field map that gets delivered to Jira")}).merge(Rt).describe("Create argument that supplies every field explicitly"),y.object({summary:y.string().min(1).describe("Title or summary of the new issue"),projectKey:y.string().min(1).describe("Project key where the issue is created"),issueType:y.string().min(1).describe("Type name for the new issue (story, task, etc.)"),description:y.string().optional().describe("Optional textual description for the issue")}).merge(Rt).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 Ct(e,t,n){const i=((e.url??"")+"").match(/^(attachment|jira-attachment):(.+)$/i);if(!i)return null;const r=i[2],o=n.resolveAttachment?.(r);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 Pt(e,t){if(!e)return[];if(!t.enableAtMentions&&!t.enableEmojiShortcodes)return[{type:"text",text:e}];let n=0;const i=[],r=/(^|[^A-Za-z0-9_])@([A-Za-z0-9._-]{1,64})/g,o=/:([a-z0-9_+-]{1,64}):/gi;for(;n<e.length;){const s=_t(t.enableAtMentions?Nt(r,e,n):null,t.enableEmojiShortcodes?Nt(o,e,n):null);if(!s){i.push({type:"text",text:e.slice(n)});break}if(s.index>n&&i.push({type:"text",text:e.slice(n,s.index)}),"mention"===s.kind){const{full:e,groups:r}=s,o=r[0]??"",a=r[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}),n=s.index+e.length;continue}if("emoji"===s.kind){const{full:e,groups:r}=s,o=`:${r[0]}:`,a=t.resolveEmoji?.(o);i.push({type:"emoji",attrs:a?{shortName:a.shortName,text:a.text}:{shortName:o}}),n=s.index+e.length;continue}}return(e=>{const t=[];for(const n of e){const e=t[t.length-1];"text"!==n.type||"text"!==e?.type||e.marks||n.marks?t.push(n):e.text=(e.text??"")+(n.text??"")}return t})(i)}function Nt(e,t,n){e.lastIndex=n;const i=e.exec(t);if(!i)return null;const r=e.source.includes("@")?"mention":"emoji";return{index:i.index,full:i[0],groups:i.slice(1),kind:r}}function _t(e,t){return e?t&&e.index>t.index?t:e:t}function Dt(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 Jt(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 $t(e,t){const n=[];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??"")+"",r=Ht(i.children??[],e),o=Ct(i,0,t);if(o){"inline"===o.type?n.push(o.node):n.push({type:"text",text:r,marks:[{type:"link",attrs:{href:e}}]});continue}if(t.enableSmartCards&&Lt(r,e)){n.push({type:"inlineCard",attrs:{url:e}});continue}n.push({type:"text",text:r,marks:[{type:"link",attrs:{href:e}}]});continue}if("textDirective"===i.type&&"status"===i.name){const e=Dt(i)||"Status",t=Ft(i.attributes?.color)??"neutral";n.push({type:"status",attrs:{text:e,color:t}});continue}if("textDirective"===i.type&&"emoji"===i.name){const e=Gt(i);n.push(qt(e,t));continue}}else n.push({type:"hardBreak"});else n.push({type:"text",text:(i.value??"")+"",marks:[{type:"code"}]});else n.push(...Mt($t(i.children??[],t),{type:"strike"}));else n.push(...Mt($t(i.children??[],t),{type:"em"}));else n.push(...Mt($t(i.children??[],t),{type:"strong"}));else n.push(...Pt((i.value??"")+"",t));return n.filter(e=>!("text"===e.type&&""===(e.text??"")))}function Mt(e,t){return e.map(e=>{if("text"!==e.type)return e;if(e.marks?.some(e=>"code"===e.type))return e;const n=e.marks?[...e.marks,t]:[t];return{...e,marks:n}})}function Ht(e,t){const n=[];for(const t of e??[])"text"===t.type||"inlineCode"===t.type?n.push((t.value??"")+""):"emphasis"!==t.type&&"strong"!==t.type&&"delete"!==t.type||n.push(Ht(t.children??[],""));return n.join("")||t}function Lt(e,t){const n=(e??"").trim(),i=(t??"").trim();return n===i&&/^https?:\/\//i.test(i)}function Gt(e){return(e.children??[]).map(e=>"text"===e.type?(e.value??"")+"":"").join("").trim()||""}function qt(e,t){const n=e.startsWith(":")?e:`:${e}:`,i=t.resolveEmoji?.(n);return i?{type:"emoji",attrs:{shortName:i.shortName,text:i.text}}:{type:"emoji",attrs:{shortName:n}}}function Ut(e){return e?"string"==typeof e?e:"text"===e.type||"inlineCode"===e.type?(e.value??"")+"":Array.isArray(e.children)?e.children.map(Ut).join(""):"":""}function Wt(e,t){if(!e?.type)return null;if((e=>"containerDirective"===e?.type&&"panel"===e?.name)(e))return((e,t)=>{const n=e.attributes??{},i=Jt(n.type)??"info",r="string"==typeof n.title?n.title:void 0,o=(e.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean);return{type:"panel",attrs:{panelType:i,...r?{panelType:i,title:r}:{panelType:i}},content:o.length?o:[{type:"paragraph",content:[]}]}})(e,t);switch(e.type){case"heading":return{type:"heading",attrs:{level:zt(e.depth??1,1,6)},content:$t(e.children??[],t)};case"paragraph":return(e=>{const t=e.children??[];if(1!==t.length)return null;const n=t[0];if("image"!==n?.type)return null;const i=(n.url??"")+"";return i?{type:"mediaSingle",attrs:{layout:"center"},content:[{type:"media",attrs:{type:"external",url:i}}]}:null})(e)||{type:"paragraph",content:$t(e.children??[],t)};case"blockquote":return{type:"blockquote",content:(e.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean)};case"list":return((e,t)=>t.enableTaskLists&&(e.children??[]).some(e=>"boolean"==typeof e.checked)?((e,t)=>{const n=[];let i=0;for(const r of e.children??[]){if("boolean"!=typeof r.checked)continue;i+=1;const e=(r.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean);n.push({type:"taskItem",attrs:{localId:"task-"+i,state:r.checked?"DONE":"TODO"},content:e.length?e:[{type:"paragraph",content:[]}]})}return{type:"taskList",content:n}})(e,t):{type:e.ordered?"orderedList":"bulletList",content:(e.children??[]).map(e=>((e,t)=>{const n=(e.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean);return{type:"listItem",content:n.length?n:[{type:"paragraph",content:[]}]}})(e,t))})(e,t);case"code":{const n=((e,t)=>{const n=(e??"").toString().trim().toLowerCase();return n?t.enableMermaid&&n.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})(n):null})(e.lang,t);return{type:"codeBlock",attrs:{language:n},content:[{type:"text",text:(e.value??"")+""}]}}case"thematicBreak":return{type:"rule"};case"table":return((e,t)=>({type:"table",content:(e.children??[]).map((e,n)=>({type:"tableRow",content:(e.children??[]).map(e=>({type:0===n?"tableHeader":"tableCell",content:[{type:"paragraph",content:$t(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:Dt(e)||"Status",color:t}}]}})(e):"panel"===e.name?((e,t)=>{const n=e.attributes??{},i=Jt(n.type)??"info",r="string"==typeof n.title?n.title:void 0;return{type:"panel",attrs:{panelType:i,...r?{title:r}:{}},content:[{type:"paragraph",content:$t([{type:"text",value:Dt(e)}],t)}]}})(e,t):Kt(e,t);default:return Kt(e,t)}}function Kt(e,t){if("drop"===t.unknownNodeStrategy)return null;const n=Ut(e);return n?{type:"paragraph",content:[{type:"text",text:n}]}:null}function zt(e,t,n){const i=Number.isFinite(e)?Math.trunc(e):t;return Math.max(t,Math.min(n,i))}const Bt={resolveMention:void 0,resolveAttachment:void 0,resolveEmoji:void 0,enableSmartCards:!0,enableMermaid:!0,enableEmojiShortcodes:!0,enableAtMentions:!0,enableTaskLists:!0,unknownNodeStrategy:"text"};function Yt(e,t={}){const n={...Bt,...t},i=e??"",r=F().use(H.default||H).use($.default||$).use(M.default||H),o=r.parse(i),s=r.runSync(o);return Xt(s),((e,t)=>{const n=[];for(const i of e.children??[]){const e=Wt(i,t);e&&(Array.isArray(e)?n.push(...e):n.push(e))}return((e,t)=>{if(!t.enableSmartCards)return e;const n=e.content.map(e=>(e=>{if("paragraph"!==e.type)return e;const t=e.content??[];if(1!==t.length)return e;const n=t[0];if("inlineCard"!==n?.type)return e;const i=n.attrs?.url;return i?[{type:"blockCard",attrs:{url:i}}]:e})(e)).flat();return{...e,content:n}})({version:1,type:"doc",content:n},t)})(s,n)}function Xt(e){if(!e||!Array.isArray(e.children))return;const t=[];for(const n of e.children)"definition"!==n?.type&&("html"!==n?.type?(Xt(n),t.push(n)):t.push({type:"text",value:(n.value??"")+""}));e.children=t}function Vt(e){return{...e,content:Zt(e.content??[])}}function Zt(e){return e.flatMap(e=>"panel"===e.type?Zt(e.content??[]):[Qt(e)])}function Qt(e){return e.content?{...e,content:Zt(e.content)}:{...e}}const en=/\{\{\s*([^}]+)\s*\}\}/g;async function tn(e,t){const n=e=>e&&e.trim()?e.trim():void 0,i=((e,t,n)=>{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:n}})(t,n(ht.jira.projectKey),n(ht.jira.issueType));let r,o;try{r=Ot.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)(r))o={...r.fields};else{const e=r;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 n=(i=t.content,r=t.placeholders,i?i.replace(en,(e,t)=>{const n=t.trim();if(!n)return"";if(r&&Object.prototype.hasOwnProperty.call(r,n)){const e=r[n];return null==e?"":e+""}return e}):"");var i,r;if(!n.trim())return e;const o=Yt(n),s=(a=e.description)?"object"==typeof a&&"doc"===a.type&&Array.isArray(a.content)?a.content:"string"==typeof a?Yt(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)(r));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 nn={name:"jira-issue-create",inputSchema:Ot,runTool:async(e,t)=>Et(await tn(e,t))};class rn extends Error{constructor({code:e,message:t,details:n}){super(t),Object.setPrototypeOf(this,new.target.prototype),this.name="NormalizedJiraError",this.code=e,this.details=n}}const on=s.for("jira.errors");function sn(e){if(!e)return new rn({code:"jira_error",message:"Unknown Jira error",details:{raw:e}});const t=e?.status??e?.statusCode??e?.response?.status??e?.response?.statusCode,n="number"==typeof t?t:Number(t)||void 0,i=e?.response?.data??e?.data??e?.response?.body??e?.body,r=e?.response?.statusText??(n?""+n:void 0),o=e?.response?.headers?Tt(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=n?`Jira API error (${n})`:"Jira API error",c=s.length>0?s.join(" | "):a,p=n?"jira_"+n:e?.code??"jira_error",d=e?.config,l=d?{method:d.method?d.method.toString().toUpperCase():void 0,url:d.url,headers:Tt(d.headers),data:jt(d.data)}:void 0,u={httpStatus:n,body:i,request:l,response:o?{statusText:r,headers:o}:r?{statusText:r}:void 0,raw:e};return on.error("jira.error",{code:p,message:c,httpStatus:n,statusText:r,responseHeaders:o,request:l,body:jt(i)??i}),new rn({code:p,message:c,details:u})}const an=y.object({issueId:y.string().min(1).describe("Issue key or ID to delete"),deleteSubtasks:y.boolean().optional().default(!0).describe("Whether to delete the subtasks alongside this issue")}).describe("Arguments used to delete a Jira issue (with optional subtasks)"),cn={name:"jira-issue-delete",inputSchema:an,runTool:async(e,t)=>{try{const n=an.parse(t),i={issueIdOrKey:n.issueId,deleteSubtasks:n.deleteSubtasks};return await e.issues.deleteIssue(i),Et({success:!0,message:`Issue ${n.issueId} deleted successfully`})}catch(e){throw sn(e)}}},pn=y.object({projectKey:y.string().trim().min(1).optional().describe("Project key used to scope the issue search"),issueType:y.string().trim().min(1).optional().describe("Issue type name used to filter the results"),parentIssueId:y.string().trim().min(1).optional().describe("Optional parent issue key/ID to limit results to a subtree"),name:y.string().trim().min(1).optional().describe("Issue summary to match exactly"),reference:y.string().trim().min(1).optional().describe("External reference or custom identifier to filter by"),jql:y.string().trim().min(1).optional().describe("Free-form JQL query to drive the search"),nextPageToken:y.string().trim().min(1).optional().describe("Opaque pagination token returned by Jira enhanced search"),maxResults:y.number().int().min(1).optional().describe("Maximum number of issues to return"),fields:y.array(y.string()).optional().describe("List of issue fields to include in the response"),expand:y.string().optional().describe("Optional expansion clause for the results"),orderBy:y.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 dn(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}const ln={name:"jira-issue-list",inputSchema:pn,runTool:async(e,t)=>{try{const n=pn.parse(t),i=n.maxResults??50;let r=n.jql?.trim();if(r){if(n.orderBy){const e=n.orderBy.trim();e&&(r=/\border\s+by\b/i.test(r)?`${r}, ${e}`:`${r} ORDER BY ${e}`)}}else r=(e=>{const t=[];if(e.projectKey&&t.push(`project = "${dn(e.projectKey)}"`),e.issueType&&t.push(`issuetype = "${dn(e.issueType)}"`),e.parentIssueId&&t.push(`parent = "${dn(e.parentIssueId)}"`),e.name&&t.push(`summary ~ "${dn(e.name)}"`),e.reference){const n=dn(e.reference);t.push(`(key ~ "${n}" OR summary ~ "${n}" OR text ~ "${n}")`)}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 n=t.join(" AND ");if(e.orderBy){const t=e.orderBy.trim();t&&(n=/\border\s+by\b/i.test(n)?`${n}, ${t}`:`${n} ORDER BY ${t}`)}return n})(n);const o={jql:r,nextPageToken:n.nextPageToken,maxResults:i,fields:n.fields,expand:n.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 Et({...a,startAt:a?.startAt??0,maxResults:a?.maxResults??i})}catch(e){throw sn(e)}}},un=y.object({issueId:y.string().min(1).describe("Jira issue key or numeric ID to read"),expand:y.string().optional().describe("Optional expand clause for nested fields or changelog"),fields:y.array(y.string()).optional().describe("Explicit list of issue fields to return"),properties:y.array(y.string()).optional().describe("Specific issue properties to include in the response")}).describe("Arguments required to read a Jira issue"),mn={name:"jira-issue-read",inputSchema:un,runTool:async(e,t)=>{try{const n=un.parse(t),i={issueIdOrKey:n.issueId,expand:n.expand,fields:n.fields,properties:n.properties};return Et(await e.issues.getIssue(i))}catch(e){throw sn(e)}}},hn=y.object({issueId:y.string().min(1).describe("Target issue key or ID to transition"),transitionId:y.union([y.string(),y.number()]).describe("Identifier for the transition to execute"),fields:y.record(y.string(),y.any()).optional().describe("Optional field updates to apply during the transition"),update:y.record(y.string(),y.array(y.object({set:y.any().optional().describe("Set operation for the transition update"),add:y.any().optional().describe("Add operation for the transition update"),remove:y.any().optional().describe("Remove operation for the transition update")}))).optional().describe("Structured update operations to send alongside the transition"),comment:y.string().optional().describe("Optional comment to attach during the transition")}).describe("Inputs needed to transition a Jira issue"),fn={name:"jira-issue-transition",inputSchema:hn,runTool:async(e,t)=>{try{const n=hn.parse(t),i={issueIdOrKey:n.issueId,transition:{id:n.transitionId+""}};if(n.fields&&(i.fields=n.fields),n.update&&(i.update=n.update),await e.issues.doTransition(i),n.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:n.issueId,comment:Yt(n.comment)})}return Et({success:!0,message:"Issue transitioned to "+n.transitionId})}catch(e){throw sn(e)}}},gn=y.object({issueId:y.string().min(1).describe("Issue key or ID for which to list transitions"),expand:y.string().optional().describe("Optional expand parameter for the transition response")}).describe("Inputs used to fetch available transitions for an issue"),yn={name:"jira-transition-list",inputSchema:gn,runTool:async(e,t)=>{try{const n=gn.parse(t),i=e.issues;if(!i||"function"!=typeof i.getTransitions)throw Error("Jira transitions API is unavailable on the client");const r={issueIdOrKey:n.issueId,expand:n.expand};return Et(await i.getTransitions(r))}catch(e){throw sn(e)}}},bn=y.object({key:y.string().min(1).describe("The key of the issue property"),value:y.any().describe("The value of the issue property")}).describe("Details of issue properties to be add or update."),wn=y.object({description:y.string().optional().describe("Markdown description that is converted to Jira ADF (use jira-md-to-adf if you need raw ADF input)")}).catchall(y.any()).describe("Field map that gets delivered to Jira (labels, components, etc.)"),kn=y.object({issueId:y.string().min(1).describe("Issue key or ID to update"),fields:wn.optional(),update:y.record(y.string(),y.array(y.object({set:y.any().optional().describe("Set operation alongside the update key"),add:y.any().optional().describe("Add operation alongside the update key"),remove:y.any().optional().describe("Remove operation alongside the update key"),edit:y.any().optional().describe("Edit operation alongside the update key")}))).optional().describe("Structured update operations for array/set fields"),properties:y.array(bn).optional().describe("Property payloads to attach to the issue"),notifyUsers:y.boolean().optional().default(!0).describe("Whether to notify watchers when the issue is updated"),issueTemplateId:y.string().optional().describe("Optional template ID to render issue descriptions"),overrideScreenSecurity:y.boolean().optional().default(!1).describe("Temporarily bypass screen security restrictions"),overrideEditableFlag:y.boolean().optional().default(!1).describe("Temporarily bypass the editable flag on the screen")}).describe("Arguments used to update existing Jira issues"),vn=y.record(y.string(),y.any()).optional(),jn=y.object({type:y.string().describe("Mark name, such as strong, emphasis, code, or link"),attrs:vn}).describe("Inline formatting or link marks applied to text nodes"),Tn=y.object({type:y.literal("text"),text:y.string().describe("Rendered string content for the text node"),marks:y.array(jn).optional()}).describe("Plain text node that carries optional formatting marks"),Sn=y.object({type:y.literal("mention"),attrs:y.object({id:y.string().describe("Jira internal identifier for the mention"),text:y.string().describe("Human readable mention text"),userType:y.string().optional(),accessLevel:y.string().optional(),localizedAccessLevel:y.string().optional()}).describe("Metadata describing the mentioned user")}).describe("Represents a user or team mention in a block or inline context"),xn=y.object({type:y.literal("emoji"),attrs:y.object({shortName:y.string().describe("Emoji shortcode such as smiling_face"),id:y.string().optional(),text:y.string().optional()}).describe("Emoji metadata")}).describe("Emoji inline node"),In=y.object({type:y.literal("inlineCard"),attrs:y.object({url:y.string().url().describe("Target URL that backs the inline card")}).describe("Inline card attributes")}).describe("Inline card that represents a linked resource"),En=y.object({type:y.literal("status"),attrs:y.object({text:y.string().describe("Status label text"),color:y.string().describe("Color code applied by Jira"),localId:y.string().optional(),style:y.string().optional()}).describe("Status metadata published by Jira")}).describe("Status node used for Jira workflow or custom fields"),An=y.object({type:y.literal("date"),attrs:y.object({representation:y.string().optional(),timestamp:y.number().optional()}).describe("Date metadata, usually RFC3339 or timestamp")}).describe("Date node that embeds a Jira date reference"),Rn=y.object({type:y.literal("hardBreak")}).describe("Inline hard break that forces a newline"),On=y.object({type:y.literal("rule")}).describe("Horizontal rule dividing sections of the document");let Cn,Pn;const Nn=y.lazy(()=>y.union([Tn,Sn,xn,In,En,An,Rn])),_n=y.lazy(()=>y.object({type:y.literal("paragraph"),content:y.array(Nn).describe("Inline nodes contained by the paragraph")})),Dn=y.lazy(()=>y.object({type:y.literal("heading"),attrs:y.object({level:y.number().int().min(1).max(6).describe("Heading level, 1-6")}).optional(),content:y.array(Nn).describe("Inline nodes composing the heading")})),Jn=y.lazy(()=>y.object({type:y.literal("listItem"),attrs:y.object({localId:y.string().optional()}).optional(),content:y.array(y.lazy(()=>Cn)).describe("Block level nodes nested inside the list item")})),Fn=y.lazy(()=>y.object({type:y.literal("bulletList"),content:y.array(Jn).describe("List items within the bullet list")})),$n=y.lazy(()=>y.object({type:y.literal("orderedList"),attrs:y.object({order:y.number().int().min(1).optional()}).optional(),content:y.array(Jn)})),Mn=y.lazy(()=>y.object({type:y.literal("taskItem"),attrs:y.object({localId:y.string().optional(),state:y.enum(["TODO","IN_PROGRESS","DONE"]).optional()}).optional(),content:y.array(y.lazy(()=>Cn)).describe("Blocks living inside the task item")})),Hn=y.lazy(()=>y.object({type:y.literal("taskList"),content:y.array(Mn).describe("Task items inside the list")})),Ln=y.lazy(()=>y.object({type:y.literal("codeBlock"),attrs:y.object({language:y.string().optional()}).optional(),content:y.array(Tn).optional()})),Gn=y.lazy(()=>y.object({type:y.literal("panel"),attrs:y.object({panelType:y.enum(["info","note","tip","warning","success"]).optional(),title:y.string().optional()}).optional(),content:y.array(y.lazy(()=>Cn)).describe("Panels may nest paragraphs, lists, or other blocks")})),qn=y.lazy(()=>y.object({type:y.literal("blockquote"),content:y.array(y.lazy(()=>Cn)).describe("Quoted block content")})),Un=y.lazy(()=>y.object({type:y.literal("blockCard"),attrs:y.object({url:y.string().url().describe("URL for the card")})})),Wn=y.lazy(()=>y.object({type:y.literal("media"),attrs:y.object({id:y.string().describe("Media identifier in Jira storage"),type:y.string().describe("Media type, e.g., file or link"),collection:y.string().optional(),width:y.number().optional(),height:y.number().optional()}).describe("Metadata describing the embedded media")})),Kn=y.lazy(()=>y.object({type:y.literal("mediaSingle"),content:y.array(Wn).describe("Single media block content")})),zn=y.lazy(()=>y.object({type:y.literal("mediaGroup"),content:y.array(Wn).describe("Gallery-style media grouping")})),Bn=y.object({type:y.literal("tableCell"),attrs:y.object({colspan:y.number().int().min(1).optional(),rowspan:y.number().int().min(1).optional()}).optional(),content:y.array(y.lazy(()=>Cn)).describe("Content inside the table cell")}).describe("A regular table cell container"),Yn=y.lazy(()=>Bn),Xn=y.lazy(()=>Bn.extend({type:y.literal("tableHeader")})),Vn=y.lazy(()=>y.object({type:y.literal("tableRow"),content:y.array(y.union([Yn,Xn]))})),Zn=y.lazy(()=>y.object({type:y.literal("table"),content:y.array(Vn)})),Qn=y.lazy(()=>y.object({type:y.literal("decisionItem"),attrs:y.object({localId:y.string().optional(),state:y.enum(["DECIDED","DECIDING"]).optional()}).optional(),content:y.array(y.lazy(()=>Cn))})),ei=y.lazy(()=>y.object({type:y.literal("decisionList"),content:y.array(Qn)})),ti=y.lazy(()=>y.object({type:y.string(),attrs:y.record(y.string(),y.any()).optional(),content:y.array(y.lazy(()=>Pn)).optional(),marks:y.array(jn).optional(),text:y.string().optional()}).describe("Unknown or extended Jira node"));Cn=y.lazy(()=>y.union([_n,Dn,Fn,$n,Jn,Hn,Mn,Ln,Gn,qn,Un,Kn,zn,Zn,Vn,Yn,Xn,ei,Qn,On,ti])),Pn=y.lazy(()=>y.union([Cn,Nn]));const ni=y.object({type:y.literal("doc"),version:y.literal(1),content:y.array(Cn).describe("Top-level block nodes in the document")}).describe("Jira ADF document structure; run jira-md-to-adf when converting markdown"),ii=s.for("jira.rate-limit"),ri=ht.jira.rateLimitRetryDelayMs??3e3;let oi=!1;const si="jira-issue-update",ai=kn,ci={name:si,inputSchema:ai,runTool:async(e,t)=>{try{const n=ai.parse(t),i={issueIdOrKey:n.issueId};if(n.fields&&(i.fields=(e=>{const t={...e},n=t.description;if("string"==typeof n){const e=Vt(Yt(n));t.description=ni.parse(e)}else if(n&&"object"==typeof n){const e=Vt(ni.parse(n));t.description=e}return t})(n.fields)),n.update&&(i.update=n.update),n.properties||n.issueTemplateId){const e=[...n.properties??[]];n.issueTemplateId&&e.push({key:"issueTemplateId",value:n.issueTemplateId}),i.properties=e}return void 0!==n.notifyUsers&&(i.notifyUsers=n.notifyUsers),void 0!==n.overrideScreenSecurity&&(i.overrideScreenSecurity=n.overrideScreenSecurity),void 0!==n.overrideEditableFlag&&(i.overrideEditableFlag=n.overrideEditableFlag),Et(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 n=(e=>{const t=e?.response?.data??e?.data??e?.response?.body??e,n=[];return"string"==typeof t&&n.push(t),"string"==typeof t?.message&&n.push(t.message),"string"==typeof t?.errorMessage&&n.push(t.errorMessage),Array.isArray(t?.errorMessages)&&n.push(...t.errorMessages.filter(e=>"string"==typeof e)),"string"==typeof t?.details?.message&&n.push(t.details.message),n.join(" ")||""})(e);return/rate\s?limit/i.test(n)})(i))return oi||(ii.warn(`Jira rate limit detected for ${e}; waiting ${ri}ms before retrying.`,{retryDelayMs:ri}),oi=!0),ri>0&&await(n=ri,new Promise(e=>setTimeout(e,n))),t();throw i}var n})(si,()=>e.issues.editIssue(i)))}catch(e){throw sn(e)}}},pi=y.object({markdown:y.string().describe("Markdown source that will be converted into Jira ADF"),options:y.record(y.string(),y.any()).optional().describe("Optional MarkdownToAdfOptions passed to the converter")}).describe("Convert markdown into a sanitized Jira ADF document"),di={name:"jira-md-to-adf",inputSchema:pi,runTool:async(e,t)=>{const n=pi.parse(t),i=Vt(Yt(n.markdown,n.options));return Et(ni.parse(i))}},li=y.object({issueId:y.string().min(1).describe("Issue key or ID for the assignment change"),assignee:y.union([y.string().describe("Account ID of the new assignee"),y.object({accountId:y.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"),ui={name:"jira-assign-issue",inputSchema:li,runTool:async(e,t)=>{try{const n=li.parse(t);let i=null;"string"==typeof n.assignee?i=n.assignee:"accountId"in n.assignee&&(i=n.assignee.accountId);const r={issueIdOrKey:n.issueId,accountId:i};return await e.issues.assignIssue(r),Et({success:!0,message:"Issue assigned to "+(i??"unassigned")})}catch(e){throw sn(e)}}},mi=y.object({issueId:y.string().min(1).describe("Issue key or ID to remove the assignee from")}).describe("Inputs required to unassign a Jira issue"),hi={name:"jira-unassign-issue",inputSchema:mi,runTool:async(e,t)=>{try{const n=mi.parse(t),i={issueIdOrKey:n.issueId,accountId:null};return await e.issues.assignIssue(i),Et({success:!0,message:`Issue ${n.issueId} unassigned successfully`})}catch(e){throw sn(e)}}},fi=y.object({issueId:y.string().min(1).describe("The Jira issue key or numeric ID receiving the comment"),body:y.string().min(1).describe("The markdown-compatible text of the comment"),visibility:y.object({type:y.enum(["role","group"]).describe("Visibility type that restricts the comment to a role or group"),value:y.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"),gi={name:"jira-comment-add",inputSchema:fi,runTool:async(e,t)=>{try{const n=fi.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.addComment)throw Error("Jira issueComments API is unavailable on the client");const r={issueIdOrKey:n.issueId,comment:n.body,visibility:n.visibility};return Et(await i.addComment(r))}catch(e){throw sn(e)}}},yi=y.object({issueId:y.string().min(1).describe("Issue key or ID whose comments should be retrieved"),start:y.number().optional().default(0).describe("Zero-based index to start pagination from"),maxResults:y.number().optional().default(50).describe("Maximum number of comments to return"),orderBy:y.string().optional().describe("Field name to order the returned comments by"),expand:y.string().optional().describe("Optional expansion clause for the comment response")}).describe("Parameters for fetching comments on a Jira issue"),bi={name:"jira-comment-list",inputSchema:yi,runTool:async(e,t)=>{try{const n=yi.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.getComments)throw Error("Jira issueComments API is unavailable on the client");const r={issueIdOrKey:n.issueId,startAt:n.start,maxResults:n.maxResults,orderBy:n.orderBy,expand:n.expand};return Et(await i.getComments(r))}catch(e){throw sn(e)}}},wi=y.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"),ki=y.object({id:y.string().optional().describe("Numeric Jira ID used when referencing an issue"),key:y.string().optional().describe("Human-readable key of the linked issue")}).describe("An issue reference (ID or key) used when building a link payload"),vi=y.object({type:y.enum(["role","group"]).describe("Visibility scope type attached to the comment"),value:y.string().min(1).describe("Name of the role or group granted visibility to the comment")}).describe("Optional visibility settings applied to the comment"),ji=y.object({body:y.string().optional().describe("Markdown text to include as a linked-comment"),visibility:vi.optional().describe("Optional ACL for the comment")}).describe("Optional comment applied at the time the link is created or updated"),Ti=y.object({link:y.object({relationship:wi,inwardIssue:ki,outwardIssue:ki,comment:ji.optional()}).describe("Definition of the link that should be created between two issues")}).describe("Arguments required to create a Jira issue link");let Si=[];function xi(e){return(e||"").trim().toLowerCase()}async function Ii(e,t){if(!t)throw Error("Link relationship is required");0===Si.length&&(Si=await(async e=>{const t=e?.issueLinkTypes;if(!t||"function"!=typeof t.getIssueLinkTypes)throw Error("Jira issueLinkTypes API is unavailable on the client");const n=await t.getIssueLinkTypes();return n?.issueLinkTypes??[]})(e));const n=xi(t),i=Si.find(e=>[e.name,e.inward,e.outward].some(e=>xi(e)===n));if(!i)throw Error(`No issue link type matching '${t}' found.`);return i}function Ei(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 Ai(e){if(!e)return;const t={};return e.body&&(t.body=Yt(e.body)),e.visibility&&(t.visibility=e.visibility),Object.keys(t).length>0?t:void 0}const Ri=Ti,Oi={name:"jira-link-create",inputSchema:Ri,runTool:async(e,t)=>{try{const n=Ri.parse(t).link,i=Ai(n.comment),r=e.issueLinks;if(!r||"function"!=typeof r.linkIssues)throw Error("Jira issueLinks API is unavailable on the client");const o=await Ii(e,n.relationship),s={inwardIssue:Ei(n.inwardIssue),outwardIssue:Ei(n.outwardIssue),type:Ci(o),...i?{comment:i}:{}};return await r.linkIssues(s),Et({success:!0,message:"Issue link created with relationship "+n.relationship})}catch(e){throw sn(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")}const Pi=y.object({issueId:y.string().min(1).describe("Issue key or ID receiving the attachment"),file:y.string().min(1).describe("Base64 or path to the file contents to upload"),mimeType:y.string().optional().describe("Optional MIME type override for the attachment"),comment:y.string().optional().describe("Optional comment to associate with the attachment")}).describe("Inputs needed to attach a file to a Jira issue"),Ni={name:"jira-attach",inputSchema:Pi,runTool:async(e,t)=>{try{const n=Pi.parse(t),r=S.resolve(n.file);let o=n.file,s="attachment",a=!1;try{await i.access(r),a=!0}catch{o=n.file,s="attachment"}a&&(o=await i.readFile(r),s=S.basename(r));const c=e.issueAttachments;if(!c||"function"!=typeof c.addAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const p={filename:s,file:o,mimeType:n.mimeType},d=await c.addAttachment({issueIdOrKey:n.issueId,attachment:p});if(n.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:n.issueId,comment:Yt(n.comment)})}return Et(d)}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 sn(e)}}},_i=y.object({issueId:y.string().min(1).describe("Issue key or ID whose attachments should be listed")}).describe("Arguments used to fetch attachments for a Jira issue"),Di={name:"jira-attachment-list",inputSchema:_i,runTool:async(e,t)=>{try{const n=_i.parse(t),i=e.issues;if(!i||"function"!=typeof i.getIssue)throw Error("Jira issues API is unavailable on the client");const r={issueIdOrKey:n.issueId,fields:["attachment"]},o=await i.getIssue(r);return Et({attachments:Array.isArray(o.fields?.attachment)?o.fields.attachment:[]})}catch(e){throw sn(e)}}},Ji=y.object({issueId:y.string().min(1).describe("Issue key or ID owning the attachment"),attachmentId:y.string().min(1).describe("ID of the attachment to delete")}).describe("Arguments required to remove an attachment from Jira"),Fi={name:"jira-attachment-delete",inputSchema:Ji,runTool:async(e,t)=>{try{const n=Ji.parse(t),i=e.issueAttachments;if(!i||"function"!=typeof i.removeAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const r={id:n.attachmentId};return await i.removeAttachment(r),Et({success:!0,message:`Attachment ${n.attachmentId} deleted successfully`})}catch(e){throw sn(e)}}},$i=y.object({issueId:y.string().min(1).describe("Target issue key or ID for the worklog entry"),timeSpent:y.string().min(1).describe('Time spent text (e.g., "1h 30m")'),comment:y.string().optional().describe("Optional worklog comment in markdown"),author:y.object({accountId:y.string().min(1).describe("Account ID of the user logging the work")}).optional().describe("Optional author override for the worklog entry"),startingOn:y.string().optional().describe("Optional timestamp for when the work started (ISO)"),artifact:y.string().optional().describe("Optional identifier linking the worklog to another artifact")}).describe("Arguments required to add a worklog entry to a Jira issue"),Mi={name:"jira-worklog-add",inputSchema:$i,runTool:async(e,t)=>{try{const n=$i.parse(t),i={timeSpent:n.timeSpent,issueIdOrKey:n.issueId};if(n.comment&&(i.comment=n.comment),n.author&&(i.author=n.author),n.startingOn&&(i.started=n.startingOn),n.artifact){const e=[...i.properties??[]];e.push({key:"artifact",value:n.artifact}),i.properties=e}const r=e.issueWorklogs;if(!r||"function"!=typeof r.addWorklog)throw Error("Jira issueWorklogs API is unavailable on the client");return Et(await r.addWorklog(i))}catch(e){throw sn(e)}}},Hi=s.for("jira.xray");class Li{constructor(){this.clientId=ht.orThrow().xray.apiUser,this.clientSecret=ht.orThrow().xray.apiSecret,this.baseUrl=ht.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 n={query:e,variables:t};Hi.info("xray.graphql.request",{payload:jt(n)});try{const e=await fetch(this.baseUrl+"/api/v2/graphql",{method:"POST",headers:{Authorization:"Bearer "+this.token,"Content-Type":"application/json"},body:JSON.stringify(n)}),t=await e.json();if(Hi.info("xray.graphql.response",{status:e.status,headers:e.headers?.get?e.headers.get("content-type"):void 0,body:jt(t)}),t.errors)throw Hi.error("xray.graphql.errors",{errors:jt(t.errors)}),Error(JSON.stringify(t.errors,null,2));return t.data}catch(e){throw Hi.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 n=(await this.getTest(e)).steps||[],i=[],r=[],o=[];for(let e=0;e<t.length;e++){const o=t[e],s=n[e];s?s.action===o.action&&s.data===o.data&&s.result===o.result||i.push({stepId:s.id,step:o}):r.push(o)}if(n.length>t.length)for(let e=t.length;e<n.length;e++)o.push(n[e].id);await this.addSteps(e,r),await this.updateSteps(i),await this.deleteSteps(o)}}let Gi=null;const qi=new Map;function Ui(e){const t=e?.fields,n=e?.action??t?.Action??t?.action;if(!n||"string"!=typeof n)throw Error("Xray step action is required");const i=e.data??e.fields?.Data??e.fields?.data??void 0,r=e.result??e.fields?.Result??e.fields?.result??void 0;return{action:n.toString(),data:"string"==typeof i?i:void 0,result:"string"==typeof r?r:void 0}}async function Wi(e,t){if(!t)throw Error("Issue reference is required when interacting with Xray steps");if(qi.has(t))return qi.get(t);if(/^[0-9]+$/.test(t))return qi.set(t,t),t;const n=e?.issues;if(!n?.getIssue)throw Error("Jira client does not expose issue lookup functionality");const i=await n.getIssue({issueIdOrKey:t,fields:["id"]}),r=i?.id;if(!r)throw Error("Unable to resolve Jira issue ID for "+t);return qi.set(t,r),r}async function Ki(e){if(e?.test?.step)return e.test.step;const t=await(async()=>{if(Gi)return Gi;const e=ht.orThrow().xray.apiUser?.trim(),t=ht.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 n=await xt(),i=new Li,r={async createStep(e,t){const r=await Wi(n,e),o=await i.addStep(r,Ui(t));return{step:o,id:o?.id}},async updateStep(e,t,r){await Wi(n,e);const o=Ui(r),s=await i.updateStep(t.toString(),o);return{step:s,id:s?.id}},deleteStep:async(e,t)=>(await Wi(n,e),{success:!0===await i.deleteStep(t.toString())}),async getSteps(e){const t=await Wi(n,e),r=await i.getTest(t);return{steps:r?.steps??[]}}};return Gi={test:{step:r}},Gi})();if(!t?.test?.step)throw Error("Xray step API is unavailable on the client");return t.test.step}const zi=y.object({issueId:y.string().min(1).describe("Xray test case key or ID that owns the step"),action:y.string().min(1).describe("Action description for the new Xray step"),data:y.string().optional().describe("Optional data or context used by this step"),result:y.string().optional().describe("Optional expected result for the step")}).describe("Inputs for adding a step to an Xray test case"),Bi={name:"jira-xray-step-add",inputSchema:zi,runTool:async(e,t)=>{try{const n=zi.parse(t),i=await Ki(e),r={action:n.action,data:n.data,result:n.result};return Et(await i.createStep(n.issueId,r))}catch(e){throw sn(e)}}},Yi=y.object({issueId:y.string().min(1).describe("Xray test case key or ID that owns the step"),stepId:y.union([y.string(),y.number()]).describe("Identifier for the step that should be updated"),action:y.string().min(1).describe("New action text for the step"),data:y.string().optional().describe("Updated data/context for the step"),result:y.string().optional().describe("Updated expected result for the step")}).describe("Inputs required to modify an Xray test step"),Xi={name:"jira-xray-step-update",inputSchema:Yi,runTool:async(e,t)=>{try{const n=Yi.parse(t),i=await Ki(e),r=n.stepId+"",o={action:n.action,data:n.data,result:n.result};return Et(await i.updateStep(n.issueId,r,o))}catch(e){throw sn(e)}}},Vi=y.object({issueId:y.string().min(1).describe("Xray test case key or ID owning the step"),stepId:y.union([y.string(),y.number()]).describe("Identifier of the step to delete")}).describe("Arguments used to remove an Xray test step"),Zi={name:"jira-xray-step-delete",inputSchema:Vi,runTool:async(e,t)=>{try{const n=Vi.parse(t),i=await Ki(e);return await i.deleteStep(n.issueId,n.stepId.toString()),Et({success:!0})}catch(e){throw sn(e)}}},Qi=y.object({issueId:y.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"),er={name:"jira-xray-step-list",inputSchema:Qi,runTool:async(e,t)=>{try{const n=Qi.parse(t),i=await Ki(e);return Et(await i.getSteps(n.issueId))}catch(e){throw sn(e)}}},tr=y.object({linkId:y.string().min(1).describe("Identifier for the Jira issue link to remove")}).describe("Inputs required to delete an existing Jira issue link"),nr={name:"jira-link-delete",inputSchema:tr,runTool:async(e,t)=>{try{const n=tr.parse(t),i=e.issueLinks;if(!i||"function"!=typeof i.deleteIssueLink)throw Error("Jira issueLinks API is unavailable on the client");const r={linkId:n.linkId};return await i.deleteIssueLink(r),Et({success:!0,message:`Issue link ${n.linkId} deleted successfully`})}catch(e){throw sn(e)}}},ir=y.object({linkId:y.string().min(1).describe("ID of the existing issue link to change"),relationship:wi,comment:ji.optional().describe("Optional comment to attach while recreating the link")}).describe("Inputs required to update (recreate) a Jira issue link"),rr={name:"jira-link-update",inputSchema:ir,runTool:async(e,t)=>{try{const n=ir.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 r=await i.getIssueLink({linkId:n.linkId});if(!r)throw Error(`Issue link ${n.linkId} not found`);const o=r.inwardIssue,s=r.outwardIssue;if(!o||!s)throw Error("Issue link payload is missing linked issues");const a=await Ii(e,n.relationship);await i.deleteIssueLink({linkId:n.linkId});const c=Ai(n.comment),p={inwardIssue:Ei(o),outwardIssue:Ei(s),type:or(a),...c?{comment:c}:{}};return await i.linkIssues(p),Et({success:!0,message:`Issue link ${n.linkId} updated to ${n.relationship}`})}catch(e){throw sn(e)}}};function or(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 sr(e=[]){return e.map(ar).join("")}function ar(e){switch(e.type){case"text":return(e=>{let t=e.text||"";for(const n of e.marks||[])switch(n.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}](${n.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 cr(e){switch(e.type){case"heading":return"#".repeat(e.attrs?.level)+" "+sr(e.content);case"paragraph":return sr(e.content);case"blockquote":return e.content.map(cr).map(e=>"> "+e).join("\n");case"bulletList":case"orderedList":case"taskList":return(e=>{const t=[];let n=1;for(const i of e.content){let r="- ";"orderedList"===e.type&&(r=n+++". "),"taskList"===e.type&&(r="- "+("DONE"===i.attrs?.state?"[x] ":"[ ] "));const o=i.content.map(cr).join(" ");t.push(r+o)}return t.join("\n")})(e);case"table":return(e=>{const t=e.content||[];return t.length?["| "+t[0].content.map(e=>sr(e.content[0].content)).join(" | ")+" |","| "+t[0].content.map(()=>"---").join(" | ")+" |",...t.slice(1).map(e=>e.content.map(e=>sr(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(cr).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 pr=y.object({document:ni.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"),dr={name:"jira-adf-to-markdown",inputSchema:pr,runTool:async(e,t)=>{return Et({markdown:(n=pr.parse(t).document,(e=>{if(!e||"doc"!==e.type)return"";const t=[];for(const n of e.content||[])t.push(cr(n));return t.join("\n\n")})(n))});var n}},lr=y.enum(["bug","incident","release","feature","test"]),ur=y.object({ticketType:lr.optional(),template_path:y.string().min(1).optional(),project:y.string().min(1).optional(),projectKey:y.string().min(1).optional(),issueType:y.string().min(1).optional(),summary:y.string().min(1).optional(),description:y.string().optional(),assignee:y.string().optional(),customFields:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional(),fields:y.record(y.string(),y.any()).optional(),template:y.object({content:y.string().min(1),placeholders:y.record(y.string(),y.union([y.string(),y.number(),y.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 mr(e){return e&&e.trim()?e.trim():void 0}const hr={name:"jira-ticket-create",inputSchema:ur,runTool:async(e,t)=>Et(await(async(e,t)=>{const n=ur.parse(t),i=n.template_path??n.ticketType,r=(e=>{if(e)try{return Ue(e)}catch{return}})(i),o=n.template?.content??(r?We(i):void 0),s=n.projectKey??n.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 n=e?.projectKey;return"string"==typeof n&&n.trim()?n.trim():void 0})(n.fields)??mr(ht.jira.projectKey)??"",a=n.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 n=e?.issueType;return"string"==typeof n&&n.trim()?n.trim():void 0})(n.fields)??r?.issueType??mr(ht.jira.issueType)??"Task",c=n.summary??(e=>{const t=e?.summary;return"string"==typeof t&&t.trim()?t.trim():void 0})(n.fields)??"",p=o||n.template?{content:o??n.template.content,placeholders:{...n.customFields??{},summary:c,projectKey:s??"",issueType:a,ticketType:r?.type??n.ticketType??"",templatePath:r?.uri??n.template_path??"",templateName:r?.name??"",templateTitle:r?.title??"",...n.template?.placeholders??{}}}:void 0;return await tn(e,n.fields?{fields:n.fields,...p?{template:p}:{}}:{summary:c,projectKey:s,issueType:a,...n.description?{description:n.description}:{},...n.assignee?{assignee:n.assignee}:{},...p?{template:p}:{}})})(e,t))},fr={[nn.name]:{title:"Jira Issue Create",description:"Create a Jira issue (optionally applying a markdown template)",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[hr.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}},[mn.name]:{title:"Jira Issue Read",description:"Read a Jira issue with expandable fields and properties",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[ln.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}},[ci.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}},[di.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}},[dr.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}},[cn.name]:{title:"Jira Issue Delete",description:"Delete a Jira issue and optionally remove its subtasks",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[fn.name]:{title:"Jira Issue Transition",description:"Transition a Jira issue while optionally adding a comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[yn.name]:{title:"Jira Transition List",description:"List available transitions for a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[ui.name]:{title:"Jira Issue Assign",description:"Assign a Jira issue to a user or account",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[hi.name]:{title:"Jira Issue Unassign",description:"Unassign the current owner from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[gi.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}},[bi.name]:{title:"Jira Comment List",description:"List comments on a Jira issue with pagination support",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Oi.name]:{title:"Jira Link Create",description:"Create an issue link relationship with optional comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[rr.name]:{title:"Jira Link Update",description:"Change the relationship type for an existing issue link",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[nr.name]:{title:"Jira Link Delete",description:"Delete an issue link from Jira",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Ni.name]:{title:"Jira Attachment Add",description:"Attach a local file to a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Di.name]:{title:"Jira Attachment List",description:"List attachments on a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Fi.name]:{title:"Jira Attachment Delete",description:"Delete an attachment from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Mi.name]:{title:"Jira Worklog Add",description:"Log time spent on a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Bi.name]:{title:"Jira Xray Step Add",description:"Add a step to an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Xi.name]:{title:"Jira Xray Step Update",description:"Update a step on an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Zi.name]:{title:"Jira Xray Step Delete",description:"Delete a step from an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[er.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 gr(e){const t=s.for(gr);let n,i=null;try{n=await xt()}catch(e){if(!(e instanceof bt))return void t.warn("Skipping Jira tool registration; unable to create Jira client",{error:e});i=e,t.warn("Registering Jira tools without credentials; each tool will report configuration requirements.",{error:e})}const r=[nn,hr,mn,ln,ci,di,dr,cn,fn,yn,ui,hi,gi,bi,Oi,rr,nr,Ni,Di,Fi,Mi,Bi,Xi,Zi,er];for(const o of r){const r=fr[o.name];if(r)try{await e.registerTool(o.name,{title:r.title,description:r.description,inputSchema:o.inputSchema,annotations:r.annotations},async e=>{if(!n)throw i??Error("Jira client unavailable because credentials could not be loaded.");return await o.runTool(n,e)}),t.info("Registered Jira tool "+o.name)}catch(e){t.error("Failed to register Jira tool "+o.name,{error:e})}}}async function yr(e){const t=s.for(yr);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:ot.shape,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},async e=>(async e=>{const t=ot.parse(e??{}),n=t?.filePath?x(process.cwd(),t.filePath):st,i=(()=>{const e=(process.env.AGENT_PROVIDER||"codex").toLowerCase();return"claude"===e||"copilot"===e||"codex"===e?e:"codex"})(),r=((e,t)=>{if(t)return t;if(!e)return"text";const n=e.split(".").pop()?.toLowerCase();return n&&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(n)?"code":"text"})(t.filePath,t.textType);try{const e=await P(n,"utf8"),o=await rt({provider:i,prompt:tt({filePath:n,textType:r,context:t.context},e),toolMetadata:{tool:"file-summarizer",filePath:n,textType:r,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 n=(e=>{const t=e.trim();if(t.startsWith("{")&&t.endsWith("}"))return t;const n=t.indexOf("{"),i=t.lastIndexOf("}");return-1!==n&&-1!==i&&i>n?t.slice(n,i+1):void 0})(t);if(!n)return{summary:t};try{const e=JSON.parse(n);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:n,status:"ok",provider:i,textType:r,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:n,status:"error",provider:i,textType:r,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=at.map(e=>e.getName()).sort();return{content:[{type:"text",text:["Name: "+ht.name,"Title: "+ht.title,"Version: "+ht.version,"Prompts: "+(e.join(", ")||"<none>")].join("\n")}]}})})(e)}catch(e){t.error("Failed to register server info tool",e)}try{await gr(e)}catch(e){t.error("Failed to register Jira tools",e)}}class br extends pe{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 br}build(e){const t=this.hasErrors();if(t)throw Error(t.toString());try{const t="string"==typeof this.uriOrTemplate&&this.uriOrTemplate.includes("{")?new L(new q(this.uriOrTemplate),{list:void 0}):this.uriOrTemplate,n=Object.assign(this.config,{_meta:{}}),i=async(e,t)=>{const n=this.logFor(t);n.verbose(`Requesting resource ${this.name} from ${e.toString()}`);const i=await Promise.resolve(this.cb(e,t));return n.verbose(`Resource ${this.name} retrieved successfully.`),n.debug("Resource retrieval meta: "+JSON.stringify(i._meta)),i};return e.resource(this.name,t,n,i)}catch(e){throw s.for(this).error("Error registering resource "+this.name,e),e}}}ne([m(),ie("design:type",Object)],br.prototype,"uriOrTemplate",void 0),ne([m(),ie("design:type",Function)],br.prototype,"cb",void 0),ne([m(),ie("design:type",Object)],br.prototype,"config",void 0);const wr=K.join("workdocs","ai"),kr=K.join("project"),vr=K.join(kr,"agent"),jr=K.join(vr,"prompts"),Tr=K.join(vr,"behaviors"),Sr=je()??ke("src","assets"),xr=K.join(Sr,"prompts","agent"),Ir=K.join(Sr,"resources","agent"),Er=K.join(Sr,"templates"),Ar="catalog.json";function Rr(e){return K.resolve(e||ke(wr))}function Or(e){return K.join(e,kr)}function Cr(e){return K.join(e,vr)}function Pr(e){return K.join(e,jr)}function Nr(e){return K.join(e,Tr)}function _r(e="./AGENTS.md"){return K.resolve(process.cwd(),e)}function Dr(e){return K.join(Cr(e),Ar)}function Jr(e={}){const t=Rr(e.workspacePath),n=Or(t),i=Cr(t),r=[];Gr(n),Gr(i),Gr(Pr(t)),Gr(Nr(t)),Lr(K.join(Er,"AGENTS.md"),_r(e.entryFile),!1!==e.preserveExisting,r),Lr(K.join(Er,"instructions_template.md"),K.join(n,"instructions.md"),!1!==e.preserveExisting,r),Lr(K.join(Er,"constitution_template.md"),K.join(n,"constitution.md"),!1!==e.preserveExisting,r),Lr(K.join(Er,"plan_template.md"),K.join(n,"plan.md"),!1!==e.preserveExisting,r),Lr(K.join(Er,"specification_template.md"),K.join(n,"specifications","specification_template.md"),!1!==e.preserveExisting,r),Lr(K.join(Er,"task_template.md"),K.join(n,"specifications","task_template.md"),!1!==e.preserveExisting,r);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)Lr(K.join(Sr,"prompts",t),K.join(n,"commands",t),!1!==e.preserveExisting,r);const s=qr(xr,[".md",".json"]);for(const n of s)Lr(K.join(xr,n),K.join(Pr(t),n),!1!==e.preserveExisting,r);const a=qr(Ir,[".json"]);for(const n of a)Lr(K.join(Ir,n),K.join(Nr(t),n),!1!==e.preserveExisting,r);return Lr(K.join(Ir,Ar),Dr(t),!1!==e.preserveExisting,r),{workspaceRoot:t,projectRoot:n,agentRoot:i,entryFile:_r(e.entryFile),copiedFiles:r}}function Fr(e={}){const t=Rr(e.workspacePath),n=Cr(t),i=Dr(t),r=_r(e.entryFile);return U.existsSync(n)&&U.existsSync(i)?(U.existsSync(r)||(Gr(K.dirname(r)),U.copyFileSync(K.join(Er,"AGENTS.md"),r)),{workspaceRoot:t,projectRoot:Or(t),agentRoot:n,entryFile:r,copiedFiles:[]}):Jr({workspacePath:e.workspacePath,entryFile:e.entryFile,preserveExisting:!0})}function $r(e){return Ur(Dr(e))||Wr(K.join(Ir,Ar))}function Mr(e,t){return Ur(K.join(Nr(e),t.behaviorFile))||Wr(K.join(Ir,t.behaviorFile))}function Hr(e,t){const n=K.join(Pr(e),t.promptFile);if(!U.existsSync(n))throw Error("Missing copied agent prompt file: "+n);return U.readFileSync(n,"utf8")}function Lr(e,t,n,i){Gr(K.dirname(t)),n&&U.existsSync(t)||(U.copyFileSync(e,t),i.push(t))}function Gr(e){U.mkdirSync(e,{recursive:!0})}function qr(e,t){return U.existsSync(e)?U.readdirSync(e,{withFileTypes:!0}).filter(e=>e.isFile()).map(e=>e.name).filter(e=>t.includes(K.extname(e))).sort():[]}function Ur(e){if(U.existsSync(e))return Wr(e)}function Wr(e){return JSON.parse(U.readFileSync(e,"utf8"))}const Kr=["prompt","goap","workflow"];function zr(e){return(e=>{const t=(e+"").toLowerCase();if(Kr.includes(t))return t;if("default"===t)return"prompt";throw Error("Unsupported agent model type: "+e)})(e||process.env.AGENT_MODEL_TYPE||"prompt")}function Br(e){return"goap"===e}function Yr(e){return"prompt"===e}class Xr{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 Vr={plan:"architect",review:"reviewer","create-specs":"architect",implement:"implementation",execute:"orchestrator",manage:"manager"};class Zr{constructor(e,t,n={}){this.definition=e,this.options=t,this.blackboard=new Xr,this.modelType=zr(t.modelType),this.providerCommand=it(this.options.provider),this.behavior=this.createBehaviourHost(n),Br(this.modelType)||(this.tree=new z(e.tree,this.behavior))}get log(){return this._log||(this._log=s.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),Br(this.modelType)?this.runGoap():this.runWorkflow()}report(e,t,n){this.options.onProgress&&this.options.onProgress({agentName:this.definition.name,operation:Br(this.modelType)?"goap":"workflow",specRef:this.options.specRef,taskRef:this.options.specRefs?.[0],status:e,summary:t,progress:n})}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?B.SUCCEEDED:B.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()===B.RUNNING&&50>e&&(this.tree.step(),e+=1,this.emitWorkflowStateProgress(e),this.tree.getState()===B.RUNNING););this.tree.getState()===B.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()===B.SUCCEEDED,n=t?this.definition.name+" completed":this.definition.name+" failed",i=this.blackboard.get("lastActionResult"),r=this.blackboard.get("blocker");return this.report(t?"completed":"blocked",n,t?1:.85),{stage:this.definition.name,ok:t,confidence:Qr(t,r),summary:n,details:i,blocker:r}}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=Y(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 n of e){const i=this.definition.actions.find(e=>e.name===n.name);if(!i)return this.report("blocked","Missing action handler for GOAP action "+n.name),{stage:this.definition.name,ok:!1,confidence:35,summary:this.definition.name+" blocked",blocker:"Missing action handler for GOAP action "+n.name,details:t.join(", ")||void 0};const r=this.executeAction(i);if(t.push(i.name),this.blackboard.set("lastActionResult",r.summary),r.blocker&&this.blackboard.set("blocker",r.blocker),this.notifyActionProgress(i,t.length/e.length,r),!r.ok)return this.report("blocked",r.blocker||"GOAP action failed",t.length/e.length),{stage:this.definition.name,ok:!1,confidence:Qr(!1,r.blocker),summary:this.definition.name+" blocked",blocker:r.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,n){const i=n?.summary??this.blackboard.get("lastActionResult")??e.kind+" handled",r=!1===n?.ok||n?.blocker?"blocked":"completed";this.report(r,`${e.name}: ${i}`,t)}emitWorkflowStateProgress(e){const t=this.tree?.getState();t!==B.RUNNING?t!==B.SUCCEEDED?t===B.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,n,i){return{stage:e,ok:t,confidence:Qr(t,i),summary:n,blocker:i}}}function Qr(e,t){return e?t?55:90:t?35:45}const eo=new Map;function to(e,t){return e+"::"+t}class no{constructor(){this.options={},this.behaviours={}}static get builder(){return new no}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??zr(),t=new Zr(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 n,i,r;return n=this.options.workspaceRoot,i=this.definition.name,r=t,eo.set(to(n,i),r),t}}function io(e){const t=$r(e.workspaceRoot).agents.find(t=>t.name===e.agentName);if(!t)throw Error("Unknown agent: "+e.agentName);const n=(i=e.workspaceRoot,r=e.agentName,eo.get(to(i,r)));var i,r;if(n)return n;const o=Mr(e.workspaceRoot,t);return no.builder.setDefinition(o).setWorkspaceRoot(e.workspaceRoot).setProvider(e.provider).setModelType(e.modelType??zr()).setSpecRef(e.specRef??t.name).setSpecRefs(e.specRefs??[]).setObjective(e.objective??o.objective).setProgressHook(e.onProgress).build()}function ro(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 oo(e,t,n,i){const r=`${t}\n${n}`.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})(r),s=0===i&&!o;return{stage:e,ok:s,confidence:so(s,o),summary:s?e+" completed":e+" blocked",details:r||void 0,blocker:o}}function so(e,t){return e?t?55:90:t?35:45}function ao(e,t,n,i,r){const o=K.join(Or(e),"specifications",t+".md"),s=(e=>{if(!U.existsSync(e))return[];const t=U.readFileSync(e,"utf8");return Array.from(new Set(t.match(/TASK-\d+/g)??[]))})(o),a=`- ${(new Date).toISOString()} ${n}: ${i}${r?" - "+r:""}\n`;co(o,"Agent Progress",a);for(const t of s)co(K.join(Or(e),"specifications","tasks",t+".md"),"Agent Progress",a)}function co(e,t,n){if(!U.existsSync(e))return;const i=U.readFileSync(e,"utf8"),r="## "+t;i.includes(r)?U.writeFileSync(e,i.replace(RegExp(r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"\\n([\\s\\S]*?)$","m"),`${r}\n${n}$1`)):U.writeFileSync(e,`${i.trimEnd()}\n\n${r}\n${n}`)}async function po(e,t,n,i){if("true"===process.env.JIRA_ENABLED)try{const r=(await xt()).issueComments;if(!r?.addComment)return;await r.addComment({issueIdOrKey:e,comment:Yt(`Agent stage **${t}** ${n.ok?"completed":"blocked"}.\n\n${n.summary}${n.blocker?"\n\nBlocker: "+n.blocker:""}\n\nModel type: ${i}.`)})}catch{}}function lo(e){return Vr[e]}async function uo(e){const t=Fr({workspacePath:e.workspacePath,entryFile:e.entryFile}),n=zr(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=zr(e.modelType),n=((e,t)=>{const n=U.mkdtempSync(K.join(X.tmpdir(),`decaf-agent-${t.toLowerCase()}-`));try{return _("git",["worktree","add","--detach",n,"HEAD"],{cwd:e,stdio:"pipe"}),{repoRoot:e,path:n,created:!0}}catch{return{repoRoot:e,path:e,created:!1}}})(Fr({workspacePath:e.workspacePath,entryFile:e.entryFile}).workspaceRoot,e.specRef),i=K.join(n.path,"workdocs","ai"),r=[];try{Fr({workspacePath:i,entryFile:e.entryFile});const n=$r(i),o=["manager","orchestrator","architect","implementation","reviewer","documentation"].map(e=>n.agents.find(t=>t.name===e)).filter(e=>!!e);for(const n of o){const s=Mr(i,n);let a,c;if(ao(i,e.specRef,n.name,"started"),e.onProgress?.({agentName:n.name,operation:"execute",specRef:e.specRef,status:"started",summary:n.name+" stage started",progress:r.length/o.length}),Yr(t)){const r=Hr(i,n);a=await rt({provider:e.provider,prompt:ro({specRef:e.specRef,stageName:n.name,definition:s,prompt:r,workspaceRoot:i,agentRoot:Nr(i),promptRoot:Pr(i),projectRoot:Or(i)}),toolMetadata:{specRef:e.specRef,stage:n.name,modelType:t},cwd:i}).catch(t=>({exitCode:1,stdout:"",stderr:t+"",command:{executable:e.provider,args:[]}})),c=oo(n.name,a.stdout,a.stderr,a.exitCode)}else c=io({workspaceRoot:i,provider:e.provider,modelType:t,specRef:e.specRef,objective:s.objective,agentName:n.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:[n.name]}};if(r.push(c),ao(i,e.specRef,n.name,c.ok?"completed":"blocked",c.summary),e.onProgress?.({agentName:n.name,operation:"execute",specRef:e.specRef,status:c.ok?"completed":"blocked",summary:c.summary,progress:r.length/o.length}),await po(e.specRef,n.name,c,t),!c.ok)return{specRef:e.specRef,workspaceRoot:i,provider:e.provider,modelType:t,stages:r,blocked:!0}}return ao(i,e.specRef,"documentation","completed","workflow completed"),{specRef:e.specRef,workspaceRoot:i,provider:e.provider,modelType:t,stages:r,blocked:!1}}finally{(e=>{if(e.created){try{_("git",["worktree","remove","--force",e.path],{cwd:e.repoRoot,stdio:"pipe"})}catch{}try{U.rmSync(e.path,{recursive:!0,force:!0})}catch{}}})(n)}})({specRef:e.specRef||e.executeSpec||"SPEC-UNKNOWN",provider:e.provider,modelType:n,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:n,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=$r(t.workspaceRoot),r=lo(e.operation),o=i.agents.find(e=>e.name===r);if(!o)throw Error("Unknown agent for operation: "+e.operation);let s,a;if(Yr(n)){const i=Mr(t.workspaceRoot,o),c=Hr(t.workspaceRoot,o);e.onProgress?.({agentName:r,operation:e.operation,specRef:e.specRef??e.executeSpec,status:"started",summary:r+" prompt stage started",progress:0}),s=await rt({provider:e.provider,prompt:mo({operation:e.operation,specRef:e.specRef,workspaceRoot:t.workspaceRoot,agentRoot:Nr(t.workspaceRoot),promptRoot:Pr(t.workspaceRoot),projectRoot:Or(t.workspaceRoot),prompt:c,definition:i}),toolMetadata:{operation:e.operation,specRef:e.specRef,provider:e.provider,modelType:n,workspacePath:t.workspaceRoot},cwd:t.workspaceRoot}).catch(t=>({exitCode:1,stdout:"",stderr:t+"",command:{executable:e.provider,args:[]}})),a=((e,t,n,i)=>{const r=`${t}\n${n}`.trim(),o=ho(r),s=0===i&&!o;return{stage:e,ok:s,confidence:s?90:o?35:45,summary:s?e+" completed":e+" blocked",details:r||void 0,blocker:o}})(o.name,s.stdout,s.stderr,s.exitCode),e.onProgress?.({agentName:r,operation:e.operation,specRef:e.specRef??e.executeSpec,status:a.ok?"completed":"blocked",summary:a.summary,progress:1})}else{const i=Mr(t.workspaceRoot,o);a=io({workspaceRoot:t.workspaceRoot,provider:e.provider,modelType:n,specRef:e.specRef??e.executeSpec,objective:e.objective??i.objective,agentName:r,onProgress:e.onProgress}).run(),s={exitCode:0,stdout:JSON.stringify({modelType:n,stage:a,agentName:r},null,2)+"\n",stderr:"",command:{executable:n,args:[e.operation]}}}const c=!1===a.ok||0!==s.exitCode||void 0!==ho(s.stdout+"\n"+s.stderr),p=ho(s.stdout+"\n"+s.stderr)??a.blocker,d={operation:e.operation,agentName:r,provider:e.provider,modelType:n,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,n,i)=>{if("true"===process.env.JIRA_ENABLED)try{const r=(await xt()).issueComments;if(!r?.addComment)return;await r.addComment({issueIdOrKey:e,comment:Yt(`Agent stage **${t}** ${n.ok?"completed":"blocked"}.\n\n${n.summary}${n.blocker?"\n\nBlocker: "+n.blocker:""}\n\nModel type: ${i}.`)})}catch{}})(e.specRef||r,e.operation,a,n),d}function mo(e){const t="agent."+e.operation,n=["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,"",n,"","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 ho(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 fo=["plan","review","create-specs","implement","execute","manage"];async function go(e,t={}){const n=s.for(go),i=Fr({workspacePath:t.workspacePath,entryFile:t.entryFile}),r=$r(i.workspaceRoot),o=["resource://agent.catalog"],a=[],c=[];yo(br.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(r,null,2)}],_meta:{agentMode:!0}})),e,o);for(const{entry:n,definition:s}of(e=>$r(e).agents.map(t=>({entry:t,definition:Mr(e,t)})))(i.workspaceRoot))io({workspaceRoot:i.workspaceRoot,provider:r.defaultProvider,modelType:zr(t.modelType),agentName:n.name}),yo(br.builder.setName("agent.behavior."+n.name).setTitle(s.title+" behavior").setDescription(`Behavior tree and GOAP metadata for ${s.title}.`).setUriOtTemplate("resource://agent.behavior."+n.name).setConfig({mimeType:"application/json",description:`Behavior tree JSON for ${s.title}.`}).setCb(async()=>{return{contents:[{uri:"resource://agent.behavior."+n.name,mimeType:"application/json",text:JSON.stringify(s,null,2)}],_meta:{source:(e=i.workspaceRoot,t=n.behaviorFile,K.join(Nr(e),t)),agent:n.name}};var e,t}),e,o),yo(br.builder.setName("agent.prompt."+n.name).setTitle(s.title+" prompt").setDescription(`Prompt for ${s.title} loaded from the repo-copied workspace files.`).setUriOtTemplate("resource://agent.prompt."+n.name).setConfig({mimeType:"text/markdown",description:`Prompt text for ${s.title}.`}).setCb(async()=>{return{contents:[{uri:"resource://agent.prompt."+n.name,mimeType:"text/markdown",text:Hr(i.workspaceRoot,n)}],_meta:{source:(e=i.workspaceRoot,t=n.promptFile,K.join(Pr(e),t)),agent:n.name}};var e,t}),e,o),bo(Se.builder.setName("agent-"+n.name).setTitle(s.title+" prompt").setDescription(`Repository-backed prompt for ${s.title}.`).setArgsSchema(y.object({})).setCb(async()=>({messages:[{role:"user",content:{type:"text",text:Hr(i.workspaceRoot,n)}}],_meta:{agent:n.name}})),e,a);const p=y.object({operation:y.enum(fo),specRef:y.string().optional(),objective:y.string().optional(),provider:y.enum(r.providers).optional(),modelType:y.enum(["prompt","goap","workflow"]).optional()}).shape;wo({name:"agent.notify",title:"Agent progress notifier",description:"Emit a progress notification for agent mode tooling.",inputSchema:y.object({agentName:y.string(),operation:y.string(),specRef:y.string().optional(),taskRef:y.string().optional(),status:y.enum(["started","completed","blocked"]),summary:y.string(),confidence:y.number().int().min(1).max(100).optional(),progress:y.number().min(0).max(1).optional()}).shape},e,c,async(e,t)=>{const n={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(n,null,2)+"\nTASK COMPLETE"}],_meta:{confidence:n.confidence,status:n.status}}}),wo({name:"agent.do",title:"Agent dispatcher",description:"Dispatch an agent operation to the appropriate concrete agent.",inputSchema:p},e,c,async(e,n)=>{const o=zr(e.modelType);return await ko(n,{agentName:lo(e.operation),operation:e.operation,specRef:e.specRef,status:"started",summary:"dispatching "+e.operation,progress:0}),vo(await uo({operation:e.operation,provider:e.provider??r.defaultProvider,modelType:o,workspacePath:i.workspaceRoot,entryFile:t.entryFile,specRef:e.specRef,objective:e.objective,onProgress:e=>ko(n,e)}))});for(const n of fo)wo({name:"agent."+n,title:"Agent "+n,description:`Run the ${n} agent workflow via the dispatcher.`,inputSchema:y.object({specRef:y.string().optional(),objective:y.string().optional(),provider:y.enum(r.providers).optional(),modelType:y.enum(["prompt","goap","workflow"]).optional()}).shape},e,c,async(e,o)=>{const s=zr(e.modelType);return await ko(o,{agentName:lo(n),operation:n,specRef:e.specRef,status:"started",summary:"starting "+n,progress:0}),vo(await uo({operation:n,provider:e.provider??r.defaultProvider,modelType:s,workspacePath:i.workspaceRoot,entryFile:t.entryFile,specRef:e.specRef,objective:e.objective,onProgress:e=>ko(o,e)}))});return n.info(`Registered agent-mode assets for ${r.agents.length} agents`),{resourceUris:o,templateNames:[],promptNames:a,toolNames:c}}function yo(e,t,n){try{const i=e.getName();e.build(t);const r=i?"resource://"+i:void 0;r&&!n.includes(r)&&n.push(r)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}function bo(e,t,n){try{const i=e.getName();e.build(t),i&&!n.includes(i)&&n.push(i)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}function wo(e,t,n,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),n.push(e.name)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}async function ko(e,t){if(!e?.sendNotification||void 0===e._meta?.progressToken)return;const n=[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:`${n.join(" ")}: ${t.summary}`}}).catch(()=>{})}function vo(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 jo="resource://repo.metadata",To=Me("repo-metadata.json"),So=br.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(jo).setConfig({mimeType:"application/json",description:"Static repository metadata that documents the MCP surface."}).setCb(async()=>{const e=ht.version,t=ht.jira.projectKey??To.jira?.projectKey??"DECAF",n={...To,version:e,projectKey:t};return{contents:[{uri:jo,mimeType:"application/json",text:JSON.stringify(n,null,2)}],_meta:{source:"assets/repo-metadata.json"}}}),xo="resource://decoration.schematic.metadata",Io=$e("decoration/metadata.json"),Eo=br.builder.setName("decoration.schematic.metadata").setTitle("Decoration metadata schematic").setDescription("Outlines the annotation and field metadata contracts that decorators expose.").setUriOtTemplate(xo).setConfig({mimeType:"application/json",description:"Annotation metadata definitions for decorator tooling."}).setCb(async()=>({contents:[{uri:xo,mimeType:"application/json",text:Io}],_meta:{schematic:"metadata"}})),Ao="resource://decoration.schematic.builder",Ro=$e("decoration/builder.json"),Oo=br.builder.setName("decoration.schematic.builder").setTitle("Decoration builder pattern schematic").setDescription("Describes how decorated models spawn builder classes with fluent setters and validation.").setUriOtTemplate(Ao).setConfig({mimeType:"application/json",description:"Builder conventions for decorated models."}).setCb(async()=>({contents:[{uri:Ao,mimeType:"application/json",text:Ro}],_meta:{schematic:"builder"}})),Co="resource://decoration.schematic.validation",Po=$e("decoration/validation.json"),No=br.builder.setName("decoration.schematic.validation").setTitle("Decoration validation schematic").setDescription("Tracks how decorator metadata flows through validation routines and error serialization.").setUriOtTemplate(Co).setConfig({mimeType:"application/json",description:"Validation lifecycle and error contract for decorated models."}).setCb(async()=>({contents:[{uri:Co,mimeType:"application/json",text:Po}],_meta:{schematic:"validation"}})),_o="resource://golden.override.model-builder",Do=$e("golden/model-builder.txt"),Jo=br.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(_o).setConfig({mimeType:"text/plain",description:"Model builder golden snippet for copy/paste reference."}).setCb(async()=>({contents:[{uri:_o,mimeType:"text/plain",text:Do}],_meta:{override:"model-builder"}})),Fo="resource://golden.override.validation-errors",$o=$e("golden/validation-errors.json"),Mo=br.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:$o}],_meta:{override:"validation-errors"}})),Ho="resource://golden.override.xray-step-template",Lo=$e("golden/xray-step-template.txt"),Go=br.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(Ho).setConfig({mimeType:"text/plain",description:"Template for documenting Xray steps."}).setCb(async()=>({contents:[{uri:Ho,mimeType:"text/plain",text:Lo}],_meta:{override:"xray-step-template"}})),qo="resource://jira.ticket.templates",Uo=br.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(qo).setConfig({mimeType:"application/json",description:"Catalog describing the default Jira ticket template resources."}).setCb(async()=>({contents:[{uri:qo,mimeType:"application/json",text:JSON.stringify({defaultType:He.defaultType,templates:Object.fromEntries(Object.entries(Le).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 Wo(e){const t=Le[e];return br.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:We(t.type)}],_meta:{type:t.type}}))}const Ko=[So,Eo,Oo,No,Jo,Mo,Go,Uo,Wo("bug"),Wo("incident"),Wo("release"),Wo("feature"),Wo("test")];async function zo(e){const t=s.for(zo);for(const n of Ko)try{await n.build(e),t.info("Registered resource "+n.getName())}catch(e){t.error("Failed to register resource "+n.getName(),e)}}const Bo=new WeakMap;function Yo(e){if("1"===process.env.MCP_DEBUG_BOOT)try{W("/tmp/mcp-boot.log",`${(new Date).toISOString()} ${e}\n`)}catch{}}class Xo extends a{get client(){const e=Bo.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 at)try{e.info("loading prompt "+t.getName());const n=t.build(this.client);e.verbose(`Loaded prompt ${n.title} from ${t.getName()} definition`)}catch(n){e.error("Failed to load prompt "+t.getName(),n)}try{await yr(this.client),e.verbose("Registered built-in tools")}catch(e){}try{await zo(this.client),e.verbose("Registered built-in resources")}catch(e){}if(this.runtimeOptions.agentMode)try{await go(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&&s.setFactory(te),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 n=((Array.isArray(ht.icons)?ht.icons:[ht.icons])||[]).map(e=>{const t="string"==typeof e?.src?e.src:(e?.src??"")+"",n="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:n,sizes:i}}),i={name:ht.name,title:ht.title,websiteUrl:ht.websiteUrl,version:ht.version,icons:n},r={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}}},o=new G(i,r);switch(((e,t)=>{Bo.set(e,t)})(this,o),o.onerror=e=>{this.log.error("MCP instance onerror",e)},e){case"stdio":e=new Z;break;case"http":e=new Q({sessionIdGenerator:()=>V(),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 I("Invalid transport type: "+e)}var a;try{Yo("before load"),await this.load(),Yo("after load")}catch(e){throw Yo("load failed: "+e),e}if(Yo("before connect"),await this.client.connect(e),Yo("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){}}}const Vo=()=>{const e=je(),t=[S.join(e,"templates"),S.resolve(__dirname,"../../assets/templates"),S.resolve(__dirname,"../assets/templates"),S.resolve(__dirname,"../../../../src/assets/templates")],i=[...new Set(t)];for(const e of i)if(n.existsSync(e))return e;throw Error("Templates directory not found. Searched: "+i.join(", "))};function Zo(e){n.existsSync(e)||n.mkdirSync(e,{recursive:!0})}function Qo(e){if(e.endsWith(".enc")&&n.existsSync(e))return{path:e,encrypted:!0};if(n.existsSync(e))return{path:e,encrypted:!1};const t=e+".enc";return n.existsSync(t)?{path:t,encrypted:!0}:null}function es(e,t,i=!1,r){const o=Qo(e);if(!o)return!1;if(i&&n.existsSync(t))return!1;if(Zo(S.dirname(t)),!o.encrypted&&!r)return n.copyFileSync(o.path,t),!0;const s=o.encrypted?he(n.readFileSync(o.path)).toString("utf-8"):n.readFileSync(o.path,"utf-8"),a=r?r(s):s;return n.writeFileSync(t,a,"utf-8"),!0}function ts(e,t,i=[],r=!1){const o=[];if(!n.existsSync(e))return o;const s=n.readdirSync(e);for(const a of s){if(i.some(e=>a.includes(e)))continue;const s=S.join(e,a);if(n.statSync(s).isDirectory()){const e=S.join(t,a);Zo(e),o.push(...ts(s,e,i,r))}else{const e=a.endsWith(".enc")?a.slice(0,-4):a,n=S.join(t,e);es(s,n,r)&&o.push(n)}}return o}function ns(e,t){return e.replace(/<PROJECT_NAME\s*[-|/]?\s*[^>]*?>/g,t).replace(/\[INSERT PROJECT DESCRIPTION HERE\]/g,t||"Decaf-ts Project")}function is(e){switch(e){case"opencode":return{entryFile:"./.opencode/README.md",workspacePath:".opencode",additionalSetup:["Create .opencode/skills/ directory for agent skills","Configure opencode.json for model selection","Link AGENTS.md to .opencode/README.md"]};case"codex":return{entryFile:"./.codex/config.yaml",workspacePath:".codex",additionalSetup:["Create .codex/agents/ directory for agent definitions","Create .codex/skills/ directory for agent skills","Configure config.yaml for codex provider","Link AGENTS.md to .codex/config.yaml"]};case"claude":return{entryFile:"./.claude.json",workspacePath:".claude",additionalSetup:["Create .claude/projects/ directory for project configs","Create .claude/skills/ directory for agent skills","Configure .claude.json for Claude Code","Link AGENTS.md to .claude.json"]};default:return{entryFile:"./AGENTS.md",workspacePath:"workdocs/ai",additionalSetup:[]}}}function rs(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 os(e,t){return zr(e??(t?"goap":void 0))}async function ss(e){const t=await uo({operation:e.operation,specRef:e.specRef,objective:e.objective,provider:rs(e.provider),modelType:e.modelType?os(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 as(e){"1"===process.env.MCP_DEBUG_BOOT&&process.stderr.write("agent start command invoked\n");const t=rs(e.agentProvider),i=os(e.modelType),r=Fr({workspacePath:e.path,entryFile:e.entryFile}),o=$r(r.workspaceRoot);if(e.execute&&(await ss({operation:"execute",specRef:e.execute,provider:t,modelType:i,workspacePath:r.workspaceRoot,entryFile:e.entryFile})).blocked)return;const s=ke("package.json"),a=JSON.parse(n.readFileSync(s,"utf-8")),c=e.transport??"stdio",p=(new ee).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 Xo;await d.boot(c,{agentMode:!0,workspacePath:r.workspaceRoot,agentProvider:t,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 vs(d)}const cs=new e("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 as({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 t=ke("package.json"),i=JSON.parse(n.readFileSync(t,"utf-8")),r=e.transport??"stdio",o=(new ee).for("mcp-server");if("stdio"!==r)throw Error("Unsupported transport mode: "+r);o.info("Transport stdio"),o.debug("running with options: "+JSON.stringify(e)+" for "+i.name+" version "+i.version);const s=new Xo;await s.boot(r,{workspacePath:e.path,entryFile:e.entryFile}),o.info("Decaf MCP server is now running. Press CTRL+C to stop."),await vs(s)}),ps=new e("md-to-ast").description("pipes markdown to jira ast and writes JSON to stdout").action(async e=>{const t=ke("package.json"),i=JSON.parse(n.readFileSync(t,"utf-8")),r=i.version;s.for("md-to-ast").debug("running with options: "+JSON.stringify(e)+" for "+i.name+" version "+r);const o=Yt(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(o,null,2)+"\n")}),ds=new e("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=Jr({workspacePath:e.path,entryFile:e.entryFile,preserveExisting:!0});process.stdout.write(JSON.stringify(t,null,2)+"\n")}),ls=new e("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 ss({operation:e.operation,specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:os(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),us=new e("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 ss({operation:"manage",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:os(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),ms=new e("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 ss({operation:"plan",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:os(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),hs=new e("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 ss({operation:"review",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:os(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),fs=new e("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 ss({operation:"create-specs",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:os(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),gs=new e("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 ss({operation:"implement",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:os(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),ys=new e("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 ss({operation:"execute",specRef:e,provider:t.agentProvider,modelType:os(t.modelType,t.goap),workspacePath:t.path,entryFile:t.entryFile})}),bs=new e("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(as),ws=new e("agent").description("agent workspace setup and agent-mode execution").addCommand(ds).addCommand(bs).addCommand(ls).addCommand(us).addCommand(ms).addCommand(hs).addCommand(fs).addCommand(gs).addCommand(ys).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 ss({operation:"execute",specRef:e.execute,provider:e.agentProvider,modelType:os(e.modelType,e.goap),workspacePath:e.path||"workdocs/ai",entryFile:e.entryFile||"./AGENTS.md"}):ws.help({error:!1})}),ks=new e("repo:init").description("initialize a repository with decaf-ts agent workspace templates").argument("[targetPath]","path to the repository to initialize",".").option("--name <name>","project name","my-project").option("--orchestration","include ADOS orchestration templates (agents, commands)",!1).option("--skills","copy repository skill templates into the selected agent workspace(s)",!1).option("--agent <agent...>","configure for specific agent(s) (codex|claude|opencode). Use multiple --agent flags for multiple agents.",[]).action(async(e,t)=>{const i=Array.isArray(t.agent)?t.agent:t.agent?[t.agent]:[],r=(e=>{const t={success:!0,filesCreated:[],errors:[],warnings:[]},i=S.resolve(e.targetPath);let r=e.projectName||"my-project";const o=S.join(i,"package.json");if(n.existsSync(o))try{const e=JSON.parse(n.readFileSync(o,"utf-8"));e.name&&(r=e.name)}catch(e){t.warnings.push("Could not read package.json. Using default project name.")}else t.warnings.push(`No package.json found in ${i}. Using default project name.`);try{Zo(i);const o=S.join(i,"workdocs","ai","project"),s=S.join(o,"specifications"),a=S.join(s,"tasks"),c=S.join(o,"commands");Zo(o),Zo(s),Zo(a),Zo(c);const p=[{source:"constitution_template.md",target:S.join(o,"constitution.md")},{source:"plan_template.md",target:S.join(o,"plan.md")},{source:"instructions_template.md",target:S.join(o,"instructions.md")},{source:"specification_template.md",target:S.join(s,"specification_template.md")},{source:"task_template.md",target:S.join(a,"task_template.md")},{source:"commands/startup_command.md",target:S.join(c,"startup_command.md")},{source:"commands/git_commands.md",target:S.join(c,"git_commands.md")},{source:"commands/constitution_commands.md",target:S.join(c,"constitution_commands.md")},{source:"commands/plan_commands.md",target:S.join(c,"plan_commands.md")},{source:"commands/specification_commands.md",target:S.join(c,"specification_commands.md")},{source:"commands/task_commands.md",target:S.join(c,"task_commands.md")},{source:"commands/mode_commands.md",target:S.join(c,"mode_commands.md")}];for(const e of p)es(S.join(Vo(),e.source),e.target,!1,e=>ns(e,r))?t.filesCreated.push(e.target):t.warnings.push("Template not found: "+e.source);if(es(S.join(Vo(),"AGENTS.md"),S.join(i,"AGENTS.md"),!1,e=>ns(e,r))&&t.filesCreated.push(S.join(i,"AGENTS.md")),e.orchestration){const e=S.join(Vo(),"ados"),r=S.join(e,".opencode","agent"),s=S.join(i,".opencode","agent");Zo(s);const a=ts(r,s,[],!0);t.filesCreated.push(...a);const c=S.join(e,".opencode","command"),p=S.join(i,".opencode","command");Zo(p);const d=ts(c,p,[],!0);t.filesCreated.push(...d);const l=S.join(e,".opencode"),u=S.join(i,".opencode");Zo(u);const m=["opencode.jsonc","opencode-github-copilot.jsonc","README.md"];for(const e of m){const i=S.join(l,e),r=S.join(u,e);es(i,r,!0)?t.filesCreated.push(r):Qo(i)&&n.existsSync(r)&&t.warnings.push(`.opencode/${e} already exists, skipping (preserving existing)`)}const h=S.join(e,".ai","agent"),f=S.join(i,".ai","agent");Zo(f);const g=ts(h,f,[],!0);t.filesCreated.push(...g);const y=S.join(e,".ai","rules"),b=S.join(i,".ai","rules");if(n.existsSync(y)){Zo(b);const e=ts(y,b,[],!0);t.filesCreated.push(...e)}const w=S.join(e,"MIGRATION_GUIDE.md"),k=S.join(i,"MIGRATION_GUIDE.md");es(w,k,!0)?t.filesCreated.push(k):Qo(w)&&n.existsSync(k)&&t.warnings.push("MIGRATION_GUIDE.md already exists, skipping (preserving existing)");const v=S.join(e,"doc"),j=S.join(i,"doc");if(n.existsSync(v)){Zo(j);const e=ts(v,j,[],!0);t.filesCreated.push(...e)}const T=S.join(o,"specifications","changes");Zo(T),t.filesCreated.includes(T)||t.filesCreated.push(T);const x=S.join(o,"specifications","planning");Zo(x),t.filesCreated.includes(x)||t.filesCreated.push(x);const I=S.join(o,"specifications","decisions");Zo(I),t.filesCreated.push(I);const E=S.join(i,".gitignore");let A="";n.existsSync(E)&&(A=n.readFileSync(E,"utf-8"));const R=A+"\n# ADOS local state (git-ignored).ai/local/.opencode/local/\n";n.writeFileSync(E,R,"utf-8"),A.includes(".ai/local/")||t.filesCreated.push(E)}const d=(()=>{const t=[];if(e.agent&&t.push(e.agent),e.additionalAgents)for(const n of e.additionalAgents)n&&t.push(n);return t})();e.skills&&!d.length&&t.warnings.push("--skills was requested without --agent; no agent workspace was selected for skill installation");for(const r of d){const o=is(r),s=S.join(i,"AGENTS.md");if(n.existsSync(s)&&r===d[0]){let e=n.readFileSync(s,"utf-8"),t=`\n## Multi-Agent Configuration\n\nThis project is configured for: ${d.join(", ")}\n\n`;for(const e of d){const n=is(e);t+=`### ${e.toUpperCase()}\n`,t+=`- Entry point: \`${n.entryFile}\`\n`,t+=`- Workspace: \`${n.workspacePath}/\`\n`,t+=`- Agents location: \`${n.workspacePath}/agents/\` (if applicable)\n`,t+=`- Skills location: \`${n.workspacePath}/skills/\` (if requested)\n\n`}t+="Run the appropriate entry point to start the agent workflow.\n",e=e.replace(/## Commands:/,t+"\n## Commands:"),n.writeFileSync(s,e,"utf-8")}const a=S.join(i,o.workspacePath);Zo(a);const c=S.join(a,".gitignore");n.existsSync(c)||(n.writeFileSync(c,"*.tmp\n*.log\n*.cache\n","utf-8"),t.filesCreated.push(c));const p=S.join(a,"README.md");n.existsSync(p)||(n.writeFileSync(p,`# ${r.toUpperCase()} Agent Workspace\n\nThis directory contains ${r}-specific configurations and agent definitions.\n\n## Structure\n\n- \`agents/\` - Agent prompt definitions\n- \`commands/\` - Command definitions \n- \`skills/\` - Agent skills and tools\n- \`local/\` - Local state (git-ignored)\n\n## Getting Started\n\n1. Review the main AGENTS.md file in the project root\n2. Configure your ${r} provider settings\n3. Run the bootstrap command to initialize the project\n\n## Commands\n\nSee the main AGENTS.md file for available commands.\n`,"utf-8"),t.filesCreated.push(p));const l=S.join(a,"agents");Zo(l);const u=S.join(l,"README.md");if(n.existsSync(u)||(n.writeFileSync(u,`# Agent Definitions\n\nThis directory contains agent prompt definitions for ${r}.\n\n## Available Agents\n\nCopy agent definitions from \`src/assets/templates/ados/.opencode/agent/\` into this directory as needed.\n\n## Agent Naming Convention\n\nEach agent should be a markdown file named \`<agent-name>.md\`.\n\n## Example\n\n\`pm.md\` - Product Manager agent for orchestrating changes\n`,"utf-8"),t.filesCreated.push(u)),e.skills){const e=S.join(Vo(),"skills"),n=S.join(a,"skills");Zo(n);const i=ts(e,n,[],!0);t.filesCreated.push(...i)}}t.success=0===t.errors.length}catch(e){t.success=!1,t.errors.push(e.message||"Unknown error during initialization")}return t})({targetPath:e||".",projectName:t.name,orchestration:t.orchestration,skills:t.skills,agent:i.length>0?i[0]:void 0,additionalAgents:i.slice(1)});r.success?(process.stdout.write("Repository initialized successfully!\n\n"),process.stdout.write("Files created:\n"),r.filesCreated.forEach(e=>{process.stdout.write(` - ${e}\n`)}),t.orchestration&&(process.stdout.write("\n\ud83d\udce6 ADOS orchestration templates included\n"),process.stdout.write(" See the ADOS README in the generated workspace for details\n")),i.length>0&&(process.stdout.write(`\n\ud83e\udd16 Configured for: ${i.join(", ")}\n`),process.stdout.write(" Check AGENTS.md for agent-specific instructions\n")),t.skills&&process.stdout.write("\n\ud83e\udde0 Skill templates were installed into each selected agent workspace\n"),r.warnings.length>0&&(process.stdout.write("\nWarnings:\n"),r.warnings.forEach(e=>{process.stdout.write(` \u26a0 ${e}\n`)}))):(process.stderr.write("Failed to initialize repository:\n"),r.errors.forEach(e=>{process.stderr.write(` \u2717 ${e}\n`)}),process.exitCode=1)});async function vs(e){const t=["SIGINT","SIGTERM"];await new Promise(n=>{let i=!1;const r=setInterval(()=>{},1e6),o=async()=>{if(!i){i=!0,clearInterval(r);try{const t=e.client;t?.close&&await t.close()}catch{}finally{n()}}};for(const e of t)process.once(e,o)})}(new e).name("decaf-mcp").description("decaf mcp server and agentic functionality").addCommand(cs).addCommand(ws).addCommand(ps).addCommand(ks).parseAsync(process.argv).catch(e=>{process.exit(1)});
|
|
1
|
+
import{Command as e}from"commander";import*as t from"fs";import n,{promises as i}from"fs";import{MiniLogger as r,NumericLogLevels as o,Logging as s,LoggedClass as a,toSnakeCase as c,sf as p,toPascalCase as d,LogLevel as l,LoggedEnvironment as u}from"@decaf-ts/logging";import{required as m,Model as h,list as f,minlength as g}from"@decaf-ts/decorator-validation";import{z as y,ZodObject as b}from"zod";import{injectable as w,inject as k}from"@decaf-ts/injectable-decorators";import{prop as v,Metadata as j}from"@decaf-ts/decoration";import*as T from"path";import S,{resolve as x}from"path";import{InternalError as I,SerializationError as E,ValidationError as A}from"@decaf-ts/db-decorators";import R from"crypto";import O from"zlib";import{fileURLToPath as C}from"url";import{readFile as P}from"fs/promises";import{spawn as N,execFileSync as _}from"node:child_process";import{inspect as D}from"node:util";import{createRequire as J}from"node:module";import{unified as F}from"unified";import $ from"remark-directive";import M from"remark-gfm";import H from"remark-parse";import{ResourceTemplate as L,McpServer as G}from"@modelcontextprotocol/sdk/server/mcp.js";import{UriTemplate as q}from"@modelcontextprotocol/sdk/shared/uriTemplate.js";import U,{appendFileSync as W}from"node:fs";import K from"node:path";import{BehaviourTree as z,State as B}from"mistreevous";import{planner as Y}from"goap-solver";import X from"node:os";import{v4 as V}from"uuid";import{StdioServerTransport as Z}from"@modelcontextprotocol/sdk/server/stdio.js";import{StreamableHTTPServerTransport as Q}from"@modelcontextprotocol/sdk/server/streamableHttp.js";class ee extends r{constructor(e,t,n){super(e,t,n)}log(e,t,n,i){const r=this.config("level");o[r],o[e]}}const te=(e,t,...n)=>{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 ee(i,t)};function ne(e,t,n,i){var r,o=arguments.length,s=3>o?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,i);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(s=(3>o?r(s):o>3?r(t,n,s):r(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s}function ie(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}var re,oe,se,ae,ce;"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"})(re||(re={})),(e=>{e[e.NONE=0]="NONE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(oe||(oe={})),(e=>{e[e.FREE=0]="FREE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(se||(se={}));class pe extends h{get log(){return this._log||(this._log=s.for(this)),this._log}constructor(e){super(e)}logFor(e){const{sessionId:t,requestId:n,authInfo:i}=e||{};let r="string"==typeof t&&t.length>0?this.log.for(t):this.log;return i&&i.clientId&&(r=r.for(i.clientId)),n&&(r=r.for(n.toString())),r}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}}ne([m(),ie("design:type",String)],pe.prototype,"description",void 0),ne([m(),ie("design:type",String)],pe.prototype,"name",void 0),ne([m(),ie("design:type",String)],pe.prototype,"title",void 0);class de extends pe{constructor(e){super(e),this.reasoning=re.NONE,this.effort=oe.NONE,this.cost=se.FREE}setReasoning(e){return this.reasoning=e,this}setEffort(e){return this.effort=e,this}setCost(e){return this.cost=e,this}}function le(e){if(!e)return;let t=e,n=t&&t._def;for(;n&&"ZodObject"!==n.typeName;){if("ZodEffects"===n.typeName&&n.schema)t=n.schema;else if("ZodOptional"===n.typeName&&n.innerType)t=n.innerType;else if("ZodDefault"===n.typeName&&n.innerType)t=n.innerType;else if("ZodNullable"===n.typeName&&n.innerType)t=n.innerType;else{if(!n.schema)return;t=n.schema}n=t&&t._def}return n&&"ZodObject"===n.typeName?n:void 0}function ue(e){return!(!e||"object"!=typeof e||!e._def)}ne([m(),ie("design:type",Number)],de.prototype,"reasoning",void 0),ne([m(),ie("design:type",Number)],de.prototype,"effort",void 0),ne([m(),ie("design:type",Number)],de.prototype,"cost",void 0),(e=>{e.ASSETS="assets"})(ae||(ae={})),(e=>{e.PROMPT="prompts",e.DOCUMENTATION="documentation",e.CODE="code"})(ce||(ce={}));const me=Buffer.from("DCAF1","ascii");function he(e){if(e.length<me.length+16+12+16)throw Error("Invalid prompt payload (too short)");if(!e.subarray(0,me.length).equals(me))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 n=me.length;const i=e.subarray(n,n+16);n+=16;const r=e.subarray(n,n+12);n+=12;const o=e.subarray(n,n+16);n+=16;const s=e.subarray(n),a=((e,t)=>R.scryptSync(e,t,32))(t,i),c=R.createDecipheriv("aes-256-gcm",a,r);c.setAuthTag(o);const p=Buffer.concat([c.update(s),c.final()]);return O.gunzipSync(p)}function fe(e){let t=S.resolve(e);for(;;){if(n.existsSync(S.join(t,"package.json")))return t;const e=S.dirname(t);if(e===t)break;t=e}}const ge=process.argv?.[1]?fe(S.dirname(S.resolve(process.argv[1]))):void 0,ye=(()=>{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 n=t[1];if(n.startsWith("file://"))try{n=C(n)}catch{continue}if(!n.includes("node:internal"))return S.dirname(n)}})(),be=ye?fe(ye):void 0,we=ge??be??process.cwd();function ke(...e){return S.join(we,...e)}function ve(e){let n=e;for(;;){const e=T.join(n,"lib","assets");if(t.existsSync(e))return e;const i=T.join(n,"src","assets");if(t.existsSync(i))return i;const r=T.join(n,"assets");if(t.existsSync(r))return r;const o=T.dirname(n);if(o===n)break;n=o}}function je(){const e=process.env.DECAF_ASSET_DIR||process.env.MCP_ASSET_DIR||process.env.ASSET_DIR||"";if(e&&t.existsSync(e))return e;const n=ve(__dirname);if(n)return n;const i=process.argv?.[1];if(i){const e=ve(T.dirname(i));if(e)return e}const r=[we,process.env.INIT_CWD].filter(Boolean);for(const e of r){const t=ve(e);if(t)return t}return ke("assets")}let Te=class extends a{constructor(e){super(),this.basePath=e||je()}listAssets(...e){const n=T.join(this.basePath,...e);return t.readdirSync(n)}listPrompts(){return this.listAssets(ce.PROMPT)}getAsset(e,n="md",...i){const r=T.join(this.basePath,...i),o=(e,n=!1)=>{try{return n?he(t.readFileSync(e)).toString("utf-8"):t.readFileSync(e,"utf-8")}catch(e){if("ENOENT"===e.code)return null;throw e}},s=o(T.join(r,`${e}.${n}`),"enc"===n);if(null!==s)return s;const a=o(T.join(r,e+".enc"),!0);if(null!==a)return a;throw Error("Asset not found: "+T.join(r,`${e}.${n}`))}getAllAssets(e,...t){return this.listAssets(e,...t).reduce((n,i)=>{const r=T.extname(i),o=T.basename(i,r),s=r.replace(/^\./,"")||void 0;return n[o]=this.getAsset(o,s??void 0,e,...t),n},{})}toPromptDef(e){const t=e=>"number"==typeof e?e:"string"==typeof e?(e=>{switch(e){case"none":return re.NONE;case"basic":return re.BASIC;case"advanced":return re.ADVANCED;case"high":return re.HIGH;case"medium":return oe.MEDIUM;case"low":return se.LOW;case"free":return se.FREE;default:throw new I("Cannon convert unknown level "+e)}})(e.toLowerCase()):re.NONE;return e.effort=t(e.effort),e.reasoning=t(e.reasoning),e.cost=t(e.cost),e}getPrompt(e,...t){const n=this.getAsset(c(e),"json",ce.PROMPT,...t);let i;try{i=JSON.parse(n)}catch(n){throw new E(`Failed to parse prompt ${e} in categories ${t}: ${n}`)}return this.toPromptDef(i)}getAllPrompts(...e){const t=this.getAllAssets(ce.PROMPT,...e);return Object.entries(t).reduce((t,[n,i])=>{try{t[n]=JSON.parse(i)}catch(t){throw new E(`Failed to parse prompt ${n} in categories ${e}: ${t}`)}return t},t)}};Te=ne([w(),ie("design:paramtypes",[String])],Te);class Se extends de{constructor(e){super(e)}setCb(e){return this.cb=e,this}setArgsSchema(e){return this.argsSchema=e,this}static get builder(){return new Se}static patchPrompt(e,t,n,i){const r=(t=Array.isArray(t)?t:Object.keys(t)).filter(e=>!Object.prototype.hasOwnProperty.call(n,e));if(r.length)throw new A("Missing replacements for placeholders: "+r.join(", "));i&&(i.verbose("Patching prompt with placeholders: "+JSON.stringify(t)),i.debug("Values: "+JSON.stringify(n)));const o=t.reduce((e,t)=>(e[t]=n[t],e),{});return p(e,o)}patchPrompt(e,t,n,i){return Se.patchPrompt(e,t,n,i||this.log.for(this.patchPrompt))}build(e,t){const n=this.log.for(this.build),i=this.hasErrors();if(i)throw new A(i.toString());try{this.argsSchema&&((e,t="schema")=>{if(le(e))return e;if(e&&"object"==typeof e){const t=e.def&&"object"==typeof e.def?e.def:void 0,n=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||n){const e={};if(n&&"object"==typeof n)for(const[t,i]of Object.entries(n))e[t]=ue(i)?i:y.any();return y.object(e)}}throw Error(`Registration error: provided a non-canonical ${t}. Export a ZodObject (z.object(...)).`)})(this.argsSchema,"argsSchema");const n=(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=le(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:n},async(e,n)=>{const i=this.logFor(n);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 r=await Promise.resolve(this.cb(e,n));return i.verbose(`Prompt ${this.name} executed successfully.`),i.debug("Prompt execution meta: "+JSON.stringify(r._meta)),r})}catch(e){throw n.error("Failed to register prompt "+(this.name||this.constructor.name),e),e}}}ne([k(Te),ie("design:type",Te)],Se.prototype,"assets",void 0),ne([m(),ie("design:type",Object)],Se.prototype,"cb",void 0),ne([m(),ie("design:type",b)],Se.prototype,"argsSchema",void 0),ne([v(),ie("design:type",Object)],Se.prototype,"placeholders",void 0);class xe extends Se{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);h.fromObject(this,t);const n=new Set((j.properties(xe)||[]).filter(e=>!["assets","promptCategory","prefixes","suffixes"].includes(e)));["cb","argsSchema"].forEach(e=>n.add(e));const i=this.hasErrors(...Array.from(n));if(i)throw new A(i.toString());const r=(this.prefixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),o=(this.suffixes||[]).map(e=>this.assets.getPrompt(e,this.promptCategory)),s=[...new Set([...t.placeholders,...r.map(e=>e.placeholders||[]),...o.map(e=>e.placeholders||[])].flat())].reduce((e,t)=>(e[t]=y.string().describe("The description for "+t),e),{});return this.setArgsSchema(y.object(s)),this.setCb((e,t)=>{const n=this.logFor(t).for(xe).for(this.promptCategory).for(this.name);function i(e=[]){return Array.isArray(e)?e:Object.keys(e)}const r=(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([...r.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([...r.map(e=>e.prompt),s.prompt,...o.map(e=>e.prompt)].join("\n\n"),a,e,n)}}],_meta:{}}}),super.build(e)}setReasoning(e){throw new I("Named prompt builders don't require callback")}setEffort(e){throw new I("Named prompt builders don't require callback")}setCost(e){throw new I("Named prompt builders don't require callback")}setDescription(e){throw new I("Named prompt builders don't require callback")}setTitle(e){throw new I("Named prompt builders don't require callback")}static get builder(){return new xe}}ne([m(),ie("design:type",String)],xe.prototype,"promptCategory",void 0),ne([f(String),g(1),ie("design:type",Array)],xe.prototype,"prefixes",void 0),ne([g(1),f(String),ie("design:type",Array)],xe.prototype,"suffixes",void 0);const Ie=Se.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(y.object({gist:y.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}}}),Ee=Object.assign(Ie,{name:Ie.getName()});var Ae;function Re(e,t=[],n=[]){const i=xe.builder.setCategory(Ae.DOCS).setName(e);return["prefix",...t].forEach(e=>i.addPrefix(e)),["suffix",...n].forEach(e=>i.addSuffix(e)),i}(e=>{e.DOCS="documentation",e.CODE="code"})(Ae||(Ae={}));const Oe=[Re("class"),Re("constant"),Re("decorator"),Re("function"),Re("module"),Re("file"),Re("repo",[],["iterate"])],Ce=y.object({className:y.string().describe("the class name to turn into a builder")}),Pe=Se.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(Ce).setReasoning(re.BASIC).setCb((e,t)=>(e.className=d(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:{}})),Ne=y.object({project:y.string().optional(),issueType:y.string().optional(),summary:y.string().optional(),description:y.string().optional(),assignee:y.string().optional(),fields:y.record(y.string(),y.any()).optional()}),_e=Se.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(Ne).setCb((e,t)=>{const n=e?.project??"<project-key>",i=e?.issueType??"Task",r=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 (${n})\n- issuetype: use the issue type (${i})\n- summary: use the summary (${r})\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": "${n}" },\n "issuetype": { "name": "${i}" },\n "summary": "${r}",\n "description": "${o}"\n }\n}\n`}}],_meta:{}}}),De=T.join(__dirname,"..","assets"),Je=je()||De,Fe=T.join(Je,"resources");function $e(e){const n=T.join(Fe,e);try{return t.readFileSync(n,"utf-8")}catch(e){if("ENOENT"!==e.code)throw e}const i=(e=>{const t=T.extname(e);return t?e.slice(0,-t.length)+".enc":e+".enc"})(n);if(!t.existsSync(i))throw Error("Asset not found: "+e);return he(t.readFileSync(i)).toString("utf-8")}function Me(e){const t=$e(e);return JSON.parse(t)}const He=Me("jira/ticket-templates/catalog.json"),Le=He.templates,Ge=new Map;function qe(e,t){const n=Ke(e);n&&Ge.set(n,t)}for(const e of Object.values(Le))qe(e.type,e),qe(e.name,e),qe(e.uri,e),qe(e.assetPath,e),qe(e.assetPath.replace(/^jira\/ticket-templates\//,""),e),qe(e.assetPath.replace(/\.md$/,""),e);function Ue(e){const t=Ke(e);if(!t)return Le[He.defaultType];const n=Ge.get(t);if(n)return n;throw Error("Unknown Jira ticket template reference: "+e)}function We(e){return $e(Ue(e).assetPath)}function Ke(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 ze=y.object({ticketType:y.enum(["bug","incident","release","feature","test"]).optional(),template_path:y.string().optional(),project:y.string().optional(),projectKey:y.string().optional(),issueType:y.string().optional(),summary:y.string().optional(),description:y.string().optional(),customFields:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional(),fields:y.record(y.string(),y.any()).optional()}).partial();function Be(e){try{return Ue(e)}catch{return}}function Ye(e){const t=(e=>e.template_path?e.template_path:"resource://jira.ticket.template."+(e.ticketType??"bug"))(e),n=Be(t),i=!!n,r=n?.uri??t,o=e.projectKey??e.project??"<project-key>",s=e.issueType??n?.issueType??"<issue-type>",a=e.summary??"<summary>",c=e.description??"<description>",p=i?(e=>{const t=Be(e);return t?(e=>{const t=(e=>e.customFields??[])(Ue(e));return t.length?t.map(e=>{const t=e.required?" (required)":" (optional)",n=e.example?" e.g. "+e.example:"";return`- ${e.key}${t}: ${e.label} \u2014 ${e.description}${n}`}).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(r)}\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 Xe=Se.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(ze).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:Ye(e)}}],_meta:{}})),Ve=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."},Ze=(e,t)=>{const n=e.resources.length?e.resources.join(", "):"none";return[e.description,"","Scenario:\n"+e.scenario,"","Resources: "+n,"\nProvided inputs:",Ve(t),"\nCall specification:",e.callTemplate,"\nGuidance:",(i=e.guidance,i.map((e,t)=>`${t+1}. ${e}`).join("\n"))].join("\n");var i},Qe=[{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:y.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:y.object({project:y.string().optional(),issueType:y.string().optional(),summary:y.string().optional(),description:y.string().optional(),assignee:y.string().optional(),fields:y.record(y.string(),y.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:y.object({issueId:y.string().optional(),issueKey:y.string().optional(),fields:y.array(y.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:y.object({jql:y.string().optional(),filters:y.record(y.string(),y.any()).optional(),limit:y.number().optional(),order:y.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:y.object({issueId:y.string().optional(),fields:y.record(y.string(),y.any()).optional(),comment:y.string().optional(),transition:y.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:y.object({issueId:y.string().optional(),deleteSubtasks:y.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:y.object({issueId:y.string().optional(),transition:y.string().optional(),comment:y.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:y.object({issueId:y.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:y.object({issueId:y.string().optional(),assignee:y.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:y.object({issueId:y.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:y.object({issueId:y.string().optional(),comment:y.string().optional(),visibility:y.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:y.object({issueId:y.string().optional(),page:y.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:y.object({inwardIssue:y.string().optional(),outwardIssue:y.string().optional(),linkType:y.string().optional(),comment:y.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:y.object({linkId:y.string().optional(),linkType:y.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:y.object({linkId:y.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:y.object({issueId:y.string().optional(),filePath:y.string().optional(),comment:y.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:y.object({issueId:y.string().optional(),page:y.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:y.object({issueId:y.string().optional(),attachmentId:y.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:y.object({issueId:y.string().optional(),timeSpent:y.string().optional(),comment:y.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:y.object({markdown:y.string().optional(),context:y.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:y.object({adf:y.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:y.object({testCaseKey:y.string().optional(),step:y.string().optional(),status:y.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:y.object({testCaseKey:y.string().optional(),stepId:y.string().optional(),update:y.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:y.object({testCaseKey:y.string().optional(),stepId:y.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:y.object({testCaseKey:y.string().optional()}).partial(),callTemplate:'{\n "name": "jira-xray-step-list",\n "arguments": {\n "testCaseKey": "<key>"\n }\n}'}].map(e=>Se.builder.setName(e.name).setTitle(e.title).setDescription(e.description).setArgsSchema(e.argsSchema).setCb(async(t={},n)=>({messages:[{role:"user",content:{type:"text",text:Ze(e,t)}}],structuredContent:{tool:e.toolName,args:t},result:{tool:e.toolName,args:t},_meta:{}}))),et=y.object({filePath:y.string().optional(),textType:y.enum(["text","code"]).optional(),context:y.string().optional()}).partial();function tt(e,t){const n=e.textType??"text",i=e.context?.trim()?`Context:\n${e.context.trim()}\n`:"",r=t?.trim()?"Source content:\n"+t.trim():"";return o={filePath:e.filePath??"README.md",textType:n,contextSection:i,contentSection:r},"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 nt=Se.builder.setName("guide-file-summarizer-tool").setTitle("MCP guide: file summarizer").setDescription("Professional prompt for summarizing text and code files with optional context.").setArgsSchema(et).setCb(e=>({messages:[{role:"user",content:{type:"text",text:tt(e)}}],_meta:{}}));function it(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 rt(e){const t=it(e.provider),n=N(t.executable,t.args,{cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:{...process.env,DECAF_AGENT_TOOLING:JSON.stringify(e.toolMetadata??{})}});let i="",r="";n.stdout.on("data",e=>{i+=e.toString()}),n.stderr.on("data",e=>{r+=e.toString()}),n.stdin.write(e.prompt),n.stdin.end();const o=await new Promise((e,t)=>{n.once("error",t),n.once("close",t=>e(t??0))});return{exitCode:o,stdout:i,stderr:r,command:t}}const ot=y.object({filePath:y.string().optional(),textType:y.enum(["text","code"]).optional(),context:y.string().optional()}).partial(),st=x(process.cwd(),"README.md"),at=[nt,Ee,...Oe,Pe,_e,...Qe,Xe],ct="##VERSION##",pt="##PACKAGE##";function dt(){try{let e=process.argv[1]?S.dirname(S.resolve(process.argv[1])):process.cwd();for(;;){const t=S.join(e,"package.json");if(n.existsSync(t))return JSON.parse(n.readFileSync(t,"utf-8"));const i=S.dirname(e);if(i===e)break;e=i}}catch{}return{}}const lt=ct.startsWith("##")?dt().version??"0.0.0":ct,ut=pt.startsWith("##")?dt().name??"unknown":pt;j.registerLibrary(ut,lt);const mt={mcpId:"decaf",name:"decaf-ts mcp server",title:"Decaf-TS MCP Server",description:"Provides precise coding assistance for the decaf-ts framework",version:lt,websiteUrl:"https://decaf-ts.github.io",repositoryUrl:"https://github.com/decaf-ts/mcp-server",license:"AGPL-3.0",workingDir:we,assetDir:je(),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:l.error},ht=u.accumulate(mt);function ft(){const{host:e,email:t,apiKey:n,projectKey:i,issueType:r}=ht.jira;return{host:e?.trim(),email:t?.trim(),apiKey:n?.trim(),projectKey:i?.trim(),issueType:r?.trim(),parentIssue:ht.jira.parentIssue?.trim()}}function gt(){const e=ft();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 yt(e){const t=e.value?((e,t)=>{if(e)return t?"<configured>":e})(e.value,e.sensitive):"not set",n=e.required?"(required)":"(optional)";return`\u2022 ${e.name} ${n}: ${e.description} Current state: ${t}.`}s.setConfig(ht);class bt extends Error{constructor(e){const t=gt(),n=(e=>{const t=gt();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(yt).join("\n")}`})(e);super(n),this.name="MissingJiraEnvironmentError",this.descriptors=t,this.missing=e,"function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,bt)}}const wt=s.for("jira.client"),kt=/(authorization|cookie)/i;function vt(e){if(!e)return;const t=e.baseURL??"",n=e.url??"";return t&&n?`${t.endsWith("/")?t.slice(0,-1):t}/${n.startsWith("/")?n.slice(1):n}`:n||t||void 0}function jt(e){if(void 0!==e){if("string"==typeof e)return e;try{return JSON.stringify(e,null,2)}catch(t){return D(e,{depth:null})}}}function Tt(e){if(!e)return;const t={};return Object.entries(e).forEach(([e,n])=>{t[e]=kt.test(e)&&n?"[REDACTED]":n}),t}const St=(()=>{try{return J(process.cwd())}catch(e){return}})();async function xt(){let e;try{const t=await(async e=>{try{return await import(e)}catch(t){if(!St)throw t;try{return St(e)}catch(e){throw e.cause??=t,e}}})("jira.js"),n=t.default,i=t.Version3Client??n?.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:n,apiKey:i}=(()=>{const e=ft(),t=gt().filter(e=>e.required&&!e.value);if(t.length>0)throw new bt(t);return{host:e.host,email:e.email,apiKey:e.apiKey}})(),r=new e({host:t.startsWith("http://")||t.startsWith("https://")?t:"https://"+t,authentication:{basic:{email:n,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(),n=vt(e);return wt.info("jira.request",{method:t,url:n,headers:Tt(e.headers),params:e.params,data:jt(e.data)}),e},e=>(wt.error("jira.request.error",{message:e.message}),Promise.reject(e))),e.interceptors.response.use(e=>{const t=(e.config?.method??"GET").toString().toUpperCase(),n=vt(e.config);return wt.info("jira.response",{method:t,url:n,status:e.status,headers:Tt(e.headers),data:jt(e.data)}),e},e=>{const t=e.config,n=e.response,i=(t?.method??"GET").toString().toUpperCase(),r=vt(t);return wt.error("jira.response.error",{method:i,url:r,status:n?.status,headers:Tt(n?.headers),data:jt(n?.data),message:e.message}),Promise.reject(e)}))})(r.instance),r}function It(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 D(e,{depth:null})}})(e);return t?[{type:"text",text:t}]:[]}function Et(e={},t=[]){const n=(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:It(n),result:n,structuredContent:n}}const At=y.object({name:y.string().min(1).optional().describe("Optional template name that pre-populates additional fields"),content:y.string().min(1).describe("Markdown template content to apply when constructing the description"),placeholders:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional().describe("Map of placeholder replacements used by the template")}).describe("Template metadata used to adjust the created description"),Rt=y.object({template:At.optional().describe("Optional template settings for this create request"),customFields:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional().describe("Template-specific field values that can be merged into the rendered description")}).describe("Additional template controls available when creating an issue"),Ot=y.union([y.object({fields:y.record(y.string(),y.any()).describe("Full raw field map that gets delivered to Jira")}).merge(Rt).describe("Create argument that supplies every field explicitly"),y.object({summary:y.string().min(1).describe("Title or summary of the new issue"),projectKey:y.string().min(1).describe("Project key where the issue is created"),issueType:y.string().min(1).describe("Type name for the new issue (story, task, etc.)"),description:y.string().optional().describe("Optional textual description for the issue")}).merge(Rt).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 Ct(e,t,n){const i=((e.url??"")+"").match(/^(attachment|jira-attachment):(.+)$/i);if(!i)return null;const r=i[2],o=n.resolveAttachment?.(r);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 Pt(e,t){if(!e)return[];if(!t.enableAtMentions&&!t.enableEmojiShortcodes)return[{type:"text",text:e}];let n=0;const i=[],r=/(^|[^A-Za-z0-9_])@([A-Za-z0-9._-]{1,64})/g,o=/:([a-z0-9_+-]{1,64}):/gi;for(;n<e.length;){const s=_t(t.enableAtMentions?Nt(r,e,n):null,t.enableEmojiShortcodes?Nt(o,e,n):null);if(!s){i.push({type:"text",text:e.slice(n)});break}if(s.index>n&&i.push({type:"text",text:e.slice(n,s.index)}),"mention"===s.kind){const{full:e,groups:r}=s,o=r[0]??"",a=r[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}),n=s.index+e.length;continue}if("emoji"===s.kind){const{full:e,groups:r}=s,o=`:${r[0]}:`,a=t.resolveEmoji?.(o);i.push({type:"emoji",attrs:a?{shortName:a.shortName,text:a.text}:{shortName:o}}),n=s.index+e.length;continue}}return(e=>{const t=[];for(const n of e){const e=t[t.length-1];"text"!==n.type||"text"!==e?.type||e.marks||n.marks?t.push(n):e.text=(e.text??"")+(n.text??"")}return t})(i)}function Nt(e,t,n){e.lastIndex=n;const i=e.exec(t);if(!i)return null;const r=e.source.includes("@")?"mention":"emoji";return{index:i.index,full:i[0],groups:i.slice(1),kind:r}}function _t(e,t){return e?t&&e.index>t.index?t:e:t}function Dt(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 Jt(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 $t(e,t){const n=[];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??"")+"",r=Ht(i.children??[],e),o=Ct(i,0,t);if(o){"inline"===o.type?n.push(o.node):n.push({type:"text",text:r,marks:[{type:"link",attrs:{href:e}}]});continue}if(t.enableSmartCards&&Lt(r,e)){n.push({type:"inlineCard",attrs:{url:e}});continue}n.push({type:"text",text:r,marks:[{type:"link",attrs:{href:e}}]});continue}if("textDirective"===i.type&&"status"===i.name){const e=Dt(i)||"Status",t=Ft(i.attributes?.color)??"neutral";n.push({type:"status",attrs:{text:e,color:t}});continue}if("textDirective"===i.type&&"emoji"===i.name){const e=Gt(i);n.push(qt(e,t));continue}}else n.push({type:"hardBreak"});else n.push({type:"text",text:(i.value??"")+"",marks:[{type:"code"}]});else n.push(...Mt($t(i.children??[],t),{type:"strike"}));else n.push(...Mt($t(i.children??[],t),{type:"em"}));else n.push(...Mt($t(i.children??[],t),{type:"strong"}));else n.push(...Pt((i.value??"")+"",t));return n.filter(e=>!("text"===e.type&&""===(e.text??"")))}function Mt(e,t){return e.map(e=>{if("text"!==e.type)return e;if(e.marks?.some(e=>"code"===e.type))return e;const n=e.marks?[...e.marks,t]:[t];return{...e,marks:n}})}function Ht(e,t){const n=[];for(const t of e??[])"text"===t.type||"inlineCode"===t.type?n.push((t.value??"")+""):"emphasis"!==t.type&&"strong"!==t.type&&"delete"!==t.type||n.push(Ht(t.children??[],""));return n.join("")||t}function Lt(e,t){const n=(e??"").trim(),i=(t??"").trim();return n===i&&/^https?:\/\//i.test(i)}function Gt(e){return(e.children??[]).map(e=>"text"===e.type?(e.value??"")+"":"").join("").trim()||""}function qt(e,t){const n=e.startsWith(":")?e:`:${e}:`,i=t.resolveEmoji?.(n);return i?{type:"emoji",attrs:{shortName:i.shortName,text:i.text}}:{type:"emoji",attrs:{shortName:n}}}function Ut(e){return e?"string"==typeof e?e:"text"===e.type||"inlineCode"===e.type?(e.value??"")+"":Array.isArray(e.children)?e.children.map(Ut).join(""):"":""}function Wt(e,t){if(!e?.type)return null;if((e=>"containerDirective"===e?.type&&"panel"===e?.name)(e))return((e,t)=>{const n=e.attributes??{},i=Jt(n.type)??"info",r="string"==typeof n.title?n.title:void 0,o=(e.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean);return{type:"panel",attrs:{panelType:i,...r?{panelType:i,title:r}:{panelType:i}},content:o.length?o:[{type:"paragraph",content:[]}]}})(e,t);switch(e.type){case"heading":return{type:"heading",attrs:{level:zt(e.depth??1,1,6)},content:$t(e.children??[],t)};case"paragraph":return(e=>{const t=e.children??[];if(1!==t.length)return null;const n=t[0];if("image"!==n?.type)return null;const i=(n.url??"")+"";return i?{type:"mediaSingle",attrs:{layout:"center"},content:[{type:"media",attrs:{type:"external",url:i}}]}:null})(e)||{type:"paragraph",content:$t(e.children??[],t)};case"blockquote":return{type:"blockquote",content:(e.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean)};case"list":return((e,t)=>t.enableTaskLists&&(e.children??[]).some(e=>"boolean"==typeof e.checked)?((e,t)=>{const n=[];let i=0;for(const r of e.children??[]){if("boolean"!=typeof r.checked)continue;i+=1;const e=(r.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean);n.push({type:"taskItem",attrs:{localId:"task-"+i,state:r.checked?"DONE":"TODO"},content:e.length?e:[{type:"paragraph",content:[]}]})}return{type:"taskList",content:n}})(e,t):{type:e.ordered?"orderedList":"bulletList",content:(e.children??[]).map(e=>((e,t)=>{const n=(e.children??[]).map(e=>Wt(e,t)).flat().filter(Boolean);return{type:"listItem",content:n.length?n:[{type:"paragraph",content:[]}]}})(e,t))})(e,t);case"code":{const n=((e,t)=>{const n=(e??"").toString().trim().toLowerCase();return n?t.enableMermaid&&n.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})(n):null})(e.lang,t);return{type:"codeBlock",attrs:{language:n},content:[{type:"text",text:(e.value??"")+""}]}}case"thematicBreak":return{type:"rule"};case"table":return((e,t)=>({type:"table",content:(e.children??[]).map((e,n)=>({type:"tableRow",content:(e.children??[]).map(e=>({type:0===n?"tableHeader":"tableCell",content:[{type:"paragraph",content:$t(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:Dt(e)||"Status",color:t}}]}})(e):"panel"===e.name?((e,t)=>{const n=e.attributes??{},i=Jt(n.type)??"info",r="string"==typeof n.title?n.title:void 0;return{type:"panel",attrs:{panelType:i,...r?{title:r}:{}},content:[{type:"paragraph",content:$t([{type:"text",value:Dt(e)}],t)}]}})(e,t):Kt(e,t);default:return Kt(e,t)}}function Kt(e,t){if("drop"===t.unknownNodeStrategy)return null;const n=Ut(e);return n?{type:"paragraph",content:[{type:"text",text:n}]}:null}function zt(e,t,n){const i=Number.isFinite(e)?Math.trunc(e):t;return Math.max(t,Math.min(n,i))}const Bt={resolveMention:void 0,resolveAttachment:void 0,resolveEmoji:void 0,enableSmartCards:!0,enableMermaid:!0,enableEmojiShortcodes:!0,enableAtMentions:!0,enableTaskLists:!0,unknownNodeStrategy:"text"};function Yt(e,t={}){const n={...Bt,...t},i=e??"",r=F().use(H.default||H).use($.default||$).use(M.default||M),o=r.parse(i),s=r.runSync(o);return Xt(s),((e,t)=>{const n=[];for(const i of e.children??[]){const e=Wt(i,t);e&&(Array.isArray(e)?n.push(...e):n.push(e))}return((e,t)=>{if(!t.enableSmartCards)return e;const n=e.content.map(e=>(e=>{if("paragraph"!==e.type)return e;const t=e.content??[];if(1!==t.length)return e;const n=t[0];if("inlineCard"!==n?.type)return e;const i=n.attrs?.url;return i?[{type:"blockCard",attrs:{url:i}}]:e})(e)).flat();return{...e,content:n}})({version:1,type:"doc",content:n},t)})(s,n)}function Xt(e){if(!e||!Array.isArray(e.children))return;const t=[];for(const n of e.children)"definition"!==n?.type&&("html"!==n?.type?(Xt(n),t.push(n)):t.push({type:"text",value:(n.value??"")+""}));e.children=t}function Vt(e){return{...e,content:Zt(e.content??[])}}function Zt(e){return e.map(e=>(e=>{if("panel"===e.type){const{title:t,...n}=e.attrs??{};return{...e,...Object.keys(n).length?{attrs:n}:{},content:e.content?Zt(e.content):void 0}}return e.content?{...e,content:Zt(e.content)}:{...e}})(e))}const Qt=/\{\{\s*([^}]+)\s*\}\}/g;async function en(e,t){const n=e=>e&&e.trim()?e.trim():void 0,i=((e,t,n)=>{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:n}})(t,n(ht.jira.projectKey),n(ht.jira.issueType));let r,o;try{r=Ot.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)(r))o={...r.fields};else{const e=r;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 n=(i=t.content,r=t.placeholders,i?i.replace(Qt,(e,t)=>{const n=t.trim();if(!n)return"";if(r&&Object.prototype.hasOwnProperty.call(r,n)){const e=r[n];return null==e?"":e+""}return e}):"");var i,r;if(!n.trim())return e;const o=Yt(n),s=(a=e.description)?"object"==typeof a&&"doc"===a.type&&Array.isArray(a.content)?a.content:"string"==typeof a?Yt(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)(r));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 tn={name:"jira-issue-create",inputSchema:Ot,runTool:async(e,t)=>Et(await en(e,t))};class nn extends Error{constructor({code:e,message:t,details:n}){super(t),Object.setPrototypeOf(this,new.target.prototype),this.name="NormalizedJiraError",this.code=e,this.details=n}}const rn=s.for("jira.errors");function on(e){if(!e)return new nn({code:"jira_error",message:"Unknown Jira error",details:{raw:e}});const t=e?.status??e?.statusCode??e?.response?.status??e?.response?.statusCode,n="number"==typeof t?t:Number(t)||void 0,i=e?.response?.data??e?.data??e?.response?.body??e?.body,r=e?.response?.statusText??(n?""+n:void 0),o=e?.response?.headers?Tt(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=n?`Jira API error (${n})`:"Jira API error",c=s.length>0?s.join(" | "):a,p=n?"jira_"+n:e?.code??"jira_error",d=e?.config,l=d?{method:d.method?d.method.toString().toUpperCase():void 0,url:d.url,headers:Tt(d.headers),data:jt(d.data)}:void 0,u={httpStatus:n,body:i,request:l,response:o?{statusText:r,headers:o}:r?{statusText:r}:void 0,raw:e};return rn.error("jira.error",{code:p,message:c,httpStatus:n,statusText:r,responseHeaders:o,request:l,body:jt(i)??i}),new nn({code:p,message:c,details:u})}const sn=y.object({issueId:y.string().min(1).describe("Issue key or ID to delete"),deleteSubtasks:y.boolean().optional().default(!0).describe("Whether to delete the subtasks alongside this issue")}).describe("Arguments used to delete a Jira issue (with optional subtasks)"),an={name:"jira-issue-delete",inputSchema:sn,runTool:async(e,t)=>{try{const n=sn.parse(t),i={issueIdOrKey:n.issueId,deleteSubtasks:n.deleteSubtasks};return await e.issues.deleteIssue(i),Et({success:!0,message:`Issue ${n.issueId} deleted successfully`})}catch(e){throw on(e)}}},cn=y.object({projectKey:y.string().trim().min(1).optional().describe("Project key used to scope the issue search"),issueType:y.string().trim().min(1).optional().describe("Issue type name used to filter the results"),parentIssueId:y.string().trim().min(1).optional().describe("Optional parent issue key/ID to limit results to a subtree"),name:y.string().trim().min(1).optional().describe("Issue summary to match exactly"),reference:y.string().trim().min(1).optional().describe("External reference or custom identifier to filter by"),jql:y.string().trim().min(1).optional().describe("Free-form JQL query to drive the search"),nextPageToken:y.string().trim().min(1).optional().describe("Opaque pagination token returned by Jira enhanced search"),maxResults:y.number().int().min(1).optional().describe("Maximum number of issues to return"),fields:y.array(y.string()).optional().describe("List of issue fields to include in the response"),expand:y.string().optional().describe("Optional expansion clause for the results"),orderBy:y.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 pn(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}const dn={name:"jira-issue-list",inputSchema:cn,runTool:async(e,t)=>{try{const n=cn.parse(t),i=n.maxResults??50;let r=n.jql?.trim();if(r){if(n.orderBy){const e=n.orderBy.trim();e&&(r=/\border\s+by\b/i.test(r)?`${r}, ${e}`:`${r} ORDER BY ${e}`)}}else r=(e=>{const t=[];if(e.projectKey&&t.push(`project = "${pn(e.projectKey)}"`),e.issueType&&t.push(`issuetype = "${pn(e.issueType)}"`),e.parentIssueId&&t.push(`parent = "${pn(e.parentIssueId)}"`),e.name&&t.push(`summary ~ "${pn(e.name)}"`),e.reference){const n=pn(e.reference);t.push(`(key ~ "${n}" OR summary ~ "${n}" OR text ~ "${n}")`)}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 n=t.join(" AND ");if(e.orderBy){const t=e.orderBy.trim();t&&(n=/\border\s+by\b/i.test(n)?`${n}, ${t}`:`${n} ORDER BY ${t}`)}return n})(n);const o={jql:r,nextPageToken:n.nextPageToken,maxResults:i,fields:n.fields,expand:n.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 Et({...a,startAt:a?.startAt??0,maxResults:a?.maxResults??i})}catch(e){throw on(e)}}},ln=y.object({issueId:y.string().min(1).describe("Jira issue key or numeric ID to read"),expand:y.string().optional().describe("Optional expand clause for nested fields or changelog"),fields:y.array(y.string()).optional().describe("Explicit list of issue fields to return"),properties:y.array(y.string()).optional().describe("Specific issue properties to include in the response")}).describe("Arguments required to read a Jira issue"),un={name:"jira-issue-read",inputSchema:ln,runTool:async(e,t)=>{try{const n=ln.parse(t),i={issueIdOrKey:n.issueId,expand:n.expand,fields:n.fields,properties:n.properties};return Et(await e.issues.getIssue(i))}catch(e){throw on(e)}}},mn=y.object({issueId:y.string().min(1).describe("Target issue key or ID to transition"),transitionId:y.union([y.string(),y.number()]).describe("Identifier for the transition to execute"),fields:y.record(y.string(),y.any()).optional().describe("Optional field updates to apply during the transition"),update:y.record(y.string(),y.array(y.object({set:y.any().optional().describe("Set operation for the transition update"),add:y.any().optional().describe("Add operation for the transition update"),remove:y.any().optional().describe("Remove operation for the transition update")}))).optional().describe("Structured update operations to send alongside the transition"),comment:y.string().optional().describe("Optional comment to attach during the transition")}).describe("Inputs needed to transition a Jira issue"),hn={name:"jira-issue-transition",inputSchema:mn,runTool:async(e,t)=>{try{const n=mn.parse(t),i={issueIdOrKey:n.issueId,transition:{id:n.transitionId+""}};if(n.fields&&(i.fields=n.fields),n.update&&(i.update=n.update),await e.issues.doTransition(i),n.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:n.issueId,comment:Yt(n.comment)})}return Et({success:!0,message:"Issue transitioned to "+n.transitionId})}catch(e){throw on(e)}}},fn=y.object({issueId:y.string().min(1).describe("Issue key or ID for which to list transitions"),expand:y.string().optional().describe("Optional expand parameter for the transition response")}).describe("Inputs used to fetch available transitions for an issue"),gn={name:"jira-transition-list",inputSchema:fn,runTool:async(e,t)=>{try{const n=fn.parse(t),i=e.issues;if(!i||"function"!=typeof i.getTransitions)throw Error("Jira transitions API is unavailable on the client");const r={issueIdOrKey:n.issueId,expand:n.expand};return Et(await i.getTransitions(r))}catch(e){throw on(e)}}},yn=y.record(y.string(),y.any()).optional(),bn=y.object({type:y.string().describe("Mark name, such as strong, emphasis, code, or link"),attrs:yn}).describe("Inline formatting or link marks applied to text nodes"),wn=y.object({type:y.literal("text"),text:y.string().describe("Rendered string content for the text node"),marks:y.array(bn).optional()}).describe("Plain text node that carries optional formatting marks"),kn=y.object({type:y.literal("mention"),attrs:y.object({id:y.string().describe("Jira internal identifier for the mention"),text:y.string().describe("Human readable mention text"),userType:y.string().optional(),accessLevel:y.string().optional(),localizedAccessLevel:y.string().optional()}).describe("Metadata describing the mentioned user")}).describe("Represents a user or team mention in a block or inline context"),vn=y.object({type:y.literal("emoji"),attrs:y.object({shortName:y.string().describe("Emoji shortcode such as smiling_face"),id:y.string().optional(),text:y.string().optional()}).describe("Emoji metadata")}).describe("Emoji inline node"),jn=y.object({type:y.literal("inlineCard"),attrs:y.object({url:y.string().url().describe("Target URL that backs the inline card")}).describe("Inline card attributes")}).describe("Inline card that represents a linked resource"),Tn=y.object({type:y.literal("status"),attrs:y.object({text:y.string().describe("Status label text"),color:y.string().describe("Color code applied by Jira"),localId:y.string().optional(),style:y.string().optional()}).describe("Status metadata published by Jira")}).describe("Status node used for Jira workflow or custom fields"),Sn=y.object({type:y.literal("date"),attrs:y.object({representation:y.string().optional(),timestamp:y.number().optional()}).describe("Date metadata, usually RFC3339 or timestamp")}).describe("Date node that embeds a Jira date reference"),xn=y.object({type:y.literal("hardBreak")}).describe("Inline hard break that forces a newline"),In=y.object({type:y.literal("rule")}).describe("Horizontal rule dividing sections of the document");let En,An;const Rn=y.lazy(()=>y.union([wn,kn,vn,jn,Tn,Sn,xn])),On=y.lazy(()=>y.object({type:y.literal("paragraph"),content:y.array(Rn).describe("Inline nodes contained by the paragraph")})),Cn=y.lazy(()=>y.object({type:y.literal("heading"),attrs:y.object({level:y.number().int().min(1).max(6).describe("Heading level, 1-6")}).optional(),content:y.array(Rn).describe("Inline nodes composing the heading")})),Pn=y.lazy(()=>y.object({type:y.literal("listItem"),attrs:y.object({localId:y.string().optional()}).optional(),content:y.array(y.lazy(()=>En)).describe("Block level nodes nested inside the list item")})),Nn=y.lazy(()=>y.object({type:y.literal("bulletList"),content:y.array(Pn).describe("List items within the bullet list")})),_n=y.lazy(()=>y.object({type:y.literal("orderedList"),attrs:y.object({order:y.number().int().min(1).optional()}).optional(),content:y.array(Pn)})),Dn=y.lazy(()=>y.object({type:y.literal("taskItem"),attrs:y.object({localId:y.string().optional(),state:y.enum(["TODO","IN_PROGRESS","DONE"]).optional()}).optional(),content:y.array(y.lazy(()=>En)).describe("Blocks living inside the task item")})),Jn=y.lazy(()=>y.object({type:y.literal("taskList"),content:y.array(Dn).describe("Task items inside the list")})),Fn=y.lazy(()=>y.object({type:y.literal("codeBlock"),attrs:y.object({language:y.string().optional()}).optional(),content:y.array(wn).optional()})),$n=y.lazy(()=>y.object({type:y.literal("panel"),attrs:y.object({panelType:y.enum(["info","note","tip","warning","success"]).optional(),title:y.string().optional()}).optional(),content:y.array(y.lazy(()=>En)).describe("Panels may nest paragraphs, lists, or other blocks")})),Mn=y.lazy(()=>y.object({type:y.literal("blockquote"),content:y.array(y.lazy(()=>En)).describe("Quoted block content")})),Hn=y.lazy(()=>y.object({type:y.literal("blockCard"),attrs:y.object({url:y.string().url().describe("URL for the card")})})),Ln=y.lazy(()=>y.object({type:y.literal("media"),attrs:y.object({id:y.string().describe("Media identifier in Jira storage"),type:y.string().describe("Media type, e.g., file or link"),collection:y.string().optional(),width:y.number().optional(),height:y.number().optional()}).describe("Metadata describing the embedded media")})),Gn=y.lazy(()=>y.object({type:y.literal("mediaSingle"),content:y.array(Ln).describe("Single media block content")})),qn=y.lazy(()=>y.object({type:y.literal("mediaGroup"),content:y.array(Ln).describe("Gallery-style media grouping")})),Un=y.object({type:y.literal("tableCell"),attrs:y.object({colspan:y.number().int().min(1).optional(),rowspan:y.number().int().min(1).optional()}).optional(),content:y.array(y.lazy(()=>En)).describe("Content inside the table cell")}).describe("A regular table cell container"),Wn=y.lazy(()=>Un),Kn=y.lazy(()=>Un.extend({type:y.literal("tableHeader")})),zn=y.lazy(()=>y.object({type:y.literal("tableRow"),content:y.array(y.union([Wn,Kn]))})),Bn=y.lazy(()=>y.object({type:y.literal("table"),content:y.array(zn)})),Yn=y.lazy(()=>y.object({type:y.literal("decisionItem"),attrs:y.object({localId:y.string().optional(),state:y.enum(["DECIDED","DECIDING"]).optional()}).optional(),content:y.array(y.lazy(()=>En))})),Xn=y.lazy(()=>y.object({type:y.literal("decisionList"),content:y.array(Yn)})),Vn=y.lazy(()=>y.object({type:y.string(),attrs:y.record(y.string(),y.any()).optional(),content:y.array(y.lazy(()=>An)).optional(),marks:y.array(bn).optional(),text:y.string().optional()}).describe("Unknown or extended Jira node"));En=y.lazy(()=>y.union([On,Cn,Nn,_n,Pn,Jn,Dn,Fn,$n,Mn,Hn,Gn,qn,Bn,zn,Wn,Kn,Xn,Yn,In,Vn])),An=y.lazy(()=>y.union([En,Rn]));const Zn=y.object({type:y.literal("doc"),version:y.literal(1),content:y.array(En).describe("Top-level block nodes in the document")}).describe("Jira ADF document structure; run jira-md-to-adf when converting markdown"),Qn=y.object({key:y.string().min(1).describe("The key of the issue property"),value:y.any().describe("The value of the issue property")}).describe("Details of issue properties to be add or update."),ei=y.object({description:y.union([y.string(),Zn]).optional().describe("Markdown description or raw Jira ADF document (use jira-md-to-adf if you need raw ADF input)")}).catchall(y.any()).describe("Field map that gets delivered to Jira (labels, components, etc.)"),ti=y.object({issueId:y.string().min(1).describe("Issue key or ID to update"),fields:ei.optional(),update:y.record(y.string(),y.array(y.object({set:y.any().optional().describe("Set operation alongside the update key"),add:y.any().optional().describe("Add operation alongside the update key"),remove:y.any().optional().describe("Remove operation alongside the update key"),edit:y.any().optional().describe("Edit operation alongside the update key")}))).optional().describe("Structured update operations for array/set fields"),properties:y.array(Qn).optional().describe("Property payloads to attach to the issue"),notifyUsers:y.boolean().optional().default(!0).describe("Whether to notify watchers when the issue is updated"),issueTemplateId:y.string().optional().describe("Optional template ID to render issue descriptions"),overrideScreenSecurity:y.boolean().optional().default(!1).describe("Temporarily bypass screen security restrictions"),overrideEditableFlag:y.boolean().optional().default(!1).describe("Temporarily bypass the editable flag on the screen")}).describe("Arguments used to update existing Jira issues"),ni=s.for("jira.rate-limit"),ii=ht.jira.rateLimitRetryDelayMs??3e3;let ri=!1;const oi="jira-issue-update",si=ti,ai={name:oi,inputSchema:si,runTool:async(e,t)=>{try{const n=si.parse(t),i={issueIdOrKey:n.issueId};if(n.fields&&(i.fields=(e=>{const t={...e},n=t.description;if("string"==typeof n){const e=Vt(Yt(n));t.description=Zn.parse(e)}else if(n&&"object"==typeof n){const e=Vt(Zn.parse(n));t.description=e}return t})(n.fields)),n.update&&(i.update=n.update),n.properties||n.issueTemplateId){const e=[...n.properties??[]];n.issueTemplateId&&e.push({key:"issueTemplateId",value:n.issueTemplateId}),i.properties=e}return void 0!==n.notifyUsers&&(i.notifyUsers=n.notifyUsers),void 0!==n.overrideScreenSecurity&&(i.overrideScreenSecurity=n.overrideScreenSecurity),void 0!==n.overrideEditableFlag&&(i.overrideEditableFlag=n.overrideEditableFlag),Et(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 n=(e=>{const t=e?.response?.data??e?.data??e?.response?.body??e,n=[];return"string"==typeof t&&n.push(t),"string"==typeof t?.message&&n.push(t.message),"string"==typeof t?.errorMessage&&n.push(t.errorMessage),Array.isArray(t?.errorMessages)&&n.push(...t.errorMessages.filter(e=>"string"==typeof e)),"string"==typeof t?.details?.message&&n.push(t.details.message),n.join(" ")||""})(e);return/rate\s?limit/i.test(n)})(i))return ri||(ni.warn(`Jira rate limit detected for ${e}; waiting ${ii}ms before retrying.`,{retryDelayMs:ii}),ri=!0),ii>0&&await(n=ii,new Promise(e=>setTimeout(e,n))),t();throw i}var n})(oi,()=>e.issues.editIssue(i)))}catch(e){throw on(e)}}},ci=y.object({markdown:y.string().describe("Markdown source that will be converted into Jira ADF"),options:y.record(y.string(),y.any()).optional().describe("Optional MarkdownToAdfOptions passed to the converter")}).describe("Convert markdown into a sanitized Jira ADF document"),pi={name:"jira-md-to-adf",inputSchema:ci,runTool:async(e,t)=>{const n=ci.parse(t),i=Vt(Yt(n.markdown,n.options));return Et(Zn.parse(i))}},di=y.object({issueId:y.string().min(1).describe("Issue key or ID for the assignment change"),assignee:y.union([y.string().describe("Account ID of the new assignee"),y.object({accountId:y.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"),li={name:"jira-assign-issue",inputSchema:di,runTool:async(e,t)=>{try{const n=di.parse(t);let i=null;"string"==typeof n.assignee?i=n.assignee:"accountId"in n.assignee&&(i=n.assignee.accountId);const r={issueIdOrKey:n.issueId,accountId:i};return await e.issues.assignIssue(r),Et({success:!0,message:"Issue assigned to "+(i??"unassigned")})}catch(e){throw on(e)}}},ui=y.object({issueId:y.string().min(1).describe("Issue key or ID to remove the assignee from")}).describe("Inputs required to unassign a Jira issue"),mi={name:"jira-unassign-issue",inputSchema:ui,runTool:async(e,t)=>{try{const n=ui.parse(t),i={issueIdOrKey:n.issueId,accountId:null};return await e.issues.assignIssue(i),Et({success:!0,message:`Issue ${n.issueId} unassigned successfully`})}catch(e){throw on(e)}}},hi=y.object({issueId:y.string().min(1).describe("The Jira issue key or numeric ID receiving the comment"),body:y.string().min(1).describe("The markdown-compatible text of the comment"),visibility:y.object({type:y.enum(["role","group"]).describe("Visibility type that restricts the comment to a role or group"),value:y.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"),fi={name:"jira-comment-add",inputSchema:hi,runTool:async(e,t)=>{try{const n=hi.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.addComment)throw Error("Jira issueComments API is unavailable on the client");const r={issueIdOrKey:n.issueId,comment:n.body,visibility:n.visibility};return Et(await i.addComment(r))}catch(e){throw on(e)}}},gi=y.object({issueId:y.string().min(1).describe("Issue key or ID whose comments should be retrieved"),start:y.number().optional().default(0).describe("Zero-based index to start pagination from"),maxResults:y.number().optional().default(50).describe("Maximum number of comments to return"),orderBy:y.string().optional().describe("Field name to order the returned comments by"),expand:y.string().optional().describe("Optional expansion clause for the comment response")}).describe("Parameters for fetching comments on a Jira issue"),yi={name:"jira-comment-list",inputSchema:gi,runTool:async(e,t)=>{try{const n=gi.parse(t),i=e.issueComments;if(!i||"function"!=typeof i.getComments)throw Error("Jira issueComments API is unavailable on the client");const r={issueIdOrKey:n.issueId,startAt:n.start,maxResults:n.maxResults,orderBy:n.orderBy,expand:n.expand};return Et(await i.getComments(r))}catch(e){throw on(e)}}},bi=y.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"),wi=y.object({id:y.string().optional().describe("Numeric Jira ID used when referencing an issue"),key:y.string().optional().describe("Human-readable key of the linked issue")}).describe("An issue reference (ID or key) used when building a link payload"),ki=y.object({type:y.enum(["role","group"]).describe("Visibility scope type attached to the comment"),value:y.string().min(1).describe("Name of the role or group granted visibility to the comment")}).describe("Optional visibility settings applied to the comment"),vi=y.object({body:y.string().optional().describe("Markdown text to include as a linked-comment"),visibility:ki.optional().describe("Optional ACL for the comment")}).describe("Optional comment applied at the time the link is created or updated"),ji=y.object({link:y.object({relationship:bi,inwardIssue:wi,outwardIssue:wi,comment:vi.optional()}).describe("Definition of the link that should be created between two issues")}).describe("Arguments required to create a Jira issue link");let Ti=[];function Si(e){return(e||"").trim().toLowerCase()}async function xi(e,t){if(!t)throw Error("Link relationship is required");0===Ti.length&&(Ti=await(async e=>{const t=e?.issueLinkTypes;if(!t||"function"!=typeof t.getIssueLinkTypes)throw Error("Jira issueLinkTypes API is unavailable on the client");const n=await t.getIssueLinkTypes();return n?.issueLinkTypes??[]})(e));const n=Si(t),i=Ti.find(e=>[e.name,e.inward,e.outward].some(e=>Si(e)===n));if(!i)throw Error(`No issue link type matching '${t}' found.`);return i}function Ii(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 Ei(e){if(!e)return;const t={};return e.body&&(t.body=Yt(e.body)),e.visibility&&(t.visibility=e.visibility),Object.keys(t).length>0?t:void 0}const Ai=ji,Ri={name:"jira-link-create",inputSchema:Ai,runTool:async(e,t)=>{try{const n=Ai.parse(t).link,i=Ei(n.comment),r=e.issueLinks;if(!r||"function"!=typeof r.linkIssues)throw Error("Jira issueLinks API is unavailable on the client");const o=await xi(e,n.relationship),s={inwardIssue:Ii(n.inwardIssue),outwardIssue:Ii(n.outwardIssue),type:Oi(o),...i?{comment:i}:{}};return await r.linkIssues(s),Et({success:!0,message:"Issue link created with relationship "+n.relationship})}catch(e){throw on(e)}}};function Oi(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 Ci=y.object({issueId:y.string().min(1).describe("Issue key or ID receiving the attachment"),file:y.string().min(1).describe("Base64 or path to the file contents to upload"),mimeType:y.string().optional().describe("Optional MIME type override for the attachment"),comment:y.string().optional().describe("Optional comment to associate with the attachment")}).describe("Inputs needed to attach a file to a Jira issue"),Pi={name:"jira-attach",inputSchema:Ci,runTool:async(e,t)=>{try{const n=Ci.parse(t),r=S.resolve(n.file);let o=n.file,s="attachment",a=!1;try{await i.access(r),a=!0}catch{o=n.file,s="attachment"}a&&(o=await i.readFile(r),s=S.basename(r));const c=e.issueAttachments;if(!c||"function"!=typeof c.addAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const p={filename:s,file:o,mimeType:n.mimeType},d=await c.addAttachment({issueIdOrKey:n.issueId,attachment:p});if(n.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:n.issueId,comment:Yt(n.comment)})}return Et(d)}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 on(e)}}},Ni=y.object({issueId:y.string().min(1).describe("Issue key or ID whose attachments should be listed")}).describe("Arguments used to fetch attachments for a Jira issue"),_i={name:"jira-attachment-list",inputSchema:Ni,runTool:async(e,t)=>{try{const n=Ni.parse(t),i=e.issues;if(!i||"function"!=typeof i.getIssue)throw Error("Jira issues API is unavailable on the client");const r={issueIdOrKey:n.issueId,fields:["attachment"]},o=await i.getIssue(r);return Et({attachments:Array.isArray(o.fields?.attachment)?o.fields.attachment:[]})}catch(e){throw on(e)}}},Di=y.object({issueId:y.string().min(1).describe("Issue key or ID owning the attachment"),attachmentId:y.string().min(1).describe("ID of the attachment to delete")}).describe("Arguments required to remove an attachment from Jira"),Ji={name:"jira-attachment-delete",inputSchema:Di,runTool:async(e,t)=>{try{const n=Di.parse(t),i=e.issueAttachments;if(!i||"function"!=typeof i.removeAttachment)throw Error("Jira issueAttachments API is unavailable on the client");const r={id:n.attachmentId};return await i.removeAttachment(r),Et({success:!0,message:`Attachment ${n.attachmentId} deleted successfully`})}catch(e){throw on(e)}}},Fi=y.object({issueId:y.string().min(1).describe("Target issue key or ID for the worklog entry"),timeSpent:y.string().min(1).describe('Time spent text (e.g., "1h 30m")'),comment:y.string().optional().describe("Optional worklog comment in markdown"),author:y.object({accountId:y.string().min(1).describe("Account ID of the user logging the work")}).optional().describe("Optional author override for the worklog entry"),startingOn:y.string().optional().describe("Optional timestamp for when the work started (ISO)"),artifact:y.string().optional().describe("Optional identifier linking the worklog to another artifact")}).describe("Arguments required to add a worklog entry to a Jira issue"),$i={name:"jira-worklog-add",inputSchema:Fi,runTool:async(e,t)=>{try{const n=Fi.parse(t),i={timeSpent:n.timeSpent,issueIdOrKey:n.issueId};if(n.comment&&(i.comment=n.comment),n.author&&(i.author=n.author),n.startingOn&&(i.started=n.startingOn),n.artifact){const e=[...i.properties??[]];e.push({key:"artifact",value:n.artifact}),i.properties=e}const r=e.issueWorklogs;if(!r||"function"!=typeof r.addWorklog)throw Error("Jira issueWorklogs API is unavailable on the client");return Et(await r.addWorklog(i))}catch(e){throw on(e)}}},Mi=s.for("jira.xray");class Hi{constructor(){this.clientId=ht.orThrow().xray.apiUser,this.clientSecret=ht.orThrow().xray.apiSecret,this.baseUrl=ht.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 n={query:e,variables:t};Mi.info("xray.graphql.request",{payload:jt(n)});try{const e=await fetch(this.baseUrl+"/api/v2/graphql",{method:"POST",headers:{Authorization:"Bearer "+this.token,"Content-Type":"application/json"},body:JSON.stringify(n)}),t=await e.json();if(Mi.info("xray.graphql.response",{status:e.status,headers:e.headers?.get?e.headers.get("content-type"):void 0,body:jt(t)}),t.errors)throw Mi.error("xray.graphql.errors",{errors:jt(t.errors)}),Error(JSON.stringify(t.errors,null,2));return t.data}catch(e){throw Mi.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 n=(await this.getTest(e)).steps||[],i=[],r=[],o=[];for(let e=0;e<t.length;e++){const o=t[e],s=n[e];s?s.action===o.action&&s.data===o.data&&s.result===o.result||i.push({stepId:s.id,step:o}):r.push(o)}if(n.length>t.length)for(let e=t.length;e<n.length;e++)o.push(n[e].id);await this.addSteps(e,r),await this.updateSteps(i),await this.deleteSteps(o)}}let Li=null;const Gi=new Map;function qi(e){const t=e?.fields,n=e?.action??t?.Action??t?.action;if(!n||"string"!=typeof n)throw Error("Xray step action is required");const i=e.data??e.fields?.Data??e.fields?.data??void 0,r=e.result??e.fields?.Result??e.fields?.result??void 0;return{action:n.toString(),data:"string"==typeof i?i:void 0,result:"string"==typeof r?r:void 0}}async function Ui(e,t){if(!t)throw Error("Issue reference is required when interacting with Xray steps");if(Gi.has(t))return Gi.get(t);if(/^[0-9]+$/.test(t))return Gi.set(t,t),t;const n=e?.issues;if(!n?.getIssue)throw Error("Jira client does not expose issue lookup functionality");const i=await n.getIssue({issueIdOrKey:t,fields:["id"]}),r=i?.id;if(!r)throw Error("Unable to resolve Jira issue ID for "+t);return Gi.set(t,r),r}async function Wi(e){if(e?.test?.step)return e.test.step;const t=await(async()=>{if(Li)return Li;const e=ht.orThrow().xray.apiUser?.trim(),t=ht.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 n=await xt(),i=new Hi,r={async createStep(e,t){const r=await Ui(n,e),o=await i.addStep(r,qi(t));return{step:o,id:o?.id}},async updateStep(e,t,r){await Ui(n,e);const o=qi(r),s=await i.updateStep(t.toString(),o);return{step:s,id:s?.id}},deleteStep:async(e,t)=>(await Ui(n,e),{success:!0===await i.deleteStep(t.toString())}),async getSteps(e){const t=await Ui(n,e),r=await i.getTest(t);return{steps:r?.steps??[]}}};return Li={test:{step:r}},Li})();if(!t?.test?.step)throw Error("Xray step API is unavailable on the client");return t.test.step}const Ki=y.object({issueId:y.string().min(1).describe("Xray test case key or ID that owns the step"),action:y.string().min(1).describe("Action description for the new Xray step"),data:y.string().optional().describe("Optional data or context used by this step"),result:y.string().optional().describe("Optional expected result for the step")}).describe("Inputs for adding a step to an Xray test case"),zi={name:"jira-xray-step-add",inputSchema:Ki,runTool:async(e,t)=>{try{const n=Ki.parse(t),i=await Wi(e),r={action:n.action,data:n.data,result:n.result};return Et(await i.createStep(n.issueId,r))}catch(e){throw on(e)}}},Bi=y.object({issueId:y.string().min(1).describe("Xray test case key or ID that owns the step"),stepId:y.union([y.string(),y.number()]).describe("Identifier for the step that should be updated"),action:y.string().min(1).describe("New action text for the step"),data:y.string().optional().describe("Updated data/context for the step"),result:y.string().optional().describe("Updated expected result for the step")}).describe("Inputs required to modify an Xray test step"),Yi={name:"jira-xray-step-update",inputSchema:Bi,runTool:async(e,t)=>{try{const n=Bi.parse(t),i=await Wi(e),r=n.stepId+"",o={action:n.action,data:n.data,result:n.result};return Et(await i.updateStep(n.issueId,r,o))}catch(e){throw on(e)}}},Xi=y.object({issueId:y.string().min(1).describe("Xray test case key or ID owning the step"),stepId:y.union([y.string(),y.number()]).describe("Identifier of the step to delete")}).describe("Arguments used to remove an Xray test step"),Vi={name:"jira-xray-step-delete",inputSchema:Xi,runTool:async(e,t)=>{try{const n=Xi.parse(t),i=await Wi(e);return await i.deleteStep(n.issueId,n.stepId.toString()),Et({success:!0})}catch(e){throw on(e)}}},Zi=y.object({issueId:y.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"),Qi={name:"jira-xray-step-list",inputSchema:Zi,runTool:async(e,t)=>{try{const n=Zi.parse(t),i=await Wi(e);return Et(await i.getSteps(n.issueId))}catch(e){throw on(e)}}},er=y.object({linkId:y.string().min(1).describe("Identifier for the Jira issue link to remove")}).describe("Inputs required to delete an existing Jira issue link"),tr={name:"jira-link-delete",inputSchema:er,runTool:async(e,t)=>{try{const n=er.parse(t),i=e.issueLinks;if(!i||"function"!=typeof i.deleteIssueLink)throw Error("Jira issueLinks API is unavailable on the client");const r={linkId:n.linkId};return await i.deleteIssueLink(r),Et({success:!0,message:`Issue link ${n.linkId} deleted successfully`})}catch(e){throw on(e)}}},nr=y.object({linkId:y.string().min(1).describe("ID of the existing issue link to change"),relationship:bi,comment:vi.optional().describe("Optional comment to attach while recreating the link")}).describe("Inputs required to update (recreate) a Jira issue link"),ir={name:"jira-link-update",inputSchema:nr,runTool:async(e,t)=>{try{const n=nr.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 r=await i.getIssueLink({linkId:n.linkId});if(!r)throw Error(`Issue link ${n.linkId} not found`);const o=r.inwardIssue,s=r.outwardIssue;if(!o||!s)throw Error("Issue link payload is missing linked issues");const a=await xi(e,n.relationship);await i.deleteIssueLink({linkId:n.linkId});const c=Ei(n.comment),p={inwardIssue:Ii(o),outwardIssue:Ii(s),type:rr(a),...c?{comment:c}:{}};return await i.linkIssues(p),Et({success:!0,message:`Issue link ${n.linkId} updated to ${n.relationship}`})}catch(e){throw on(e)}}};function rr(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 or(e=[]){return e.map(sr).join("")}function sr(e){switch(e.type){case"text":return(e=>{let t=e.text||"";for(const n of e.marks||[])switch(n.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}](${n.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 ar(e){switch(e.type){case"heading":return"#".repeat(e.attrs?.level)+" "+or(e.content);case"paragraph":return or(e.content);case"blockquote":return e.content.map(ar).map(e=>"> "+e).join("\n");case"bulletList":case"orderedList":case"taskList":return(e=>{const t=[];let n=1;for(const i of e.content){let r="- ";"orderedList"===e.type&&(r=n+++". "),"taskList"===e.type&&(r="- "+("DONE"===i.attrs?.state?"[x] ":"[ ] "));const o=i.content.map(ar).join(" ");t.push(r+o)}return t.join("\n")})(e);case"table":return(e=>{const t=e.content||[];return t.length?["| "+t[0].content.map(e=>or(e.content[0].content)).join(" | ")+" |","| "+t[0].content.map(()=>"---").join(" | ")+" |",...t.slice(1).map(e=>e.content.map(e=>or(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(ar).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 cr=y.object({document:Zn.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"),pr={name:"jira-adf-to-markdown",inputSchema:cr,runTool:async(e,t)=>{return Et({markdown:(n=cr.parse(t).document,(e=>{if(!e||"doc"!==e.type)return"";const t=[];for(const n of e.content||[])t.push(ar(n));return t.join("\n\n")})(n))});var n}},dr=y.enum(["bug","incident","release","feature","test"]),lr=y.object({ticketType:dr.optional(),template_path:y.string().min(1).optional(),project:y.string().min(1).optional(),projectKey:y.string().min(1).optional(),issueType:y.string().min(1).optional(),summary:y.string().min(1).optional(),description:y.string().optional(),assignee:y.string().optional(),customFields:y.record(y.string(),y.union([y.string(),y.number(),y.boolean()])).optional(),fields:y.record(y.string(),y.any()).optional(),template:y.object({content:y.string().min(1),placeholders:y.record(y.string(),y.union([y.string(),y.number(),y.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 ur(e){return e&&e.trim()?e.trim():void 0}const mr={name:"jira-ticket-create",inputSchema:lr,runTool:async(e,t)=>Et(await(async(e,t)=>{const n=lr.parse(t),i=n.template_path??n.ticketType,r=(e=>{if(e)try{return Ue(e)}catch{return}})(i),o=n.template?.content??(r?We(i):void 0),s=n.projectKey??n.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 n=e?.projectKey;return"string"==typeof n&&n.trim()?n.trim():void 0})(n.fields)??ur(ht.jira.projectKey)??"",a=n.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 n=e?.issueType;return"string"==typeof n&&n.trim()?n.trim():void 0})(n.fields)??r?.issueType??ur(ht.jira.issueType)??"Task",c=n.summary??(e=>{const t=e?.summary;return"string"==typeof t&&t.trim()?t.trim():void 0})(n.fields)??"",p=o||n.template?{content:o??n.template.content,placeholders:{...n.customFields??{},summary:c,projectKey:s??"",issueType:a,ticketType:r?.type??n.ticketType??"",templatePath:r?.uri??n.template_path??"",templateName:r?.name??"",templateTitle:r?.title??"",...n.template?.placeholders??{}}}:void 0;return await en(e,n.fields?{fields:n.fields,...p?{template:p}:{}}:{summary:c,projectKey:s,issueType:a,...n.description?{description:n.description}:{},...n.assignee?{assignee:n.assignee}:{},...p?{template:p}:{}})})(e,t))},hr={[tn.name]:{title:"Jira Issue Create",description:"Create a Jira issue (optionally applying a markdown template)",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[mr.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}},[un.name]:{title:"Jira Issue Read",description:"Read a Jira issue with expandable fields and properties",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[dn.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}},[ai.name]:{title:"Jira Issue Update",description:"Update a Jira issue using fields, update ops, and property toggles; fields.description accepts either Markdown or raw Jira ADF",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[pi.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}},[pr.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}},[an.name]:{title:"Jira Issue Delete",description:"Delete a Jira issue and optionally remove its subtasks",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[hn.name]:{title:"Jira Issue Transition",description:"Transition a Jira issue while optionally adding a comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[gn.name]:{title:"Jira Transition List",description:"List available transitions for a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[li.name]:{title:"Jira Issue Assign",description:"Assign a Jira issue to a user or account",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[mi.name]:{title:"Jira Issue Unassign",description:"Unassign the current owner from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[fi.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}},[yi.name]:{title:"Jira Comment List",description:"List comments on a Jira issue with pagination support",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Ri.name]:{title:"Jira Link Create",description:"Create an issue link relationship with optional comment",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[ir.name]:{title:"Jira Link Update",description:"Change the relationship type for an existing issue link",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[tr.name]:{title:"Jira Link Delete",description:"Delete an issue link from Jira",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Pi.name]:{title:"Jira Attachment Add",description:"Attach a local file to a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[_i.name]:{title:"Jira Attachment List",description:"List attachments on a Jira issue",annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},[Ji.name]:{title:"Jira Attachment Delete",description:"Delete an attachment from a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[$i.name]:{title:"Jira Worklog Add",description:"Log time spent on a Jira issue",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[zi.name]:{title:"Jira Xray Step Add",description:"Add a step to an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Yi.name]:{title:"Jira Xray Step Update",description:"Update a step on an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0}},[Vi.name]:{title:"Jira Xray Step Delete",description:"Delete a step from an Xray test case",annotations:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},[Qi.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 fr(e){const t=s.for(fr);let n,i=null;try{n=await xt()}catch(e){if(!(e instanceof bt))return void t.warn("Skipping Jira tool registration; unable to create Jira client",{error:e});i=e,t.warn("Registering Jira tools without credentials; each tool will report configuration requirements.",{error:e})}const r=[tn,mr,un,dn,ai,pi,pr,an,hn,gn,li,mi,fi,yi,Ri,ir,tr,Pi,_i,Ji,$i,zi,Yi,Vi,Qi];for(const o of r){const r=hr[o.name];if(r)try{await e.registerTool(o.name,{title:r.title,description:r.description,inputSchema:o.inputSchema,annotations:r.annotations},async e=>{if(!n)throw i??Error("Jira client unavailable because credentials could not be loaded.");return await o.runTool(n,e)}),t.info("Registered Jira tool "+o.name)}catch(e){t.error("Failed to register Jira tool "+o.name,{error:e})}}}async function gr(e){const t=s.for(gr);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:ot.shape,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},async e=>(async e=>{const t=ot.parse(e??{}),n=t?.filePath?x(process.cwd(),t.filePath):st,i=(()=>{const e=(process.env.AGENT_PROVIDER||"codex").toLowerCase();return"claude"===e||"copilot"===e||"codex"===e?e:"codex"})(),r=((e,t)=>{if(t)return t;if(!e)return"text";const n=e.split(".").pop()?.toLowerCase();return n&&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(n)?"code":"text"})(t.filePath,t.textType);try{const e=await P(n,"utf8"),o=await rt({provider:i,prompt:tt({filePath:n,textType:r,context:t.context},e),toolMetadata:{tool:"file-summarizer",filePath:n,textType:r,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 n=(e=>{const t=e.trim();if(t.startsWith("{")&&t.endsWith("}"))return t;const n=t.indexOf("{"),i=t.lastIndexOf("}");return-1!==n&&-1!==i&&i>n?t.slice(n,i+1):void 0})(t);if(!n)return{summary:t};try{const e=JSON.parse(n);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:n,status:"ok",provider:i,textType:r,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:n,status:"error",provider:i,textType:r,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=at.map(e=>e.getName()).sort();return{content:[{type:"text",text:["Name: "+ht.name,"Title: "+ht.title,"Version: "+ht.version,"Prompts: "+(e.join(", ")||"<none>")].join("\n")}]}})})(e)}catch(e){t.error("Failed to register server info tool",e)}try{await fr(e)}catch(e){t.error("Failed to register Jira tools",e)}}class yr extends pe{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 yr}build(e){const t=this.hasErrors();if(t)throw Error(t.toString());try{const t="string"==typeof this.uriOrTemplate&&this.uriOrTemplate.includes("{")?new L(new q(this.uriOrTemplate),{list:void 0}):this.uriOrTemplate,n=Object.assign(this.config,{_meta:{}}),i=async(e,t)=>{const n=this.logFor(t);n.verbose(`Requesting resource ${this.name} from ${e.toString()}`);const i=await Promise.resolve(this.cb(e,t));return n.verbose(`Resource ${this.name} retrieved successfully.`),n.debug("Resource retrieval meta: "+JSON.stringify(i._meta)),i};return e.resource(this.name,t,n,i)}catch(e){throw s.for(this).error("Error registering resource "+this.name,e),e}}}ne([m(),ie("design:type",Object)],yr.prototype,"uriOrTemplate",void 0),ne([m(),ie("design:type",Function)],yr.prototype,"cb",void 0),ne([m(),ie("design:type",Object)],yr.prototype,"config",void 0);const br=K.join("workdocs","ai"),wr=K.join("project"),kr=K.join(wr,"agent"),vr=K.join(kr,"prompts"),jr=K.join(kr,"behaviors"),Tr=je()??ke("src","assets"),Sr=K.join(Tr,"prompts","agent"),xr=K.join(Tr,"resources","agent"),Ir=K.join(Tr,"templates"),Er="catalog.json";function Ar(e){return K.resolve(e||ke(br))}function Rr(e){return K.join(e,wr)}function Or(e){return K.join(e,kr)}function Cr(e){return K.join(e,vr)}function Pr(e){return K.join(e,jr)}function Nr(e="./AGENTS.md"){return K.resolve(process.cwd(),e)}function _r(e){return K.join(Or(e),Er)}function Dr(e={}){const t=Ar(e.workspacePath),n=Rr(t),i=Or(t),r=[];Lr(n),Lr(i),Lr(Cr(t)),Lr(Pr(t)),Hr(K.join(Ir,"AGENTS.md"),Nr(e.entryFile),!1!==e.preserveExisting,r),Hr(K.join(Ir,"instructions_template.md"),K.join(n,"instructions.md"),!1!==e.preserveExisting,r),Hr(K.join(Ir,"constitution_template.md"),K.join(n,"constitution.md"),!1!==e.preserveExisting,r),Hr(K.join(Ir,"plan_template.md"),K.join(n,"plan.md"),!1!==e.preserveExisting,r),Hr(K.join(Ir,"specification_template.md"),K.join(n,"specifications","specification_template.md"),!1!==e.preserveExisting,r),Hr(K.join(Ir,"task_template.md"),K.join(n,"specifications","task_template.md"),!1!==e.preserveExisting,r);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)Hr(K.join(Tr,"prompts",t),K.join(n,"commands",t),!1!==e.preserveExisting,r);const s=Gr(Sr,[".md",".json"]);for(const n of s)Hr(K.join(Sr,n),K.join(Cr(t),n),!1!==e.preserveExisting,r);const a=Gr(xr,[".json"]);for(const n of a)Hr(K.join(xr,n),K.join(Pr(t),n),!1!==e.preserveExisting,r);return Hr(K.join(xr,Er),_r(t),!1!==e.preserveExisting,r),{workspaceRoot:t,projectRoot:n,agentRoot:i,entryFile:Nr(e.entryFile),copiedFiles:r}}function Jr(e={}){const t=Ar(e.workspacePath),n=Or(t),i=_r(t),r=Nr(e.entryFile);return U.existsSync(n)&&U.existsSync(i)?(U.existsSync(r)||(Lr(K.dirname(r)),U.copyFileSync(K.join(Ir,"AGENTS.md"),r)),{workspaceRoot:t,projectRoot:Rr(t),agentRoot:n,entryFile:r,copiedFiles:[]}):Dr({workspacePath:e.workspacePath,entryFile:e.entryFile,preserveExisting:!0})}function Fr(e){return qr(_r(e))||Ur(K.join(xr,Er))}function $r(e,t){return qr(K.join(Pr(e),t.behaviorFile))||Ur(K.join(xr,t.behaviorFile))}function Mr(e,t){const n=K.join(Cr(e),t.promptFile);if(!U.existsSync(n))throw Error("Missing copied agent prompt file: "+n);return U.readFileSync(n,"utf8")}function Hr(e,t,n,i){Lr(K.dirname(t)),n&&U.existsSync(t)||(U.copyFileSync(e,t),i.push(t))}function Lr(e){U.mkdirSync(e,{recursive:!0})}function Gr(e,t){return U.existsSync(e)?U.readdirSync(e,{withFileTypes:!0}).filter(e=>e.isFile()).map(e=>e.name).filter(e=>t.includes(K.extname(e))).sort():[]}function qr(e){if(U.existsSync(e))return Ur(e)}function Ur(e){return JSON.parse(U.readFileSync(e,"utf8"))}const Wr=["prompt","goap","workflow"];function Kr(e){return(e=>{const t=(e+"").toLowerCase();if(Wr.includes(t))return t;if("default"===t)return"prompt";throw Error("Unsupported agent model type: "+e)})(e||process.env.AGENT_MODEL_TYPE||"prompt")}function zr(e){return"goap"===e}function Br(e){return"prompt"===e}class Yr{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 Xr={plan:"architect",review:"reviewer","create-specs":"architect",implement:"implementation",execute:"orchestrator",manage:"manager"};class Vr{constructor(e,t,n={}){this.definition=e,this.options=t,this.blackboard=new Yr,this.modelType=Kr(t.modelType),this.providerCommand=it(this.options.provider),this.behavior=this.createBehaviourHost(n),zr(this.modelType)||(this.tree=new z(e.tree,this.behavior))}get log(){return this._log||(this._log=s.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),zr(this.modelType)?this.runGoap():this.runWorkflow()}report(e,t,n){this.options.onProgress&&this.options.onProgress({agentName:this.definition.name,operation:zr(this.modelType)?"goap":"workflow",specRef:this.options.specRef,taskRef:this.options.specRefs?.[0],status:e,summary:t,progress:n})}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?B.SUCCEEDED:B.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()===B.RUNNING&&50>e&&(this.tree.step(),e+=1,this.emitWorkflowStateProgress(e),this.tree.getState()===B.RUNNING););this.tree.getState()===B.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()===B.SUCCEEDED,n=t?this.definition.name+" completed":this.definition.name+" failed",i=this.blackboard.get("lastActionResult"),r=this.blackboard.get("blocker");return this.report(t?"completed":"blocked",n,t?1:.85),{stage:this.definition.name,ok:t,confidence:Zr(t,r),summary:n,details:i,blocker:r}}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=Y(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 n of e){const i=this.definition.actions.find(e=>e.name===n.name);if(!i)return this.report("blocked","Missing action handler for GOAP action "+n.name),{stage:this.definition.name,ok:!1,confidence:35,summary:this.definition.name+" blocked",blocker:"Missing action handler for GOAP action "+n.name,details:t.join(", ")||void 0};const r=this.executeAction(i);if(t.push(i.name),this.blackboard.set("lastActionResult",r.summary),r.blocker&&this.blackboard.set("blocker",r.blocker),this.notifyActionProgress(i,t.length/e.length,r),!r.ok)return this.report("blocked",r.blocker||"GOAP action failed",t.length/e.length),{stage:this.definition.name,ok:!1,confidence:Zr(!1,r.blocker),summary:this.definition.name+" blocked",blocker:r.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,n){const i=n?.summary??this.blackboard.get("lastActionResult")??e.kind+" handled",r=!1===n?.ok||n?.blocker?"blocked":"completed";this.report(r,`${e.name}: ${i}`,t)}emitWorkflowStateProgress(e){const t=this.tree?.getState();t!==B.RUNNING?t!==B.SUCCEEDED?t===B.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,n,i){return{stage:e,ok:t,confidence:Zr(t,i),summary:n,blocker:i}}}function Zr(e,t){return e?t?55:90:t?35:45}const Qr=new Map;function eo(e,t){return e+"::"+t}class to{constructor(){this.options={},this.behaviours={}}static get builder(){return new to}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??Kr(),t=new Vr(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 n,i,r;return n=this.options.workspaceRoot,i=this.definition.name,r=t,Qr.set(eo(n,i),r),t}}function no(e){const t=Fr(e.workspaceRoot).agents.find(t=>t.name===e.agentName);if(!t)throw Error("Unknown agent: "+e.agentName);const n=(i=e.workspaceRoot,r=e.agentName,Qr.get(eo(i,r)));var i,r;if(n)return n;const o=$r(e.workspaceRoot,t);return to.builder.setDefinition(o).setWorkspaceRoot(e.workspaceRoot).setProvider(e.provider).setModelType(e.modelType??Kr()).setSpecRef(e.specRef??t.name).setSpecRefs(e.specRefs??[]).setObjective(e.objective??o.objective).setProgressHook(e.onProgress).build()}function io(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 ro(e,t,n,i){const r=`${t}\n${n}`.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})(r),s=0===i&&!o;return{stage:e,ok:s,confidence:oo(s,o),summary:s?e+" completed":e+" blocked",details:r||void 0,blocker:o}}function oo(e,t){return e?t?55:90:t?35:45}function so(e,t,n,i,r){const o=K.join(Rr(e),"specifications",t+".md"),s=(e=>{if(!U.existsSync(e))return[];const t=U.readFileSync(e,"utf8");return Array.from(new Set(t.match(/TASK-\d+/g)??[]))})(o),a=`- ${(new Date).toISOString()} ${n}: ${i}${r?" - "+r:""}\n`;ao(o,"Agent Progress",a);for(const t of s)ao(K.join(Rr(e),"specifications","tasks",t+".md"),"Agent Progress",a)}function ao(e,t,n){if(!U.existsSync(e))return;const i=U.readFileSync(e,"utf8"),r="## "+t;i.includes(r)?U.writeFileSync(e,i.replace(RegExp(r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"\\n([\\s\\S]*?)$","m"),`${r}\n${n}$1`)):U.writeFileSync(e,`${i.trimEnd()}\n\n${r}\n${n}`)}async function co(e,t,n,i){if("true"===process.env.JIRA_ENABLED)try{const r=(await xt()).issueComments;if(!r?.addComment)return;await r.addComment({issueIdOrKey:e,comment:Yt(`Agent stage **${t}** ${n.ok?"completed":"blocked"}.\n\n${n.summary}${n.blocker?"\n\nBlocker: "+n.blocker:""}\n\nModel type: ${i}.`)})}catch{}}function po(e){return Xr[e]}async function lo(e){const t=Jr({workspacePath:e.workspacePath,entryFile:e.entryFile}),n=Kr(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=Kr(e.modelType),n=((e,t)=>{const n=U.mkdtempSync(K.join(X.tmpdir(),`decaf-agent-${t.toLowerCase()}-`));try{return _("git",["worktree","add","--detach",n,"HEAD"],{cwd:e,stdio:"pipe"}),{repoRoot:e,path:n,created:!0}}catch{return{repoRoot:e,path:e,created:!1}}})(Jr({workspacePath:e.workspacePath,entryFile:e.entryFile}).workspaceRoot,e.specRef),i=K.join(n.path,"workdocs","ai"),r=[];try{Jr({workspacePath:i,entryFile:e.entryFile});const n=Fr(i),o=["manager","orchestrator","architect","implementation","reviewer","documentation"].map(e=>n.agents.find(t=>t.name===e)).filter(e=>!!e);for(const n of o){const s=$r(i,n);let a,c;if(so(i,e.specRef,n.name,"started"),e.onProgress?.({agentName:n.name,operation:"execute",specRef:e.specRef,status:"started",summary:n.name+" stage started",progress:r.length/o.length}),Br(t)){const r=Mr(i,n);a=await rt({provider:e.provider,prompt:io({specRef:e.specRef,stageName:n.name,definition:s,prompt:r,workspaceRoot:i,agentRoot:Pr(i),promptRoot:Cr(i),projectRoot:Rr(i)}),toolMetadata:{specRef:e.specRef,stage:n.name,modelType:t},cwd:i}).catch(t=>({exitCode:1,stdout:"",stderr:t+"",command:{executable:e.provider,args:[]}})),c=ro(n.name,a.stdout,a.stderr,a.exitCode)}else c=no({workspaceRoot:i,provider:e.provider,modelType:t,specRef:e.specRef,objective:s.objective,agentName:n.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:[n.name]}};if(r.push(c),so(i,e.specRef,n.name,c.ok?"completed":"blocked",c.summary),e.onProgress?.({agentName:n.name,operation:"execute",specRef:e.specRef,status:c.ok?"completed":"blocked",summary:c.summary,progress:r.length/o.length}),await co(e.specRef,n.name,c,t),!c.ok)return{specRef:e.specRef,workspaceRoot:i,provider:e.provider,modelType:t,stages:r,blocked:!0}}return so(i,e.specRef,"documentation","completed","workflow completed"),{specRef:e.specRef,workspaceRoot:i,provider:e.provider,modelType:t,stages:r,blocked:!1}}finally{(e=>{if(e.created){try{_("git",["worktree","remove","--force",e.path],{cwd:e.repoRoot,stdio:"pipe"})}catch{}try{U.rmSync(e.path,{recursive:!0,force:!0})}catch{}}})(n)}})({specRef:e.specRef||e.executeSpec||"SPEC-UNKNOWN",provider:e.provider,modelType:n,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:n,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=Fr(t.workspaceRoot),r=po(e.operation),o=i.agents.find(e=>e.name===r);if(!o)throw Error("Unknown agent for operation: "+e.operation);let s,a;if(Br(n)){const i=$r(t.workspaceRoot,o),c=Mr(t.workspaceRoot,o);e.onProgress?.({agentName:r,operation:e.operation,specRef:e.specRef??e.executeSpec,status:"started",summary:r+" prompt stage started",progress:0}),s=await rt({provider:e.provider,prompt:uo({operation:e.operation,specRef:e.specRef,workspaceRoot:t.workspaceRoot,agentRoot:Pr(t.workspaceRoot),promptRoot:Cr(t.workspaceRoot),projectRoot:Rr(t.workspaceRoot),prompt:c,definition:i}),toolMetadata:{operation:e.operation,specRef:e.specRef,provider:e.provider,modelType:n,workspacePath:t.workspaceRoot},cwd:t.workspaceRoot}).catch(t=>({exitCode:1,stdout:"",stderr:t+"",command:{executable:e.provider,args:[]}})),a=((e,t,n,i)=>{const r=`${t}\n${n}`.trim(),o=mo(r),s=0===i&&!o;return{stage:e,ok:s,confidence:s?90:o?35:45,summary:s?e+" completed":e+" blocked",details:r||void 0,blocker:o}})(o.name,s.stdout,s.stderr,s.exitCode),e.onProgress?.({agentName:r,operation:e.operation,specRef:e.specRef??e.executeSpec,status:a.ok?"completed":"blocked",summary:a.summary,progress:1})}else{const i=$r(t.workspaceRoot,o);a=no({workspaceRoot:t.workspaceRoot,provider:e.provider,modelType:n,specRef:e.specRef??e.executeSpec,objective:e.objective??i.objective,agentName:r,onProgress:e.onProgress}).run(),s={exitCode:0,stdout:JSON.stringify({modelType:n,stage:a,agentName:r},null,2)+"\n",stderr:"",command:{executable:n,args:[e.operation]}}}const c=!1===a.ok||0!==s.exitCode||void 0!==mo(s.stdout+"\n"+s.stderr),p=mo(s.stdout+"\n"+s.stderr)??a.blocker,d={operation:e.operation,agentName:r,provider:e.provider,modelType:n,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,n,i)=>{if("true"===process.env.JIRA_ENABLED)try{const r=(await xt()).issueComments;if(!r?.addComment)return;await r.addComment({issueIdOrKey:e,comment:Yt(`Agent stage **${t}** ${n.ok?"completed":"blocked"}.\n\n${n.summary}${n.blocker?"\n\nBlocker: "+n.blocker:""}\n\nModel type: ${i}.`)})}catch{}})(e.specRef||r,e.operation,a,n),d}function uo(e){const t="agent."+e.operation,n=["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,"",n,"","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 mo(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 ho=["plan","review","create-specs","implement","execute","manage"];async function fo(e,t={}){const n=s.for(fo),i=Jr({workspacePath:t.workspacePath,entryFile:t.entryFile}),r=Fr(i.workspaceRoot),o=["resource://agent.catalog"],a=[],c=[];go(yr.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(r,null,2)}],_meta:{agentMode:!0}})),e,o);for(const{entry:n,definition:s}of(e=>Fr(e).agents.map(t=>({entry:t,definition:$r(e,t)})))(i.workspaceRoot))no({workspaceRoot:i.workspaceRoot,provider:r.defaultProvider,modelType:Kr(t.modelType),agentName:n.name}),go(yr.builder.setName("agent.behavior."+n.name).setTitle(s.title+" behavior").setDescription(`Behavior tree and GOAP metadata for ${s.title}.`).setUriOtTemplate("resource://agent.behavior."+n.name).setConfig({mimeType:"application/json",description:`Behavior tree JSON for ${s.title}.`}).setCb(async()=>{return{contents:[{uri:"resource://agent.behavior."+n.name,mimeType:"application/json",text:JSON.stringify(s,null,2)}],_meta:{source:(e=i.workspaceRoot,t=n.behaviorFile,K.join(Pr(e),t)),agent:n.name}};var e,t}),e,o),go(yr.builder.setName("agent.prompt."+n.name).setTitle(s.title+" prompt").setDescription(`Prompt for ${s.title} loaded from the repo-copied workspace files.`).setUriOtTemplate("resource://agent.prompt."+n.name).setConfig({mimeType:"text/markdown",description:`Prompt text for ${s.title}.`}).setCb(async()=>{return{contents:[{uri:"resource://agent.prompt."+n.name,mimeType:"text/markdown",text:Mr(i.workspaceRoot,n)}],_meta:{source:(e=i.workspaceRoot,t=n.promptFile,K.join(Cr(e),t)),agent:n.name}};var e,t}),e,o),yo(Se.builder.setName("agent-"+n.name).setTitle(s.title+" prompt").setDescription(`Repository-backed prompt for ${s.title}.`).setArgsSchema(y.object({})).setCb(async()=>({messages:[{role:"user",content:{type:"text",text:Mr(i.workspaceRoot,n)}}],_meta:{agent:n.name}})),e,a);const p=y.object({operation:y.enum(ho),specRef:y.string().optional(),objective:y.string().optional(),provider:y.enum(r.providers).optional(),modelType:y.enum(["prompt","goap","workflow"]).optional()}).shape;bo({name:"agent.notify",title:"Agent progress notifier",description:"Emit a progress notification for agent mode tooling.",inputSchema:y.object({agentName:y.string(),operation:y.string(),specRef:y.string().optional(),taskRef:y.string().optional(),status:y.enum(["started","completed","blocked"]),summary:y.string(),confidence:y.number().int().min(1).max(100).optional(),progress:y.number().min(0).max(1).optional()}).shape},e,c,async(e,t)=>{const n={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(n,null,2)+"\nTASK COMPLETE"}],_meta:{confidence:n.confidence,status:n.status}}}),bo({name:"agent.do",title:"Agent dispatcher",description:"Dispatch an agent operation to the appropriate concrete agent.",inputSchema:p},e,c,async(e,n)=>{const o=Kr(e.modelType);return await wo(n,{agentName:po(e.operation),operation:e.operation,specRef:e.specRef,status:"started",summary:"dispatching "+e.operation,progress:0}),ko(await lo({operation:e.operation,provider:e.provider??r.defaultProvider,modelType:o,workspacePath:i.workspaceRoot,entryFile:t.entryFile,specRef:e.specRef,objective:e.objective,onProgress:e=>wo(n,e)}))});for(const n of ho)bo({name:"agent."+n,title:"Agent "+n,description:`Run the ${n} agent workflow via the dispatcher.`,inputSchema:y.object({specRef:y.string().optional(),objective:y.string().optional(),provider:y.enum(r.providers).optional(),modelType:y.enum(["prompt","goap","workflow"]).optional()}).shape},e,c,async(e,o)=>{const s=Kr(e.modelType);return await wo(o,{agentName:po(n),operation:n,specRef:e.specRef,status:"started",summary:"starting "+n,progress:0}),ko(await lo({operation:n,provider:e.provider??r.defaultProvider,modelType:s,workspacePath:i.workspaceRoot,entryFile:t.entryFile,specRef:e.specRef,objective:e.objective,onProgress:e=>wo(o,e)}))});return n.info(`Registered agent-mode assets for ${r.agents.length} agents`),{resourceUris:o,templateNames:[],promptNames:a,toolNames:c}}function go(e,t,n){try{const i=e.getName();e.build(t);const r=i?"resource://"+i:void 0;r&&!n.includes(r)&&n.push(r)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}function yo(e,t,n){try{const i=e.getName();e.build(t),i&&!n.includes(i)&&n.push(i)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}function bo(e,t,n,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),n.push(e.name)}catch(e){if(!(e instanceof Error?e.message:e+"").includes("already registered"))throw e}}async function wo(e,t){if(!e?.sendNotification||void 0===e._meta?.progressToken)return;const n=[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:`${n.join(" ")}: ${t.summary}`}}).catch(()=>{})}function ko(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 vo="resource://repo.metadata",jo=Me("repo-metadata.json"),To=yr.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(vo).setConfig({mimeType:"application/json",description:"Static repository metadata that documents the MCP surface."}).setCb(async()=>{const e=ht.version,t=ht.jira.projectKey??jo.jira?.projectKey??"DECAF",n={...jo,version:e,projectKey:t};return{contents:[{uri:vo,mimeType:"application/json",text:JSON.stringify(n,null,2)}],_meta:{source:"assets/repo-metadata.json"}}}),So="resource://decoration.schematic.metadata",xo=$e("decoration/metadata.json"),Io=yr.builder.setName("decoration.schematic.metadata").setTitle("Decoration metadata schematic").setDescription("Outlines the annotation and field metadata contracts that decorators expose.").setUriOtTemplate(So).setConfig({mimeType:"application/json",description:"Annotation metadata definitions for decorator tooling."}).setCb(async()=>({contents:[{uri:So,mimeType:"application/json",text:xo}],_meta:{schematic:"metadata"}})),Eo="resource://decoration.schematic.builder",Ao=$e("decoration/builder.json"),Ro=yr.builder.setName("decoration.schematic.builder").setTitle("Decoration builder pattern schematic").setDescription("Describes how decorated models spawn builder classes with fluent setters and validation.").setUriOtTemplate(Eo).setConfig({mimeType:"application/json",description:"Builder conventions for decorated models."}).setCb(async()=>({contents:[{uri:Eo,mimeType:"application/json",text:Ao}],_meta:{schematic:"builder"}})),Oo="resource://decoration.schematic.validation",Co=$e("decoration/validation.json"),Po=yr.builder.setName("decoration.schematic.validation").setTitle("Decoration validation schematic").setDescription("Tracks how decorator metadata flows through validation routines and error serialization.").setUriOtTemplate(Oo).setConfig({mimeType:"application/json",description:"Validation lifecycle and error contract for decorated models."}).setCb(async()=>({contents:[{uri:Oo,mimeType:"application/json",text:Co}],_meta:{schematic:"validation"}})),No="resource://golden.override.model-builder",_o=$e("golden/model-builder.txt"),Do=yr.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(No).setConfig({mimeType:"text/plain",description:"Model builder golden snippet for copy/paste reference."}).setCb(async()=>({contents:[{uri:No,mimeType:"text/plain",text:_o}],_meta:{override:"model-builder"}})),Jo="resource://golden.override.validation-errors",Fo=$e("golden/validation-errors.json"),$o=yr.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(Jo).setConfig({mimeType:"application/json",description:"Example validation error payload emitted by decorated models."}).setCb(async()=>({contents:[{uri:Jo,mimeType:"application/json",text:Fo}],_meta:{override:"validation-errors"}})),Mo="resource://golden.override.xray-step-template",Ho=$e("golden/xray-step-template.txt"),Lo=yr.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(Mo).setConfig({mimeType:"text/plain",description:"Template for documenting Xray steps."}).setCb(async()=>({contents:[{uri:Mo,mimeType:"text/plain",text:Ho}],_meta:{override:"xray-step-template"}})),Go="resource://jira.ticket.templates",qo=yr.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(Go).setConfig({mimeType:"application/json",description:"Catalog describing the default Jira ticket template resources."}).setCb(async()=>({contents:[{uri:Go,mimeType:"application/json",text:JSON.stringify({defaultType:He.defaultType,templates:Object.fromEntries(Object.entries(Le).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 Uo(e){const t=Le[e];return yr.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:We(t.type)}],_meta:{type:t.type}}))}const Wo=[To,Io,Ro,Po,Do,$o,Lo,qo,Uo("bug"),Uo("incident"),Uo("release"),Uo("feature"),Uo("test")];async function Ko(e){const t=s.for(Ko);for(const n of Wo)try{await n.build(e),t.info("Registered resource "+n.getName())}catch(e){t.error("Failed to register resource "+n.getName(),e)}}const zo=new WeakMap;function Bo(e){if("1"===process.env.MCP_DEBUG_BOOT)try{W("/tmp/mcp-boot.log",`${(new Date).toISOString()} ${e}\n`)}catch{}}class Yo extends a{get client(){const e=zo.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 at)try{e.info("loading prompt "+t.getName());const n=t.build(this.client);e.verbose(`Loaded prompt ${n.title} from ${t.getName()} definition`)}catch(n){e.error("Failed to load prompt "+t.getName(),n)}try{await gr(this.client),e.verbose("Registered built-in tools")}catch(e){}try{await Ko(this.client),e.verbose("Registered built-in resources")}catch(e){}if(this.runtimeOptions.agentMode)try{await fo(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&&s.setFactory(te),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 n=((Array.isArray(ht.icons)?ht.icons:[ht.icons])||[]).map(e=>{const t="string"==typeof e?.src?e.src:(e?.src??"")+"",n="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:n,sizes:i}}),i={name:ht.name,title:ht.title,websiteUrl:ht.websiteUrl,version:ht.version,icons:n},r={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}}},o=new G(i,r);switch(((e,t)=>{zo.set(e,t)})(this,o),o.onerror=e=>{this.log.error("MCP instance onerror",e)},e){case"stdio":e=new Z;break;case"http":e=new Q({sessionIdGenerator:()=>V(),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 I("Invalid transport type: "+e)}var a;try{Bo("before load"),await this.load(),Bo("after load")}catch(e){throw Bo("load failed: "+e),e}if(Bo("before connect"),await this.client.connect(e),Bo("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){}}}const Xo=()=>{const e=je(),t=[S.join(e,"templates"),S.resolve(__dirname,"../../assets/templates"),S.resolve(__dirname,"../assets/templates"),S.resolve(__dirname,"../../../../src/assets/templates")],i=[...new Set(t)];for(const e of i)if(n.existsSync(e))return e;throw Error("Templates directory not found. Searched: "+i.join(", "))};function Vo(e){n.existsSync(e)||n.mkdirSync(e,{recursive:!0})}function Zo(e){if(e.endsWith(".enc")&&n.existsSync(e))return{path:e,encrypted:!0};if(n.existsSync(e))return{path:e,encrypted:!1};const t=e+".enc";return n.existsSync(t)?{path:t,encrypted:!0}:null}function Qo(e,t,i=!1,r){const o=Zo(e);if(!o)return!1;if(i&&n.existsSync(t))return!1;if(Vo(S.dirname(t)),!o.encrypted&&!r)return n.copyFileSync(o.path,t),!0;const s=o.encrypted?he(n.readFileSync(o.path)).toString("utf-8"):n.readFileSync(o.path,"utf-8"),a=r?r(s):s;return n.writeFileSync(t,a,"utf-8"),!0}function es(e,t,i=[],r=!1){const o=[];if(!n.existsSync(e))return o;const s=n.readdirSync(e);for(const a of s){if(i.some(e=>a.includes(e)))continue;const s=S.join(e,a);if(n.statSync(s).isDirectory()){const e=S.join(t,a);Vo(e),o.push(...es(s,e,i,r))}else{const e=a.endsWith(".enc")?a.slice(0,-4):a,n=S.join(t,e);Qo(s,n,r)&&o.push(n)}}return o}function ts(e,t){return e.replace(/<PROJECT_NAME\s*[-|/]?\s*[^>]*?>/g,t).replace(/\[INSERT PROJECT DESCRIPTION HERE\]/g,t||"Decaf-ts Project")}function ns(e){switch(e){case"opencode":return{entryFile:"./.opencode/README.md",workspacePath:".opencode",additionalSetup:["Create .opencode/skills/ directory for agent skills","Configure opencode.json for model selection","Link AGENTS.md to .opencode/README.md"]};case"codex":return{entryFile:"./.codex/config.yaml",workspacePath:".codex",additionalSetup:["Create .codex/agents/ directory for agent definitions","Create .codex/skills/ directory for agent skills","Configure config.yaml for codex provider","Link AGENTS.md to .codex/config.yaml"]};case"claude":return{entryFile:"./.claude.json",workspacePath:".claude",additionalSetup:["Create .claude/projects/ directory for project configs","Create .claude/skills/ directory for agent skills","Configure .claude.json for Claude Code","Link AGENTS.md to .claude.json"]};default:return{entryFile:"./AGENTS.md",workspacePath:"workdocs/ai",additionalSetup:[]}}}function is(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 rs(e,t){return Kr(e??(t?"goap":void 0))}async function os(e){const t=await lo({operation:e.operation,specRef:e.specRef,objective:e.objective,provider:is(e.provider),modelType:e.modelType?rs(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 ss(e){"1"===process.env.MCP_DEBUG_BOOT&&process.stderr.write("agent start command invoked\n");const t=is(e.agentProvider),i=rs(e.modelType),r=Jr({workspacePath:e.path,entryFile:e.entryFile}),o=Fr(r.workspaceRoot);if(e.execute&&(await os({operation:"execute",specRef:e.execute,provider:t,modelType:i,workspacePath:r.workspaceRoot,entryFile:e.entryFile})).blocked)return;const s=ke("package.json"),a=JSON.parse(n.readFileSync(s,"utf-8")),c=e.transport??"stdio",p=(new ee).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 Yo;await d.boot(c,{agentMode:!0,workspacePath:r.workspaceRoot,agentProvider:t,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 ks(d)}const as=new e("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 ss({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 t=ke("package.json"),i=JSON.parse(n.readFileSync(t,"utf-8")),r=e.transport??"stdio",o=(new ee).for("mcp-server");if("stdio"!==r)throw Error("Unsupported transport mode: "+r);o.info("Transport stdio"),o.debug("running with options: "+JSON.stringify(e)+" for "+i.name+" version "+i.version);const s=new Yo;await s.boot(r,{workspacePath:e.path,entryFile:e.entryFile}),o.info("Decaf MCP server is now running. Press CTRL+C to stop."),await ks(s)}),cs=new e("md-to-ast").description("pipes markdown to jira ast and writes JSON to stdout").action(async e=>{const t=ke("package.json"),i=JSON.parse(n.readFileSync(t,"utf-8")),r=i.version;s.for("md-to-ast").debug("running with options: "+JSON.stringify(e)+" for "+i.name+" version "+r);const o=Yt(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(o,null,2)+"\n")}),ps=new e("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=Dr({workspacePath:e.path,entryFile:e.entryFile,preserveExisting:!0});process.stdout.write(JSON.stringify(t,null,2)+"\n")}),ds=new e("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 os({operation:e.operation,specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:rs(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),ls=new e("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 os({operation:"manage",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:rs(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),us=new e("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 os({operation:"plan",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:rs(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),ms=new e("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 os({operation:"review",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:rs(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),hs=new e("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 os({operation:"create-specs",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:rs(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),fs=new e("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 os({operation:"implement",specRef:e.specRef,objective:e.objective,provider:e.agentProvider,modelType:rs(e.modelType,e.goap),workspacePath:e.path,entryFile:e.entryFile})}),gs=new e("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 os({operation:"execute",specRef:e,provider:t.agentProvider,modelType:rs(t.modelType,t.goap),workspacePath:t.path,entryFile:t.entryFile})}),ys=new e("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(ss),bs=new e("agent").description("agent workspace setup and agent-mode execution").addCommand(ps).addCommand(ys).addCommand(ds).addCommand(ls).addCommand(us).addCommand(ms).addCommand(hs).addCommand(fs).addCommand(gs).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 os({operation:"execute",specRef:e.execute,provider:e.agentProvider,modelType:rs(e.modelType,e.goap),workspacePath:e.path||"workdocs/ai",entryFile:e.entryFile||"./AGENTS.md"}):bs.help({error:!1})}),ws=new e("repo:init").description("initialize a repository with decaf-ts agent workspace templates").argument("[targetPath]","path to the repository to initialize",".").option("--name <name>","project name","my-project").option("--orchestration","include ADOS orchestration templates (agents, commands)",!1).option("--skills","copy repository skill templates into the selected agent workspace(s)",!1).option("--agent <agent...>","configure for specific agent(s) (codex|claude|opencode). Use multiple --agent flags for multiple agents.",[]).action(async(e,t)=>{const i=Array.isArray(t.agent)?t.agent:t.agent?[t.agent]:[],r=(e=>{const t={success:!0,filesCreated:[],errors:[],warnings:[]},i=S.resolve(e.targetPath);let r=e.projectName||"my-project";const o=S.join(i,"package.json");if(n.existsSync(o))try{const e=JSON.parse(n.readFileSync(o,"utf-8"));e.name&&(r=e.name)}catch(e){t.warnings.push("Could not read package.json. Using default project name.")}else t.warnings.push(`No package.json found in ${i}. Using default project name.`);try{Vo(i);const o=S.join(i,"workdocs","ai","project"),s=S.join(o,"specifications"),a=S.join(s,"tasks"),c=S.join(o,"commands");Vo(o),Vo(s),Vo(a),Vo(c);const p=[{source:"constitution_template.md",target:S.join(o,"constitution.md")},{source:"plan_template.md",target:S.join(o,"plan.md")},{source:"instructions_template.md",target:S.join(o,"instructions.md")},{source:"specification_template.md",target:S.join(s,"specification_template.md")},{source:"task_template.md",target:S.join(a,"task_template.md")},{source:"commands/startup_command.md",target:S.join(c,"startup_command.md")},{source:"commands/git_commands.md",target:S.join(c,"git_commands.md")},{source:"commands/constitution_commands.md",target:S.join(c,"constitution_commands.md")},{source:"commands/plan_commands.md",target:S.join(c,"plan_commands.md")},{source:"commands/specification_commands.md",target:S.join(c,"specification_commands.md")},{source:"commands/task_commands.md",target:S.join(c,"task_commands.md")},{source:"commands/mode_commands.md",target:S.join(c,"mode_commands.md")}];for(const e of p)Qo(S.join(Xo(),e.source),e.target,!1,e=>ts(e,r))?t.filesCreated.push(e.target):t.warnings.push("Template not found: "+e.source);if(Qo(S.join(Xo(),"AGENTS.md"),S.join(i,"AGENTS.md"),!1,e=>ts(e,r))&&t.filesCreated.push(S.join(i,"AGENTS.md")),e.orchestration){const e=S.join(Xo(),"ados"),r=S.join(e,".opencode","agent"),s=S.join(i,".opencode","agent");Vo(s);const a=es(r,s,[],!0);t.filesCreated.push(...a);const c=S.join(e,".opencode","command"),p=S.join(i,".opencode","command");Vo(p);const d=es(c,p,[],!0);t.filesCreated.push(...d);const l=S.join(e,".opencode"),u=S.join(i,".opencode");Vo(u);const m=["opencode.jsonc","opencode-github-copilot.jsonc","README.md"];for(const e of m){const i=S.join(l,e),r=S.join(u,e);Qo(i,r,!0)?t.filesCreated.push(r):Zo(i)&&n.existsSync(r)&&t.warnings.push(`.opencode/${e} already exists, skipping (preserving existing)`)}const h=S.join(e,".ai","agent"),f=S.join(i,".ai","agent");Vo(f);const g=es(h,f,[],!0);t.filesCreated.push(...g);const y=S.join(e,".ai","rules"),b=S.join(i,".ai","rules");if(n.existsSync(y)){Vo(b);const e=es(y,b,[],!0);t.filesCreated.push(...e)}const w=S.join(e,"MIGRATION_GUIDE.md"),k=S.join(i,"MIGRATION_GUIDE.md");Qo(w,k,!0)?t.filesCreated.push(k):Zo(w)&&n.existsSync(k)&&t.warnings.push("MIGRATION_GUIDE.md already exists, skipping (preserving existing)");const v=S.join(e,"doc"),j=S.join(i,"doc");if(n.existsSync(v)){Vo(j);const e=es(v,j,[],!0);t.filesCreated.push(...e)}const T=S.join(o,"specifications","changes");Vo(T),t.filesCreated.includes(T)||t.filesCreated.push(T);const x=S.join(o,"specifications","planning");Vo(x),t.filesCreated.includes(x)||t.filesCreated.push(x);const I=S.join(o,"specifications","decisions");Vo(I),t.filesCreated.push(I);const E=S.join(i,".gitignore");let A="";n.existsSync(E)&&(A=n.readFileSync(E,"utf-8"));const R=A+"\n# ADOS local state (git-ignored).ai/local/.opencode/local/\n";n.writeFileSync(E,R,"utf-8"),A.includes(".ai/local/")||t.filesCreated.push(E)}const d=(()=>{const t=[];if(e.agent&&t.push(e.agent),e.additionalAgents)for(const n of e.additionalAgents)n&&t.push(n);return t})();e.skills&&!d.length&&t.warnings.push("--skills was requested without --agent; no agent workspace was selected for skill installation");for(const r of d){const o=ns(r),s=S.join(i,"AGENTS.md");if(n.existsSync(s)&&r===d[0]){let e=n.readFileSync(s,"utf-8"),t=`\n## Multi-Agent Configuration\n\nThis project is configured for: ${d.join(", ")}\n\n`;for(const e of d){const n=ns(e);t+=`### ${e.toUpperCase()}\n`,t+=`- Entry point: \`${n.entryFile}\`\n`,t+=`- Workspace: \`${n.workspacePath}/\`\n`,t+=`- Agents location: \`${n.workspacePath}/agents/\` (if applicable)\n`,t+=`- Skills location: \`${n.workspacePath}/skills/\` (if requested)\n\n`}t+="Run the appropriate entry point to start the agent workflow.\n",e=e.replace(/## Commands:/,t+"\n## Commands:"),n.writeFileSync(s,e,"utf-8")}const a=S.join(i,o.workspacePath);Vo(a);const c=S.join(a,".gitignore");n.existsSync(c)||(n.writeFileSync(c,"*.tmp\n*.log\n*.cache\n","utf-8"),t.filesCreated.push(c));const p=S.join(a,"README.md");n.existsSync(p)||(n.writeFileSync(p,`# ${r.toUpperCase()} Agent Workspace\n\nThis directory contains ${r}-specific configurations and agent definitions.\n\n## Structure\n\n- \`agents/\` - Agent prompt definitions\n- \`commands/\` - Command definitions \n- \`skills/\` - Agent skills and tools\n- \`local/\` - Local state (git-ignored)\n\n## Getting Started\n\n1. Review the main AGENTS.md file in the project root\n2. Configure your ${r} provider settings\n3. Run the bootstrap command to initialize the project\n\n## Commands\n\nSee the main AGENTS.md file for available commands.\n`,"utf-8"),t.filesCreated.push(p));const l=S.join(a,"agents");Vo(l);const u=S.join(l,"README.md");if(n.existsSync(u)||(n.writeFileSync(u,`# Agent Definitions\n\nThis directory contains agent prompt definitions for ${r}.\n\n## Available Agents\n\nCopy agent definitions from \`src/assets/templates/ados/.opencode/agent/\` into this directory as needed.\n\n## Agent Naming Convention\n\nEach agent should be a markdown file named \`<agent-name>.md\`.\n\n## Example\n\n\`pm.md\` - Product Manager agent for orchestrating changes\n`,"utf-8"),t.filesCreated.push(u)),e.skills){const e=S.join(Xo(),"skills"),n=S.join(a,"skills");Vo(n);const i=es(e,n,[],!0);t.filesCreated.push(...i)}}t.success=0===t.errors.length}catch(e){t.success=!1,t.errors.push(e.message||"Unknown error during initialization")}return t})({targetPath:e||".",projectName:t.name,orchestration:t.orchestration,skills:t.skills,agent:i.length>0?i[0]:void 0,additionalAgents:i.slice(1)});r.success?(process.stdout.write("Repository initialized successfully!\n\n"),process.stdout.write("Files created:\n"),r.filesCreated.forEach(e=>{process.stdout.write(` - ${e}\n`)}),t.orchestration&&(process.stdout.write("\n\ud83d\udce6 ADOS orchestration templates included\n"),process.stdout.write(" See the ADOS README in the generated workspace for details\n")),i.length>0&&(process.stdout.write(`\n\ud83e\udd16 Configured for: ${i.join(", ")}\n`),process.stdout.write(" Check AGENTS.md for agent-specific instructions\n")),t.skills&&process.stdout.write("\n\ud83e\udde0 Skill templates were installed into each selected agent workspace\n"),r.warnings.length>0&&(process.stdout.write("\nWarnings:\n"),r.warnings.forEach(e=>{process.stdout.write(` \u26a0 ${e}\n`)}))):(process.stderr.write("Failed to initialize repository:\n"),r.errors.forEach(e=>{process.stderr.write(` \u2717 ${e}\n`)}),process.exitCode=1)});async function ks(e){const t=["SIGINT","SIGTERM"];await new Promise(n=>{let i=!1;const r=setInterval(()=>{},1e6),o=async()=>{if(!i){i=!0,clearInterval(r);try{const t=e.client;t?.close&&await t.close()}catch{}finally{n()}}};for(const e of t)process.once(e,o)})}(new e).name("decaf-mcp").description("decaf mcp server and agentic functionality").addCommand(as).addCommand(bs).addCommand(cs).addCommand(ws).parseAsync(process.argv).catch(e=>{process.exit(1)});
|
|
2
2
|
//# sourceMappingURL=mcp-server.js.map
|