@firfi/huly-mcp 0.30.1 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.cjs +307 -56
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -489,6 +489,7 @@ SDK upgrade revisit:
|
|
|
489
489
|
| `update_channel` | Update fields on an existing Huly channel. Only provided fields are modified. |
|
|
490
490
|
| `delete_channel` | Permanently delete a Huly channel. This action cannot be undone. For reversible channel lifecycle changes, use archive_channel and unarchive_channel instead. |
|
|
491
491
|
| `list_channel_messages` | List messages in a Huly channel. Returns messages sorted by date (newest first). |
|
|
492
|
+
| `list_external_channel_messages` | List read-only messages for an external Gmail or Telegram channel by channel name or ID. The limit defaults to 50 and is capped at 200. When this build does not include a compatible Huly external-message SDK/model for the requested provider, returns supported=false, an unsupportedReason, and an empty messages array; it never sends, replies, deletes, mutates, or returns fake messages. |
|
|
492
493
|
| `send_channel_message` | Send a message to a Huly channel. Message body supports markdown formatting. |
|
|
493
494
|
| `update_channel_message` | Update a channel message. Only the body can be modified. |
|
|
494
495
|
| `delete_channel_message` | Permanently delete a channel message. This action cannot be undone. |
|
package/dist/index.cjs
CHANGED
|
@@ -155260,6 +155260,10 @@ var HulyClient = class _HulyClient extends Context_exports.Tag("@hulymcp/HulyCli
|
|
|
155260
155260
|
(client2) => client2.findOne(_class, query, options),
|
|
155261
155261
|
"findOne failed"
|
|
155262
155262
|
),
|
|
155263
|
+
findAllInModel: (_class, query, options) => withClient(
|
|
155264
|
+
(client2) => Promise.resolve(client2.getModel().findAllSync(_class, query, options)),
|
|
155265
|
+
"findAllInModel failed"
|
|
155266
|
+
),
|
|
155263
155267
|
createDoc: (_class, space, attributes, id) => withClient(
|
|
155264
155268
|
(client2) => client2.createDoc(_class, space, attributes, id),
|
|
155265
155269
|
"createDoc failed"
|
|
@@ -155341,6 +155345,7 @@ var HulyClient = class _HulyClient extends Context_exports.Tag("@hulymcp/HulyCli
|
|
|
155341
155345
|
markupUrlConfig: testMarkupUrlConfig,
|
|
155342
155346
|
workbenchUrlConfig: testWorkbenchUrlConfig,
|
|
155343
155347
|
findAll: noopFindAll,
|
|
155348
|
+
findAllInModel: noopFindAll,
|
|
155344
155349
|
findOne: noopFindOne,
|
|
155345
155350
|
createDoc: notImplemented("createDoc"),
|
|
155346
155351
|
updateDoc: notImplemented("updateDoc"),
|
|
@@ -165740,11 +165745,14 @@ var McpErrorCode = {
|
|
|
165740
165745
|
InternalError: -32603,
|
|
165741
165746
|
ResourceNotFound: -32002
|
|
165742
165747
|
};
|
|
165743
|
-
var createErrorResponse = (text, errorCode, errorTag) =>
|
|
165744
|
-
|
|
165745
|
-
|
|
165746
|
-
|
|
165747
|
-
|
|
165748
|
+
var createErrorResponse = (text, errorCode, errorTag, warnings = []) => {
|
|
165749
|
+
const warningContent = warnings.length > 0 ? [{ type: "text", text: encodeJsonText({ warnings }) }] : [];
|
|
165750
|
+
return {
|
|
165751
|
+
content: [{ type: "text", text }, ...warningContent],
|
|
165752
|
+
isError: true,
|
|
165753
|
+
_meta: { errorCode, errorTag }
|
|
165754
|
+
};
|
|
165755
|
+
};
|
|
165748
165756
|
var INVALID_PARAMS_TAGS = /* @__PURE__ */ new Set([
|
|
165749
165757
|
"IssueNotFoundError",
|
|
165750
165758
|
"ProjectNotFoundError",
|
|
@@ -165857,13 +165865,13 @@ var INTERNAL_ERROR_PREFIX = {
|
|
|
165857
165865
|
HulyConnectionError: "Connection error",
|
|
165858
165866
|
HulyAuthError: "Authentication error"
|
|
165859
165867
|
};
|
|
165860
|
-
var mapDomainErrorToMcp = (error2) => {
|
|
165868
|
+
var mapDomainErrorToMcp = (error2, warnings = []) => {
|
|
165861
165869
|
if (INVALID_PARAMS_TAGS.has(error2._tag)) {
|
|
165862
|
-
return createErrorResponse(error2.message, McpErrorCode.InvalidParams);
|
|
165870
|
+
return createErrorResponse(error2.message, McpErrorCode.InvalidParams, void 0, warnings);
|
|
165863
165871
|
}
|
|
165864
165872
|
const prefix = INTERNAL_ERROR_PREFIX[error2._tag];
|
|
165865
165873
|
const message = prefix !== void 0 ? `${prefix}: ${error2.message}` : error2.message;
|
|
165866
|
-
return createErrorResponse(message, McpErrorCode.InternalError, error2._tag);
|
|
165874
|
+
return createErrorResponse(message, McpErrorCode.InternalError, error2._tag, warnings);
|
|
165867
165875
|
};
|
|
165868
165876
|
var formatParseError = (error2) => {
|
|
165869
165877
|
const issues = ParseResult_exports.ArrayFormatter.formatErrorSync(error2);
|
|
@@ -165884,34 +165892,44 @@ var mapParseCauseToMcp = (cause3, toolName) => {
|
|
|
165884
165892
|
}
|
|
165885
165893
|
return createErrorResponse("An unexpected error occurred", McpErrorCode.InternalError);
|
|
165886
165894
|
};
|
|
165887
|
-
var mapDomainCauseToMcp = (cause3) => {
|
|
165895
|
+
var mapDomainCauseToMcp = (cause3, warnings = []) => {
|
|
165888
165896
|
if (Cause_exports.isFailType(cause3)) {
|
|
165889
|
-
return mapDomainErrorToMcp(cause3.error);
|
|
165897
|
+
return mapDomainErrorToMcp(cause3.error, warnings);
|
|
165890
165898
|
}
|
|
165891
165899
|
if (Cause_exports.isDieType(cause3)) {
|
|
165892
|
-
return createErrorResponse("An unexpected error occurred", McpErrorCode.InternalError, "UnexpectedError");
|
|
165900
|
+
return createErrorResponse("An unexpected error occurred", McpErrorCode.InternalError, "UnexpectedError", warnings);
|
|
165893
165901
|
}
|
|
165894
165902
|
const failures3 = Chunk_exports.toArray(Cause_exports.failures(cause3));
|
|
165895
165903
|
if (failures3.length > 0) {
|
|
165896
|
-
return mapDomainErrorToMcp(failures3[0]);
|
|
165904
|
+
return mapDomainErrorToMcp(failures3[0], warnings);
|
|
165897
165905
|
}
|
|
165898
|
-
return createErrorResponse("An unexpected error occurred", McpErrorCode.InternalError);
|
|
165906
|
+
return createErrorResponse("An unexpected error occurred", McpErrorCode.InternalError, void 0, warnings);
|
|
165899
165907
|
};
|
|
165900
165908
|
var encodeJsonText = (value3) => {
|
|
165901
165909
|
const text = JSON.stringify(value3);
|
|
165902
165910
|
return typeof text === "string" ? text : "null";
|
|
165903
165911
|
};
|
|
165904
|
-
var createSuccessResponse = (result) => ({
|
|
165905
|
-
content: [
|
|
165906
|
-
|
|
165912
|
+
var createSuccessResponse = (result, warnings = []) => ({
|
|
165913
|
+
content: [
|
|
165914
|
+
{ type: "text", text: encodeJsonText(result) },
|
|
165915
|
+
...warnings.length > 0 ? [{ type: "text", text: encodeJsonText({ warnings }) }] : []
|
|
165916
|
+
],
|
|
165917
|
+
structuredContent: warnings.length > 0 ? {
|
|
165918
|
+
result,
|
|
165919
|
+
warnings
|
|
165920
|
+
} : {
|
|
165907
165921
|
result
|
|
165908
165922
|
}
|
|
165909
165923
|
});
|
|
165910
165924
|
var createUnknownToolError = (toolName) => createErrorResponse(`Unknown tool: ${toolName}`, McpErrorCode.InvalidParams, "UnknownTool");
|
|
165911
165925
|
var createInvalidParamsError = (message, errorTag) => createErrorResponse(message, McpErrorCode.InvalidParams, errorTag);
|
|
165912
|
-
var toMcpResponse = (response) => {
|
|
165913
|
-
|
|
165914
|
-
|
|
165926
|
+
var toMcpResponse = (response) => response.isError === true ? {
|
|
165927
|
+
content: response.content,
|
|
165928
|
+
isError: true
|
|
165929
|
+
} : {
|
|
165930
|
+
content: response.content,
|
|
165931
|
+
...response.structuredContent === void 0 ? {} : { structuredContent: response.structuredContent },
|
|
165932
|
+
...response.isError === void 0 ? {} : { isError: response.isError }
|
|
165915
165933
|
};
|
|
165916
165934
|
|
|
165917
165935
|
// src/mcp/http-2026-dispatcher.ts
|
|
@@ -166468,6 +166486,24 @@ var StdioServerTransport = class {
|
|
|
166468
166486
|
}
|
|
166469
166487
|
};
|
|
166470
166488
|
|
|
166489
|
+
// src/domain/schemas/tool-warnings.ts
|
|
166490
|
+
var ToolWarningCodeSchema = Schema_exports.Literal("status_metadata_unresolved").annotations({
|
|
166491
|
+
identifier: "ToolWarningCode",
|
|
166492
|
+
title: "ToolWarningCode",
|
|
166493
|
+
description: "Machine-readable code for an agent-visible MCP tool warning."
|
|
166494
|
+
});
|
|
166495
|
+
var StatusMetadataUnresolvedWarningCode = ToolWarningCodeSchema.literals[0];
|
|
166496
|
+
var ToolWarningSchema = Schema_exports.Struct({
|
|
166497
|
+
code: ToolWarningCodeSchema,
|
|
166498
|
+
message: Schema_exports.Trim.pipe(Schema_exports.nonEmptyString()).annotations({
|
|
166499
|
+
description: "LLM-facing explanation of what part of the returned tool payload is degraded and how the agent should interpret it."
|
|
166500
|
+
})
|
|
166501
|
+
}).annotations({
|
|
166502
|
+
identifier: "ToolWarning",
|
|
166503
|
+
title: "ToolWarning",
|
|
166504
|
+
description: "Warning surfaced to an agent when a tool result is intentionally degraded instead of failing."
|
|
166505
|
+
});
|
|
166506
|
+
|
|
166471
166507
|
// src/domain/schemas/recurrence-primitives.ts
|
|
166472
166508
|
var MAX_ZERO_BASED_MONTH_INDEX = 11;
|
|
166473
166509
|
var MAX_MONTH_DAY = 31;
|
|
@@ -167252,6 +167288,7 @@ var ProjectTypeDetailSchema = Schema_exports.Struct({
|
|
|
167252
167288
|
descriptor: NonEmptyString2,
|
|
167253
167289
|
classic: Schema_exports.Boolean,
|
|
167254
167290
|
isDefaultClassic: Schema_exports.Boolean,
|
|
167291
|
+
statusCount: Count,
|
|
167255
167292
|
taskTypes: Schema_exports.Array(TaskTypeSummarySchema),
|
|
167256
167293
|
statuses: Schema_exports.Array(IssueStatusSummarySchema),
|
|
167257
167294
|
statusCategories: Schema_exports.Array(StatusCategorySummarySchema),
|
|
@@ -170099,6 +170136,91 @@ var parseUpdatePersonParams = Schema_exports.decodeUnknown(UpdatePersonParamsSch
|
|
|
170099
170136
|
var parseDeletePersonParams = Schema_exports.decodeUnknown(DeletePersonParamsSchema);
|
|
170100
170137
|
var parseListEmployeesParams = Schema_exports.decodeUnknown(ListEmployeesParamsSchema);
|
|
170101
170138
|
|
|
170139
|
+
// src/domain/schemas/external-channel-messages.ts
|
|
170140
|
+
var ExternalChannelMessageProviderValues = ["gmail", "telegram"];
|
|
170141
|
+
var ExternalChannelMessageProviderSchema = Schema_exports.Literal(...ExternalChannelMessageProviderValues);
|
|
170142
|
+
var DEFAULT_EXTERNAL_CHANNEL_MESSAGE_LIMIT = DEFAULT_LIMIT;
|
|
170143
|
+
var ListExternalChannelMessagesParamsSchema = Schema_exports.Struct({
|
|
170144
|
+
provider: ExternalChannelMessageProviderSchema.annotations({
|
|
170145
|
+
description: "External provider to read from. Supported locator values are validated for gmail and telegram; providers without a compatible installed Huly message SDK return structured unsupported results instead of fake data."
|
|
170146
|
+
}),
|
|
170147
|
+
channel: ChannelIdentifier.annotations({
|
|
170148
|
+
description: "External channel name or Huly channel ID locator, such as a Gmail label/inbox name or Telegram chat name/id."
|
|
170149
|
+
}),
|
|
170150
|
+
limit: Schema_exports.optional(LimitParam.annotations({
|
|
170151
|
+
description: `Maximum number of external messages to return (default: ${DEFAULT_EXTERNAL_CHANNEL_MESSAGE_LIMIT}, max: 200).`
|
|
170152
|
+
}))
|
|
170153
|
+
}).annotations({
|
|
170154
|
+
title: "ListExternalChannelMessagesParams",
|
|
170155
|
+
description: "Parameters for listing read-only Gmail or Telegram external channel messages."
|
|
170156
|
+
});
|
|
170157
|
+
var ExternalChannelMessageId = NonEmptyString2.pipe(Schema_exports.brand("ExternalChannelMessageId")).annotations({
|
|
170158
|
+
identifier: "ExternalChannelMessageId",
|
|
170159
|
+
title: "ExternalChannelMessageId",
|
|
170160
|
+
description: "Opaque external provider message ID."
|
|
170161
|
+
});
|
|
170162
|
+
var ExternalChannelMessageSubject = NonEmptyString2.pipe(
|
|
170163
|
+
Schema_exports.brand("ExternalChannelMessageSubject")
|
|
170164
|
+
).annotations({
|
|
170165
|
+
identifier: "ExternalChannelMessageSubject",
|
|
170166
|
+
title: "ExternalChannelMessageSubject",
|
|
170167
|
+
description: "Non-empty external message subject. Omit the field when the provider has no subject value."
|
|
170168
|
+
});
|
|
170169
|
+
var ExternalChannelMessageSender = NonEmptyString2.pipe(Schema_exports.brand("ExternalChannelMessageSender")).annotations({
|
|
170170
|
+
identifier: "ExternalChannelMessageSender",
|
|
170171
|
+
title: "ExternalChannelMessageSender",
|
|
170172
|
+
description: "Non-empty normalized external message sender label or address."
|
|
170173
|
+
});
|
|
170174
|
+
var ExternalChannelMessageSenderId = NonEmptyString2.pipe(Schema_exports.brand("ExternalChannelMessageSenderId")).annotations({
|
|
170175
|
+
identifier: "ExternalChannelMessageSenderId",
|
|
170176
|
+
title: "ExternalChannelMessageSenderId",
|
|
170177
|
+
description: "Non-empty opaque external provider sender ID."
|
|
170178
|
+
});
|
|
170179
|
+
var ExternalChannelMessageSummarySchema = Schema_exports.Struct({
|
|
170180
|
+
id: ExternalChannelMessageId,
|
|
170181
|
+
subject: Schema_exports.optional(ExternalChannelMessageSubject),
|
|
170182
|
+
bodyPreview: NonEmptyString2,
|
|
170183
|
+
sender: Schema_exports.optional(ExternalChannelMessageSender),
|
|
170184
|
+
senderId: Schema_exports.optional(ExternalChannelMessageSenderId),
|
|
170185
|
+
createdOn: Schema_exports.optional(Timestamp),
|
|
170186
|
+
modifiedOn: Schema_exports.optional(Timestamp),
|
|
170187
|
+
url: Schema_exports.optional(UrlString)
|
|
170188
|
+
}).annotations({
|
|
170189
|
+
title: "ExternalChannelMessageSummary",
|
|
170190
|
+
description: "Normalized read-only summary of one external Gmail or Telegram message."
|
|
170191
|
+
});
|
|
170192
|
+
var ListExternalChannelMessagesSupportedResultSchema = Schema_exports.Struct({
|
|
170193
|
+
supported: Schema_exports.Literal(true),
|
|
170194
|
+
provider: ExternalChannelMessageProviderSchema,
|
|
170195
|
+
channel: ChannelIdentifier,
|
|
170196
|
+
limit: LimitParam,
|
|
170197
|
+
messages: Schema_exports.Array(ExternalChannelMessageSummarySchema)
|
|
170198
|
+
}).annotations({
|
|
170199
|
+
title: "ListExternalChannelMessagesSupportedResult",
|
|
170200
|
+
description: "External channel messages returned from a compatible installed Huly provider SDK/model."
|
|
170201
|
+
});
|
|
170202
|
+
var ListExternalChannelMessagesUnsupportedResultSchema = Schema_exports.Struct({
|
|
170203
|
+
supported: Schema_exports.Literal(false),
|
|
170204
|
+
provider: ExternalChannelMessageProviderSchema,
|
|
170205
|
+
channel: ChannelIdentifier,
|
|
170206
|
+
limit: LimitParam,
|
|
170207
|
+
unsupportedReason: NonEmptyString2,
|
|
170208
|
+
messages: Schema_exports.Tuple()
|
|
170209
|
+
}).annotations({
|
|
170210
|
+
title: "ListExternalChannelMessagesUnsupportedResult",
|
|
170211
|
+
description: "Explicit no-fake-data result when the requested external provider cannot be read in this build."
|
|
170212
|
+
});
|
|
170213
|
+
var ListExternalChannelMessagesResultSchema = Schema_exports.Union(
|
|
170214
|
+
ListExternalChannelMessagesSupportedResultSchema,
|
|
170215
|
+
ListExternalChannelMessagesUnsupportedResultSchema
|
|
170216
|
+
).annotations({
|
|
170217
|
+
title: "ListExternalChannelMessagesResult",
|
|
170218
|
+
description: "Read-only external channel message listing result."
|
|
170219
|
+
});
|
|
170220
|
+
var listExternalChannelMessagesParamsJsonSchema = JSONSchema_exports.make(ListExternalChannelMessagesParamsSchema);
|
|
170221
|
+
var parseListExternalChannelMessagesParams = Schema_exports.decodeUnknown(ListExternalChannelMessagesParamsSchema);
|
|
170222
|
+
var encodeListExternalChannelMessagesResult = Schema_exports.encodeSync(ListExternalChannelMessagesResultSchema);
|
|
170223
|
+
|
|
170102
170224
|
// src/domain/schemas/channels.ts
|
|
170103
170225
|
var ListChannelsParamsBase = Schema_exports.Struct({
|
|
170104
170226
|
nameSearch: Schema_exports.optional(Schema_exports.String.annotations({
|
|
@@ -174502,15 +174624,52 @@ var parseUpdateDriveFileCommentParams = Schema_exports.decodeUnknown(UpdateDrive
|
|
|
174502
174624
|
var parseDeleteDriveFileCommentParams = Schema_exports.decodeUnknown(DeleteDriveFileCommentParamsSchema);
|
|
174503
174625
|
var parseListDriveFileActivityParams = Schema_exports.decodeUnknown(ListDriveFileActivityParamsSchema);
|
|
174504
174626
|
|
|
174627
|
+
// src/huly/diagnostics.ts
|
|
174628
|
+
var Diagnostics = class extends Context_exports.Tag("@hulymcp/Diagnostics")() {
|
|
174629
|
+
};
|
|
174630
|
+
var warningLogText = (warning) => `Agent-visible tool warning [${warning.code}]: ${warning.message}`;
|
|
174631
|
+
var makeDiagnosticsScope = Effect_exports.gen(function* () {
|
|
174632
|
+
const warningsRef = yield* Ref_exports.make([]);
|
|
174633
|
+
return {
|
|
174634
|
+
service: {
|
|
174635
|
+
warnAgent: (warning) => Ref_exports.update(warningsRef, (warnings) => [...warnings, warning]).pipe(
|
|
174636
|
+
Effect_exports.zipRight(Effect_exports.logWarning(warningLogText(warning)))
|
|
174637
|
+
),
|
|
174638
|
+
trail: (message) => Effect_exports.logInfo(`Diagnostic trail: ${message}`)
|
|
174639
|
+
},
|
|
174640
|
+
drainWarnings: Ref_exports.get(warningsRef)
|
|
174641
|
+
};
|
|
174642
|
+
});
|
|
174643
|
+
|
|
174505
174644
|
// src/version.ts
|
|
174506
|
-
var VERSION = true ? "0.
|
|
174645
|
+
var VERSION = true ? "0.31.0" : "0.0.0-dev";
|
|
174507
174646
|
|
|
174508
174647
|
// src/mcp/tool-output-schema.ts
|
|
174648
|
+
var toolWarningCodeEnum = [...ToolWarningCodeSchema.literals];
|
|
174509
174649
|
var defaultToolOutputSchema = {
|
|
174510
174650
|
type: "object",
|
|
174511
174651
|
properties: {
|
|
174512
174652
|
result: {
|
|
174513
174653
|
description: "The successful tool result. The same value is also serialized as JSON in the text content for clients that do not read structuredContent."
|
|
174654
|
+
},
|
|
174655
|
+
warnings: {
|
|
174656
|
+
type: "array",
|
|
174657
|
+
description: "Optional agent-visible warnings about degraded result fidelity. Omitted when the server returned the documented happy-path payload.",
|
|
174658
|
+
items: {
|
|
174659
|
+
type: "object",
|
|
174660
|
+
properties: {
|
|
174661
|
+
code: {
|
|
174662
|
+
type: "string",
|
|
174663
|
+
enum: toolWarningCodeEnum
|
|
174664
|
+
},
|
|
174665
|
+
message: {
|
|
174666
|
+
type: "string",
|
|
174667
|
+
minLength: 1
|
|
174668
|
+
}
|
|
174669
|
+
},
|
|
174670
|
+
required: ["code", "message"],
|
|
174671
|
+
additionalProperties: false
|
|
174672
|
+
}
|
|
174514
174673
|
}
|
|
174515
174674
|
},
|
|
174516
174675
|
required: ["result"]
|
|
@@ -176182,7 +176341,7 @@ var findProject = (projectIdentifier) => Effect_exports.gen(function* () {
|
|
|
176182
176341
|
);
|
|
176183
176342
|
return { client, project: project3 };
|
|
176184
176343
|
});
|
|
176185
|
-
var statusCategoryValueFromRef = (category) => category === void 0 ?
|
|
176344
|
+
var statusCategoryValueFromRef = (category) => category === void 0 ? UnknownStatusCategoryValue : StatusCategoryEntries.find((entry) => entry.ref === category)?.key ?? UnknownStatusCategoryValue;
|
|
176186
176345
|
var workflowStatusFromDoc = (doc) => {
|
|
176187
176346
|
return {
|
|
176188
176347
|
_id: doc._id,
|
|
@@ -176195,7 +176354,7 @@ var workflowStatusFromRef = (statusRef) => {
|
|
|
176195
176354
|
return {
|
|
176196
176355
|
_id: statusRef,
|
|
176197
176356
|
name,
|
|
176198
|
-
category:
|
|
176357
|
+
category: UnknownStatusCategoryValue
|
|
176199
176358
|
};
|
|
176200
176359
|
};
|
|
176201
176360
|
var uniqueStatusRefs = (refs) => refs.reduce(
|
|
@@ -176207,6 +176366,51 @@ var uniqueStatusDocs = (statuses) => Array.from(statuses).reduce(
|
|
|
176207
176366
|
[]
|
|
176208
176367
|
);
|
|
176209
176368
|
var uniqueProjectTypeStatusRefs = (statuses) => uniqueStatusRefs(statuses.map((status) => status._id));
|
|
176369
|
+
var missingStatusRefs = (statusRefs, statusDocs) => statusRefs.filter((statusRef) => !statusDocs.some((statusDoc) => statusDoc._id === statusRef));
|
|
176370
|
+
var resolveByStatusRef = (statusRefs, statusDocs, fromDoc, fromRef) => {
|
|
176371
|
+
const statusDocsById = new Map(statusDocs.map((statusDoc) => [statusDoc._id, statusDoc]));
|
|
176372
|
+
return statusRefs.map((statusRef) => {
|
|
176373
|
+
const statusDoc = statusDocsById.get(statusRef);
|
|
176374
|
+
return statusDoc === void 0 ? fromRef(statusRef) : fromDoc(statusDoc);
|
|
176375
|
+
});
|
|
176376
|
+
};
|
|
176377
|
+
var workflowStatusesFromDocsOrRefs = (statusRefs, statusDocs) => resolveByStatusRef(statusRefs, statusDocs, workflowStatusFromDoc, workflowStatusFromRef);
|
|
176378
|
+
var findStatusDocs = (client, statusRefs) => Effect_exports.gen(function* () {
|
|
176379
|
+
const diagnostics = yield* Diagnostics;
|
|
176380
|
+
const remoteResult = yield* Effect_exports.either(
|
|
176381
|
+
client.findAll(
|
|
176382
|
+
core.class.Status,
|
|
176383
|
+
hulyQuery({ _id: { $in: [...statusRefs] } })
|
|
176384
|
+
)
|
|
176385
|
+
);
|
|
176386
|
+
const remoteDocs = remoteResult._tag === "Right" ? uniqueStatusDocs(remoteResult.right) : [];
|
|
176387
|
+
const unresolvedRefs = missingStatusRefs(statusRefs, remoteDocs);
|
|
176388
|
+
if (unresolvedRefs.length === 0) {
|
|
176389
|
+
return remoteDocs;
|
|
176390
|
+
}
|
|
176391
|
+
const modelResult = yield* Effect_exports.either(
|
|
176392
|
+
client.findAllInModel(
|
|
176393
|
+
core.class.Status,
|
|
176394
|
+
hulyQuery({ _id: { $in: unresolvedRefs } })
|
|
176395
|
+
)
|
|
176396
|
+
);
|
|
176397
|
+
const modelDocs = modelResult._tag === "Right" ? uniqueStatusDocs(modelResult.right) : [];
|
|
176398
|
+
const combinedDocs = uniqueStatusDocs([...remoteDocs, ...modelDocs]);
|
|
176399
|
+
const stillUnresolvedRefs = missingStatusRefs(statusRefs, combinedDocs);
|
|
176400
|
+
if (stillUnresolvedRefs.length > 0) {
|
|
176401
|
+
const remoteError = remoteResult._tag === "Left" ? ` Remote error: ${remoteResult.left.message}` : "";
|
|
176402
|
+
const modelError = modelResult._tag === "Left" ? ` Model error: ${modelResult.left.message}` : "";
|
|
176403
|
+
yield* diagnostics.warnAgent({
|
|
176404
|
+
code: StatusMetadataUnresolvedWarningCode,
|
|
176405
|
+
message: `Huly did not return metadata for ${stillUnresolvedRefs.length} workflow status ref(s). The tool result uses ref-derived status names and category "${UnknownStatusCategoryValue}" for those statuses; do not infer completion or cancellation semantics from those fallback names.${remoteError}${modelError}`
|
|
176406
|
+
});
|
|
176407
|
+
} else if (remoteResult._tag === "Left") {
|
|
176408
|
+
yield* diagnostics.trail(
|
|
176409
|
+
`Server status metadata lookup failed, but the local Huly model resolved all requested workflow statuses. Remote error: ${remoteResult.left.message}`
|
|
176410
|
+
);
|
|
176411
|
+
}
|
|
176412
|
+
return combinedDocs;
|
|
176413
|
+
});
|
|
176210
176414
|
var findProjectWithStatuses = (projectIdentifier) => Effect_exports.gen(function* () {
|
|
176211
176415
|
const client = yield* HulyClient;
|
|
176212
176416
|
const project3 = yield* findOneOrFail(
|
|
@@ -176222,19 +176426,8 @@ var findProjectWithStatuses = (projectIdentifier) => Effect_exports.gen(function
|
|
|
176222
176426
|
if (statusRefs.length === 0) {
|
|
176223
176427
|
return [];
|
|
176224
176428
|
}
|
|
176225
|
-
const
|
|
176226
|
-
|
|
176227
|
-
core.class.Status,
|
|
176228
|
-
hulyQuery({ _id: { $in: statusRefs } })
|
|
176229
|
-
)
|
|
176230
|
-
);
|
|
176231
|
-
if (statusDocsResult._tag === "Right") {
|
|
176232
|
-
return uniqueStatusDocs(statusDocsResult.right).map(workflowStatusFromDoc);
|
|
176233
|
-
}
|
|
176234
|
-
yield* Effect_exports.logWarning(
|
|
176235
|
-
`Status query failed for project ${projectIdentifier}, using fallback. statusCategory filtering is unavailable until Huly returns status metadata. Error: ${statusDocsResult.left.message}`
|
|
176236
|
-
);
|
|
176237
|
-
return statusRefs.map(workflowStatusFromRef);
|
|
176429
|
+
const statusDocs = yield* findStatusDocs(client, statusRefs);
|
|
176430
|
+
return workflowStatusesFromDocsOrRefs(statusRefs, statusDocs);
|
|
176238
176431
|
}) : [];
|
|
176239
176432
|
const defaultStatusId = project3.defaultIssueStatus || statuses[0]?._id;
|
|
176240
176433
|
return { client, defaultStatusId, project: project3, projectType, statuses };
|
|
@@ -176598,19 +176791,27 @@ var createHandler = (toolName, provide4, parse5, operation, encode8) => async (a
|
|
|
176598
176791
|
if (Exit_exports.isFailure(parseResult)) {
|
|
176599
176792
|
return mapParseCauseToMcp(parseResult.cause, toolName);
|
|
176600
176793
|
}
|
|
176601
|
-
const
|
|
176794
|
+
const diagnosticsScope = await Effect_exports.runPromise(makeDiagnosticsScope);
|
|
176795
|
+
const provided = provide4({
|
|
176796
|
+
hulyClient,
|
|
176797
|
+
storageClient,
|
|
176798
|
+
workspaceClient
|
|
176799
|
+
})(operation(parseResult.value));
|
|
176602
176800
|
if (Either_exports.isLeft(provided)) {
|
|
176603
176801
|
return provided.left;
|
|
176604
176802
|
}
|
|
176605
|
-
const operationResult = await Effect_exports.runPromiseExit(
|
|
176803
|
+
const operationResult = await Effect_exports.runPromiseExit(
|
|
176804
|
+
provided.right.pipe(Effect_exports.provideService(Diagnostics, diagnosticsScope.service))
|
|
176805
|
+
);
|
|
176806
|
+
const warnings = await Effect_exports.runPromise(diagnosticsScope.drainWarnings);
|
|
176606
176807
|
if (Exit_exports.isFailure(operationResult)) {
|
|
176607
|
-
return mapDomainCauseToMcp(operationResult.cause);
|
|
176808
|
+
return mapDomainCauseToMcp(operationResult.cause, warnings);
|
|
176608
176809
|
}
|
|
176609
176810
|
try {
|
|
176610
176811
|
const output = encode8 !== void 0 ? encode8(operationResult.value) : operationResult.value;
|
|
176611
|
-
return createSuccessResponse(output);
|
|
176812
|
+
return createSuccessResponse(output, warnings);
|
|
176612
176813
|
} catch {
|
|
176613
|
-
return mapDomainErrorToMcp(new HulyError({ message: `Tool ${toolName} produced invalid output` }));
|
|
176814
|
+
return mapDomainErrorToMcp(new HulyError({ message: `Tool ${toolName} produced invalid output` }), warnings);
|
|
176614
176815
|
}
|
|
176615
176816
|
};
|
|
176616
176817
|
var createToolHandler = (toolName, parse5, operation) => createHandler(toolName, provideHulyClient, parse5, operation);
|
|
@@ -179513,6 +179714,19 @@ var createDirectMessage = (params) => Effect_exports.gen(function* () {
|
|
|
179513
179714
|
return { id: ChannelId.make(dmId), created: true };
|
|
179514
179715
|
});
|
|
179515
179716
|
|
|
179717
|
+
// src/huly/operations/external-channel-messages.ts
|
|
179718
|
+
var EXTERNAL_CHANNEL_PACKAGE_INCOMPATIBLE_REASON = "package-incompatible: package.json and pnpm-lock.yaml include @hcengineering/contact provider refs for email/telegram, but no compatible Huly Gmail or Telegram message SDK package/model is installed; local platform-api examples only expose contact.class.Channel provider values, not external message documents";
|
|
179719
|
+
var listExternalChannelMessages = (params) => Effect_exports.sync(
|
|
179720
|
+
() => encodeListExternalChannelMessagesResult({
|
|
179721
|
+
supported: false,
|
|
179722
|
+
provider: params.provider,
|
|
179723
|
+
channel: params.channel,
|
|
179724
|
+
limit: params.limit ?? DEFAULT_EXTERNAL_CHANNEL_MESSAGE_LIMIT,
|
|
179725
|
+
unsupportedReason: EXTERNAL_CHANNEL_PACKAGE_INCOMPATIBLE_REASON,
|
|
179726
|
+
messages: []
|
|
179727
|
+
})
|
|
179728
|
+
);
|
|
179729
|
+
|
|
179516
179730
|
// src/huly/operations/threads.ts
|
|
179517
179731
|
var import_core31 = __toESM(require_lib4(), 1);
|
|
179518
179732
|
var findReply = (client, channel, message, replyId) => Effect_exports.gen(function* () {
|
|
@@ -179806,6 +180020,17 @@ var channelTools = [
|
|
|
179806
180020
|
listChannelMessages
|
|
179807
180021
|
)
|
|
179808
180022
|
},
|
|
180023
|
+
{
|
|
180024
|
+
name: "list_external_channel_messages",
|
|
180025
|
+
description: "List read-only messages for an external Gmail or Telegram channel by channel name or ID. The limit defaults to 50 and is capped at 200. When this build does not include a compatible Huly external-message SDK/model for the requested provider, returns supported=false, an unsupportedReason, and an empty messages array; it never sends, replies, deletes, mutates, or returns fake messages.",
|
|
180026
|
+
category: CATEGORY6,
|
|
180027
|
+
inputSchema: listExternalChannelMessagesParamsJsonSchema,
|
|
180028
|
+
handler: createToolHandler(
|
|
180029
|
+
"list_external_channel_messages",
|
|
180030
|
+
parseListExternalChannelMessagesParams,
|
|
180031
|
+
listExternalChannelMessages
|
|
180032
|
+
)
|
|
180033
|
+
},
|
|
179809
180034
|
{
|
|
179810
180035
|
name: "send_channel_message",
|
|
179811
180036
|
description: "Send a message to a Huly channel. Message body supports markdown formatting.",
|
|
@@ -186694,6 +186919,18 @@ var labelTools = [
|
|
|
186694
186919
|
// src/huly/operations/leads.ts
|
|
186695
186920
|
var import_core50 = __toESM(require_lib4(), 1);
|
|
186696
186921
|
var funnelAsSpace = (funnel) => toRef(funnel._id);
|
|
186922
|
+
var statusInfosWithFallbacks = (statusRefs, statusDocs) => resolveByStatusRef(
|
|
186923
|
+
statusRefs,
|
|
186924
|
+
statusDocs,
|
|
186925
|
+
(statusDoc) => ({
|
|
186926
|
+
_id: statusDoc._id,
|
|
186927
|
+
name: statusDoc.name
|
|
186928
|
+
}),
|
|
186929
|
+
(statusRef) => ({
|
|
186930
|
+
_id: statusRef,
|
|
186931
|
+
name: workflowStatusFromRef(statusRef).name
|
|
186932
|
+
})
|
|
186933
|
+
);
|
|
186697
186934
|
var markupBlobRefAsMarkupRef = (value3) => value3;
|
|
186698
186935
|
var normalizeLeadIdentifier = (identifier2) => {
|
|
186699
186936
|
const match16 = /^(?:LEAD-)?(\d+)$/i.exec(identifier2.trim());
|
|
@@ -186742,7 +186979,7 @@ var getFunnelStatuses = (client, funnel) => Effect_exports.gen(function* () {
|
|
|
186742
186979
|
})
|
|
186743
186980
|
);
|
|
186744
186981
|
}
|
|
186745
|
-
const statusRefs = projectType.statuses.map((status) => status._id);
|
|
186982
|
+
const statusRefs = uniqueStatusRefs(projectType.statuses.map((status) => status._id));
|
|
186746
186983
|
if (statusRefs.length === 0) {
|
|
186747
186984
|
return yield* Effect_exports.fail(
|
|
186748
186985
|
new HulyConnectionError({
|
|
@@ -186750,14 +186987,8 @@ var getFunnelStatuses = (client, funnel) => Effect_exports.gen(function* () {
|
|
|
186750
186987
|
})
|
|
186751
186988
|
);
|
|
186752
186989
|
}
|
|
186753
|
-
const statusDocs = yield* client
|
|
186754
|
-
|
|
186755
|
-
{ _id: { $in: [...statusRefs] } }
|
|
186756
|
-
);
|
|
186757
|
-
return statusDocs.map((doc) => ({
|
|
186758
|
-
_id: doc._id,
|
|
186759
|
-
name: doc.name
|
|
186760
|
-
}));
|
|
186990
|
+
const statusDocs = yield* findStatusDocs(client, statusRefs);
|
|
186991
|
+
return statusInfosWithFallbacks(statusRefs, statusDocs);
|
|
186761
186992
|
});
|
|
186762
186993
|
var resolveStatusName2 = (statuses, statusId) => {
|
|
186763
186994
|
const statusDoc = statuses.find((status) => status._id === statusId);
|
|
@@ -190591,7 +190822,7 @@ var STATUS_CATEGORIES = Object.values(STATUS_CATEGORY_BY_SDK_KEY).map((entry) =>
|
|
|
190591
190822
|
name: entry.name
|
|
190592
190823
|
}));
|
|
190593
190824
|
var WORKFLOW_WARNING = "This changes workspace-level tracker configuration for every project using this project type.";
|
|
190594
|
-
var toCategoryValue = (category) => category === void 0 ?
|
|
190825
|
+
var toCategoryValue = (category) => category === void 0 ? UnknownStatusCategoryValue : REF_TO_CATEGORY.get(category) ?? UnknownStatusCategoryValue;
|
|
190595
190826
|
var encodeOrConnectionError2 = (schema, value3, operation) => Schema_exports.encode(schema)(value3).pipe(
|
|
190596
190827
|
Effect_exports.as(value3),
|
|
190597
190828
|
Effect_exports.mapError(
|
|
@@ -190607,9 +190838,17 @@ var uniqueProjectStatuses = (statuses) => statuses.reduce(
|
|
|
190607
190838
|
(unique, status) => unique.some((existing) => sameProjectStatus(existing, status)) ? unique : [...unique, status],
|
|
190608
190839
|
[]
|
|
190609
190840
|
);
|
|
190610
|
-
var getStatusDocs = (client, statusIds) => statusIds.length === 0 ? Effect_exports.succeed([]) : client
|
|
190611
|
-
|
|
190612
|
-
|
|
190841
|
+
var getStatusDocs = (client, statusIds) => statusIds.length === 0 ? Effect_exports.succeed([]) : findStatusDocs(client, statusIds);
|
|
190842
|
+
var fallbackStatusDoc = (statusId) => ({
|
|
190843
|
+
_id: statusId,
|
|
190844
|
+
_class: core.class.Status,
|
|
190845
|
+
space: core.space.Model,
|
|
190846
|
+
modifiedOn: 0,
|
|
190847
|
+
modifiedBy: core.account.System,
|
|
190848
|
+
ofAttribute: tracker.attribute.IssueStatus,
|
|
190849
|
+
name: workflowStatusFromRef(statusId).name
|
|
190850
|
+
});
|
|
190851
|
+
var statusDocsWithFallbacks = (statusIds, statusDocs) => resolveByStatusRef(statusIds, statusDocs, (statusDoc) => statusDoc, fallbackStatusDoc);
|
|
190613
190852
|
var getTaskTypes = (client, taskTypeIds) => taskTypeIds.length === 0 ? Effect_exports.succeed([]) : client.findAll(task.class.TaskType, hulyQuery({ _id: { $in: [...taskTypeIds] } })).pipe(
|
|
190614
190853
|
Effect_exports.map((result) => [...result])
|
|
190615
190854
|
);
|
|
@@ -190628,7 +190867,9 @@ var getRecoverableStatusesByName = (client, name) => client.findAll(core.class.S
|
|
|
190628
190867
|
);
|
|
190629
190868
|
var loadWorkflowData = (client, projectType) => Effect_exports.gen(function* () {
|
|
190630
190869
|
const taskTypes = yield* getTaskTypes(client, projectType.tasks);
|
|
190631
|
-
const
|
|
190870
|
+
const statusIds = uniqueStatusIds(projectType);
|
|
190871
|
+
const statusDocs = yield* getStatusDocs(client, statusIds);
|
|
190872
|
+
const statuses = statusDocsWithFallbacks(statusIds, statusDocs);
|
|
190632
190873
|
return { projectType, taskTypes, statuses };
|
|
190633
190874
|
});
|
|
190634
190875
|
var isDefaultClassicProjectType = (projectType) => projectType._id === tracker.ids.ClassingProjectType || projectType.classic || normalizeForComparison(projectType.name) === "classic";
|
|
@@ -193351,6 +193592,13 @@ var DRAIN_TIMEOUT_MS2 = 3e4;
|
|
|
193351
193592
|
var NPM_FETCH_TIMEOUT_MS = 5e3;
|
|
193352
193593
|
var NPM_PACKAGE_NAME2 = "@firfi/huly-mcp";
|
|
193353
193594
|
var computeOutputBytes = (response) => response.content.reduce((sum2, c) => sum2 + c.text.length, 0);
|
|
193595
|
+
var withResourceWarnings = (result, warnings) => warnings.length === 0 ? result : {
|
|
193596
|
+
...result,
|
|
193597
|
+
_meta: {
|
|
193598
|
+
...result._meta,
|
|
193599
|
+
warnings
|
|
193600
|
+
}
|
|
193601
|
+
};
|
|
193354
193602
|
var deriveEditMode = (name, args2) => {
|
|
193355
193603
|
if (name !== "edit_document" || args2 === void 0) return void 0;
|
|
193356
193604
|
if (typeof args2 !== "object" || args2 === null || Array.isArray(args2)) return void 0;
|
|
@@ -193587,12 +193835,15 @@ var createMcpProtocolHandlers = (resolveClients, telemetry, registry2, getHulyCo
|
|
|
193587
193835
|
resolveClients,
|
|
193588
193836
|
(error2) => createResourceClientResolutionError(uri, error2)
|
|
193589
193837
|
);
|
|
193838
|
+
const diagnosticsScope = await Effect_exports.runPromise(makeDiagnosticsScope);
|
|
193590
193839
|
const resourceRead = await Effect_exports.runPromiseExit(
|
|
193591
193840
|
readHulyResource(uri).pipe(
|
|
193592
|
-
Effect_exports.provideService(HulyClient, clients.hulyClient)
|
|
193841
|
+
Effect_exports.provideService(HulyClient, clients.hulyClient),
|
|
193842
|
+
Effect_exports.provideService(Diagnostics, diagnosticsScope.service)
|
|
193593
193843
|
)
|
|
193594
193844
|
);
|
|
193595
|
-
|
|
193845
|
+
const warnings = await Effect_exports.runPromise(diagnosticsScope.drainWarnings);
|
|
193846
|
+
if (Exit_exports.isSuccess(resourceRead)) return withResourceWarnings(resourceRead.value, warnings);
|
|
193596
193847
|
return throwResourceReadError(uri, resourceRead.cause);
|
|
193597
193848
|
} finally {
|
|
193598
193849
|
leave();
|