@firfi/huly-mcp 0.30.0 → 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 +325 -62
- 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"]
|
|
@@ -174616,6 +174775,22 @@ var findActivityMessage = (client, messageId) => findOneOrFail(
|
|
|
174616
174775
|
() => new ActivityMessageNotFoundError({ messageId })
|
|
174617
174776
|
);
|
|
174618
174777
|
|
|
174778
|
+
// src/huly/operations/thread-replies-shared.ts
|
|
174779
|
+
var removeThreadReply = (client, reply) => Effect_exports.gen(function* () {
|
|
174780
|
+
const removeCollection = client.removeCollection;
|
|
174781
|
+
if (removeCollection === void 0) {
|
|
174782
|
+
return yield* new HulyError({ message: "Huly client does not support removeCollection" });
|
|
174783
|
+
}
|
|
174784
|
+
yield* removeCollection(
|
|
174785
|
+
chunter.class.ThreadMessage,
|
|
174786
|
+
reply.space,
|
|
174787
|
+
reply._id,
|
|
174788
|
+
reply.attachedTo,
|
|
174789
|
+
reply.attachedToClass,
|
|
174790
|
+
reply.collection
|
|
174791
|
+
);
|
|
174792
|
+
});
|
|
174793
|
+
|
|
174619
174794
|
// src/huly/operations/activity-messages.ts
|
|
174620
174795
|
var getActivityMessage = (params) => Effect_exports.gen(function* () {
|
|
174621
174796
|
const client = yield* HulyClient;
|
|
@@ -174732,7 +174907,7 @@ var deleteActivityReply = (params) => Effect_exports.gen(function* () {
|
|
|
174732
174907
|
hulyQuery({ _id: toRef(params.replyId) }),
|
|
174733
174908
|
() => new ActivityMessageNotFoundError({ messageId: params.replyId })
|
|
174734
174909
|
);
|
|
174735
|
-
yield* client
|
|
174910
|
+
yield* removeThreadReply(client, reply);
|
|
174736
174911
|
return { replyId: ActivityMessageId.make(reply._id), deleted: true };
|
|
174737
174912
|
});
|
|
174738
174913
|
|
|
@@ -176166,7 +176341,7 @@ var findProject = (projectIdentifier) => Effect_exports.gen(function* () {
|
|
|
176166
176341
|
);
|
|
176167
176342
|
return { client, project: project3 };
|
|
176168
176343
|
});
|
|
176169
|
-
var statusCategoryValueFromRef = (category) => category === void 0 ?
|
|
176344
|
+
var statusCategoryValueFromRef = (category) => category === void 0 ? UnknownStatusCategoryValue : StatusCategoryEntries.find((entry) => entry.ref === category)?.key ?? UnknownStatusCategoryValue;
|
|
176170
176345
|
var workflowStatusFromDoc = (doc) => {
|
|
176171
176346
|
return {
|
|
176172
176347
|
_id: doc._id,
|
|
@@ -176179,7 +176354,7 @@ var workflowStatusFromRef = (statusRef) => {
|
|
|
176179
176354
|
return {
|
|
176180
176355
|
_id: statusRef,
|
|
176181
176356
|
name,
|
|
176182
|
-
category:
|
|
176357
|
+
category: UnknownStatusCategoryValue
|
|
176183
176358
|
};
|
|
176184
176359
|
};
|
|
176185
176360
|
var uniqueStatusRefs = (refs) => refs.reduce(
|
|
@@ -176191,6 +176366,51 @@ var uniqueStatusDocs = (statuses) => Array.from(statuses).reduce(
|
|
|
176191
176366
|
[]
|
|
176192
176367
|
);
|
|
176193
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
|
+
});
|
|
176194
176414
|
var findProjectWithStatuses = (projectIdentifier) => Effect_exports.gen(function* () {
|
|
176195
176415
|
const client = yield* HulyClient;
|
|
176196
176416
|
const project3 = yield* findOneOrFail(
|
|
@@ -176206,19 +176426,8 @@ var findProjectWithStatuses = (projectIdentifier) => Effect_exports.gen(function
|
|
|
176206
176426
|
if (statusRefs.length === 0) {
|
|
176207
176427
|
return [];
|
|
176208
176428
|
}
|
|
176209
|
-
const
|
|
176210
|
-
|
|
176211
|
-
core.class.Status,
|
|
176212
|
-
hulyQuery({ _id: { $in: statusRefs } })
|
|
176213
|
-
)
|
|
176214
|
-
);
|
|
176215
|
-
if (statusDocsResult._tag === "Right") {
|
|
176216
|
-
return uniqueStatusDocs(statusDocsResult.right).map(workflowStatusFromDoc);
|
|
176217
|
-
}
|
|
176218
|
-
yield* Effect_exports.logWarning(
|
|
176219
|
-
`Status query failed for project ${projectIdentifier}, using fallback. statusCategory filtering is unavailable until Huly returns status metadata. Error: ${statusDocsResult.left.message}`
|
|
176220
|
-
);
|
|
176221
|
-
return statusRefs.map(workflowStatusFromRef);
|
|
176429
|
+
const statusDocs = yield* findStatusDocs(client, statusRefs);
|
|
176430
|
+
return workflowStatusesFromDocsOrRefs(statusRefs, statusDocs);
|
|
176222
176431
|
}) : [];
|
|
176223
176432
|
const defaultStatusId = project3.defaultIssueStatus || statuses[0]?._id;
|
|
176224
176433
|
return { client, defaultStatusId, project: project3, projectType, statuses };
|
|
@@ -176582,19 +176791,27 @@ var createHandler = (toolName, provide4, parse5, operation, encode8) => async (a
|
|
|
176582
176791
|
if (Exit_exports.isFailure(parseResult)) {
|
|
176583
176792
|
return mapParseCauseToMcp(parseResult.cause, toolName);
|
|
176584
176793
|
}
|
|
176585
|
-
const
|
|
176794
|
+
const diagnosticsScope = await Effect_exports.runPromise(makeDiagnosticsScope);
|
|
176795
|
+
const provided = provide4({
|
|
176796
|
+
hulyClient,
|
|
176797
|
+
storageClient,
|
|
176798
|
+
workspaceClient
|
|
176799
|
+
})(operation(parseResult.value));
|
|
176586
176800
|
if (Either_exports.isLeft(provided)) {
|
|
176587
176801
|
return provided.left;
|
|
176588
176802
|
}
|
|
176589
|
-
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);
|
|
176590
176807
|
if (Exit_exports.isFailure(operationResult)) {
|
|
176591
|
-
return mapDomainCauseToMcp(operationResult.cause);
|
|
176808
|
+
return mapDomainCauseToMcp(operationResult.cause, warnings);
|
|
176592
176809
|
}
|
|
176593
176810
|
try {
|
|
176594
176811
|
const output = encode8 !== void 0 ? encode8(operationResult.value) : operationResult.value;
|
|
176595
|
-
return createSuccessResponse(output);
|
|
176812
|
+
return createSuccessResponse(output, warnings);
|
|
176596
176813
|
} catch {
|
|
176597
|
-
return mapDomainErrorToMcp(new HulyError({ message: `Tool ${toolName} produced invalid output` }));
|
|
176814
|
+
return mapDomainErrorToMcp(new HulyError({ message: `Tool ${toolName} produced invalid output` }), warnings);
|
|
176598
176815
|
}
|
|
176599
176816
|
};
|
|
176600
176817
|
var createToolHandler = (toolName, parse5, operation) => createHandler(toolName, provideHulyClient, parse5, operation);
|
|
@@ -179497,6 +179714,19 @@ var createDirectMessage = (params) => Effect_exports.gen(function* () {
|
|
|
179497
179714
|
return { id: ChannelId.make(dmId), created: true };
|
|
179498
179715
|
});
|
|
179499
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
|
+
|
|
179500
179730
|
// src/huly/operations/threads.ts
|
|
179501
179731
|
var import_core31 = __toESM(require_lib4(), 1);
|
|
179502
179732
|
var findReply = (client, channel, message, replyId) => Effect_exports.gen(function* () {
|
|
@@ -179601,11 +179831,7 @@ var updateThreadReply = (params) => Effect_exports.gen(function* () {
|
|
|
179601
179831
|
var deleteThreadReply = (params) => Effect_exports.gen(function* () {
|
|
179602
179832
|
const { channel, client, message } = yield* findChannelMessage(params);
|
|
179603
179833
|
const reply = yield* findReply(client, channel, message, params.replyId);
|
|
179604
|
-
yield* client
|
|
179605
|
-
chunter.class.ThreadMessage,
|
|
179606
|
-
channel._id,
|
|
179607
|
-
reply._id
|
|
179608
|
-
);
|
|
179834
|
+
yield* removeThreadReply(client, reply);
|
|
179609
179835
|
return { id: ThreadReplyId.make(reply._id), deleted: true };
|
|
179610
179836
|
});
|
|
179611
179837
|
|
|
@@ -179794,6 +180020,17 @@ var channelTools = [
|
|
|
179794
180020
|
listChannelMessages
|
|
179795
180021
|
)
|
|
179796
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
|
+
},
|
|
179797
180034
|
{
|
|
179798
180035
|
name: "send_channel_message",
|
|
179799
180036
|
description: "Send a message to a Huly channel. Message body supports markdown formatting.",
|
|
@@ -186682,6 +186919,18 @@ var labelTools = [
|
|
|
186682
186919
|
// src/huly/operations/leads.ts
|
|
186683
186920
|
var import_core50 = __toESM(require_lib4(), 1);
|
|
186684
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
|
+
);
|
|
186685
186934
|
var markupBlobRefAsMarkupRef = (value3) => value3;
|
|
186686
186935
|
var normalizeLeadIdentifier = (identifier2) => {
|
|
186687
186936
|
const match16 = /^(?:LEAD-)?(\d+)$/i.exec(identifier2.trim());
|
|
@@ -186730,7 +186979,7 @@ var getFunnelStatuses = (client, funnel) => Effect_exports.gen(function* () {
|
|
|
186730
186979
|
})
|
|
186731
186980
|
);
|
|
186732
186981
|
}
|
|
186733
|
-
const statusRefs = projectType.statuses.map((status) => status._id);
|
|
186982
|
+
const statusRefs = uniqueStatusRefs(projectType.statuses.map((status) => status._id));
|
|
186734
186983
|
if (statusRefs.length === 0) {
|
|
186735
186984
|
return yield* Effect_exports.fail(
|
|
186736
186985
|
new HulyConnectionError({
|
|
@@ -186738,14 +186987,8 @@ var getFunnelStatuses = (client, funnel) => Effect_exports.gen(function* () {
|
|
|
186738
186987
|
})
|
|
186739
186988
|
);
|
|
186740
186989
|
}
|
|
186741
|
-
const statusDocs = yield* client
|
|
186742
|
-
|
|
186743
|
-
{ _id: { $in: [...statusRefs] } }
|
|
186744
|
-
);
|
|
186745
|
-
return statusDocs.map((doc) => ({
|
|
186746
|
-
_id: doc._id,
|
|
186747
|
-
name: doc.name
|
|
186748
|
-
}));
|
|
186990
|
+
const statusDocs = yield* findStatusDocs(client, statusRefs);
|
|
186991
|
+
return statusInfosWithFallbacks(statusRefs, statusDocs);
|
|
186749
186992
|
});
|
|
186750
186993
|
var resolveStatusName2 = (statuses, statusId) => {
|
|
186751
186994
|
const statusDoc = statuses.find((status) => status._id === statusId);
|
|
@@ -190579,7 +190822,7 @@ var STATUS_CATEGORIES = Object.values(STATUS_CATEGORY_BY_SDK_KEY).map((entry) =>
|
|
|
190579
190822
|
name: entry.name
|
|
190580
190823
|
}));
|
|
190581
190824
|
var WORKFLOW_WARNING = "This changes workspace-level tracker configuration for every project using this project type.";
|
|
190582
|
-
var toCategoryValue = (category) => category === void 0 ?
|
|
190825
|
+
var toCategoryValue = (category) => category === void 0 ? UnknownStatusCategoryValue : REF_TO_CATEGORY.get(category) ?? UnknownStatusCategoryValue;
|
|
190583
190826
|
var encodeOrConnectionError2 = (schema, value3, operation) => Schema_exports.encode(schema)(value3).pipe(
|
|
190584
190827
|
Effect_exports.as(value3),
|
|
190585
190828
|
Effect_exports.mapError(
|
|
@@ -190595,9 +190838,17 @@ var uniqueProjectStatuses = (statuses) => statuses.reduce(
|
|
|
190595
190838
|
(unique, status) => unique.some((existing) => sameProjectStatus(existing, status)) ? unique : [...unique, status],
|
|
190596
190839
|
[]
|
|
190597
190840
|
);
|
|
190598
|
-
var getStatusDocs = (client, statusIds) => statusIds.length === 0 ? Effect_exports.succeed([]) : client
|
|
190599
|
-
|
|
190600
|
-
|
|
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);
|
|
190601
190852
|
var getTaskTypes = (client, taskTypeIds) => taskTypeIds.length === 0 ? Effect_exports.succeed([]) : client.findAll(task.class.TaskType, hulyQuery({ _id: { $in: [...taskTypeIds] } })).pipe(
|
|
190602
190853
|
Effect_exports.map((result) => [...result])
|
|
190603
190854
|
);
|
|
@@ -190616,7 +190867,9 @@ var getRecoverableStatusesByName = (client, name) => client.findAll(core.class.S
|
|
|
190616
190867
|
);
|
|
190617
190868
|
var loadWorkflowData = (client, projectType) => Effect_exports.gen(function* () {
|
|
190618
190869
|
const taskTypes = yield* getTaskTypes(client, projectType.tasks);
|
|
190619
|
-
const
|
|
190870
|
+
const statusIds = uniqueStatusIds(projectType);
|
|
190871
|
+
const statusDocs = yield* getStatusDocs(client, statusIds);
|
|
190872
|
+
const statuses = statusDocsWithFallbacks(statusIds, statusDocs);
|
|
190620
190873
|
return { projectType, taskTypes, statuses };
|
|
190621
190874
|
});
|
|
190622
190875
|
var isDefaultClassicProjectType = (projectType) => projectType._id === tracker.ids.ClassingProjectType || projectType.classic || normalizeForComparison(projectType.name) === "classic";
|
|
@@ -193339,6 +193592,13 @@ var DRAIN_TIMEOUT_MS2 = 3e4;
|
|
|
193339
193592
|
var NPM_FETCH_TIMEOUT_MS = 5e3;
|
|
193340
193593
|
var NPM_PACKAGE_NAME2 = "@firfi/huly-mcp";
|
|
193341
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
|
+
};
|
|
193342
193602
|
var deriveEditMode = (name, args2) => {
|
|
193343
193603
|
if (name !== "edit_document" || args2 === void 0) return void 0;
|
|
193344
193604
|
if (typeof args2 !== "object" || args2 === null || Array.isArray(args2)) return void 0;
|
|
@@ -193575,12 +193835,15 @@ var createMcpProtocolHandlers = (resolveClients, telemetry, registry2, getHulyCo
|
|
|
193575
193835
|
resolveClients,
|
|
193576
193836
|
(error2) => createResourceClientResolutionError(uri, error2)
|
|
193577
193837
|
);
|
|
193838
|
+
const diagnosticsScope = await Effect_exports.runPromise(makeDiagnosticsScope);
|
|
193578
193839
|
const resourceRead = await Effect_exports.runPromiseExit(
|
|
193579
193840
|
readHulyResource(uri).pipe(
|
|
193580
|
-
Effect_exports.provideService(HulyClient, clients.hulyClient)
|
|
193841
|
+
Effect_exports.provideService(HulyClient, clients.hulyClient),
|
|
193842
|
+
Effect_exports.provideService(Diagnostics, diagnosticsScope.service)
|
|
193581
193843
|
)
|
|
193582
193844
|
);
|
|
193583
|
-
|
|
193845
|
+
const warnings = await Effect_exports.runPromise(diagnosticsScope.drainWarnings);
|
|
193846
|
+
if (Exit_exports.isSuccess(resourceRead)) return withResourceWarnings(resourceRead.value, warnings);
|
|
193584
193847
|
return throwResourceReadError(uri, resourceRead.cause);
|
|
193585
193848
|
} finally {
|
|
193586
193849
|
leave();
|