@neobiotechlabs/neobiotech-dev-agent 0.1.15 → 0.1.16

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/index.js CHANGED
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
+ import { fileURLToPath as __f2p } from "node:url";
4
+ import { dirname as __dn } from "node:path";
3
5
  const require = createRequire(import.meta.url);
6
+ const __filename = __f2p(import.meta.url);
7
+ const __dirname = __dn(__filename);
4
8
  var __create = Object.create;
5
9
  var __defProp = Object.defineProperty;
6
10
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -3236,8 +3240,8 @@ var require_utils = __commonJS({
3236
3240
  }
3237
3241
  return ind;
3238
3242
  }
3239
- function removeDotSegments(path2) {
3240
- let input = path2;
3243
+ function removeDotSegments(path3) {
3244
+ let input = path3;
3241
3245
  const output = [];
3242
3246
  let nextSlash = -1;
3243
3247
  let len = 0;
@@ -3489,8 +3493,8 @@ var require_schemes = __commonJS({
3489
3493
  wsComponent.secure = void 0;
3490
3494
  }
3491
3495
  if (wsComponent.resourceName) {
3492
- const [path2, query] = wsComponent.resourceName.split("?");
3493
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
3496
+ const [path3, query] = wsComponent.resourceName.split("?");
3497
+ wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
3494
3498
  wsComponent.query = query;
3495
3499
  wsComponent.resourceName = void 0;
3496
3500
  }
@@ -14950,8 +14954,8 @@ var init_jira_client = __esm({
14950
14954
  "Authorization": this.authHeader
14951
14955
  };
14952
14956
  }
14953
- async request(path2, options = {}) {
14954
- const resp = await fetch(`${this.baseUrl}/rest/api/3${path2}`, {
14957
+ async request(path3, options = {}) {
14958
+ const resp = await fetch(`${this.baseUrl}/rest/api/3${path3}`, {
14955
14959
  method: options.method || "GET",
14956
14960
  headers: this.headers(),
14957
14961
  body: options.body ? JSON.stringify(options.body) : void 0
@@ -15441,25 +15445,25 @@ var require_utils2 = __commonJS({
15441
15445
  }
15442
15446
  mkdirSync2(folder);
15443
15447
  };
15444
- Utils.prototype.writeFileTo = function(path2, content, overwrite, attr) {
15448
+ Utils.prototype.writeFileTo = function(path3, content, overwrite, attr) {
15445
15449
  const self2 = this;
15446
- if (self2.fs.existsSync(path2)) {
15450
+ if (self2.fs.existsSync(path3)) {
15447
15451
  if (!overwrite) return false;
15448
- var stat2 = self2.fs.statSync(path2);
15452
+ var stat2 = self2.fs.statSync(path3);
15449
15453
  if (stat2.isDirectory()) {
15450
15454
  return false;
15451
15455
  }
15452
15456
  }
15453
- var folder = pth.dirname(path2);
15457
+ var folder = pth.dirname(path3);
15454
15458
  if (!self2.fs.existsSync(folder)) {
15455
15459
  self2.makeDir(folder);
15456
15460
  }
15457
15461
  var fd;
15458
15462
  try {
15459
- fd = self2.fs.openSync(path2, "w", 438);
15463
+ fd = self2.fs.openSync(path3, "w", 438);
15460
15464
  } catch (e2) {
15461
- self2.fs.chmodSync(path2, 438);
15462
- fd = self2.fs.openSync(path2, "w", 438);
15465
+ self2.fs.chmodSync(path3, 438);
15466
+ fd = self2.fs.openSync(path3, "w", 438);
15463
15467
  }
15464
15468
  if (fd) {
15465
15469
  try {
@@ -15468,31 +15472,31 @@ var require_utils2 = __commonJS({
15468
15472
  self2.fs.closeSync(fd);
15469
15473
  }
15470
15474
  }
15471
- self2.fs.chmodSync(path2, attr || 438);
15475
+ self2.fs.chmodSync(path3, attr || 438);
15472
15476
  return true;
15473
15477
  };
15474
- Utils.prototype.writeFileToAsync = function(path2, content, overwrite, attr, callback) {
15478
+ Utils.prototype.writeFileToAsync = function(path3, content, overwrite, attr, callback) {
15475
15479
  if (typeof attr === "function") {
15476
15480
  callback = attr;
15477
15481
  attr = void 0;
15478
15482
  }
15479
15483
  const self2 = this;
15480
- self2.fs.exists(path2, function(exist) {
15484
+ self2.fs.exists(path3, function(exist) {
15481
15485
  if (exist && !overwrite) return callback(false);
15482
- self2.fs.stat(path2, function(err, stat2) {
15486
+ self2.fs.stat(path3, function(err, stat2) {
15483
15487
  if (exist && stat2.isDirectory()) {
15484
15488
  return callback(false);
15485
15489
  }
15486
- var folder = pth.dirname(path2);
15490
+ var folder = pth.dirname(path3);
15487
15491
  self2.fs.exists(folder, function(exists) {
15488
15492
  if (!exists) self2.makeDir(folder);
15489
- self2.fs.open(path2, "w", 438, function(err2, fd) {
15493
+ self2.fs.open(path3, "w", 438, function(err2, fd) {
15490
15494
  if (err2) {
15491
- self2.fs.chmod(path2, 438, function() {
15492
- self2.fs.open(path2, "w", 438, function(err3, fd2) {
15495
+ self2.fs.chmod(path3, 438, function() {
15496
+ self2.fs.open(path3, "w", 438, function(err3, fd2) {
15493
15497
  self2.fs.write(fd2, content, 0, content.length, 0, function() {
15494
15498
  self2.fs.close(fd2, function() {
15495
- self2.fs.chmod(path2, attr || 438, function() {
15499
+ self2.fs.chmod(path3, attr || 438, function() {
15496
15500
  callback(true);
15497
15501
  });
15498
15502
  });
@@ -15502,13 +15506,13 @@ var require_utils2 = __commonJS({
15502
15506
  } else if (fd) {
15503
15507
  self2.fs.write(fd, content, 0, content.length, 0, function() {
15504
15508
  self2.fs.close(fd, function() {
15505
- self2.fs.chmod(path2, attr || 438, function() {
15509
+ self2.fs.chmod(path3, attr || 438, function() {
15506
15510
  callback(true);
15507
15511
  });
15508
15512
  });
15509
15513
  });
15510
15514
  } else {
15511
- self2.fs.chmod(path2, attr || 438, function() {
15515
+ self2.fs.chmod(path3, attr || 438, function() {
15512
15516
  callback(true);
15513
15517
  });
15514
15518
  }
@@ -15517,7 +15521,7 @@ var require_utils2 = __commonJS({
15517
15521
  });
15518
15522
  });
15519
15523
  };
15520
- Utils.prototype.findFiles = function(path2) {
15524
+ Utils.prototype.findFiles = function(path3) {
15521
15525
  const self2 = this;
15522
15526
  function findSync(dir, pattern2, recursive) {
15523
15527
  if (typeof pattern2 === "boolean") {
@@ -15526,16 +15530,16 @@ var require_utils2 = __commonJS({
15526
15530
  }
15527
15531
  let files = [];
15528
15532
  self2.fs.readdirSync(dir).forEach(function(file) {
15529
- const path3 = pth.join(dir, file);
15530
- const stat2 = self2.fs.statSync(path3);
15531
- if (!pattern2 || pattern2.test(path3)) {
15532
- files.push(pth.normalize(path3) + (stat2.isDirectory() ? self2.sep : ""));
15533
+ const path4 = pth.join(dir, file);
15534
+ const stat2 = self2.fs.statSync(path4);
15535
+ if (!pattern2 || pattern2.test(path4)) {
15536
+ files.push(pth.normalize(path4) + (stat2.isDirectory() ? self2.sep : ""));
15533
15537
  }
15534
- if (stat2.isDirectory() && recursive) files = files.concat(findSync(path3, pattern2, recursive));
15538
+ if (stat2.isDirectory() && recursive) files = files.concat(findSync(path4, pattern2, recursive));
15535
15539
  });
15536
15540
  return files;
15537
15541
  }
15538
- return findSync(path2, void 0, true);
15542
+ return findSync(path3, void 0, true);
15539
15543
  };
15540
15544
  Utils.prototype.findFilesAsync = function(dir, cb) {
15541
15545
  const self2 = this;
@@ -15590,14 +15594,14 @@ var require_utils2 = __commonJS({
15590
15594
  return "UNSUPPORTED (" + method + ")";
15591
15595
  }
15592
15596
  };
15593
- Utils.canonical = function(path2) {
15594
- if (!path2) return "";
15595
- const safeSuffix = pth.posix.normalize("/" + path2.split("\\").join("/"));
15597
+ Utils.canonical = function(path3) {
15598
+ if (!path3) return "";
15599
+ const safeSuffix = pth.posix.normalize("/" + path3.split("\\").join("/"));
15596
15600
  return pth.join(".", safeSuffix);
15597
15601
  };
15598
- Utils.zipnamefix = function(path2) {
15599
- if (!path2) return "";
15600
- const safeSuffix = pth.posix.normalize("/" + path2.split("\\").join("/"));
15602
+ Utils.zipnamefix = function(path3) {
15603
+ if (!path3) return "";
15604
+ const safeSuffix = pth.posix.normalize("/" + path3.split("\\").join("/"));
15601
15605
  return pth.posix.join(".", safeSuffix);
15602
15606
  };
15603
15607
  Utils.findLast = function(arr, callback) {
@@ -15614,9 +15618,9 @@ var require_utils2 = __commonJS({
15614
15618
  prefix = pth.resolve(pth.normalize(prefix));
15615
15619
  var parts = name.split("/");
15616
15620
  for (var i2 = 0, l3 = parts.length; i2 < l3; i2++) {
15617
- var path2 = pth.normalize(pth.join(prefix, parts.slice(i2, l3).join(pth.sep)));
15618
- if (path2 === prefix || path2.startsWith(prefix + pth.sep)) {
15619
- return path2;
15621
+ var path3 = pth.normalize(pth.join(prefix, parts.slice(i2, l3).join(pth.sep)));
15622
+ if (path3 === prefix || path3.startsWith(prefix + pth.sep)) {
15623
+ return path3;
15620
15624
  }
15621
15625
  }
15622
15626
  return pth.normalize(pth.join(prefix, pth.basename(name)));
@@ -15663,8 +15667,8 @@ var require_fattr = __commonJS({
15663
15667
  "node_modules/adm-zip/util/fattr.js"(exports, module) {
15664
15668
  "use strict";
15665
15669
  var pth = __require("path");
15666
- module.exports = function(path2, { fs: fs4 }) {
15667
- var _path = path2 || "", _obj = newAttr(), _stat = null;
15670
+ module.exports = function(path3, { fs: fs4 }) {
15671
+ var _path = path3 || "", _obj = newAttr(), _stat = null;
15668
15672
  function newAttr() {
15669
15673
  return {
15670
15674
  directory: false,
@@ -145766,8 +145770,8 @@ function getErrorMap() {
145766
145770
 
145767
145771
  // node_modules/zod/v3/helpers/parseUtil.js
145768
145772
  var makeIssue = (params) => {
145769
- const { data, path: path2, errorMaps, issueData } = params;
145770
- const fullPath = [...path2, ...issueData.path || []];
145773
+ const { data, path: path3, errorMaps, issueData } = params;
145774
+ const fullPath = [...path3, ...issueData.path || []];
145771
145775
  const fullIssue = {
145772
145776
  ...issueData,
145773
145777
  path: fullPath
@@ -145883,11 +145887,11 @@ var errorUtil;
145883
145887
 
145884
145888
  // node_modules/zod/v3/types.js
145885
145889
  var ParseInputLazyPath = class {
145886
- constructor(parent, value, path2, key) {
145890
+ constructor(parent, value, path3, key) {
145887
145891
  this._cachedPath = [];
145888
145892
  this.parent = parent;
145889
145893
  this.data = value;
145890
- this._path = path2;
145894
+ this._path = path3;
145891
145895
  this._key = key;
145892
145896
  }
145893
145897
  get path() {
@@ -149524,10 +149528,10 @@ function assignProp(target, prop, value) {
149524
149528
  configurable: true
149525
149529
  });
149526
149530
  }
149527
- function getElementAtPath(obj, path2) {
149528
- if (!path2)
149531
+ function getElementAtPath(obj, path3) {
149532
+ if (!path3)
149529
149533
  return obj;
149530
- return path2.reduce((acc, key) => acc?.[key], obj);
149534
+ return path3.reduce((acc, key) => acc?.[key], obj);
149531
149535
  }
149532
149536
  function promiseAllObject(promisesObj) {
149533
149537
  const keys = Object.keys(promisesObj);
@@ -149847,11 +149851,11 @@ function aborted(x3, startIndex = 0) {
149847
149851
  }
149848
149852
  return false;
149849
149853
  }
149850
- function prefixIssues(path2, issues) {
149854
+ function prefixIssues(path3, issues) {
149851
149855
  return issues.map((iss) => {
149852
149856
  var _a;
149853
149857
  (_a = iss).path ?? (_a.path = []);
149854
- iss.path.unshift(path2);
149858
+ iss.path.unshift(path3);
149855
149859
  return iss;
149856
149860
  });
149857
149861
  }
@@ -159935,6 +159939,7 @@ var registerJiraCrudTools = (ctx2) => {
159935
159939
 
159936
159940
  // src/tools/confluence.ts
159937
159941
  init_markdown();
159942
+ import { readFileSync } from "fs";
159938
159943
  var STORAGE_BODY_WARN_BYTES = 2 * 1024 * 1024;
159939
159944
  var registerConfluenceTools = (ctx2) => {
159940
159945
  const { server: server2, confluence: confluence2 } = ctx2;
@@ -159990,11 +159995,28 @@ var registerConfluenceTools = (ctx2) => {
159990
159995
  server2.tool("confluence_publish_doc", "Publish a markdown document as a Confluence page. Markdown is converted to native Confluence storage format (headings/lists/tables/inline marks + code fences \u2192 code macro; YAML frontmatter auto-stripped). Create a new page, or update an existing one when page_id is provided (version auto-incremented). Use to publish doc_render output to Confluence after human review.", {
159991
159996
  space_key: external_exports.string().describe("Confluence space key (e.g. PROJ). Required even in update mode (returned for reference)."),
159992
159997
  title: external_exports.string().describe("Page title"),
159993
- markdown: external_exports.string().describe("Document content in markdown. Headings (#), bullet/ordered lists, GFM tables, fenced code blocks, and inline marks (**bold**/*italic*/`code`) are supported."),
159998
+ markdown: external_exports.string().optional().describe("Document content in markdown (inline). markdown_file\uACFC \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00. Headings (#), bullet/ordered lists, GFM tables, fenced code blocks, and inline marks (**bold**/*italic*/`code`) are supported."),
159999
+ markdown_file: external_exports.string().optional().describe("\uB85C\uCEEC \uB9C8\uD06C\uB2E4\uC6B4 \uD30C\uC77C \uACBD\uB85C. \uD070 \uBB38\uC11C(25KB+)\uB294 \uBAA8\uB378 \uD234 \uD638\uCD9C \uCD9C\uB825 \uD55C\uACC4\uB85C inline markdown \uC778\uC790\uAC00 \uC798\uB9B4 \uC218 \uC788\uC5B4 \uD30C\uC77C \uC9C1\uC811 \uC77D\uAE30 \uAD8C\uC7A5. markdown\uACFC \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00."),
159994
160000
  parent_page_id: external_exports.string().optional().describe("Parent page ID \u2014 create mode only, nests the new page under this parent. Ignored in update mode."),
159995
160001
  page_id: external_exports.string().optional().describe("Existing page ID. When provided, the page is UPDATED (current version fetched then incremented). When omitted, a NEW page is created.")
159996
- }, async ({ space_key, title, markdown, parent_page_id, page_id }) => {
159997
- const body = markdownToStorageFormat(markdown);
160002
+ }, async ({ space_key, title, markdown, markdown_file, parent_page_id, page_id }) => {
160003
+ if (!markdown && !markdown_file) {
160004
+ throw new Error("Either markdown or markdown_file must be provided");
160005
+ }
160006
+ if (markdown && markdown_file) {
160007
+ throw new Error("Provide either markdown or markdown_file, not both");
160008
+ }
160009
+ let md;
160010
+ if (markdown_file) {
160011
+ try {
160012
+ md = readFileSync(markdown_file, "utf8");
160013
+ } catch (err) {
160014
+ throw new Error(`Failed to read markdown_file "${markdown_file}": ${err?.message ?? err}`);
160015
+ }
160016
+ } else {
160017
+ md = markdown;
160018
+ }
160019
+ const body = markdownToStorageFormat(md);
159998
160020
  const bodyBytes = Buffer.byteLength(body, "utf8");
159999
160021
  const warning = bodyBytes > STORAGE_BODY_WARN_BYTES ? `storage body is ${bodyBytes} bytes (> ${STORAGE_BODY_WARN_BYTES}). Confluence may reject or render slowly \u2014 consider splitting into child pages.` : void 0;
160000
160022
  if (warning) console.error(`[confluence_publish_doc] ${warning}`);
@@ -160022,6 +160044,8 @@ var registerConfluenceTools = (ctx2) => {
160022
160044
  space_key,
160023
160045
  version: result?.version?.number,
160024
160046
  url,
160047
+ input_chars: md.length,
160048
+ input_source: markdown_file ?? "inline",
160025
160049
  body_chars: body.length,
160026
160050
  body_bytes: bodyBytes,
160027
160051
  ...warning ? { warning } : {}
@@ -160729,6 +160753,12 @@ var TOOL_CATALOG = [
160729
160753
  name: "expert_get_cybersecurity_checklist",
160730
160754
  description: "[\uC804\uBB38\uAC00\xB7\uBCF4\uC548] Cybersecurity Reviewer \uAC80\uC0AC \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uBC18\uD658 (IEC 81001-5-1 / FDA 2023 / AAMI TIR57-SW96). phase: design|implementation|verification|postmarket",
160731
160755
  category: "MDR \uC804\uBB38\uAC00"
160756
+ },
160757
+ // 문서 리뷰 soft verdict 평가 기준 (layer ② 데이터)
160758
+ {
160759
+ name: "review_get_criteria",
160760
+ description: "[\uBB38\uC11C \uB9AC\uBDF0\xB7soft verdict] document-content-reviewer\xB7requirement-coverage-tracker \uD3C9\uAC00 \uAE30\uC900(\uB808\uC774\uC5B4 \u2461) \uBC18\uD658. generic \uAE30\uBCF8 \u2014 consumer cwd\uC758 data/review-criteria.md(\uC624\uBC84\uB77C\uC774\uB4DC)\uAC00 \uC788\uC73C\uBA74 subagent\uAC00 \uCD94\uAC00 Read\uB85C \uBCF4\uC644.",
160761
+ category: "\uBB38\uC11C \uB9AC\uBDF0"
160732
160762
  }
160733
160763
  ];
160734
160764
  var WORKFLOWS = {
@@ -161351,7 +161381,7 @@ var registerDocValidationTools = (ctx2) => {
161351
161381
  };
161352
161382
 
161353
161383
  // src/tools/init.ts
161354
- import { readFileSync, writeFileSync as writeFileSync2, existsSync } from "fs";
161384
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync } from "fs";
161355
161385
  import { join as join2 } from "path";
161356
161386
  var registerInitTools = ({ server: server2 }) => {
161357
161387
  server2.tool(
@@ -161367,7 +161397,7 @@ var registerInitTools = ({ server: server2 }) => {
161367
161397
  try {
161368
161398
  let content = "";
161369
161399
  if (existsSync(claudeMdPath)) {
161370
- content = readFileSync(claudeMdPath, "utf-8");
161400
+ content = readFileSync2(claudeMdPath, "utf-8");
161371
161401
  if (content.includes(line)) {
161372
161402
  return { content: [{ type: "text", text: `\uC774\uBBF8 CLAUDE.md\uC5D0 ${project_key} \uD504\uB85C\uC81D\uD2B8 \uC124\uC815\uC774 \uC788\uC2B5\uB2C8\uB2E4.` }] };
161373
161403
  }
@@ -161392,7 +161422,7 @@ var registerInitTools = ({ server: server2 }) => {
161392
161422
  };
161393
161423
 
161394
161424
  // src/tools/doc-render.ts
161395
- import { readFileSync as readFileSync2 } from "fs";
161425
+ import { readFileSync as readFileSync3 } from "fs";
161396
161426
  import { fileURLToPath } from "url";
161397
161427
  import path from "path";
161398
161428
 
@@ -161492,7 +161522,7 @@ var registerDocRenderTools = (ctx2) => {
161492
161522
  throw new Error(`template '${template}' (mode=${entry.mode}) \uB80C\uB354\uB294 \uC544\uC9C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD604\uC7AC freeform\uB9CC \uAD6C\uD604\uB428.`);
161493
161523
  }
161494
161524
  const templatePath = path.join(TEMPLATE_DIR, entry.path);
161495
- const templateBody = readFileSync2(templatePath, "utf8");
161525
+ const templateBody = readFileSync3(templatePath, "utf8");
161496
161526
  const date3 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
161497
161527
  const { rendered, unresolved } = renderTemplate({
161498
161528
  template: templateBody,
@@ -161544,7 +161574,7 @@ var registerDocRenderTools = (ctx2) => {
161544
161574
  };
161545
161575
 
161546
161576
  // src/tools/jira-attach.ts
161547
- import { readFileSync as readFileSync4 } from "fs";
161577
+ import { readFileSync as readFileSync5 } from "fs";
161548
161578
  import { execFileSync } from "child_process";
161549
161579
 
161550
161580
  // src/utils/markdownToPdf.ts
@@ -172855,16 +172885,16 @@ var $f43aec954cdfdf21$export$2e2bcd8739ae039 = class _$f43aec954cdfdf21$export$2
172855
172885
  * @return {Path}
172856
172886
  */
172857
172887
  mapPoints(fn) {
172858
- let path2 = new _$f43aec954cdfdf21$export$2e2bcd8739ae039();
172888
+ let path3 = new _$f43aec954cdfdf21$export$2e2bcd8739ae039();
172859
172889
  for (let c of this.commands) {
172860
172890
  let args = [];
172861
172891
  for (let i2 = 0; i2 < c.args.length; i2 += 2) {
172862
172892
  let [x3, y2] = fn(c.args[i2], c.args[i2 + 1]);
172863
172893
  args.push(x3, y2);
172864
172894
  }
172865
- path2[c.command](...args);
172895
+ path3[c.command](...args);
172866
172896
  }
172867
- return path2;
172897
+ return path3;
172868
172898
  }
172869
172899
  /**
172870
172900
  * Transforms the path by the given matrix.
@@ -173557,7 +173587,7 @@ var $69aac16029968692$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173557
173587
  // Converts contours to a Path object that can be rendered
173558
173588
  _getPath() {
173559
173589
  let contours = this._getContours();
173560
- let path2 = new (0, $f43aec954cdfdf21$export$2e2bcd8739ae039)();
173590
+ let path3 = new (0, $f43aec954cdfdf21$export$2e2bcd8739ae039)();
173561
173591
  for (let i2 = 0; i2 < contours.length; i2++) {
173562
173592
  let contour = contours[i2];
173563
173593
  let firstPt = contour[0];
@@ -173573,26 +173603,26 @@ var $69aac16029968692$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173573
173603
  firstPt = new $69aac16029968692$export$baf26146a414f24a(false, false, (firstPt.x + lastPt.x) / 2, (firstPt.y + lastPt.y) / 2);
173574
173604
  var curvePt = firstPt;
173575
173605
  }
173576
- path2.moveTo(firstPt.x, firstPt.y);
173606
+ path3.moveTo(firstPt.x, firstPt.y);
173577
173607
  for (let j2 = start; j2 < contour.length; j2++) {
173578
173608
  let pt = contour[j2];
173579
173609
  let prevPt = j2 === 0 ? firstPt : contour[j2 - 1];
173580
- if (prevPt.onCurve && pt.onCurve) path2.lineTo(pt.x, pt.y);
173610
+ if (prevPt.onCurve && pt.onCurve) path3.lineTo(pt.x, pt.y);
173581
173611
  else if (prevPt.onCurve && !pt.onCurve) var curvePt = pt;
173582
173612
  else if (!prevPt.onCurve && !pt.onCurve) {
173583
173613
  let midX = (prevPt.x + pt.x) / 2;
173584
173614
  let midY = (prevPt.y + pt.y) / 2;
173585
- path2.quadraticCurveTo(prevPt.x, prevPt.y, midX, midY);
173615
+ path3.quadraticCurveTo(prevPt.x, prevPt.y, midX, midY);
173586
173616
  var curvePt = pt;
173587
173617
  } else if (!prevPt.onCurve && pt.onCurve) {
173588
- path2.quadraticCurveTo(curvePt.x, curvePt.y, pt.x, pt.y);
173618
+ path3.quadraticCurveTo(curvePt.x, curvePt.y, pt.x, pt.y);
173589
173619
  var curvePt = null;
173590
173620
  } else throw new Error("Unknown TTF path state");
173591
173621
  }
173592
- if (curvePt) path2.quadraticCurveTo(curvePt.x, curvePt.y, firstPt.x, firstPt.y);
173593
- path2.closePath();
173622
+ if (curvePt) path3.quadraticCurveTo(curvePt.x, curvePt.y, firstPt.x, firstPt.y);
173623
+ path3.closePath();
173594
173624
  }
173595
- return path2;
173625
+ return path3;
173596
173626
  }
173597
173627
  constructor(...args) {
173598
173628
  super(...args);
@@ -173615,7 +173645,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173615
173645
  let str = cff.topDict.CharStrings[this.id];
173616
173646
  let end = str.offset + str.length;
173617
173647
  stream2.pos = str.offset;
173618
- let path2 = new (0, $f43aec954cdfdf21$export$2e2bcd8739ae039)();
173648
+ let path3 = new (0, $f43aec954cdfdf21$export$2e2bcd8739ae039)();
173619
173649
  let stack = [];
173620
173650
  let trans = [];
173621
173651
  let width = null;
@@ -173643,8 +173673,8 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173643
173673
  return stack.length = 0;
173644
173674
  }
173645
173675
  function moveTo(x4, y3) {
173646
- if (open) path2.closePath();
173647
- path2.moveTo(x4, y3);
173676
+ if (open) path3.closePath();
173677
+ path3.moveTo(x4, y3);
173648
173678
  open = true;
173649
173679
  }
173650
173680
  let parse4 = function() {
@@ -173671,7 +173701,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173671
173701
  while (stack.length >= 2) {
173672
173702
  x3 += stack.shift();
173673
173703
  y2 += stack.shift();
173674
- path2.lineTo(x3, y2);
173704
+ path3.lineTo(x3, y2);
173675
173705
  }
173676
173706
  break;
173677
173707
  case 6:
@@ -173680,7 +173710,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173680
173710
  while (stack.length >= 1) {
173681
173711
  if (phase) x3 += stack.shift();
173682
173712
  else y2 += stack.shift();
173683
- path2.lineTo(x3, y2);
173713
+ path3.lineTo(x3, y2);
173684
173714
  phase = !phase;
173685
173715
  }
173686
173716
  break;
@@ -173692,7 +173722,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173692
173722
  c2y = c1y + stack.shift();
173693
173723
  x3 = c2x + stack.shift();
173694
173724
  y2 = c2y + stack.shift();
173695
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173725
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173696
173726
  }
173697
173727
  break;
173698
173728
  case 10:
@@ -173716,7 +173746,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173716
173746
  if (cff.version >= 2) break;
173717
173747
  if (stack.length > 0) checkWidth();
173718
173748
  if (open) {
173719
- path2.closePath();
173749
+ path3.closePath();
173720
173750
  open = false;
173721
173751
  }
173722
173752
  break;
@@ -173764,17 +173794,17 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173764
173794
  c2y = c1y + stack.shift();
173765
173795
  x3 = c2x + stack.shift();
173766
173796
  y2 = c2y + stack.shift();
173767
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173797
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173768
173798
  }
173769
173799
  x3 += stack.shift();
173770
173800
  y2 += stack.shift();
173771
- path2.lineTo(x3, y2);
173801
+ path3.lineTo(x3, y2);
173772
173802
  break;
173773
173803
  case 25:
173774
173804
  while (stack.length >= 8) {
173775
173805
  x3 += stack.shift();
173776
173806
  y2 += stack.shift();
173777
- path2.lineTo(x3, y2);
173807
+ path3.lineTo(x3, y2);
173778
173808
  }
173779
173809
  c1x = x3 + stack.shift();
173780
173810
  c1y = y2 + stack.shift();
@@ -173782,7 +173812,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173782
173812
  c2y = c1y + stack.shift();
173783
173813
  x3 = c2x + stack.shift();
173784
173814
  y2 = c2y + stack.shift();
173785
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173815
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173786
173816
  break;
173787
173817
  case 26:
173788
173818
  if (stack.length % 2) x3 += stack.shift();
@@ -173793,7 +173823,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173793
173823
  c2y = c1y + stack.shift();
173794
173824
  x3 = c2x;
173795
173825
  y2 = c2y + stack.shift();
173796
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173826
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173797
173827
  }
173798
173828
  break;
173799
173829
  case 27:
@@ -173805,7 +173835,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173805
173835
  c2y = c1y + stack.shift();
173806
173836
  x3 = c2x + stack.shift();
173807
173837
  y2 = c2y;
173808
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173838
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173809
173839
  }
173810
173840
  break;
173811
173841
  case 28:
@@ -173844,7 +173874,7 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173844
173874
  x3 = c2x + stack.shift();
173845
173875
  y2 = c2y + (stack.length === 1 ? stack.shift() : 0);
173846
173876
  }
173847
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173877
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, x3, y2);
173848
173878
  phase = !phase;
173849
173879
  }
173850
173880
  break;
@@ -173970,8 +174000,8 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173970
174000
  c6y = c5y;
173971
174001
  x3 = c6x;
173972
174002
  y2 = c6y;
173973
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);
173974
- path2.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);
174003
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);
174004
+ path3.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);
173975
174005
  break;
173976
174006
  case 35:
173977
174007
  pts = [];
@@ -173980,8 +174010,8 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173980
174010
  y2 += stack.shift();
173981
174011
  pts.push(x3, y2);
173982
174012
  }
173983
- path2.bezierCurveTo(...pts.slice(0, 6));
173984
- path2.bezierCurveTo(...pts.slice(6));
174013
+ path3.bezierCurveTo(...pts.slice(0, 6));
174014
+ path3.bezierCurveTo(...pts.slice(6));
173985
174015
  stack.shift();
173986
174016
  break;
173987
174017
  case 36:
@@ -173999,8 +174029,8 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
173999
174029
  c6y = c5y;
174000
174030
  x3 = c6x;
174001
174031
  y2 = c6y;
174002
- path2.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);
174003
- path2.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);
174032
+ path3.bezierCurveTo(c1x, c1y, c2x, c2y, c3x, c3y);
174033
+ path3.bezierCurveTo(c4x, c4y, c5x, c5y, c6x, c6y);
174004
174034
  break;
174005
174035
  case 37:
174006
174036
  let startx = x3;
@@ -174019,8 +174049,8 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
174019
174049
  y2 += stack.shift();
174020
174050
  }
174021
174051
  pts.push(x3, y2);
174022
- path2.bezierCurveTo(...pts.slice(0, 6));
174023
- path2.bezierCurveTo(...pts.slice(6));
174052
+ path3.bezierCurveTo(...pts.slice(0, 6));
174053
+ path3.bezierCurveTo(...pts.slice(6));
174024
174054
  break;
174025
174055
  default:
174026
174056
  throw new Error(`Unknown op: 12 ${op}`);
@@ -174040,8 +174070,8 @@ var $62cc5109c6101893$export$2e2bcd8739ae039 = class extends (0, $f92906be28e617
174040
174070
  }
174041
174071
  };
174042
174072
  parse4();
174043
- if (open) path2.closePath();
174044
- return path2;
174073
+ if (open) path3.closePath();
174074
+ return path3;
174045
174075
  }
174046
174076
  constructor(...args) {
174047
174077
  super(...args);
@@ -174501,7 +174531,7 @@ var $807e58506be70005$var$Glyf = new Struct({
174501
174531
  yPoints: new ArrayT($807e58506be70005$var$Point, 0)
174502
174532
  });
174503
174533
  var $807e58506be70005$export$2e2bcd8739ae039 = class {
174504
- encodeSimple(path2, instructions = []) {
174534
+ encodeSimple(path3, instructions = []) {
174505
174535
  let endPtsOfContours = [];
174506
174536
  let xPoints = [];
174507
174537
  let yPoints = [];
@@ -174509,14 +174539,14 @@ var $807e58506be70005$export$2e2bcd8739ae039 = class {
174509
174539
  let same = 0;
174510
174540
  let lastX = 0, lastY = 0, lastFlag = 0;
174511
174541
  let pointCount = 0;
174512
- for (let i2 = 0; i2 < path2.commands.length; i2++) {
174513
- let c = path2.commands[i2];
174542
+ for (let i2 = 0; i2 < path3.commands.length; i2++) {
174543
+ let c = path3.commands[i2];
174514
174544
  for (let j2 = 0; j2 < c.args.length; j2 += 2) {
174515
174545
  let x3 = c.args[j2];
174516
174546
  let y2 = c.args[j2 + 1];
174517
174547
  let flag = 0;
174518
174548
  if (c.command === "quadraticCurveTo" && j2 === 2) {
174519
- let next = path2.commands[i2 + 1];
174549
+ let next = path3.commands[i2 + 1];
174520
174550
  if (next && next.command === "quadraticCurveTo") {
174521
174551
  let midX = (lastX + next.args[0]) / 2;
174522
174552
  let midY = (lastY + next.args[1]) / 2;
@@ -174543,8 +174573,8 @@ var $807e58506be70005$export$2e2bcd8739ae039 = class {
174543
174573
  }
174544
174574
  if (c.command === "closePath") endPtsOfContours.push(pointCount - 1);
174545
174575
  }
174546
- if (path2.commands.length > 1 && path2.commands[path2.commands.length - 1].command !== "closePath") endPtsOfContours.push(pointCount - 1);
174547
- let bbox = path2.bbox;
174576
+ if (path3.commands.length > 1 && path3.commands[path3.commands.length - 1].command !== "closePath") endPtsOfContours.push(pointCount - 1);
174577
+ let bbox = path3.bbox;
174548
174578
  let glyf = {
174549
174579
  numberOfContours: endPtsOfContours.length,
174550
174580
  xMin: bbox.minX,
@@ -174651,7 +174681,7 @@ var $001d739428a71d5a$export$2e2bcd8739ae039 = class extends (0, $5cc7476da92df3
174651
174681
  for (let gid of this.glyphs) {
174652
174682
  this.charstrings.push(this.cff.getCharString(gid));
174653
174683
  let glyph = this.font.getGlyph(gid);
174654
- let path2 = glyph.path;
174684
+ let path3 = glyph.path;
174655
174685
  for (let subr in glyph._usedGsubrs) gsubrs[subr] = true;
174656
174686
  }
174657
174687
  this.gsubrs = this.subsetSubrs(this.cff.globalSubrIndex, gsubrs);
@@ -174689,7 +174719,7 @@ var $001d739428a71d5a$export$2e2bcd8739ae039 = class extends (0, $5cc7476da92df3
174689
174719
  used_fds[fd] = true;
174690
174720
  topDict.FDSelect.fds.push(fd_select[fd]);
174691
174721
  let glyph = this.font.getGlyph(gid);
174692
- let path2 = glyph.path;
174722
+ let path3 = glyph.path;
174693
174723
  for (let subr in glyph._usedSubrs) used_subrs[fd_select[fd]][subr] = true;
174694
174724
  }
174695
174725
  for (let i2 = 0; i2 < topDict.FDArray.length; i2++) {
@@ -174706,7 +174736,7 @@ var $001d739428a71d5a$export$2e2bcd8739ae039 = class extends (0, $5cc7476da92df3
174706
174736
  let used_subrs = {};
174707
174737
  for (let gid of this.glyphs) {
174708
174738
  let glyph = this.font.getGlyph(gid);
174709
- let path2 = glyph.path;
174739
+ let path3 = glyph.path;
174710
174740
  for (let subr in glyph._usedSubrs) used_subrs[subr] = true;
174711
174741
  }
174712
174742
  let privateDict = Object.assign({}, this.cff.topDict.Private);
@@ -177014,17 +177044,17 @@ $557adaaeb0c7885f$exports = $557adaaeb0c7885f$var$LineBreaker;
177014
177044
  import fs2 from "fs";
177015
177045
  import zlib2 from "zlib";
177016
177046
  var PNG = class _PNG {
177017
- static decode(path2, fn) {
177047
+ static decode(path3, fn) {
177018
177048
  {
177019
- return fs2.readFile(path2, function(err, file) {
177049
+ return fs2.readFile(path3, function(err, file) {
177020
177050
  const png = new _PNG(file);
177021
177051
  return png.decode((pixels) => fn(pixels));
177022
177052
  });
177023
177053
  }
177024
177054
  }
177025
- static load(path2) {
177055
+ static load(path3) {
177026
177056
  {
177027
- const file = fs2.readFileSync(path2);
177057
+ const file = fs2.readFileSync(path3);
177028
177058
  return new _PNG(file);
177029
177059
  }
177030
177060
  }
@@ -178892,15 +178922,15 @@ var readNumber = function(string3, cursor) {
178892
178922
  }
178893
178923
  return [i2 - 1, number4];
178894
178924
  };
178895
- var parse3 = function(path2) {
178925
+ var parse3 = function(path3) {
178896
178926
  const pathData = [];
178897
178927
  let command = null;
178898
178928
  let args = [];
178899
178929
  let argsCount = 0;
178900
178930
  let canHaveComma = false;
178901
178931
  let hadComma = false;
178902
- for (let i2 = 0; i2 < path2.length; i2 += 1) {
178903
- const c = path2.charAt(i2);
178932
+ for (let i2 = 0; i2 < path3.length; i2 += 1) {
178933
+ const c = path3.charAt(i2);
178904
178934
  if (isWsp(c)) {
178905
178935
  continue;
178906
178936
  }
@@ -178945,11 +178975,11 @@ var parse3 = function(path2) {
178945
178975
  const position = args.length;
178946
178976
  if (position === 0 || position === 1) {
178947
178977
  if (c !== "+" && c !== "-") {
178948
- [newCursor, number4] = readNumber(path2, i2);
178978
+ [newCursor, number4] = readNumber(path3, i2);
178949
178979
  }
178950
178980
  }
178951
178981
  if (position === 2 || position === 5 || position === 6) {
178952
- [newCursor, number4] = readNumber(path2, i2);
178982
+ [newCursor, number4] = readNumber(path3, i2);
178953
178983
  }
178954
178984
  if (position === 3 || position === 4) {
178955
178985
  if (c === "0") {
@@ -178960,7 +178990,7 @@ var parse3 = function(path2) {
178960
178990
  }
178961
178991
  }
178962
178992
  } else {
178963
- [newCursor, number4] = readNumber(path2, i2);
178993
+ [newCursor, number4] = readNumber(path3, i2);
178964
178994
  }
178965
178995
  if (number4 == null) {
178966
178996
  return pathData;
@@ -179216,8 +179246,8 @@ var segmentToBezier = function(cx2, cy2, th0, th1, rx, ry, sin_th, cos_th) {
179216
179246
  return [a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x22 + a01 * y2, a10 * x22 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3];
179217
179247
  };
179218
179248
  var SVGPath = class {
179219
- static apply(doc, path2) {
179220
- const commands = parse3(path2);
179249
+ static apply(doc, path3) {
179250
+ const commands = parse3(path3);
179221
179251
  apply(commands, doc);
179222
179252
  }
179223
179253
  };
@@ -179402,8 +179432,8 @@ var VectorMixin = {
179402
179432
  }
179403
179433
  return this.closePath();
179404
179434
  },
179405
- path(path2) {
179406
- SVGPath.apply(this, path2);
179435
+ path(path3) {
179436
+ SVGPath.apply(this, path3);
179407
179437
  return this;
179408
179438
  },
179409
179439
  _windingRule(rule) {
@@ -184121,9 +184151,9 @@ function renderHr(doc) {
184121
184151
  doc.y = y2 + SPACE2.HR_AFTER;
184122
184152
  }
184123
184153
  function writePdfToTempFile(buffer) {
184124
- const path2 = join3(tmpdir(), `${randomUUID()}.pdf`);
184125
- writeFileSync3(path2, buffer);
184126
- return path2;
184154
+ const path3 = join3(tmpdir(), `${randomUUID()}.pdf`);
184155
+ writeFileSync3(path3, buffer);
184156
+ return path3;
184127
184157
  }
184128
184158
 
184129
184159
  // src/tools/jira-attach.ts
@@ -184164,7 +184194,8 @@ var registerJiraAttachTools = (ctx2) => {
184164
184194
  "markdown_to_pdf",
184165
184195
  "\uB9C8\uD06C\uB2E4\uC6B4\uC744 PDF\uB85C \uBCC0\uD658 (\uC2DC\uC2A4\uD15C \uD3F0\uD2B8 \uC790\uB3D9 \uAC10\uC9C0, \uD45C\uC9C0/\uBA38\uB9AC\uB9D0\xB7\uAF2C\uB9AC\uB9D0 \uC635\uC158). Jira \uCCA8\uBD80 \uC5C6\uC774 PDF \uACB0\uACFC\uB9CC \uBC18\uD658.",
184166
184196
  {
184167
- markdown: external_exports.string().describe("PDF\uB85C \uBCC0\uD658\uD560 \uB9C8\uD06C\uB2E4\uC6B4 \uBCF8\uBB38"),
184197
+ markdown: external_exports.string().optional().describe("PDF\uB85C \uBCC0\uD658\uD560 \uB9C8\uD06C\uB2E4\uC6B4 \uBCF8\uBB38 (inline). markdown_file\uACFC \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00."),
184198
+ markdown_file: external_exports.string().optional().describe("\uB85C\uCEEC \uB9C8\uD06C\uB2E4\uC6B4 \uD30C\uC77C \uACBD\uB85C. \uD070 \uBB38\uC11C(25KB+)\uB294 \uBAA8\uB378 \uD234 \uD638\uCD9C \uCD9C\uB825 \uD55C\uACC4\uB85C inline markdown \uC778\uC790\uAC00 \uC798\uB9B4 \uC218 \uC788\uC5B4 \uD30C\uC77C \uC9C1\uC811 \uC77D\uAE30 \uAD8C\uC7A5. markdown\uACFC \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00."),
184168
184199
  title: external_exports.string().optional().describe('\uBA38\uB9AC\uB9D0\xB7\uD45C\uC9C0\uC5D0 \uD45C\uC2DC\uD560 \uC81C\uBAA9 (\uAE30\uBCF8: source_ref \uB610\uB294 "Document")'),
184169
184200
  source_ref: external_exports.string().optional().describe('\uAF2C\uB9AC\uB9D0\xB7\uD45C\uC9C0 \uD478\uD130\uC5D0 \uD45C\uC2DC\uD560 \uCD9C\uCC98 (\uC608: "DYN-100 \xB7 2026-07-14")'),
184170
184201
  include_cover: external_exports.boolean().optional().default(false).describe("\uD45C\uC9C0 \uD398\uC774\uC9C0 \uD3EC\uD568 \uC5EC\uBD80 (\uAE30\uBCF8 false)"),
@@ -184174,8 +184205,24 @@ var registerJiraAttachTools = (ctx2) => {
184174
184205
  page_size: external_exports.enum(["A4", "LETTER", "LEGAL"]).optional().default("A4").describe("\uD398\uC774\uC9C0 \uD06C\uAE30"),
184175
184206
  output_mode: external_exports.enum(["base64", "tmpfile"]).optional().default("base64").describe("base64(\uAE30\uBCF8, JSON \uC548\uC804) / tmpfile(\uC808\uB300\uACBD\uB85C \uBC18\uD658, consumer\uAC00 unlink \uCC45\uC784)")
184176
184207
  },
184177
- async ({ markdown, title, source_ref, include_cover, author, font_path, font_family_name, page_size, output_mode }) => {
184178
- const result = await markdownToPdf(markdown, {
184208
+ async ({ markdown, markdown_file, title, source_ref, include_cover, author, font_path, font_family_name, page_size, output_mode }) => {
184209
+ if (!markdown && !markdown_file) {
184210
+ throw new Error("Either markdown or markdown_file must be provided");
184211
+ }
184212
+ if (markdown && markdown_file) {
184213
+ throw new Error("Provide either markdown or markdown_file, not both");
184214
+ }
184215
+ let md;
184216
+ if (markdown_file) {
184217
+ try {
184218
+ md = readFileSync5(markdown_file, "utf8");
184219
+ } catch (err) {
184220
+ throw new Error(`Failed to read markdown_file "${markdown_file}": ${err?.message ?? err}`);
184221
+ }
184222
+ } else {
184223
+ md = markdown;
184224
+ }
184225
+ const result = await markdownToPdf(md, {
184179
184226
  ...title !== void 0 ? { title } : {},
184180
184227
  ...source_ref !== void 0 ? { sourceRef: source_ref } : {},
184181
184228
  includeCover: include_cover,
@@ -184187,9 +184234,9 @@ var registerJiraAttachTools = (ctx2) => {
184187
184234
  });
184188
184235
  const buffer = result.buffer;
184189
184236
  if (output_mode === "tmpfile") {
184190
- const path2 = writePdfToTempFile(buffer);
184237
+ const path3 = writePdfToTempFile(buffer);
184191
184238
  const payload2 = {
184192
- path: path2,
184239
+ path: path3,
184193
184240
  bytes: buffer.length,
184194
184241
  encoding: "utf8"
184195
184242
  };
@@ -184226,7 +184273,7 @@ var registerJiraAttachTools = (ctx2) => {
184226
184273
  let buffer;
184227
184274
  if (file_path) {
184228
184275
  try {
184229
- buffer = readFileSync4(file_path);
184276
+ buffer = readFileSync5(file_path);
184230
184277
  } catch (err) {
184231
184278
  throw new Error(`Failed to read file_path "${file_path}": ${err?.message ?? err}`);
184232
184279
  }
@@ -184266,7 +184313,8 @@ var registerJiraAttachTools = (ctx2) => {
184266
184313
  "\uB9C8\uD06C\uB2E4\uC6B4 \u2192 PDF \uBCC0\uD658 \u2192 Jira \uCCA8\uBD80 \uC6D0\uC0F7. description\uC740 \uC218\uC815\uD558\uC9C0 \uC54A\uC73C\uBA70, summary \uC635\uC158\uC774 \uC788\uC73C\uBA74 \uCF54\uBA58\uD2B8\uB85C \uAC8C\uC2DC.",
184267
184314
  {
184268
184315
  issue_key: external_exports.string().describe("Jira \uC774\uC288 \uD0A4 (\uC608: DYN-100)"),
184269
- markdown: external_exports.string().describe("PDF\uB85C \uBCC0\uD658\uD560 \uB9C8\uD06C\uB2E4\uC6B4 \uBCF8\uBB38"),
184316
+ markdown: external_exports.string().optional().describe("PDF\uB85C \uBCC0\uD658\uD560 \uB9C8\uD06C\uB2E4\uC6B4 \uBCF8\uBB38 (inline). markdown_file\uACFC \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00."),
184317
+ markdown_file: external_exports.string().optional().describe("\uB85C\uCEEC \uB9C8\uD06C\uB2E4\uC6B4 \uD30C\uC77C \uACBD\uB85C. \uD070 \uBB38\uC11C(25KB+)\uB294 \uBAA8\uB378 \uD234 \uD638\uCD9C \uCD9C\uB825 \uD55C\uACC4\uB85C inline markdown \uC778\uC790\uAC00 \uC798\uB9B4 \uC218 \uC788\uC5B4 \uD30C\uC77C \uC9C1\uC811 \uC77D\uAE30 \uAD8C\uC7A5. markdown\uACFC \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00."),
184270
184318
  filename: external_exports.string().optional().default(DEFAULT_PDF_FILENAME).describe('\uCCA8\uBD80 \uD30C\uC77C\uBA85 (\uAE30\uBCF8 "document.pdf")'),
184271
184319
  summary: external_exports.string().optional().describe("\uCF54\uBA58\uD2B8\uB85C \uAC8C\uC2DC\uD560 \uC694\uC57D (Markdown ADF \uBCC0\uD658, description\uC740 \uBBF8\uC218\uC815)"),
184272
184320
  // pdfkit 옵션 위임 — title/source_ref/include_cover/author/font_path/font_family_name/page_size
@@ -184281,6 +184329,7 @@ var registerJiraAttachTools = (ctx2) => {
184281
184329
  async ({
184282
184330
  issue_key,
184283
184331
  markdown,
184332
+ markdown_file,
184284
184333
  filename,
184285
184334
  summary,
184286
184335
  title,
@@ -184291,7 +184340,23 @@ var registerJiraAttachTools = (ctx2) => {
184291
184340
  font_family_name,
184292
184341
  page_size
184293
184342
  }) => {
184294
- const result = await markdownToPdf(markdown, {
184343
+ if (!markdown && !markdown_file) {
184344
+ throw new Error("Either markdown or markdown_file must be provided");
184345
+ }
184346
+ if (markdown && markdown_file) {
184347
+ throw new Error("Provide either markdown or markdown_file, not both");
184348
+ }
184349
+ let md;
184350
+ if (markdown_file) {
184351
+ try {
184352
+ md = readFileSync5(markdown_file, "utf8");
184353
+ } catch (err) {
184354
+ throw new Error(`Failed to read markdown_file "${markdown_file}": ${err?.message ?? err}`);
184355
+ }
184356
+ } else {
184357
+ md = markdown;
184358
+ }
184359
+ const result = await markdownToPdf(md, {
184295
184360
  ...title !== void 0 ? { title } : {},
184296
184361
  ...source_ref !== void 0 ? { sourceRef: source_ref } : {},
184297
184362
  includeCover: include_cover,
@@ -184575,6 +184640,40 @@ var registerExpertTools = (ctx2) => {
184575
184640
  );
184576
184641
  };
184577
184642
 
184643
+ // src/tools/review-criteria.ts
184644
+ import { readFileSync as readFileSync6 } from "fs";
184645
+ import { fileURLToPath as fileURLToPath2 } from "url";
184646
+ import path2 from "path";
184647
+ var __dirname3 = path2.dirname(fileURLToPath2(import.meta.url));
184648
+ var CRITERIA_PATH = path2.resolve(__dirname3, "../data/review-criteria.md");
184649
+ var registerReviewCriteriaTools = (ctx2) => {
184650
+ ctx2.server.tool(
184651
+ "review_get_criteria",
184652
+ "[\uBB38\uC11C \uB9AC\uBDF0\xB7soft verdict] document-content-reviewer\xB7requirement-coverage-tracker\uC758 \uD3C9\uAC00 \uAE30\uC900(\uB808\uC774\uC5B4 \u2461) \uBC18\uD658. \uC758\uB8CC\uAE30\uAE30 \uD45C\uC900 \uAE30\uBC18 generic \uAE30\uBCF8 \u2014 consumer cwd\uC758 data/review-criteria.md(\uD504\uB85C\uC81D\uD2B8 \uC624\uBC84\uB77C\uC774\uB4DC)\uAC00 \uBCC4\uB3C4 \uC874\uC7AC\uD558\uBA74 subagent\uAC00 \uADF8\uAC83\uC744 \uCD94\uAC00 Read\uB85C \uBCF4\uC644. \uB9E4 \uD638\uCD9C \uC2DC \uB514\uC2A4\uD06C\uC5D0\uC11C \uC77D\uC74C(watch rebuild/installPath \uAC31\uC2E0 \uBC18\uC601).",
184653
+ {},
184654
+ async () => {
184655
+ let body;
184656
+ try {
184657
+ body = readFileSync6(CRITERIA_PATH, "utf8");
184658
+ } catch (err) {
184659
+ body = [
184660
+ "# Review Criteria \u2014 \uB85C\uB4DC \uC2E4\uD328",
184661
+ "",
184662
+ `\uACBD\uB85C: ${CRITERIA_PATH}`,
184663
+ `\uC624\uB958: ${err?.message ?? err}`,
184664
+ "",
184665
+ "plugin \uBC88\uB4E4\uC5D0 data/review-criteria.md\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
184666
+ '- package.json files \uBC30\uC5F4\uC5D0 "data" \uD3EC\uD568 \uC5EC\uBD80 \uD655\uC778.',
184667
+ "- installPath(dist/index.js \uC606)\uC5D0 data/ \uB514\uB809\uD130\uB9AC \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778.",
184668
+ "",
184669
+ "\uD3C9\uAC00\uB294 \uACC4\uC18D \uAC00\uB2A5\uD558\uB098 generic \uAE30\uC900 \uC5C6\uC774 subagent\uC758 \uC77C\uBC18\uC801 LLM \uD3C9\uAC00\uB85C\uB9CC \uC9C4\uD589\uB429\uB2C8\uB2E4. findings\uC758 \uC2E0\uB8B0\uB3C4\uAC00 \uB0AE\uC544\uC9C8 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
184670
+ ].join("\n");
184671
+ }
184672
+ return { content: [{ type: "text", text: body }] };
184673
+ }
184674
+ );
184675
+ };
184676
+
184578
184677
  // src/index.ts
184579
184678
  var jiraUrl = process.env.JIRA_URL || "";
184580
184679
  var jiraEmail = process.env.JIRA_EMAIL || "";
@@ -184592,7 +184691,7 @@ var xrayClientSecret = process.env.XRAY_CLIENT_SECRET || "";
184592
184691
  var xray = xrayClientId && xrayClientSecret ? new XrayClient(xrayClientId, xrayClientSecret, jiraUrl, jiraEmail, jiraToken) : null;
184593
184692
  var server = new McpServer({
184594
184693
  name: "jira-confluence",
184595
- version: "0.1.15"
184694
+ version: "0.1.16"
184596
184695
  });
184597
184696
  var ctx = { server, jira, confluence, risk, xray };
184598
184697
  registerJiraCrudTools(ctx);
@@ -184609,6 +184708,7 @@ registerInitTools(ctx);
184609
184708
  registerDocRenderTools(ctx);
184610
184709
  registerJiraAttachTools(ctx);
184611
184710
  registerExpertTools(ctx);
184711
+ registerReviewCriteriaTools(ctx);
184612
184712
  var transport = new StdioServerTransport();
184613
184713
  server.connect(transport).catch((err) => {
184614
184714
  console.error("Failed to start MCP server:", err);