@firfi/huly-mcp 0.17.2 → 0.18.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 +6 -6
- package/dist/index.cjs +362 -180
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -273,7 +273,7 @@ Resource roadmap:
|
|
|
273
273
|
|------|-------------|
|
|
274
274
|
| `list_projects` | List all Huly projects. Returns projects sorted by name. Supports filtering by archived status. |
|
|
275
275
|
| `get_project` | Get full details of a Huly project including its statuses. Returns project name, description, archived flag, default status, and all available statuses. |
|
|
276
|
-
| `list_statuses` | List all issue statuses for a Huly project with category info. Returns status name,
|
|
276
|
+
| `list_statuses` | List all issue statuses for a Huly project with workflow category and default info. Returns status name, category, and isDefault. Use this to discover valid statuses before creating or updating issues. |
|
|
277
277
|
| `create_project` | Create a new Huly tracker project. Idempotent: returns existing project if one with the same identifier already exists (created=false). Identifier must be 1-5 uppercase alphanumeric chars starting with a letter. |
|
|
278
278
|
| `update_project` | Update a Huly project. Only provided fields are modified. Set description to null to clear it. |
|
|
279
279
|
| `delete_project` | Permanently delete a Huly project. All issues, milestones, and components in this project will be orphaned. This action cannot be undone. |
|
|
@@ -283,7 +283,7 @@ Resource roadmap:
|
|
|
283
283
|
| Tool | Description |
|
|
284
284
|
|------|-------------|
|
|
285
285
|
| `preview_deletion` | Preview the impact of deleting a Huly entity before actually deleting it. Shows affected sub-entities, relations, and warnings. Supports issues, projects, components, and milestones. Use this to understand cascade effects before calling a delete operation. |
|
|
286
|
-
| `list_issues` | Query Huly issues with optional filters. Returns issues sorted by modification date (newest first). Supports filtering by project, status, assignee, component, and parentIssue (to list children of a specific issue). Supports searching by title substring (titleSearch) and description content (descriptionSearch). |
|
|
286
|
+
| `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). |
|
|
287
287
|
| `get_issue` | Retrieve full details for a Huly issue including markdown description. Use this to view issue content, comments, or full metadata. |
|
|
288
288
|
| `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. |
|
|
289
289
|
| `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. |
|
|
@@ -453,9 +453,9 @@ Resource roadmap:
|
|
|
453
453
|
| `list_associations` | List Huly association definitions: class-level typed links that define which document classes may be related. Use this before create_relation to discover association IDs, source/target classes, and whether relation writes are supported. |
|
|
454
454
|
| `create_association` | Idempotently create one Huly association definition between two non-system classes. Use sourceClass/targetClass with sourceRole/targetRole and cardinality; returns an existing identical association by default. |
|
|
455
455
|
| `delete_association` | Idempotently delete one Huly association definition only when no concrete relations reference it. If relations exist, delete_relation must clean them up first; deleting an already-missing association is a successful no-op. |
|
|
456
|
-
| `list_relations` | List concrete Huly relation instances under an association, optionally filtered by source and target documents. Requires at least one filter to avoid broad workspace scans. |
|
|
457
|
-
| `create_relation` | Idempotently create one concrete relation between two resolved documents for a writable association. Enforces association endpoint classes, direction, duplicate handling, automation-only restrictions, and cardinality. |
|
|
458
|
-
| `delete_relation` | Idempotently delete one concrete relation by relation ID or by exact association/source/target triple. Triple deletes use the same direction semantics as create_relation and fail if the selector is ambiguous. |
|
|
456
|
+
| `list_relations` | List concrete Huly relation instances under an association, optionally filtered by source and target documents. Endpoint locators support raw, issue, document, and card. Requires at least one filter to avoid broad workspace scans. |
|
|
457
|
+
| `create_relation` | Idempotently create one concrete relation between two resolved documents for a writable association. Endpoint locators support raw, issue, document, and card. Enforces association endpoint classes, direction, duplicate handling, automation-only restrictions, and cardinality. |
|
|
458
|
+
| `delete_relation` | Idempotently delete one concrete relation by relation ID or by exact association/source/target triple. Triple endpoint locators support raw, issue, document, and card. Triple deletes use the same direction semantics as create_relation and fail if the selector is ambiguous. |
|
|
459
459
|
|
|
460
460
|
### Activity
|
|
461
461
|
|
|
@@ -568,7 +568,7 @@ Resource roadmap:
|
|
|
568
568
|
| `get_project_type` | Inspect one Huly tracker project type in a single call. Accepts projectType as ID or display name; when omitted, uses the unambiguous Classic tracker type. Returns task types, statuses, categories, and task-type-to-status mappings. |
|
|
569
569
|
| `list_task_types` | List Huly issue/task types. Optionally filter by projectType ID or display name. Returns task type identity, parent project type, kind, issue class, and available status count. |
|
|
570
570
|
| `create_task_type` | Add a Huly issue/task type to a project type idempotently by normalized name. Copies required workflow configuration from an existing template task type unless templateTaskType is supplied. Returns created, IDs, affected task type IDs, and a workspace-level workflow warning. |
|
|
571
|
-
| `create_issue_status` | Add a Huly issue workflow status idempotently by normalized name within a project type and task type scope. Accepts category as
|
|
571
|
+
| `create_issue_status` | Add a Huly issue workflow status idempotently by normalized name within a project type and task type scope. Accepts category as a Huly SDK task.statusCategory key: UnStarted, ToDo, Active, Won, Lost; taskType may be ID or display name, and omission applies the status to every task type in the project type. |
|
|
572
572
|
|
|
573
573
|
### Test-Management
|
|
574
574
|
|
package/dist/index.cjs
CHANGED
|
@@ -151180,7 +151180,9 @@ var Email = Schema_exports.NonEmptyString.pipe(
|
|
|
151180
151180
|
}),
|
|
151181
151181
|
Schema_exports.brand("Email")
|
|
151182
151182
|
);
|
|
151183
|
-
var StatusName = NonEmptyString2.
|
|
151183
|
+
var StatusName = NonEmptyString2.annotations({
|
|
151184
|
+
description: "Exact workflow status display name from the target project. Status names are workspace data, not a fixed enum; call list_statuses or get_project_type to discover valid values."
|
|
151185
|
+
}).pipe(Schema_exports.brand("StatusName"));
|
|
151184
151186
|
var PersonName = NonEmptyString2.pipe(Schema_exports.brand("PersonName"));
|
|
151185
151187
|
var PersonRefInput = Schema_exports.Union(Email, PersonName);
|
|
151186
151188
|
var ComponentLabel = NonEmptyString2.pipe(Schema_exports.brand("ComponentLabel"));
|
|
@@ -151585,6 +151587,7 @@ var RelationDirectionSchema = Schema_exports.Literal(...RelationDirectionValues)
|
|
|
151585
151587
|
var DefaultRelationDirection = "source-to-target";
|
|
151586
151588
|
var relationDirectionDescription = `Relation traversal direction: ${enumValuesDescription(RelationDirectionValues)}. Defaults to ${DefaultRelationDirection}.`;
|
|
151587
151589
|
var RelationIfExistsSchema = Schema_exports.Literal("return_existing", "fail");
|
|
151590
|
+
var RelationEndpointFieldSchema = Schema_exports.Literal("source", "target");
|
|
151588
151591
|
var AssociationIfExistsSchema = Schema_exports.Literal("return_existing", "fail");
|
|
151589
151592
|
var RawObjectLocatorSchema = Schema_exports.Struct({
|
|
151590
151593
|
kind: Schema_exports.Literal("raw"),
|
|
@@ -151613,19 +151616,29 @@ var DocumentObjectLocatorSchema = Schema_exports.Struct({
|
|
|
151613
151616
|
description: "Teamspace name or ID. If omitted, document title matches must be unique across the workspace."
|
|
151614
151617
|
}))
|
|
151615
151618
|
});
|
|
151619
|
+
var CardObjectLocatorSchema = Schema_exports.Struct({
|
|
151620
|
+
kind: Schema_exports.Literal("card"),
|
|
151621
|
+
card: CardIdentifier.annotations({
|
|
151622
|
+
description: "Card ID or exact card title. Card IDs can be resolved without cardSpace; title lookup requires cardSpace."
|
|
151623
|
+
}),
|
|
151624
|
+
cardSpace: Schema_exports.optional(CardSpaceIdentifier.annotations({
|
|
151625
|
+
description: "Card space name or ID. Required when card is a title so title lookup is scoped and not ambiguous across the workspace."
|
|
151626
|
+
}))
|
|
151627
|
+
});
|
|
151616
151628
|
var GenericObjectLocatorSchema = Schema_exports.Union(
|
|
151617
151629
|
RawObjectLocatorSchema,
|
|
151618
151630
|
IssueObjectLocatorSchema,
|
|
151619
|
-
DocumentObjectLocatorSchema
|
|
151631
|
+
DocumentObjectLocatorSchema,
|
|
151632
|
+
CardObjectLocatorSchema
|
|
151620
151633
|
).annotations({
|
|
151621
151634
|
title: "GenericObjectLocator",
|
|
151622
|
-
description: "Explicit locator for a Huly document endpoint. Use raw for known _id
|
|
151635
|
+
description: "Explicit locator for a Huly document endpoint. Use raw for known _id/class pairs, issue for tracker issues, document for Huly documents, or card for Huly cards."
|
|
151623
151636
|
});
|
|
151624
151637
|
var ResolvedObjectSummarySchema = Schema_exports.Struct({
|
|
151625
151638
|
id: DocId,
|
|
151626
151639
|
class: ObjectClassName,
|
|
151627
151640
|
display: NonEmptyString2,
|
|
151628
|
-
locatorKind: Schema_exports.Literal("raw", "issue", "document"),
|
|
151641
|
+
locatorKind: Schema_exports.Literal("raw", "issue", "document", "card"),
|
|
151629
151642
|
warning: Schema_exports.optional(Schema_exports.String)
|
|
151630
151643
|
});
|
|
151631
151644
|
var AssociationSummarySchema = Schema_exports.Struct({
|
|
@@ -151986,7 +151999,7 @@ var RelationDirectionAmbiguousError = class extends Schema_exports.TaggedError()
|
|
|
151986
151999
|
var RelationEndpointClassMismatchError = class extends Schema_exports.TaggedError()(
|
|
151987
152000
|
"RelationEndpointClassMismatchError",
|
|
151988
152001
|
{
|
|
151989
|
-
field:
|
|
152002
|
+
field: RelationEndpointFieldSchema,
|
|
151990
152003
|
expectedClass: Schema_exports.String,
|
|
151991
152004
|
actualClass: Schema_exports.String
|
|
151992
152005
|
}
|
|
@@ -151998,7 +152011,7 @@ var RelationEndpointClassMismatchError = class extends Schema_exports.TaggedErro
|
|
|
151998
152011
|
var GenericObjectIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
|
|
151999
152012
|
"GenericObjectIdentifierAmbiguousError",
|
|
152000
152013
|
{
|
|
152001
|
-
field:
|
|
152014
|
+
field: RelationEndpointFieldSchema,
|
|
152002
152015
|
identifier: Schema_exports.String,
|
|
152003
152016
|
candidates: Schema_exports.Array(Schema_exports.Struct({
|
|
152004
152017
|
id: DocId,
|
|
@@ -152015,7 +152028,7 @@ var GenericObjectIdentifierAmbiguousError = class extends Schema_exports.TaggedE
|
|
|
152015
152028
|
var GenericObjectLocatorInvalidError = class extends Schema_exports.TaggedError()(
|
|
152016
152029
|
"GenericObjectLocatorInvalidError",
|
|
152017
152030
|
{
|
|
152018
|
-
field:
|
|
152031
|
+
field: RelationEndpointFieldSchema,
|
|
152019
152032
|
reason: Schema_exports.String
|
|
152020
152033
|
}
|
|
152021
152034
|
) {
|
|
@@ -152026,7 +152039,7 @@ var GenericObjectLocatorInvalidError = class extends Schema_exports.TaggedError(
|
|
|
152026
152039
|
var GenericObjectNotFoundError = class extends Schema_exports.TaggedError()(
|
|
152027
152040
|
"GenericObjectNotFoundError",
|
|
152028
152041
|
{
|
|
152029
|
-
field:
|
|
152042
|
+
field: RelationEndpointFieldSchema,
|
|
152030
152043
|
identifier: Schema_exports.String,
|
|
152031
152044
|
class: Schema_exports.optional(Schema_exports.String)
|
|
152032
152045
|
}
|
|
@@ -163495,101 +163508,73 @@ var GetHulyContextResultSchema = Schema_exports.Struct({
|
|
|
163495
163508
|
});
|
|
163496
163509
|
var getHulyContextResultJsonSchema = JSONSchema_exports.make(GetHulyContextResultSchema);
|
|
163497
163510
|
|
|
163498
|
-
// src/
|
|
163499
|
-
var
|
|
163500
|
-
|
|
163501
|
-
|
|
163502
|
-
|
|
163503
|
-
|
|
163504
|
-
|
|
163505
|
-
|
|
163506
|
-
|
|
163507
|
-
|
|
163508
|
-
var
|
|
163509
|
-
|
|
163510
|
-
|
|
163511
|
-
|
|
163512
|
-
limit: Schema_exports.optional(
|
|
163513
|
-
LimitParam.annotations({
|
|
163514
|
-
description: "Maximum number of projects to return (default: 50)"
|
|
163515
|
-
})
|
|
163516
|
-
)
|
|
163517
|
-
}).annotations({
|
|
163518
|
-
title: "ListProjectsParams",
|
|
163519
|
-
description: "Parameters for listing projects"
|
|
163520
|
-
});
|
|
163521
|
-
var ProjectSchema = Schema_exports.Struct({
|
|
163522
|
-
identifier: ProjectIdentifier,
|
|
163523
|
-
name: NonEmptyString2,
|
|
163524
|
-
description: Schema_exports.optional(Schema_exports.String),
|
|
163525
|
-
archived: Schema_exports.Boolean,
|
|
163526
|
-
defaultStatus: Schema_exports.optional(StatusName),
|
|
163527
|
-
statuses: Schema_exports.optional(Schema_exports.Array(StatusName))
|
|
163528
|
-
}).annotations({
|
|
163529
|
-
title: "Project",
|
|
163530
|
-
description: "Full project with status information"
|
|
163531
|
-
});
|
|
163532
|
-
var GetProjectParamsSchema = Schema_exports.Struct({
|
|
163533
|
-
project: ProjectIdentifier.annotations({ description: "Project identifier (e.g., 'HULY')" })
|
|
163534
|
-
}).annotations({ title: "GetProjectParams", description: "Parameters for getting a project" });
|
|
163535
|
-
var CreateProjectParamsSchema = Schema_exports.Struct({
|
|
163536
|
-
name: NonEmptyString2.annotations({ description: "Project name" }),
|
|
163537
|
-
identifier: Schema_exports.String.pipe(
|
|
163538
|
-
Schema_exports.pattern(/^[A-Z][A-Z0-9_]{0,4}$/)
|
|
163539
|
-
).annotations({
|
|
163540
|
-
description: "Unique project identifier, 1-5 uppercase alphanumeric chars starting with letter (e.g., 'HULY', 'QA')"
|
|
163541
|
-
}),
|
|
163542
|
-
description: Schema_exports.optional(Schema_exports.String.annotations({ description: "Project description" })),
|
|
163543
|
-
private: Schema_exports.optional(Schema_exports.Boolean.annotations({ description: "Whether project is private (default: false)" }))
|
|
163544
|
-
}).annotations({ title: "CreateProjectParams", description: "Parameters for creating a project" });
|
|
163545
|
-
var UPDATE_PROJECT_FIELDS = ["name", "description"];
|
|
163546
|
-
var UpdateProjectParamsSchema = Schema_exports.Struct({
|
|
163547
|
-
project: ProjectIdentifier.annotations({ description: "Project identifier to update" }),
|
|
163548
|
-
name: Schema_exports.optional(NonEmptyString2.annotations({ description: "New project name" })),
|
|
163549
|
-
description: Schema_exports.optional(
|
|
163550
|
-
Schema_exports.NullOr(Schema_exports.String).annotations({ description: "New description (null to clear)" })
|
|
163551
|
-
)
|
|
163552
|
-
}).annotations({
|
|
163553
|
-
title: "UpdateProjectParams",
|
|
163554
|
-
description: `Parameters for updating a project. ${atLeastOneUpdateFieldMessage(UPDATE_PROJECT_FIELDS)}`
|
|
163555
|
-
});
|
|
163556
|
-
var DeleteProjectParamsSchema = Schema_exports.Struct({
|
|
163557
|
-
project: ProjectIdentifier.annotations({ description: "Project identifier to delete" })
|
|
163558
|
-
}).annotations({ title: "DeleteProjectParams", description: "Parameters for deleting a project" });
|
|
163559
|
-
var ListStatusesParamsSchema = Schema_exports.Struct({
|
|
163560
|
-
project: ProjectIdentifier.annotations({ description: "Project identifier (e.g., 'HULY')" })
|
|
163561
|
-
}).annotations({ title: "ListStatusesParams", description: "Parameters for listing project statuses" });
|
|
163562
|
-
var StatusDetailSchema = Schema_exports.Struct({
|
|
163563
|
-
name: StatusName,
|
|
163564
|
-
isDone: Schema_exports.Boolean,
|
|
163565
|
-
isCanceled: Schema_exports.Boolean,
|
|
163566
|
-
isDefault: Schema_exports.Boolean
|
|
163567
|
-
}).annotations({
|
|
163568
|
-
title: "StatusDetail",
|
|
163569
|
-
description: "Issue status with category and default info"
|
|
163570
|
-
});
|
|
163571
|
-
var listProjectsParamsJsonSchema = JSONSchema_exports.make(ListProjectsParamsSchema);
|
|
163572
|
-
var listStatusesParamsJsonSchema = JSONSchema_exports.make(ListStatusesParamsSchema);
|
|
163573
|
-
var getProjectParamsJsonSchema = JSONSchema_exports.make(GetProjectParamsSchema);
|
|
163574
|
-
var createProjectParamsJsonSchema = JSONSchema_exports.make(CreateProjectParamsSchema);
|
|
163575
|
-
var updateProjectParamsJsonSchema = withAtLeastOneRequired(
|
|
163576
|
-
JSONSchema_exports.make(UpdateProjectParamsSchema),
|
|
163577
|
-
UPDATE_PROJECT_FIELDS
|
|
163578
|
-
);
|
|
163579
|
-
var deleteProjectParamsJsonSchema = JSONSchema_exports.make(DeleteProjectParamsSchema);
|
|
163580
|
-
var parseListProjectsParams = Schema_exports.decodeUnknown(ListProjectsParamsSchema);
|
|
163581
|
-
var parseListStatusesParams = Schema_exports.decodeUnknown(ListStatusesParamsSchema);
|
|
163582
|
-
var parseGetProjectParams = Schema_exports.decodeUnknown(GetProjectParamsSchema);
|
|
163583
|
-
var parseCreateProjectParams = Schema_exports.decodeUnknown(CreateProjectParamsSchema);
|
|
163584
|
-
var parseUpdateProjectParams = Schema_exports.decodeUnknown(UpdateProjectParamsSchema);
|
|
163585
|
-
var parseDeleteProjectParams = Schema_exports.decodeUnknown(DeleteProjectParamsSchema);
|
|
163586
|
-
var parseProject = Schema_exports.decodeUnknown(ProjectSchema);
|
|
163511
|
+
// src/huly/huly-plugins.ts
|
|
163512
|
+
var activity = require_lib23().default;
|
|
163513
|
+
var attachment = require_lib24().default;
|
|
163514
|
+
var calendar = require_lib25().default;
|
|
163515
|
+
var cardPlugin = require_lib26().default;
|
|
163516
|
+
var chunter = require_lib27().default;
|
|
163517
|
+
var contact = require_lib28().default;
|
|
163518
|
+
var core = require_lib4().default;
|
|
163519
|
+
var documentPlugin = require_lib29().default;
|
|
163520
|
+
var notification = require_lib30().default;
|
|
163521
|
+
var tags = require_lib31().default;
|
|
163522
|
+
var task = require_lib34().default;
|
|
163523
|
+
var time3 = require_lib35().default;
|
|
163524
|
+
var tracker = require_lib36().default;
|
|
163587
163525
|
|
|
163588
163526
|
// src/domain/schemas/task-management.ts
|
|
163589
|
-
var
|
|
163527
|
+
var StatusCategoryBySdkKey = {
|
|
163528
|
+
UnStarted: task.statusCategory.UnStarted,
|
|
163529
|
+
ToDo: task.statusCategory.ToDo,
|
|
163530
|
+
Active: task.statusCategory.Active,
|
|
163531
|
+
Won: task.statusCategory.Won,
|
|
163532
|
+
Lost: task.statusCategory.Lost
|
|
163533
|
+
};
|
|
163534
|
+
var StatusCategoryKeys = [
|
|
163535
|
+
"UnStarted",
|
|
163536
|
+
"ToDo",
|
|
163537
|
+
"Active",
|
|
163538
|
+
"Won",
|
|
163539
|
+
"Lost"
|
|
163540
|
+
];
|
|
163541
|
+
var exactStatusCategoryKeys = (value3) => value3;
|
|
163542
|
+
exactStatusCategoryKeys(true);
|
|
163543
|
+
var StatusCategoryEntries = [
|
|
163544
|
+
{ key: "UnStarted", ref: StatusCategoryBySdkKey.UnStarted },
|
|
163545
|
+
{ key: "ToDo", ref: StatusCategoryBySdkKey.ToDo },
|
|
163546
|
+
{ key: "Active", ref: StatusCategoryBySdkKey.Active },
|
|
163547
|
+
{ key: "Won", ref: StatusCategoryBySdkKey.Won },
|
|
163548
|
+
{ key: "Lost", ref: StatusCategoryBySdkKey.Lost }
|
|
163549
|
+
];
|
|
163550
|
+
var exactStatusCategoryEntries = (value3) => value3;
|
|
163551
|
+
exactStatusCategoryEntries(true);
|
|
163552
|
+
var StatusCategoryValues = StatusCategoryKeys;
|
|
163590
163553
|
var UnknownStatusCategoryValue = "unknown";
|
|
163591
163554
|
var StatusCategoryValueSchema = Schema_exports.Literal(...StatusCategoryValues, UnknownStatusCategoryValue);
|
|
163592
|
-
var
|
|
163555
|
+
var KnownStatusCategoryValueLiteral = Schema_exports.Literal(...StatusCategoryValues);
|
|
163556
|
+
var normalizedStatusCategoryLookup = new Map(
|
|
163557
|
+
StatusCategoryValues.map((value3) => [value3.toLowerCase(), value3])
|
|
163558
|
+
);
|
|
163559
|
+
var KnownStatusCategoryValueSchema = Schema_exports.transformOrFail(
|
|
163560
|
+
Schema_exports.String,
|
|
163561
|
+
KnownStatusCategoryValueLiteral,
|
|
163562
|
+
{
|
|
163563
|
+
strict: true,
|
|
163564
|
+
decode: (input, _options, ast) => {
|
|
163565
|
+
const match16 = normalizedStatusCategoryLookup.get(input.toLowerCase());
|
|
163566
|
+
return match16 !== void 0 ? ParseResult_exports.succeed(match16) : ParseResult_exports.fail(
|
|
163567
|
+
new ParseResult_exports.Type(ast, input, `Expected one of: ${enumValuesDescription(StatusCategoryValues)}`)
|
|
163568
|
+
);
|
|
163569
|
+
},
|
|
163570
|
+
encode: ParseResult_exports.succeed
|
|
163571
|
+
}
|
|
163572
|
+
).annotations({
|
|
163573
|
+
title: "KnownStatusCategoryValue",
|
|
163574
|
+
description: `Huly SDK task.statusCategory key: ${enumValuesDescription(StatusCategoryValues)}`,
|
|
163575
|
+
jsonSchema: { type: "string", enum: [...StatusCategoryValues] }
|
|
163576
|
+
});
|
|
163577
|
+
var CreateStatusCategoryValueSchema = KnownStatusCategoryValueSchema;
|
|
163593
163578
|
var TaskTypeKindSchema = Schema_exports.Literal("task", "subtask", "both");
|
|
163594
163579
|
var ProjectTypeRefSchema = NonEmptyString2.pipe(Schema_exports.brand("ProjectTypeRef"));
|
|
163595
163580
|
var TaskTypeRefSchema = NonEmptyString2.pipe(Schema_exports.brand("TaskTypeRef"));
|
|
@@ -163663,7 +163648,7 @@ var CreateIssueStatusParamsSchema = Schema_exports.Struct({
|
|
|
163663
163648
|
})),
|
|
163664
163649
|
name: NonEmptyString2.annotations({ description: "Display name for the workflow status to add." }),
|
|
163665
163650
|
category: CreateStatusCategoryValueSchema.annotations({
|
|
163666
|
-
description: `
|
|
163651
|
+
description: `Huly SDK task.statusCategory key: ${enumValuesDescription(StatusCategoryValues)}.`
|
|
163667
163652
|
}),
|
|
163668
163653
|
taskType: Schema_exports.optional(TaskTypeRefSchema.annotations({
|
|
163669
163654
|
description: "Optional task type ID or display name to scope the status to. If omitted, the status is added to every task type in the project type."
|
|
@@ -163702,6 +163687,95 @@ var parseListTaskTypesParams = Schema_exports.decodeUnknown(ListTaskTypesParamsS
|
|
|
163702
163687
|
var parseCreateTaskTypeParams = Schema_exports.decodeUnknown(CreateTaskTypeParamsSchema);
|
|
163703
163688
|
var parseCreateIssueStatusParams = Schema_exports.decodeUnknown(CreateIssueStatusParamsSchema);
|
|
163704
163689
|
|
|
163690
|
+
// src/domain/schemas/projects.ts
|
|
163691
|
+
var ProjectSummarySchema = Schema_exports.Struct({
|
|
163692
|
+
identifier: ProjectIdentifier,
|
|
163693
|
+
name: NonEmptyString2,
|
|
163694
|
+
description: Schema_exports.optional(Schema_exports.String),
|
|
163695
|
+
archived: Schema_exports.Boolean
|
|
163696
|
+
}).annotations({
|
|
163697
|
+
title: "ProjectSummary",
|
|
163698
|
+
description: "Project summary for list operations"
|
|
163699
|
+
});
|
|
163700
|
+
var ListProjectsParamsSchema = Schema_exports.Struct({
|
|
163701
|
+
includeArchived: Schema_exports.optional(Schema_exports.Boolean.annotations({
|
|
163702
|
+
description: "Include archived projects in results (default: false, showing only active)"
|
|
163703
|
+
})),
|
|
163704
|
+
limit: Schema_exports.optional(
|
|
163705
|
+
LimitParam.annotations({
|
|
163706
|
+
description: "Maximum number of projects to return (default: 50)"
|
|
163707
|
+
})
|
|
163708
|
+
)
|
|
163709
|
+
}).annotations({
|
|
163710
|
+
title: "ListProjectsParams",
|
|
163711
|
+
description: "Parameters for listing projects"
|
|
163712
|
+
});
|
|
163713
|
+
var ProjectSchema = Schema_exports.Struct({
|
|
163714
|
+
identifier: ProjectIdentifier,
|
|
163715
|
+
name: NonEmptyString2,
|
|
163716
|
+
description: Schema_exports.optional(Schema_exports.String),
|
|
163717
|
+
archived: Schema_exports.Boolean,
|
|
163718
|
+
defaultStatus: Schema_exports.optional(StatusName),
|
|
163719
|
+
statuses: Schema_exports.optional(Schema_exports.Array(StatusName))
|
|
163720
|
+
}).annotations({
|
|
163721
|
+
title: "Project",
|
|
163722
|
+
description: "Full project with status information"
|
|
163723
|
+
});
|
|
163724
|
+
var GetProjectParamsSchema = Schema_exports.Struct({
|
|
163725
|
+
project: ProjectIdentifier.annotations({ description: "Project identifier (e.g., 'HULY')" })
|
|
163726
|
+
}).annotations({ title: "GetProjectParams", description: "Parameters for getting a project" });
|
|
163727
|
+
var CreateProjectParamsSchema = Schema_exports.Struct({
|
|
163728
|
+
name: NonEmptyString2.annotations({ description: "Project name" }),
|
|
163729
|
+
identifier: Schema_exports.String.pipe(
|
|
163730
|
+
Schema_exports.pattern(/^[A-Z][A-Z0-9_]{0,4}$/)
|
|
163731
|
+
).annotations({
|
|
163732
|
+
description: "Unique project identifier, 1-5 uppercase alphanumeric chars starting with letter (e.g., 'HULY', 'QA')"
|
|
163733
|
+
}),
|
|
163734
|
+
description: Schema_exports.optional(Schema_exports.String.annotations({ description: "Project description" })),
|
|
163735
|
+
private: Schema_exports.optional(Schema_exports.Boolean.annotations({ description: "Whether project is private (default: false)" }))
|
|
163736
|
+
}).annotations({ title: "CreateProjectParams", description: "Parameters for creating a project" });
|
|
163737
|
+
var UPDATE_PROJECT_FIELDS = ["name", "description"];
|
|
163738
|
+
var UpdateProjectParamsSchema = Schema_exports.Struct({
|
|
163739
|
+
project: ProjectIdentifier.annotations({ description: "Project identifier to update" }),
|
|
163740
|
+
name: Schema_exports.optional(NonEmptyString2.annotations({ description: "New project name" })),
|
|
163741
|
+
description: Schema_exports.optional(
|
|
163742
|
+
Schema_exports.NullOr(Schema_exports.String).annotations({ description: "New description (null to clear)" })
|
|
163743
|
+
)
|
|
163744
|
+
}).annotations({
|
|
163745
|
+
title: "UpdateProjectParams",
|
|
163746
|
+
description: `Parameters for updating a project. ${atLeastOneUpdateFieldMessage(UPDATE_PROJECT_FIELDS)}`
|
|
163747
|
+
});
|
|
163748
|
+
var DeleteProjectParamsSchema = Schema_exports.Struct({
|
|
163749
|
+
project: ProjectIdentifier.annotations({ description: "Project identifier to delete" })
|
|
163750
|
+
}).annotations({ title: "DeleteProjectParams", description: "Parameters for deleting a project" });
|
|
163751
|
+
var ListStatusesParamsSchema = Schema_exports.Struct({
|
|
163752
|
+
project: ProjectIdentifier.annotations({ description: "Project identifier (e.g., 'HULY')" })
|
|
163753
|
+
}).annotations({ title: "ListStatusesParams", description: "Parameters for listing project statuses" });
|
|
163754
|
+
var StatusDetailSchema = Schema_exports.Struct({
|
|
163755
|
+
name: StatusName,
|
|
163756
|
+
category: StatusCategoryValueSchema,
|
|
163757
|
+
isDefault: Schema_exports.Boolean
|
|
163758
|
+
}).annotations({
|
|
163759
|
+
title: "StatusDetail",
|
|
163760
|
+
description: "Issue status with workflow category and default info"
|
|
163761
|
+
});
|
|
163762
|
+
var listProjectsParamsJsonSchema = JSONSchema_exports.make(ListProjectsParamsSchema);
|
|
163763
|
+
var listStatusesParamsJsonSchema = JSONSchema_exports.make(ListStatusesParamsSchema);
|
|
163764
|
+
var getProjectParamsJsonSchema = JSONSchema_exports.make(GetProjectParamsSchema);
|
|
163765
|
+
var createProjectParamsJsonSchema = JSONSchema_exports.make(CreateProjectParamsSchema);
|
|
163766
|
+
var updateProjectParamsJsonSchema = withAtLeastOneRequired(
|
|
163767
|
+
JSONSchema_exports.make(UpdateProjectParamsSchema),
|
|
163768
|
+
UPDATE_PROJECT_FIELDS
|
|
163769
|
+
);
|
|
163770
|
+
var deleteProjectParamsJsonSchema = JSONSchema_exports.make(DeleteProjectParamsSchema);
|
|
163771
|
+
var parseListProjectsParams = Schema_exports.decodeUnknown(ListProjectsParamsSchema);
|
|
163772
|
+
var parseListStatusesParams = Schema_exports.decodeUnknown(ListStatusesParamsSchema);
|
|
163773
|
+
var parseGetProjectParams = Schema_exports.decodeUnknown(GetProjectParamsSchema);
|
|
163774
|
+
var parseCreateProjectParams = Schema_exports.decodeUnknown(CreateProjectParamsSchema);
|
|
163775
|
+
var parseUpdateProjectParams = Schema_exports.decodeUnknown(UpdateProjectParamsSchema);
|
|
163776
|
+
var parseDeleteProjectParams = Schema_exports.decodeUnknown(DeleteProjectParamsSchema);
|
|
163777
|
+
var parseProject = Schema_exports.decodeUnknown(ProjectSchema);
|
|
163778
|
+
|
|
163705
163779
|
// src/domain/schemas/cards.ts
|
|
163706
163780
|
var ListCardSpacesParamsSchema = Schema_exports.Struct({
|
|
163707
163781
|
includeArchived: Schema_exports.optional(Schema_exports.Boolean.annotations({
|
|
@@ -164081,7 +164155,10 @@ var ListIssuesParamsBase = Schema_exports.Struct({
|
|
|
164081
164155
|
description: "Project identifier (e.g., 'HULY')"
|
|
164082
164156
|
}),
|
|
164083
164157
|
status: Schema_exports.optional(StatusName.annotations({
|
|
164084
|
-
description: "Filter by status name"
|
|
164158
|
+
description: "Filter by exact workflow status name. Does not accept category aliases."
|
|
164159
|
+
})),
|
|
164160
|
+
statusCategory: Schema_exports.optional(KnownStatusCategoryValueSchema.annotations({
|
|
164161
|
+
description: `Filter by Huly SDK task.statusCategory key: ${enumValuesDescription(StatusCategoryValues)}. Use status for exact project-specific status names.`
|
|
164085
164162
|
})),
|
|
164086
164163
|
assignee: Schema_exports.optional(PersonRefInput.annotations({
|
|
164087
164164
|
description: "Filter by assignee email or display name"
|
|
@@ -164124,6 +164201,9 @@ var ListIssuesParamsSchema = ListIssuesParamsBase.pipe(
|
|
|
164124
164201
|
if (params.titleSearch !== void 0 && params.titleRegex !== void 0) {
|
|
164125
164202
|
return "Cannot provide both 'titleSearch' and 'titleRegex'. Use one or the other.";
|
|
164126
164203
|
}
|
|
164204
|
+
if (params.status !== void 0 && params.statusCategory !== void 0) {
|
|
164205
|
+
return "Cannot provide both 'status' and 'statusCategory'. Use status for exact workflow status names or statusCategory for Huly workflow categories.";
|
|
164206
|
+
}
|
|
164127
164207
|
if (params.assignee !== void 0 && params.hasAssignee !== void 0) {
|
|
164128
164208
|
return "Cannot provide both 'assignee' and 'hasAssignee'. Use one or the other.";
|
|
164129
164209
|
}
|
|
@@ -167891,7 +167971,7 @@ var parseDeleteTestResultParams = Schema_exports.decodeUnknown(DeleteTestResultP
|
|
|
167891
167971
|
var parseRunTestPlanParams = Schema_exports.decodeUnknown(RunTestPlanParamsSchema);
|
|
167892
167972
|
|
|
167893
167973
|
// src/version.ts
|
|
167894
|
-
var VERSION = true ? "0.
|
|
167974
|
+
var VERSION = true ? "0.18.0" : "0.0.0-dev";
|
|
167895
167975
|
|
|
167896
167976
|
// src/mcp/error-mapping.ts
|
|
167897
167977
|
var McpErrorCode = {
|
|
@@ -168105,21 +168185,6 @@ var clampLimit = (limit) => Math.min(limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
|
168105
168185
|
// src/huly/operations/update-guards.ts
|
|
168106
168186
|
var requireUpdateFields = (operation, params, fields) => hasAtLeastOneDefined(params, fields) ? Effect_exports.void : Effect_exports.fail(new NoUpdateFieldsError({ operation, fields: fields.map(String) }));
|
|
168107
168187
|
|
|
168108
|
-
// src/huly/huly-plugins.ts
|
|
168109
|
-
var activity = require_lib23().default;
|
|
168110
|
-
var attachment = require_lib24().default;
|
|
168111
|
-
var calendar = require_lib25().default;
|
|
168112
|
-
var cardPlugin = require_lib26().default;
|
|
168113
|
-
var chunter = require_lib27().default;
|
|
168114
|
-
var contact = require_lib28().default;
|
|
168115
|
-
var core = require_lib4().default;
|
|
168116
|
-
var documentPlugin = require_lib29().default;
|
|
168117
|
-
var notification = require_lib30().default;
|
|
168118
|
-
var tags = require_lib31().default;
|
|
168119
|
-
var task = require_lib34().default;
|
|
168120
|
-
var time3 = require_lib35().default;
|
|
168121
|
-
var tracker = require_lib36().default;
|
|
168122
|
-
|
|
168123
168188
|
// src/huly/operations/channel-messages-shared.ts
|
|
168124
168189
|
var findChannelMessage = (params) => Effect_exports.gen(function* () {
|
|
168125
168190
|
const { channel, client } = yield* findChannel(params.channel);
|
|
@@ -168203,7 +168268,7 @@ var buildSocialIdToPersonNameMap = (client, socialIds) => Effect_exports.gen(fun
|
|
|
168203
168268
|
for (const si of socialIdentities) {
|
|
168204
168269
|
const person = personById.get(si.attachedTo);
|
|
168205
168270
|
if (person !== void 0) {
|
|
168206
|
-
result.set(si._id, person.name);
|
|
168271
|
+
result.set(si._id, PersonName.make(person.name));
|
|
168207
168272
|
}
|
|
168208
168273
|
}
|
|
168209
168274
|
return result;
|
|
@@ -168219,7 +168284,7 @@ var buildAccountUuidToNameMap = (client, accountUuids) => Effect_exports.gen(fun
|
|
|
168219
168284
|
const result = /* @__PURE__ */ new Map();
|
|
168220
168285
|
for (const emp of employees) {
|
|
168221
168286
|
if (emp.personUuid !== void 0) {
|
|
168222
|
-
result.set(emp.personUuid, emp.name);
|
|
168287
|
+
result.set(emp.personUuid, PersonName.make(emp.name));
|
|
168223
168288
|
}
|
|
168224
168289
|
}
|
|
168225
168290
|
return result;
|
|
@@ -168275,7 +168340,7 @@ var getChannel = (params) => Effect_exports.gen(function* () {
|
|
|
168275
168340
|
description: channel.description || void 0,
|
|
168276
168341
|
private: channel.private,
|
|
168277
168342
|
archived: channel.archived,
|
|
168278
|
-
members: memberNames
|
|
168343
|
+
members: memberNames,
|
|
168279
168344
|
messages: channel.messages,
|
|
168280
168345
|
modifiedOn: channel.modifiedOn,
|
|
168281
168346
|
createdOn: channel.createdOn
|
|
@@ -168357,7 +168422,7 @@ var listChannelMessages = (params) => Effect_exports.gen(function* () {
|
|
|
168357
168422
|
return {
|
|
168358
168423
|
id: MessageId.make(msg._id),
|
|
168359
168424
|
body: markupToMarkdownString(msg.message, markupUrlConfig),
|
|
168360
|
-
sender: senderName
|
|
168425
|
+
sender: senderName,
|
|
168361
168426
|
senderId: msg.modifiedBy,
|
|
168362
168427
|
createdOn: msg.createdOn,
|
|
168363
168428
|
modifiedOn: msg.modifiedOn,
|
|
@@ -168408,7 +168473,7 @@ var listDirectMessages = (params) => Effect_exports.gen(function* () {
|
|
|
168408
168473
|
];
|
|
168409
168474
|
const accountUuidToName = yield* buildAccountUuidToNameMap(client, uniqueAccountUuids);
|
|
168410
168475
|
const summaries = dms.map((dm) => {
|
|
168411
|
-
const participants = dm.members.map((m) => accountUuidToName.get(m)).filter((n) => n !== void 0)
|
|
168476
|
+
const participants = dm.members.map((m) => accountUuidToName.get(m)).filter((n) => n !== void 0);
|
|
168412
168477
|
const participantIds = dm.members.map((m) => AccountUuid.make(m));
|
|
168413
168478
|
return {
|
|
168414
168479
|
id: ChannelId.make(dm._id),
|
|
@@ -168904,25 +168969,20 @@ var findProject = (projectIdentifier) => Effect_exports.gen(function* () {
|
|
|
168904
168969
|
);
|
|
168905
168970
|
return { client, project: project3 };
|
|
168906
168971
|
});
|
|
168907
|
-
var
|
|
168908
|
-
|
|
168972
|
+
var statusCategoryValueFromRef = (category) => category === void 0 ? "unknown" : StatusCategoryEntries.find((entry) => entry.ref === category)?.key ?? "unknown";
|
|
168973
|
+
var workflowStatusFromDoc = (doc) => {
|
|
168909
168974
|
return {
|
|
168910
168975
|
_id: doc._id,
|
|
168911
168976
|
name: doc.name,
|
|
168912
|
-
|
|
168913
|
-
isCanceled: categoryStr === task.statusCategory.Lost
|
|
168977
|
+
category: statusCategoryValueFromRef(doc.category)
|
|
168914
168978
|
};
|
|
168915
168979
|
};
|
|
168916
|
-
var
|
|
168980
|
+
var workflowStatusFromRef = (statusRef) => {
|
|
168917
168981
|
const name = statusRef.includes(":") ? statusRef.slice(statusRef.lastIndexOf(":") + 1) : statusRef;
|
|
168918
|
-
const nameLower = name.toLowerCase();
|
|
168919
|
-
const isDone5 = nameLower.includes("done") || nameLower.includes("complete") || nameLower.includes("finished") || nameLower.includes("resolved") || nameLower.includes("closed");
|
|
168920
|
-
const isCanceled = nameLower.includes("cancel") || nameLower.includes("reject") || nameLower.includes("abort") || nameLower.includes("wontfix") || nameLower.includes("invalid");
|
|
168921
168982
|
return {
|
|
168922
168983
|
_id: statusRef,
|
|
168923
168984
|
name,
|
|
168924
|
-
|
|
168925
|
-
isCanceled
|
|
168985
|
+
category: "unknown"
|
|
168926
168986
|
};
|
|
168927
168987
|
};
|
|
168928
168988
|
var uniqueStatusRefs = (refs) => refs.reduce(
|
|
@@ -168956,12 +169016,12 @@ var findProjectWithStatuses = (projectIdentifier) => Effect_exports.gen(function
|
|
|
168956
169016
|
)
|
|
168957
169017
|
);
|
|
168958
169018
|
if (statusDocsResult._tag === "Right") {
|
|
168959
|
-
return uniqueStatusDocs(statusDocsResult.right).map(
|
|
169019
|
+
return uniqueStatusDocs(statusDocsResult.right).map(workflowStatusFromDoc);
|
|
168960
169020
|
}
|
|
168961
169021
|
yield* Effect_exports.logWarning(
|
|
168962
|
-
`Status query failed for project ${projectIdentifier}, using fallback.
|
|
169022
|
+
`Status query failed for project ${projectIdentifier}, using fallback. statusCategory filtering is unavailable until Huly returns status metadata. Error: ${statusDocsResult.left.message}`
|
|
168963
169023
|
);
|
|
168964
|
-
return statusRefs.map(
|
|
169024
|
+
return statusRefs.map(workflowStatusFromRef);
|
|
168965
169025
|
}) : [];
|
|
168966
169026
|
const defaultStatusId = project3.defaultIssueStatus || statuses[0]?._id;
|
|
168967
169027
|
return { client, defaultStatusId, project: project3, projectType, statuses };
|
|
@@ -170876,7 +170936,7 @@ var findDirectMessage = (identifier2) => Effect_exports.gen(function* () {
|
|
|
170876
170936
|
const accountUuid = client.getAccountUuid();
|
|
170877
170937
|
const accountUuids = [
|
|
170878
170938
|
...new Set(
|
|
170879
|
-
employees.map((e) => e.personUuid).filter((u) => u !== void 0
|
|
170939
|
+
employees.map((e) => e.personUuid).filter((u) => u !== void 0).filter((u) => u !== accountUuid)
|
|
170880
170940
|
)
|
|
170881
170941
|
];
|
|
170882
170942
|
if (accountUuids.length === 0) {
|
|
@@ -170935,7 +170995,7 @@ var listDirectMessageMessages = (params) => Effect_exports.gen(function* () {
|
|
|
170935
170995
|
return {
|
|
170936
170996
|
id: MessageId.make(msg._id),
|
|
170937
170997
|
body: markupToMarkdownString(msg.message, markupUrlConfig),
|
|
170938
|
-
sender: senderName
|
|
170998
|
+
sender: senderName,
|
|
170939
170999
|
senderId: msg.modifiedBy,
|
|
170940
171000
|
createdOn: msg.createdOn,
|
|
170941
171001
|
modifiedOn: msg.modifiedOn,
|
|
@@ -171087,7 +171147,7 @@ var listThreadReplies = (params) => Effect_exports.gen(function* () {
|
|
|
171087
171147
|
return {
|
|
171088
171148
|
id: ThreadReplyId.make(msg._id),
|
|
171089
171149
|
body: markupToMarkdownString(msg.message, markupUrlConfig),
|
|
171090
|
-
sender: senderName
|
|
171150
|
+
sender: senderName,
|
|
171091
171151
|
senderId: msg.modifiedBy,
|
|
171092
171152
|
createdOn: msg.createdOn,
|
|
171093
171153
|
modifiedOn: msg.modifiedOn,
|
|
@@ -173556,6 +173616,90 @@ var resolveDocumentWithoutTeamspace = (client, identifier2, field) => Effect_exp
|
|
|
173556
173616
|
}
|
|
173557
173617
|
return resolvedSummary(byTitle[0], "document");
|
|
173558
173618
|
});
|
|
173619
|
+
var findCardById = (client, identifier2) => client.findOne(
|
|
173620
|
+
cardPlugin.class.Card,
|
|
173621
|
+
hulyQuery({ _id: toRef(identifier2) })
|
|
173622
|
+
);
|
|
173623
|
+
var findCardSpace2 = (client, identifier2, field) => Effect_exports.gen(function* () {
|
|
173624
|
+
const byId = yield* client.findOne(
|
|
173625
|
+
cardPlugin.class.CardSpace,
|
|
173626
|
+
hulyQuery({ _id: toRef(identifier2) })
|
|
173627
|
+
);
|
|
173628
|
+
if (byId !== void 0) {
|
|
173629
|
+
return byId;
|
|
173630
|
+
}
|
|
173631
|
+
const byName = yield* client.findAll(
|
|
173632
|
+
cardPlugin.class.CardSpace,
|
|
173633
|
+
hulyQuery({ name: identifier2, archived: false }),
|
|
173634
|
+
{ limit: 2 }
|
|
173635
|
+
);
|
|
173636
|
+
if (byName.length === 0) {
|
|
173637
|
+
return yield* new GenericObjectNotFoundError({
|
|
173638
|
+
field,
|
|
173639
|
+
identifier: identifier2,
|
|
173640
|
+
class: cardPlugin.class.CardSpace
|
|
173641
|
+
});
|
|
173642
|
+
}
|
|
173643
|
+
if (byName.length > 1) {
|
|
173644
|
+
return yield* new GenericObjectIdentifierAmbiguousError({
|
|
173645
|
+
field,
|
|
173646
|
+
identifier: identifier2,
|
|
173647
|
+
candidates: byName.map((space) => ({
|
|
173648
|
+
id: DocId.make(space._id),
|
|
173649
|
+
class: ObjectClassName.make(space._class),
|
|
173650
|
+
display: space.name
|
|
173651
|
+
}))
|
|
173652
|
+
});
|
|
173653
|
+
}
|
|
173654
|
+
return byName[0];
|
|
173655
|
+
});
|
|
173656
|
+
var resolveCardInSpace = (client, identifier2, cardSpace, field) => Effect_exports.gen(function* () {
|
|
173657
|
+
const byId = yield* client.findOne(
|
|
173658
|
+
cardPlugin.class.Card,
|
|
173659
|
+
hulyQuery({ _id: toRef(identifier2), space: cardSpace._id })
|
|
173660
|
+
);
|
|
173661
|
+
if (byId !== void 0) {
|
|
173662
|
+
return resolvedSummary(byId, "card");
|
|
173663
|
+
}
|
|
173664
|
+
const byTitle = yield* client.findAll(
|
|
173665
|
+
cardPlugin.class.Card,
|
|
173666
|
+
hulyQuery({ title: identifier2, space: cardSpace._id }),
|
|
173667
|
+
{ limit: 2 }
|
|
173668
|
+
);
|
|
173669
|
+
if (byTitle.length === 0) {
|
|
173670
|
+
return yield* new GenericObjectNotFoundError({
|
|
173671
|
+
field,
|
|
173672
|
+
identifier: identifier2,
|
|
173673
|
+
class: cardPlugin.class.Card
|
|
173674
|
+
});
|
|
173675
|
+
}
|
|
173676
|
+
if (byTitle.length > 1) {
|
|
173677
|
+
return yield* new GenericObjectIdentifierAmbiguousError({
|
|
173678
|
+
field,
|
|
173679
|
+
identifier: identifier2,
|
|
173680
|
+
candidates: byTitle.map((card) => ({
|
|
173681
|
+
id: DocId.make(card._id),
|
|
173682
|
+
class: ObjectClassName.make(card._class),
|
|
173683
|
+
display: card.title
|
|
173684
|
+
}))
|
|
173685
|
+
});
|
|
173686
|
+
}
|
|
173687
|
+
return resolvedSummary(byTitle[0], "card");
|
|
173688
|
+
});
|
|
173689
|
+
var resolveCardLocator = (client, locator, field) => Effect_exports.gen(function* () {
|
|
173690
|
+
if (locator.cardSpace !== void 0) {
|
|
173691
|
+
const cardSpace = yield* findCardSpace2(client, locator.cardSpace, field);
|
|
173692
|
+
return yield* resolveCardInSpace(client, locator.card, cardSpace, field);
|
|
173693
|
+
}
|
|
173694
|
+
const byId = yield* findCardById(client, locator.card);
|
|
173695
|
+
if (byId !== void 0) {
|
|
173696
|
+
return resolvedSummary(byId, "card");
|
|
173697
|
+
}
|
|
173698
|
+
return yield* new GenericObjectLocatorInvalidError({
|
|
173699
|
+
field,
|
|
173700
|
+
reason: `card '${locator.card}' was not found by ID; exact card title lookup requires cardSpace`
|
|
173701
|
+
});
|
|
173702
|
+
});
|
|
173559
173703
|
var resolveGenericObject = (client, locator, expectedClass, field) => Effect_exports.gen(function* () {
|
|
173560
173704
|
switch (locator.kind) {
|
|
173561
173705
|
case "raw": {
|
|
@@ -173594,6 +173738,11 @@ var resolveGenericObject = (client, locator, expectedClass, field) => Effect_exp
|
|
|
173594
173738
|
yield* validateExpectedClass(summary5, expectedClass, field);
|
|
173595
173739
|
return summary5;
|
|
173596
173740
|
}
|
|
173741
|
+
case "card": {
|
|
173742
|
+
const summary5 = yield* resolveCardLocator(client, locator, field);
|
|
173743
|
+
yield* validateExpectedClass(summary5, expectedClass, field);
|
|
173744
|
+
return summary5;
|
|
173745
|
+
}
|
|
173597
173746
|
}
|
|
173598
173747
|
});
|
|
173599
173748
|
var unresolvedRelationEndpoint = (id, className, warning) => ({
|
|
@@ -174079,7 +174228,7 @@ var genericAssociationTools = [
|
|
|
174079
174228
|
},
|
|
174080
174229
|
{
|
|
174081
174230
|
name: "list_relations",
|
|
174082
|
-
description: "List concrete Huly relation instances under an association, optionally filtered by source and target documents. Requires at least one filter to avoid broad workspace scans.",
|
|
174231
|
+
description: "List concrete Huly relation instances under an association, optionally filtered by source and target documents. Endpoint locators support raw, issue, document, and card. Requires at least one filter to avoid broad workspace scans.",
|
|
174083
174232
|
category: CATEGORY11,
|
|
174084
174233
|
inputSchema: listRelationsParamsJsonSchema,
|
|
174085
174234
|
handler: createEncodedToolHandler(
|
|
@@ -174091,7 +174240,7 @@ var genericAssociationTools = [
|
|
|
174091
174240
|
},
|
|
174092
174241
|
{
|
|
174093
174242
|
name: "create_relation",
|
|
174094
|
-
description: "Idempotently create one concrete relation between two resolved documents for a writable association. Enforces association endpoint classes, direction, duplicate handling, automation-only restrictions, and cardinality.",
|
|
174243
|
+
description: "Idempotently create one concrete relation between two resolved documents for a writable association. Endpoint locators support raw, issue, document, and card. Enforces association endpoint classes, direction, duplicate handling, automation-only restrictions, and cardinality.",
|
|
174095
174244
|
category: CATEGORY11,
|
|
174096
174245
|
inputSchema: createRelationParamsJsonSchema,
|
|
174097
174246
|
annotations: {
|
|
@@ -174109,7 +174258,7 @@ var genericAssociationTools = [
|
|
|
174109
174258
|
},
|
|
174110
174259
|
{
|
|
174111
174260
|
name: "delete_relation",
|
|
174112
|
-
description: "Idempotently delete one concrete relation by relation ID or by exact association/source/target triple. Triple deletes use the same direction semantics as create_relation and fail if the selector is ambiguous.",
|
|
174261
|
+
description: "Idempotently delete one concrete relation by relation ID or by exact association/source/target triple. Triple endpoint locators support raw, issue, document, and card. Triple deletes use the same direction semantics as create_relation and fail if the selector is ambiguous.",
|
|
174113
174262
|
category: CATEGORY11,
|
|
174114
174263
|
inputSchema: deleteRelationParamsJsonSchema,
|
|
174115
174264
|
annotations: {
|
|
@@ -174586,36 +174735,30 @@ var resolveStatusName = (statuses, statusId) => {
|
|
|
174586
174735
|
const statusDoc = statuses.find((s) => s._id === statusId);
|
|
174587
174736
|
return statusDoc?.name ?? "Unknown";
|
|
174588
174737
|
};
|
|
174738
|
+
var hasUnknownStatusCategory = (statuses) => statuses.some((status) => status.category === "unknown");
|
|
174739
|
+
var requireKnownStatusCategories = (statuses, category, project3) => hasUnknownStatusCategory(statuses) ? Effect_exports.fail(
|
|
174740
|
+
new HulyConnectionError({
|
|
174741
|
+
message: `Cannot filter project '${project3}' issues by status category '${category}' because Huly did not return complete status category metadata. Use an exact status name instead.`
|
|
174742
|
+
})
|
|
174743
|
+
) : Effect_exports.void;
|
|
174744
|
+
var statusIdsByCategory = (statuses, category) => statuses.filter((status) => status.category === category).map((status) => status._id);
|
|
174589
174745
|
var listIssues = (params) => Effect_exports.gen(function* () {
|
|
174590
174746
|
const { client, project: project3, statuses } = yield* findProjectWithStatuses(params.project);
|
|
174591
174747
|
const query = {
|
|
174592
174748
|
space: project3._id
|
|
174593
174749
|
};
|
|
174594
|
-
if (params.
|
|
174595
|
-
|
|
174596
|
-
|
|
174597
|
-
|
|
174598
|
-
|
|
174599
|
-
query.status = { $nin: doneAndCanceledStatuses };
|
|
174600
|
-
}
|
|
174601
|
-
} else if (statusFilter === "done") {
|
|
174602
|
-
const doneStatuses = statuses.filter((s) => s.isDone).map((s) => s._id);
|
|
174603
|
-
if (doneStatuses.length > 0) {
|
|
174604
|
-
query.status = { $in: doneStatuses };
|
|
174605
|
-
} else {
|
|
174606
|
-
return [];
|
|
174607
|
-
}
|
|
174608
|
-
} else if (statusFilter === "canceled") {
|
|
174609
|
-
const canceledStatuses = statuses.filter((s) => s.isCanceled).map((s) => s._id);
|
|
174610
|
-
if (canceledStatuses.length > 0) {
|
|
174611
|
-
query.status = { $in: canceledStatuses };
|
|
174612
|
-
} else {
|
|
174613
|
-
return [];
|
|
174614
|
-
}
|
|
174750
|
+
if (params.statusCategory !== void 0) {
|
|
174751
|
+
yield* requireKnownStatusCategories(statuses, params.statusCategory, params.project);
|
|
174752
|
+
const matchingStatuses = statusIdsByCategory(statuses, params.statusCategory);
|
|
174753
|
+
if (matchingStatuses.length > 0) {
|
|
174754
|
+
query.status = { $in: matchingStatuses };
|
|
174615
174755
|
} else {
|
|
174616
|
-
|
|
174756
|
+
return [];
|
|
174617
174757
|
}
|
|
174618
174758
|
}
|
|
174759
|
+
if (params.status !== void 0) {
|
|
174760
|
+
query.status = yield* resolveStatusByName(statuses, params.status, params.project);
|
|
174761
|
+
}
|
|
174619
174762
|
if (params.assignee !== void 0) {
|
|
174620
174763
|
const assigneePerson = yield* findPersonByEmailOrName(client, params.assignee);
|
|
174621
174764
|
if (assigneePerson !== void 0) {
|
|
@@ -175645,7 +175788,7 @@ var CATEGORY12 = "issues";
|
|
|
175645
175788
|
var issueTools = [
|
|
175646
175789
|
{
|
|
175647
175790
|
name: "list_issues",
|
|
175648
|
-
description:
|
|
175791
|
+
description: `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: ${enumValuesDescription(StatusCategoryValues)}), assignee, component, and parentIssue (to list children of a specific issue). Supports searching by title substring (titleSearch) and description content (descriptionSearch).`,
|
|
175649
175792
|
category: CATEGORY12,
|
|
175650
175793
|
inputSchema: listIssuesParamsJsonSchema,
|
|
175651
175794
|
handler: createToolHandler(
|
|
@@ -177407,8 +177550,7 @@ var listStatuses = (params) => Effect_exports.gen(function* () {
|
|
|
177407
177550
|
const { defaultStatusId, statuses } = yield* findProjectWithStatuses(params.project);
|
|
177408
177551
|
const details = statuses.map((s) => ({
|
|
177409
177552
|
name: StatusName.make(s.name),
|
|
177410
|
-
|
|
177411
|
-
isCanceled: s.isCanceled,
|
|
177553
|
+
category: s.category,
|
|
177412
177554
|
isDefault: s._id === defaultStatusId
|
|
177413
177555
|
}));
|
|
177414
177556
|
return { statuses: details, total: details.length };
|
|
@@ -177512,7 +177654,7 @@ var projectTools = [
|
|
|
177512
177654
|
},
|
|
177513
177655
|
{
|
|
177514
177656
|
name: "list_statuses",
|
|
177515
|
-
description: "List all issue statuses for a Huly project with category info. Returns status name,
|
|
177657
|
+
description: "List all issue statuses for a Huly project with workflow category and default info. Returns status name, category, and isDefault. Use this to discover valid statuses before creating or updating issues.",
|
|
177516
177658
|
category: CATEGORY18,
|
|
177517
177659
|
inputSchema: listStatusesParamsJsonSchema,
|
|
177518
177660
|
handler: createToolHandler(
|
|
@@ -177685,20 +177827,20 @@ var tagCategoryTools = [
|
|
|
177685
177827
|
var import_core38 = __toESM(require_lib4(), 1);
|
|
177686
177828
|
var import_platform3 = __toESM(require_lib(), 1);
|
|
177687
177829
|
var STATUS_CATEGORY_BY_SDK_KEY = {
|
|
177688
|
-
UnStarted: { value: "
|
|
177689
|
-
ToDo: { value: "
|
|
177690
|
-
Active: { value: "
|
|
177691
|
-
Won: { value: "
|
|
177692
|
-
Lost: { value: "
|
|
177830
|
+
UnStarted: { value: "UnStarted", ref: StatusCategoryBySdkKey.UnStarted, name: "UnStarted" },
|
|
177831
|
+
ToDo: { value: "ToDo", ref: StatusCategoryBySdkKey.ToDo, name: "ToDo" },
|
|
177832
|
+
Active: { value: "Active", ref: StatusCategoryBySdkKey.Active, name: "Active" },
|
|
177833
|
+
Won: { value: "Won", ref: StatusCategoryBySdkKey.Won, name: "Won" },
|
|
177834
|
+
Lost: { value: "Lost", ref: StatusCategoryBySdkKey.Lost, name: "Lost" }
|
|
177693
177835
|
};
|
|
177694
177836
|
var exactStatusCategoryMapping = (value3) => value3;
|
|
177695
177837
|
exactStatusCategoryMapping(true);
|
|
177696
177838
|
var CATEGORY_TO_REF = {
|
|
177697
|
-
|
|
177698
|
-
|
|
177699
|
-
|
|
177700
|
-
|
|
177701
|
-
|
|
177839
|
+
UnStarted: STATUS_CATEGORY_BY_SDK_KEY.UnStarted.ref,
|
|
177840
|
+
ToDo: STATUS_CATEGORY_BY_SDK_KEY.ToDo.ref,
|
|
177841
|
+
Active: STATUS_CATEGORY_BY_SDK_KEY.Active.ref,
|
|
177842
|
+
Won: STATUS_CATEGORY_BY_SDK_KEY.Won.ref,
|
|
177843
|
+
Lost: STATUS_CATEGORY_BY_SDK_KEY.Lost.ref
|
|
177702
177844
|
};
|
|
177703
177845
|
var REF_TO_CATEGORY = new Map(
|
|
177704
177846
|
Object.values(STATUS_CATEGORY_BY_SDK_KEY).map((entry) => [entry.ref, entry.value])
|
|
@@ -178111,7 +178253,7 @@ var taskManagementTools = [
|
|
|
178111
178253
|
},
|
|
178112
178254
|
{
|
|
178113
178255
|
name: "create_issue_status",
|
|
178114
|
-
description:
|
|
178256
|
+
description: `Add a Huly issue workflow status idempotently by normalized name within a project type and task type scope. Accepts category as a Huly SDK task.statusCategory key: ${enumValuesDescription(StatusCategoryValues)}; taskType may be ID or display name, and omission applies the status to every task type in the project type.`,
|
|
178115
178257
|
category: CATEGORY22,
|
|
178116
178258
|
inputSchema: createIssueStatusParamsJsonSchema,
|
|
178117
178259
|
annotations: { idempotentHint: true },
|
|
@@ -190293,6 +190435,37 @@ var McpServerService = class _McpServerService extends Context_exports.Tag("@hul
|
|
|
190293
190435
|
}
|
|
190294
190436
|
};
|
|
190295
190437
|
|
|
190438
|
+
// src/mcp/stdio-output.ts
|
|
190439
|
+
var redirectedMethods = [
|
|
190440
|
+
"debug",
|
|
190441
|
+
"info",
|
|
190442
|
+
"log",
|
|
190443
|
+
"warn",
|
|
190444
|
+
"error"
|
|
190445
|
+
];
|
|
190446
|
+
var redirectConsoleToStderr = (target = console) => {
|
|
190447
|
+
const original = {
|
|
190448
|
+
debug: target.debug,
|
|
190449
|
+
error: target.error,
|
|
190450
|
+
info: target.info,
|
|
190451
|
+
log: target.log,
|
|
190452
|
+
warn: target.warn
|
|
190453
|
+
};
|
|
190454
|
+
const writeToStderr = original.error.bind(target);
|
|
190455
|
+
for (const method of redirectedMethods) {
|
|
190456
|
+
target[method] = writeToStderr;
|
|
190457
|
+
}
|
|
190458
|
+
return {
|
|
190459
|
+
restore: () => {
|
|
190460
|
+
target.debug = original.debug;
|
|
190461
|
+
target.error = original.error;
|
|
190462
|
+
target.info = original.info;
|
|
190463
|
+
target.log = original.log;
|
|
190464
|
+
target.warn = original.warn;
|
|
190465
|
+
}
|
|
190466
|
+
};
|
|
190467
|
+
};
|
|
190468
|
+
|
|
190296
190469
|
// src/index.ts
|
|
190297
190470
|
var getTransportType = Config_exports.string("MCP_TRANSPORT").pipe(
|
|
190298
190471
|
Config_exports.withDefault("stdio"),
|
|
@@ -190320,6 +190493,9 @@ var getLazyEnvs = Config_exports.string("LAZY_ENVS").pipe(
|
|
|
190320
190493
|
Config_exports.withDefault("false"),
|
|
190321
190494
|
Effect_exports.map((v) => v.toLowerCase() === "true")
|
|
190322
190495
|
);
|
|
190496
|
+
var restoreConsoleRedirect = (redirect) => Effect_exports.sync(() => {
|
|
190497
|
+
redirect?.restore();
|
|
190498
|
+
});
|
|
190323
190499
|
var buildCombinedClientLayer = () => {
|
|
190324
190500
|
const configLayer = HulyConfigService.layer;
|
|
190325
190501
|
const hulyClientLayer = HulyClient.layer.pipe(
|
|
@@ -190411,8 +190587,7 @@ var buildAppLayer = (transport, httpPort, httpHost, mcpAuthToken, autoExit, auth
|
|
|
190411
190587
|
const mcpServerLayer = McpServerService.layer(mcpServerConfig).pipe(Layer_exports.provide(TelemetryService.layer));
|
|
190412
190588
|
return Layer_exports.merge(mcpServerLayer, HttpServerFactoryService.defaultLayer);
|
|
190413
190589
|
};
|
|
190414
|
-
var
|
|
190415
|
-
const transport = yield* getTransportType;
|
|
190590
|
+
var runConfiguredServer = (transport) => Effect_exports.gen(function* () {
|
|
190416
190591
|
const httpPort = yield* getHttpPort;
|
|
190417
190592
|
const httpHost = yield* getHttpHost;
|
|
190418
190593
|
const mcpAuthToken = transport === "http" ? Option_exports.map(yield* getMcpAuthToken, Redacted_exports.value).pipe(Option_exports.getOrUndefined) : void 0;
|
|
@@ -190446,6 +190621,13 @@ var main = Effect_exports.gen(function* () {
|
|
|
190446
190621
|
Effect_exports.scoped
|
|
190447
190622
|
);
|
|
190448
190623
|
});
|
|
190624
|
+
var main = Effect_exports.gen(function* () {
|
|
190625
|
+
const transport = yield* getTransportType;
|
|
190626
|
+
const consoleRedirect = yield* Effect_exports.sync(() => transport === "stdio" ? redirectConsoleToStderr() : void 0);
|
|
190627
|
+
yield* runConfiguredServer(transport).pipe(
|
|
190628
|
+
Effect_exports.ensuring(restoreConsoleRedirect(consoleRedirect))
|
|
190629
|
+
);
|
|
190630
|
+
});
|
|
190449
190631
|
var isMainModule = (() => {
|
|
190450
190632
|
if (typeof require !== "undefined" && require.main === module) return true;
|
|
190451
190633
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firfi/huly-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "MCP server for Huly integration",
|
|
5
5
|
"mcpName": "io.github.dearlordylord/huly-mcp",
|
|
6
6
|
"type": "module",
|
|
@@ -111,6 +111,6 @@
|
|
|
111
111
|
"verify-version": "node -e \"const v=require('./package.json').version; const d=require('fs').readFileSync('dist/index.cjs','utf8'); if(!d.includes('\\\"'+v+'\\\"'))throw new Error('dist version mismatch: expected '+v)\"",
|
|
112
112
|
"verify-registry-metadata": "node scripts/sync-registry-metadata.mjs --check",
|
|
113
113
|
"sync-registry-metadata": "node scripts/sync-registry-metadata.mjs",
|
|
114
|
-
"update-readme": "
|
|
114
|
+
"update-readme": "tsx scripts/update-readme-tools.mjs"
|
|
115
115
|
}
|
|
116
116
|
}
|