@firfi/huly-mcp 0.44.0 → 0.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +2 -2
  2. package/dist/index.cjs +101 -55
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -320,8 +320,8 @@ When resolved tool exposure is `proxy`, clients see the built-in tools plus thes
320
320
  | `delete_component` | Permanently delete a Huly component. This action cannot be undone. |
321
321
  | `list_issues` | Query Huly issues with optional filters. Returns issues sorted by modification date (newest first). Supports filtering by project, exact workflow status name (status), Huly SDK task.statusCategory key (statusCategory: UnStarted, ToDo, Active, Won, Lost), assignee, component, and parentIssue (to list children of a specific issue). Supports searching by title substring (titleSearch) and description content (descriptionSearch). |
322
322
  | `get_issue` | Retrieve full details for a Huly issue including markdown description. Use this to view issue content, comments, or full metadata. |
323
- | `create_issue` | Create a new issue in a Huly project. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and status is validated against that task type's workflow. Use list_task_types or get_project_type to discover valid task types and statuses. Optionally create as a sub-issue by specifying parentIssue. Description supports markdown formatting. Returns the created issue identifier. |
324
- | `update_issue` | Update fields on an existing Huly issue. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and the status is preserved only when valid for the new task type. Use list_task_types or get_project_type to discover valid task types and statuses. Only provided fields are modified. Description updates support markdown. |
323
+ | `create_issue` | Create a new issue in a Huly project. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and status is validated against that task type's workflow. Use list_task_types or get_project_type to discover valid task types and statuses. Optionally create as a sub-issue by specifying parentIssue. Description supports markdown formatting; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links. Returns the created issue identifier. |
324
+ | `update_issue` | Update fields on an existing Huly issue. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and the status is preserved only when valid for the new task type. Use list_task_types or get_project_type to discover valid task types and statuses. Only provided fields are modified. Description updates support markdown; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links. |
325
325
  | `add_issue_label` | Add a tag/label to a Huly issue. Creates the tag if it doesn't exist in the project. |
326
326
  | `remove_issue_label` | Remove a tag/label from a Huly issue. Detaches the label reference; does not delete the label definition. |
327
327
  | `delete_issue` | Permanently delete a Huly issue. This action cannot be undone. |
package/dist/index.cjs CHANGED
@@ -82690,7 +82690,7 @@ var require_connection2 = __commonJS({
82690
82690
  });
82691
82691
  module2.exports = __toCommonJS2(connection_exports);
82692
82692
  var import_analytics = require_lib3();
82693
- var import_client88 = __toESM2(require_lib7());
82693
+ var import_client89 = __toESM2(require_lib7());
82694
82694
  var import_core105 = __toESM2(require_lib5());
82695
82695
  var import_platform4 = __toESM2(require_lib());
82696
82696
  var import_rpc = require_lib19();
@@ -82801,7 +82801,7 @@ var require_connection2 = __commonJS({
82801
82801
  }
82802
82802
  if (!this.closed) {
82803
82803
  void this.sendRequest({
82804
- method: import_client88.pingConst,
82804
+ method: import_client89.pingConst,
82805
82805
  params: [],
82806
82806
  once: true,
82807
82807
  handleResult: /* @__PURE__ */ __name(async (result) => {
@@ -82834,7 +82834,7 @@ var require_connection2 = __commonJS({
82834
82834
  }
82835
82835
  }
82836
82836
  isConnected() {
82837
- return this.websocket != null && this.websocket.readyState === import_client88.ClientSocketReadyState.OPEN && this.helloReceived;
82837
+ return this.websocket != null && this.websocket.readyState === import_client89.ClientSocketReadyState.OPEN && this.helloReceived;
82838
82838
  }
82839
82839
  delay = 0;
82840
82840
  onConnectHandlers = [];
@@ -82974,8 +82974,8 @@ var require_connection2 = __commonJS({
82974
82974
  }
82975
82975
  return;
82976
82976
  }
82977
- if (resp.result === import_client88.pingConst) {
82978
- void this.sendRequest({ method: import_client88.pingConst, params: [] }).catch((err) => {
82977
+ if (resp.result === import_client89.pingConst) {
82978
+ void this.sendRequest({ method: import_client89.pingConst, params: [] }).catch((err) => {
82979
82979
  this.ctx.error("failed to send ping", { err });
82980
82980
  });
82981
82981
  return;
@@ -83067,15 +83067,15 @@ var require_connection2 = __commonJS({
83067
83067
  }
83068
83068
  }
83069
83069
  checkArrayBufferPing(data) {
83070
- if (data.byteLength === import_client88.pingConst.length || data.byteLength === import_client88.pongConst.length) {
83070
+ if (data.byteLength === import_client89.pingConst.length || data.byteLength === import_client89.pongConst.length) {
83071
83071
  const text = new TextDecoder().decode(data);
83072
- if (text === import_client88.pingConst) {
83073
- void this.sendRequest({ method: import_client88.pingConst, params: [] }).catch((err) => {
83072
+ if (text === import_client89.pingConst) {
83073
+ void this.sendRequest({ method: import_client89.pingConst, params: [] }).catch((err) => {
83074
83074
  this.ctx.error("failed to send ping", { err });
83075
83075
  });
83076
83076
  return true;
83077
83077
  }
83078
- if (text === import_client88.pongConst) {
83078
+ if (text === import_client89.pongConst) {
83079
83079
  this.pingResponse = Date.now();
83080
83080
  return true;
83081
83081
  }
@@ -83085,7 +83085,7 @@ var require_connection2 = __commonJS({
83085
83085
  openConnection(ctx, socketId) {
83086
83086
  this.binaryMode = false;
83087
83087
  this.helloReceived = false;
83088
- const clientSocketFactory = this.opt?.socketFactory ?? (0, import_platform4.getMetadata)(import_client88.default.metadata.ClientSocketFactory) ?? ((url4) => {
83088
+ const clientSocketFactory = this.opt?.socketFactory ?? (0, import_platform4.getMetadata)(import_client89.default.metadata.ClientSocketFactory) ?? ((url4) => {
83089
83089
  const s = new WebSocket(url4);
83090
83090
  return s;
83091
83091
  });
@@ -83120,12 +83120,12 @@ var require_connection2 = __commonJS({
83120
83120
  if (this.websocket !== wsocket) {
83121
83121
  return;
83122
83122
  }
83123
- if (event.data === import_client88.pongConst) {
83123
+ if (event.data === import_client89.pongConst) {
83124
83124
  this.pingResponse = Date.now();
83125
83125
  return;
83126
83126
  }
83127
- if (event.data === import_client88.pingConst) {
83128
- void this.sendRequest({ method: import_client88.pingConst, params: [] }).catch((err) => {
83127
+ if (event.data === import_client89.pingConst) {
83128
+ void this.sendRequest({ method: import_client89.pingConst, params: [] }).catch((err) => {
83129
83129
  this.ctx.error("failed to send ping", { err });
83130
83130
  });
83131
83131
  return;
@@ -83190,8 +83190,8 @@ var require_connection2 = __commonJS({
83190
83190
  if (this.websocket !== wsocket) {
83191
83191
  return;
83192
83192
  }
83193
- const useBinary = this.opt?.useBinaryProtocol ?? (0, import_platform4.getMetadata)(import_client88.default.metadata.UseBinaryProtocol) ?? true;
83194
- this.compressionMode = this.opt?.useProtocolCompression ?? (0, import_platform4.getMetadata)(import_client88.default.metadata.UseProtocolCompression) ?? false;
83193
+ const useBinary = this.opt?.useBinaryProtocol ?? (0, import_platform4.getMetadata)(import_client89.default.metadata.UseBinaryProtocol) ?? true;
83194
+ this.compressionMode = this.opt?.useProtocolCompression ?? (0, import_platform4.getMetadata)(import_client89.default.metadata.UseProtocolCompression) ?? false;
83195
83195
  const helloRequest = {
83196
83196
  method: "hello",
83197
83197
  params: [],
@@ -83237,13 +83237,13 @@ var require_connection2 = __commonJS({
83237
83237
  if (w instanceof Promise) {
83238
83238
  await w;
83239
83239
  }
83240
- if (data.method !== import_client88.pingConst) {
83240
+ if (data.method !== import_client89.pingConst) {
83241
83241
  this.requests.set(id, promise4);
83242
83242
  }
83243
83243
  promise4.sendData = () => {
83244
- if (this.websocket?.readyState === import_client88.ClientSocketReadyState.OPEN) {
83244
+ if (this.websocket?.readyState === import_client89.ClientSocketReadyState.OPEN) {
83245
83245
  promise4.startTime = Date.now();
83246
- if (data.method !== import_client88.pingConst) {
83246
+ if (data.method !== import_client89.pingConst) {
83247
83247
  const dta = this.rpcHandler.serialize(
83248
83248
  {
83249
83249
  method: data.method,
@@ -83256,7 +83256,7 @@ var require_connection2 = __commonJS({
83256
83256
  );
83257
83257
  this.websocket?.send(dta);
83258
83258
  } else {
83259
- this.websocket?.send(import_client88.pingConst);
83259
+ this.websocket?.send(import_client89.pingConst);
83260
83260
  }
83261
83261
  }
83262
83262
  };
@@ -83270,7 +83270,7 @@ var require_connection2 = __commonJS({
83270
83270
  };
83271
83271
  }
83272
83272
  promise4.sendData();
83273
- if (data.method !== import_client88.pingConst) {
83273
+ if (data.method !== import_client89.pingConst) {
83274
83274
  return await promise4.promise;
83275
83275
  }
83276
83276
  },
@@ -83436,7 +83436,7 @@ var require_lib20 = __commonJS({
83436
83436
  default: () => index_default
83437
83437
  });
83438
83438
  module2.exports = __toCommonJS2(index_exports2);
83439
- var import_client88 = __toESM2(require_lib7());
83439
+ var import_client89 = __toESM2(require_lib7());
83440
83440
  var import_core105 = __toESM2(require_lib5());
83441
83441
  var import_platform4 = __toESM2(require_lib());
83442
83442
  var import_connection = require_connection2();
@@ -83480,8 +83480,8 @@ var require_lib20 = __commonJS({
83480
83480
  return {
83481
83481
  function: {
83482
83482
  GetClient: /* @__PURE__ */ __name(async (token, endpoint, opt) => {
83483
- const filterModel = (0, import_platform4.getMetadata)(import_client88.default.metadata.FilterModel) ?? "none";
83484
- const extraFilter = (0, import_platform4.getMetadata)(import_client88.default.metadata.ExtraFilter) ?? [];
83483
+ const filterModel = (0, import_platform4.getMetadata)(import_client89.default.metadata.FilterModel) ?? "none";
83484
+ const extraFilter = (0, import_platform4.getMetadata)(import_client89.default.metadata.ExtraFilter) ?? [];
83485
83485
  const handler = /* @__PURE__ */ __name(async (handler2) => {
83486
83486
  const url4 = (0, import_core105.concatLink)(endpoint, `/${token}`);
83487
83487
  const upgradeHandler = /* @__PURE__ */ __name((...txes) => {
@@ -83509,7 +83509,7 @@ var require_lib20 = __commonJS({
83509
83509
  throw new Error("Workspace or account not found in token");
83510
83510
  }
83511
83511
  const newOpt = { ...opt };
83512
- const connectTimeout = opt?.connectionTimeout ?? (0, import_platform4.getMetadata)(import_client88.default.metadata.ConnectionTimeout);
83512
+ const connectTimeout = opt?.connectionTimeout ?? (0, import_platform4.getMetadata)(import_client89.default.metadata.ConnectionTimeout);
83513
83513
  let connectPromise;
83514
83514
  if ((connectTimeout ?? 0) > 0) {
83515
83515
  connectPromise = new Promise((resolve2, reject) => {
@@ -83561,7 +83561,7 @@ var require_lib20 = __commonJS({
83561
83561
  function returnUITxes(txes, extraFilter) {
83562
83562
  const configs = /* @__PURE__ */ new Map();
83563
83563
  (0, import_core105.fillConfiguration)(txes, configs);
83564
- const allowedPlugins = [...(0, import_platform4.getPlugins)(), ...(0, import_platform4.getMetadata)(import_client88.default.metadata.ExtraPlugins) ?? []];
83564
+ const allowedPlugins = [...(0, import_platform4.getPlugins)(), ...(0, import_platform4.getMetadata)(import_client89.default.metadata.ExtraPlugins) ?? []];
83565
83565
  const excludedPlugins = Array.from(configs.values()).filter(
83566
83566
  (it) => !it.enabled || !allowedPlugins.includes(it.pluginId) || extraFilter.includes(it.pluginId)
83567
83567
  );
@@ -83609,7 +83609,7 @@ var require_lib20 = __commonJS({
83609
83609
  }
83610
83610
  __name(returnClientTxes, "returnClientTxes");
83611
83611
  function createModelPersistence(workspace2) {
83612
- const overrideStore = (0, import_platform4.getMetadata)(import_client88.default.metadata.OverridePersistenceStore);
83612
+ const overrideStore = (0, import_platform4.getMetadata)(import_client89.default.metadata.OverridePersistenceStore);
83613
83613
  if (overrideStore !== void 0) {
83614
83614
  return overrideStore;
83615
83615
  }
@@ -83706,7 +83706,7 @@ var require_client6 = __commonJS({
83706
83706
  });
83707
83707
  module2.exports = __toCommonJS2(client_exports);
83708
83708
  var import_account_client2 = require_lib6();
83709
- var import_client88 = __toESM2(require_lib7());
83709
+ var import_client89 = __toESM2(require_lib7());
83710
83710
  var import_core105 = require_lib5();
83711
83711
  var import_platform4 = require_lib();
83712
83712
  var import_config10 = require_config();
@@ -83732,9 +83732,9 @@ var require_client6 = __commonJS({
83732
83732
  }
83733
83733
  __name(connect, "connect");
83734
83734
  async function createClient(url4, endpoint, token, workspaceUuid, account, config3, options) {
83735
- (0, import_platform4.addLocation)(import_client88.clientId, () => Promise.resolve().then(() => __toESM(require_lib20())));
83735
+ (0, import_platform4.addLocation)(import_client89.clientId, () => Promise.resolve().then(() => __toESM(require_lib20())));
83736
83736
  const { socketFactory, connectionTimeout } = options;
83737
- const clientFactory = await (0, import_platform4.getResource)(import_client88.default.function.GetClient);
83737
+ const clientFactory = await (0, import_platform4.getResource)(import_client89.default.function.GetClient);
83738
83738
  const connection = await clientFactory(token, endpoint, {
83739
83739
  socketFactory,
83740
83740
  connectionTimeout
@@ -84855,11 +84855,11 @@ var require_storage2 = __commonJS({
84855
84855
  var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
84856
84856
  var storage_exports = {};
84857
84857
  __export2(storage_exports, {
84858
- connectStorage: () => import_client88.connectStorage,
84859
- createStorageClient: () => import_client88.createStorageClient
84858
+ connectStorage: () => import_client89.connectStorage,
84859
+ createStorageClient: () => import_client89.createStorageClient
84860
84860
  });
84861
84861
  module2.exports = __toCommonJS2(storage_exports);
84862
- var import_client88 = require_client7();
84862
+ var import_client89 = require_client7();
84863
84863
  __reExport2(storage_exports, require_error3(), module2.exports);
84864
84864
  __reExport2(storage_exports, require_types8(), module2.exports);
84865
84865
  }
@@ -158122,6 +158122,16 @@ var InvalidStatusError = class extends Schema_exports.TaggedError()(
158122
158122
  return `Invalid status '${this.status}' for project '${this.project}'`;
158123
158123
  }
158124
158124
  };
158125
+ var IssueReferenceError = class extends Schema_exports.TaggedError()(
158126
+ "IssueReferenceError",
158127
+ {
158128
+ reason: Schema_exports.String
158129
+ }
158130
+ ) {
158131
+ get message() {
158132
+ return `Invalid issue references: ${this.reason}`;
158133
+ }
158134
+ };
158125
158135
  var CommentNotFoundError = class extends Schema_exports.TaggedError()(
158126
158136
  "CommentNotFoundError",
158127
158137
  {
@@ -158263,6 +158273,7 @@ var HulyDomainError = Schema_exports.Union(
158263
158273
  ViewletNotFoundError,
158264
158274
  ViewletIdentifierAmbiguousError,
158265
158275
  IssueNotFoundError,
158276
+ IssueReferenceError,
158266
158277
  ProjectNotFoundError,
158267
158278
  InvalidStatusError,
158268
158279
  ContactChannelConflictError,
@@ -169336,6 +169347,7 @@ var createErrorResponse = (text, errorCode, errorTag, warnings = []) => {
169336
169347
  };
169337
169348
  var INVALID_PARAMS_TAGS = /* @__PURE__ */ new Set([
169338
169349
  "IssueNotFoundError",
169350
+ "IssueReferenceError",
169339
169351
  "ApprovalRequestNotFoundError",
169340
169352
  "ApprovalRequestTargetNotFoundError",
169341
169353
  "ApprovalRequestInvalidApprovalThresholdError",
@@ -172850,7 +172862,7 @@ var CreateIssueParamsSchema = Schema_exports.Struct({
172850
172862
  description: "Issue title"
172851
172863
  }),
172852
172864
  description: Schema_exports.optional(Schema_exports.String.annotations({
172853
- description: "Issue description (markdown supported)"
172865
+ description: "Issue description in markdown. Markdown links to current-workspace Huly browse URLs with _class, _id, and label become native Huly references. External URLs and other-workspace browse URLs stay normal links."
172854
172866
  })),
172855
172867
  priority: Schema_exports.optional(IssuePrioritySchema.annotations({
172856
172868
  description: "Issue priority (urgent, high, medium, low, no-priority)"
@@ -172899,7 +172911,9 @@ var UpdateIssueParamsSchema = Schema_exports.Struct({
172899
172911
  title: Schema_exports.optional(NonEmptyString2.annotations({
172900
172912
  description: "New issue title"
172901
172913
  })),
172902
- description: Schema_exports.optional(clearableText("New issue description (markdown supported).")),
172914
+ description: Schema_exports.optional(clearableText(
172915
+ "New issue description in markdown. Markdown links to current-workspace Huly browse URLs with _class, _id, and label become native Huly references. External URLs and other-workspace browse URLs stay normal links."
172916
+ )),
172903
172917
  priority: Schema_exports.optional(IssuePrioritySchema.annotations({
172904
172918
  description: "New issue priority"
172905
172919
  })),
@@ -181626,7 +181640,7 @@ var parseDeleteDriveFileCommentParams = Schema_exports.decodeUnknown(DeleteDrive
181626
181640
  var parseListDriveFileActivityParams = Schema_exports.decodeUnknown(ListDriveFileActivityParamsSchema);
181627
181641
 
181628
181642
  // src/version.ts
181629
- var VERSION = true ? "0.44.0" : "0.0.0-dev";
181643
+ var VERSION = true ? "0.44.1" : "0.0.0-dev";
181630
181644
 
181631
181645
  // src/mcp/json-schema-refs.ts
181632
181646
  var isJsonObject = (value3) => typeof value3 === "object" && value3 !== null && !Array.isArray(value3);
@@ -182986,17 +183000,30 @@ var listDirectMessages = (params) => Effect_exports.gen(function* () {
182986
183000
  var import_core19 = __toESM(require_lib5(), 1);
182987
183001
  var import_rank = __toESM(require_lib37(), 1);
182988
183002
 
182989
- // src/huly/operations/document-native-references.ts
183003
+ // src/huly/operations/native-reference-markup.ts
182990
183004
  var malformedReferenceList = (entries2) => entries2.map((entry) => `'${entry}'`).join(", ");
183005
+ var renderMarkdownWithNativeReferencesForWrite = (content, urls, fieldName) => {
183006
+ const rendered = markdownToMarkupStringWithHulyLinks(content, urls);
183007
+ if (rendered.malformedReferences.length > 0) {
183008
+ return {
183009
+ _tag: "malformed",
183010
+ reason: `malformed Huly native reference links in ${fieldName}: ${malformedReferenceList(rendered.malformedReferences)}`
183011
+ };
183012
+ }
183013
+ return {
183014
+ _tag: "success",
183015
+ rendered: { markup: rendered.markup, format: "markup" }
183016
+ };
183017
+ };
183018
+
183019
+ // src/huly/operations/document-native-references.ts
182991
183020
  var renderDocumentContentForWrite = (content) => Effect_exports.gen(function* () {
182992
183021
  const client = yield* HulyClient;
182993
- const rendered = markdownToMarkupStringWithHulyLinks(content, client.markupUrlConfig);
182994
- if (rendered.malformedReferences.length > 0) {
182995
- return yield* new DocumentReferenceError({
182996
- reason: `malformed Huly native reference links in content: ${malformedReferenceList(rendered.malformedReferences)}`
182997
- });
183022
+ const rendered = renderMarkdownWithNativeReferencesForWrite(content, client.markupUrlConfig, "content");
183023
+ if (rendered._tag === "malformed") {
183024
+ return yield* new DocumentReferenceError({ reason: rendered.reason });
182998
183025
  }
182999
- return { markup: rendered.markup, format: "markup" };
183026
+ return rendered.rendered;
183000
183027
  });
183001
183028
 
183002
183029
  // src/huly/operations/documents-shared.ts
@@ -196712,6 +196739,16 @@ var getIssue = (params) => Effect_exports.gen(function* () {
196712
196739
  );
196713
196740
  });
196714
196741
 
196742
+ // src/huly/operations/issue-native-references.ts
196743
+ var renderIssueDescriptionForWrite = (description) => Effect_exports.gen(function* () {
196744
+ const client = yield* HulyClient;
196745
+ const rendered = renderMarkdownWithNativeReferencesForWrite(description, client.markupUrlConfig, "description");
196746
+ if (rendered._tag === "malformed") {
196747
+ return yield* new IssueReferenceError({ reason: rendered.reason });
196748
+ }
196749
+ return rendered.rendered;
196750
+ });
196751
+
196715
196752
  // src/huly/operations/issues-write-shared.ts
196716
196753
  var resolveAssignee = (client, assigneeIdentifier) => Effect_exports.gen(function* () {
196717
196754
  const person = yield* findPersonByEmailOrName(client, assigneeIdentifier);
@@ -196803,24 +196840,32 @@ var updateIssue = (params) => Effect_exports.gen(function* () {
196803
196840
  params.project
196804
196841
  );
196805
196842
  const descriptionUpdatedInPlace = params.description !== void 0 && textContentOrClear(params.description) !== void 0 && Boolean(issue2.description);
196843
+ const descriptionUpdateEntry = (operations) => coveredUpdateEntry("description", operations);
196806
196844
  const updateEntries = {
196807
196845
  title: Effect_exports.succeed(coveredUpdateEntry("title", params.title === void 0 ? {} : { title: params.title })),
196808
196846
  description: Effect_exports.gen(function* () {
196809
- if (params.description === void 0) return coveredUpdateEntry("description", {});
196847
+ if (params.description === void 0) return descriptionUpdateEntry({});
196810
196848
  const description = textContentOrClear(params.description);
196811
- if (description === void 0) return coveredUpdateEntry("description", { description: null });
196849
+ if (description === void 0) return descriptionUpdateEntry({ description: null });
196850
+ const renderedDescription = yield* renderIssueDescriptionForWrite(description);
196812
196851
  if (issue2.description) {
196813
- yield* client.updateMarkup(tracker.class.Issue, issue2._id, "description", description, "markdown");
196814
- return coveredUpdateEntry("description", {});
196852
+ yield* client.updateMarkup(
196853
+ tracker.class.Issue,
196854
+ issue2._id,
196855
+ "description",
196856
+ renderedDescription.markup,
196857
+ renderedDescription.format
196858
+ );
196859
+ return descriptionUpdateEntry({});
196815
196860
  }
196816
196861
  const descriptionMarkupRef = yield* client.uploadMarkup(
196817
196862
  tracker.class.Issue,
196818
196863
  issue2._id,
196819
196864
  "description",
196820
- description,
196821
- "markdown"
196865
+ renderedDescription.markup,
196866
+ renderedDescription.format
196822
196867
  );
196823
- return coveredUpdateEntry("description", { description: descriptionMarkupRef });
196868
+ return descriptionUpdateEntry({ description: descriptionMarkupRef });
196824
196869
  }),
196825
196870
  priority: Effect_exports.succeed(
196826
196871
  coveredUpdateEntry(
@@ -196901,6 +196946,7 @@ var createIssue = (params) => Effect_exports.gen(function* () {
196901
196946
  const taskTypeStatusRef = taskTypeWorkflow === void 0 ? void 0 : yield* chooseStatusForTaskType(taskTypeWorkflow, params.status, void 0, params.project);
196902
196947
  const statusRef = taskTypeStatusRef !== void 0 ? taskTypeStatusRef : params.status !== void 0 ? yield* resolveStatusByName(statuses, params.status, params.project) : defaultStatusId !== void 0 ? defaultStatusId : yield* Effect_exports.fail(new InvalidStatusError({ status: "(default)", project: params.project }));
196903
196948
  const assigneeRef = params.assignee !== void 0 ? (yield* resolveAssignee(client, params.assignee))._id : null;
196949
+ const renderedDescription = params.description !== void 0 && params.description.trim() !== "" ? yield* renderIssueDescriptionForWrite(params.description) : void 0;
196904
196950
  const parentIssueParam = params.parentIssue;
196905
196951
  const { attachedTo, attachedToClass, collection, parents } = parentIssueParam !== void 0 ? yield* Effect_exports.gen(function* () {
196906
196952
  const parentIssue = yield* findIssueInProject(client, project3, parentIssueParam);
@@ -196939,13 +196985,13 @@ var createIssue = (params) => Effect_exports.gen(function* () {
196939
196985
  { sort: { rank: import_core60.SortingOrder.Descending } }
196940
196986
  );
196941
196987
  const rank = (0, import_rank5.makeRank)(lastIssue?.rank, void 0);
196942
- const descriptionMarkupRef = params.description !== void 0 && params.description.trim() !== "" ? yield* client.uploadMarkup(
196988
+ const descriptionMarkupRef = renderedDescription === void 0 ? null : yield* client.uploadMarkup(
196943
196989
  tracker.class.Issue,
196944
196990
  issueId,
196945
196991
  "description",
196946
- params.description,
196947
- "markdown"
196948
- ) : null;
196992
+ renderedDescription.markup,
196993
+ renderedDescription.format
196994
+ );
196949
196995
  const priority = stringToPriority(params.priority ?? DEFAULT_ISSUE_PRIORITY);
196950
196996
  const identifier2 = `${project3.identifier}-${sequence}`;
196951
196997
  const issueData = {
@@ -197631,7 +197677,7 @@ var issueTools = [
197631
197677
  defineTool(
197632
197678
  {
197633
197679
  name: "create_issue",
197634
- description: "Create a new issue in a Huly project. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and status is validated against that task type's workflow. Use list_task_types or get_project_type to discover valid task types and statuses. Optionally create as a sub-issue by specifying parentIssue. Description supports markdown formatting. Returns the created issue identifier.",
197680
+ description: "Create a new issue in a Huly project. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and status is validated against that task type's workflow. Use list_task_types or get_project_type to discover valid task types and statuses. Optionally create as a sub-issue by specifying parentIssue. Description supports markdown formatting; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links. Returns the created issue identifier.",
197635
197681
  category: CATEGORY21,
197636
197682
  inputSchema: createIssueParamsJsonSchema,
197637
197683
  resultSchema: CreateIssueResultSchema
@@ -197642,7 +197688,7 @@ var issueTools = [
197642
197688
  defineTool(
197643
197689
  {
197644
197690
  name: "update_issue",
197645
- description: "Update fields on an existing Huly issue. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and the status is preserved only when valid for the new task type. Use list_task_types or get_project_type to discover valid task types and statuses. Only provided fields are modified. Description updates support markdown.",
197691
+ description: "Update fields on an existing Huly issue. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and the status is preserved only when valid for the new task type. Use list_task_types or get_project_type to discover valid task types and statuses. Only provided fields are modified. Description updates support markdown; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links.",
197646
197692
  category: CATEGORY21,
197647
197693
  inputSchema: updateIssueParamsJsonSchema,
197648
197694
  resultSchema: UpdateIssueResultSchema
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firfi/huly-mcp",
3
- "version": "0.44.0",
3
+ "version": "0.44.1",
4
4
  "description": "Huly MCP: feature-complete MCP server for Huly integration",
5
5
  "mcpName": "io.github.dearlordylord/huly-mcp",
6
6
  "type": "module",