@firfi/huly-mcp 0.17.1 → 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 +465 -236
- 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,6 +168969,31 @@ var findProject = (projectIdentifier) => Effect_exports.gen(function* () {
|
|
|
168904
168969
|
);
|
|
168905
168970
|
return { client, project: project3 };
|
|
168906
168971
|
});
|
|
168972
|
+
var statusCategoryValueFromRef = (category) => category === void 0 ? "unknown" : StatusCategoryEntries.find((entry) => entry.ref === category)?.key ?? "unknown";
|
|
168973
|
+
var workflowStatusFromDoc = (doc) => {
|
|
168974
|
+
return {
|
|
168975
|
+
_id: doc._id,
|
|
168976
|
+
name: doc.name,
|
|
168977
|
+
category: statusCategoryValueFromRef(doc.category)
|
|
168978
|
+
};
|
|
168979
|
+
};
|
|
168980
|
+
var workflowStatusFromRef = (statusRef) => {
|
|
168981
|
+
const name = statusRef.includes(":") ? statusRef.slice(statusRef.lastIndexOf(":") + 1) : statusRef;
|
|
168982
|
+
return {
|
|
168983
|
+
_id: statusRef,
|
|
168984
|
+
name,
|
|
168985
|
+
category: "unknown"
|
|
168986
|
+
};
|
|
168987
|
+
};
|
|
168988
|
+
var uniqueStatusRefs = (refs) => refs.reduce(
|
|
168989
|
+
(unique, ref) => unique.includes(ref) ? unique : [...unique, ref],
|
|
168990
|
+
[]
|
|
168991
|
+
);
|
|
168992
|
+
var uniqueStatusDocs = (statuses) => Array.from(statuses).reduce(
|
|
168993
|
+
(unique, status) => unique.some((existing) => existing._id === status._id) ? unique : [...unique, status],
|
|
168994
|
+
[]
|
|
168995
|
+
);
|
|
168996
|
+
var uniqueProjectTypeStatusRefs = (statuses) => uniqueStatusRefs(statuses.map((status) => status._id));
|
|
168907
168997
|
var findProjectWithStatuses = (projectIdentifier) => Effect_exports.gen(function* () {
|
|
168908
168998
|
const client = yield* HulyClient;
|
|
168909
168999
|
const project3 = yield* findOneOrFail(
|
|
@@ -168914,45 +169004,25 @@ var findProjectWithStatuses = (projectIdentifier) => Effect_exports.gen(function
|
|
|
168914
169004
|
{ lookup: { type: task.class.ProjectType } }
|
|
168915
169005
|
);
|
|
168916
169006
|
const projectType = project3.$lookup?.type;
|
|
168917
|
-
const statuses =
|
|
168918
|
-
|
|
168919
|
-
|
|
168920
|
-
|
|
168921
|
-
const statusDocsResult = yield* Effect_exports.either(
|
|
168922
|
-
client.findAll(
|
|
168923
|
-
core.class.Status,
|
|
168924
|
-
hulyQuery({ _id: { $in: statusRefs } })
|
|
168925
|
-
)
|
|
168926
|
-
);
|
|
168927
|
-
if (statusDocsResult._tag === "Right") {
|
|
168928
|
-
for (const doc of statusDocsResult.right) {
|
|
168929
|
-
const categoryStr = doc.category ? doc.category : "";
|
|
168930
|
-
statuses.push({
|
|
168931
|
-
_id: doc._id,
|
|
168932
|
-
name: doc.name,
|
|
168933
|
-
isDone: categoryStr === task.statusCategory.Won,
|
|
168934
|
-
isCanceled: categoryStr === task.statusCategory.Lost
|
|
168935
|
-
});
|
|
168936
|
-
}
|
|
168937
|
-
} else {
|
|
168938
|
-
yield* Effect_exports.logWarning(
|
|
168939
|
-
`Status query failed for project ${projectIdentifier}, using fallback. Category-based filtering (open/done/canceled) will use name heuristics. Error: ${statusDocsResult.left.message}`
|
|
168940
|
-
);
|
|
168941
|
-
for (const ps of projectType.statuses) {
|
|
168942
|
-
const name = ps._id.split(":").pop() ?? "Unknown";
|
|
168943
|
-
const nameLower = name.toLowerCase();
|
|
168944
|
-
const isDone5 = nameLower.includes("done") || nameLower.includes("complete") || nameLower.includes("finished") || nameLower.includes("resolved") || nameLower.includes("closed");
|
|
168945
|
-
const isCanceled = nameLower.includes("cancel") || nameLower.includes("reject") || nameLower.includes("abort") || nameLower.includes("wontfix") || nameLower.includes("invalid");
|
|
168946
|
-
statuses.push({
|
|
168947
|
-
_id: ps._id,
|
|
168948
|
-
name,
|
|
168949
|
-
isDone: isDone5,
|
|
168950
|
-
isCanceled
|
|
168951
|
-
});
|
|
168952
|
-
}
|
|
168953
|
-
}
|
|
169007
|
+
const statuses = projectType?.statuses ? yield* Effect_exports.gen(function* () {
|
|
169008
|
+
const statusRefs = uniqueProjectTypeStatusRefs(projectType.statuses);
|
|
169009
|
+
if (statusRefs.length === 0) {
|
|
169010
|
+
return [];
|
|
168954
169011
|
}
|
|
168955
|
-
|
|
169012
|
+
const statusDocsResult = yield* Effect_exports.either(
|
|
169013
|
+
client.findAll(
|
|
169014
|
+
core.class.Status,
|
|
169015
|
+
hulyQuery({ _id: { $in: statusRefs } })
|
|
169016
|
+
)
|
|
169017
|
+
);
|
|
169018
|
+
if (statusDocsResult._tag === "Right") {
|
|
169019
|
+
return uniqueStatusDocs(statusDocsResult.right).map(workflowStatusFromDoc);
|
|
169020
|
+
}
|
|
169021
|
+
yield* Effect_exports.logWarning(
|
|
169022
|
+
`Status query failed for project ${projectIdentifier}, using fallback. statusCategory filtering is unavailable until Huly returns status metadata. Error: ${statusDocsResult.left.message}`
|
|
169023
|
+
);
|
|
169024
|
+
return statusRefs.map(workflowStatusFromRef);
|
|
169025
|
+
}) : [];
|
|
168956
169026
|
const defaultStatusId = project3.defaultIssueStatus || statuses[0]?._id;
|
|
168957
169027
|
return { client, defaultStatusId, project: project3, projectType, statuses };
|
|
168958
169028
|
});
|
|
@@ -170866,7 +170936,7 @@ var findDirectMessage = (identifier2) => Effect_exports.gen(function* () {
|
|
|
170866
170936
|
const accountUuid = client.getAccountUuid();
|
|
170867
170937
|
const accountUuids = [
|
|
170868
170938
|
...new Set(
|
|
170869
|
-
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)
|
|
170870
170940
|
)
|
|
170871
170941
|
];
|
|
170872
170942
|
if (accountUuids.length === 0) {
|
|
@@ -170925,7 +170995,7 @@ var listDirectMessageMessages = (params) => Effect_exports.gen(function* () {
|
|
|
170925
170995
|
return {
|
|
170926
170996
|
id: MessageId.make(msg._id),
|
|
170927
170997
|
body: markupToMarkdownString(msg.message, markupUrlConfig),
|
|
170928
|
-
sender: senderName
|
|
170998
|
+
sender: senderName,
|
|
170929
170999
|
senderId: msg.modifiedBy,
|
|
170930
171000
|
createdOn: msg.createdOn,
|
|
170931
171001
|
modifiedOn: msg.modifiedOn,
|
|
@@ -171077,7 +171147,7 @@ var listThreadReplies = (params) => Effect_exports.gen(function* () {
|
|
|
171077
171147
|
return {
|
|
171078
171148
|
id: ThreadReplyId.make(msg._id),
|
|
171079
171149
|
body: markupToMarkdownString(msg.message, markupUrlConfig),
|
|
171080
|
-
sender: senderName
|
|
171150
|
+
sender: senderName,
|
|
171081
171151
|
senderId: msg.modifiedBy,
|
|
171082
171152
|
createdOn: msg.createdOn,
|
|
171083
171153
|
modifiedOn: msg.modifiedOn,
|
|
@@ -173546,6 +173616,90 @@ var resolveDocumentWithoutTeamspace = (client, identifier2, field) => Effect_exp
|
|
|
173546
173616
|
}
|
|
173547
173617
|
return resolvedSummary(byTitle[0], "document");
|
|
173548
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
|
+
});
|
|
173549
173703
|
var resolveGenericObject = (client, locator, expectedClass, field) => Effect_exports.gen(function* () {
|
|
173550
173704
|
switch (locator.kind) {
|
|
173551
173705
|
case "raw": {
|
|
@@ -173584,6 +173738,11 @@ var resolveGenericObject = (client, locator, expectedClass, field) => Effect_exp
|
|
|
173584
173738
|
yield* validateExpectedClass(summary5, expectedClass, field);
|
|
173585
173739
|
return summary5;
|
|
173586
173740
|
}
|
|
173741
|
+
case "card": {
|
|
173742
|
+
const summary5 = yield* resolveCardLocator(client, locator, field);
|
|
173743
|
+
yield* validateExpectedClass(summary5, expectedClass, field);
|
|
173744
|
+
return summary5;
|
|
173745
|
+
}
|
|
173587
173746
|
}
|
|
173588
173747
|
});
|
|
173589
173748
|
var unresolvedRelationEndpoint = (id, className, warning) => ({
|
|
@@ -174069,7 +174228,7 @@ var genericAssociationTools = [
|
|
|
174069
174228
|
},
|
|
174070
174229
|
{
|
|
174071
174230
|
name: "list_relations",
|
|
174072
|
-
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.",
|
|
174073
174232
|
category: CATEGORY11,
|
|
174074
174233
|
inputSchema: listRelationsParamsJsonSchema,
|
|
174075
174234
|
handler: createEncodedToolHandler(
|
|
@@ -174081,7 +174240,7 @@ var genericAssociationTools = [
|
|
|
174081
174240
|
},
|
|
174082
174241
|
{
|
|
174083
174242
|
name: "create_relation",
|
|
174084
|
-
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.",
|
|
174085
174244
|
category: CATEGORY11,
|
|
174086
174245
|
inputSchema: createRelationParamsJsonSchema,
|
|
174087
174246
|
annotations: {
|
|
@@ -174099,7 +174258,7 @@ var genericAssociationTools = [
|
|
|
174099
174258
|
},
|
|
174100
174259
|
{
|
|
174101
174260
|
name: "delete_relation",
|
|
174102
|
-
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.",
|
|
174103
174262
|
category: CATEGORY11,
|
|
174104
174263
|
inputSchema: deleteRelationParamsJsonSchema,
|
|
174105
174264
|
annotations: {
|
|
@@ -174576,36 +174735,30 @@ var resolveStatusName = (statuses, statusId) => {
|
|
|
174576
174735
|
const statusDoc = statuses.find((s) => s._id === statusId);
|
|
174577
174736
|
return statusDoc?.name ?? "Unknown";
|
|
174578
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);
|
|
174579
174745
|
var listIssues = (params) => Effect_exports.gen(function* () {
|
|
174580
174746
|
const { client, project: project3, statuses } = yield* findProjectWithStatuses(params.project);
|
|
174581
174747
|
const query = {
|
|
174582
174748
|
space: project3._id
|
|
174583
174749
|
};
|
|
174584
|
-
if (params.
|
|
174585
|
-
|
|
174586
|
-
|
|
174587
|
-
|
|
174588
|
-
|
|
174589
|
-
query.status = { $nin: doneAndCanceledStatuses };
|
|
174590
|
-
}
|
|
174591
|
-
} else if (statusFilter === "done") {
|
|
174592
|
-
const doneStatuses = statuses.filter((s) => s.isDone).map((s) => s._id);
|
|
174593
|
-
if (doneStatuses.length > 0) {
|
|
174594
|
-
query.status = { $in: doneStatuses };
|
|
174595
|
-
} else {
|
|
174596
|
-
return [];
|
|
174597
|
-
}
|
|
174598
|
-
} else if (statusFilter === "canceled") {
|
|
174599
|
-
const canceledStatuses = statuses.filter((s) => s.isCanceled).map((s) => s._id);
|
|
174600
|
-
if (canceledStatuses.length > 0) {
|
|
174601
|
-
query.status = { $in: canceledStatuses };
|
|
174602
|
-
} else {
|
|
174603
|
-
return [];
|
|
174604
|
-
}
|
|
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 };
|
|
174605
174755
|
} else {
|
|
174606
|
-
|
|
174756
|
+
return [];
|
|
174607
174757
|
}
|
|
174608
174758
|
}
|
|
174759
|
+
if (params.status !== void 0) {
|
|
174760
|
+
query.status = yield* resolveStatusByName(statuses, params.status, params.project);
|
|
174761
|
+
}
|
|
174609
174762
|
if (params.assignee !== void 0) {
|
|
174610
174763
|
const assigneePerson = yield* findPersonByEmailOrName(client, params.assignee);
|
|
174611
174764
|
if (assigneePerson !== void 0) {
|
|
@@ -175635,7 +175788,7 @@ var CATEGORY12 = "issues";
|
|
|
175635
175788
|
var issueTools = [
|
|
175636
175789
|
{
|
|
175637
175790
|
name: "list_issues",
|
|
175638
|
-
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).`,
|
|
175639
175792
|
category: CATEGORY12,
|
|
175640
175793
|
inputSchema: listIssuesParamsJsonSchema,
|
|
175641
175794
|
handler: createToolHandler(
|
|
@@ -177397,8 +177550,7 @@ var listStatuses = (params) => Effect_exports.gen(function* () {
|
|
|
177397
177550
|
const { defaultStatusId, statuses } = yield* findProjectWithStatuses(params.project);
|
|
177398
177551
|
const details = statuses.map((s) => ({
|
|
177399
177552
|
name: StatusName.make(s.name),
|
|
177400
|
-
|
|
177401
|
-
isCanceled: s.isCanceled,
|
|
177553
|
+
category: s.category,
|
|
177402
177554
|
isDefault: s._id === defaultStatusId
|
|
177403
177555
|
}));
|
|
177404
177556
|
return { statuses: details, total: details.length };
|
|
@@ -177502,7 +177654,7 @@ var projectTools = [
|
|
|
177502
177654
|
},
|
|
177503
177655
|
{
|
|
177504
177656
|
name: "list_statuses",
|
|
177505
|
-
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.",
|
|
177506
177658
|
category: CATEGORY18,
|
|
177507
177659
|
inputSchema: listStatusesParamsJsonSchema,
|
|
177508
177660
|
handler: createToolHandler(
|
|
@@ -177675,20 +177827,20 @@ var tagCategoryTools = [
|
|
|
177675
177827
|
var import_core38 = __toESM(require_lib4(), 1);
|
|
177676
177828
|
var import_platform3 = __toESM(require_lib(), 1);
|
|
177677
177829
|
var STATUS_CATEGORY_BY_SDK_KEY = {
|
|
177678
|
-
UnStarted: { value: "
|
|
177679
|
-
ToDo: { value: "
|
|
177680
|
-
Active: { value: "
|
|
177681
|
-
Won: { value: "
|
|
177682
|
-
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" }
|
|
177683
177835
|
};
|
|
177684
177836
|
var exactStatusCategoryMapping = (value3) => value3;
|
|
177685
177837
|
exactStatusCategoryMapping(true);
|
|
177686
177838
|
var CATEGORY_TO_REF = {
|
|
177687
|
-
|
|
177688
|
-
|
|
177689
|
-
|
|
177690
|
-
|
|
177691
|
-
|
|
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
|
|
177692
177844
|
};
|
|
177693
177845
|
var REF_TO_CATEGORY = new Map(
|
|
177694
177846
|
Object.values(STATUS_CATEGORY_BY_SDK_KEY).map((entry) => [entry.ref, entry.value])
|
|
@@ -177709,9 +177861,15 @@ var encodeOrConnectionError2 = (schema, value3, operation) => Schema_exports.enc
|
|
|
177709
177861
|
})
|
|
177710
177862
|
)
|
|
177711
177863
|
);
|
|
177712
|
-
var
|
|
177864
|
+
var uniqueTaskTypeRefs = (refs) => refs.reduce((unique, ref) => unique.includes(ref) ? unique : [...unique, ref], []);
|
|
177865
|
+
var uniqueStatusIds = (projectType) => uniqueStatusRefs(projectType.statuses.map((status) => status._id));
|
|
177866
|
+
var sameProjectStatus = (left3, right3) => left3._id === right3._id && left3.taskType === right3.taskType;
|
|
177867
|
+
var uniqueProjectStatuses = (statuses) => statuses.reduce(
|
|
177868
|
+
(unique, status) => unique.some((existing) => sameProjectStatus(existing, status)) ? unique : [...unique, status],
|
|
177869
|
+
[]
|
|
177870
|
+
);
|
|
177713
177871
|
var getStatusDocs = (client, statusIds) => statusIds.length === 0 ? Effect_exports.succeed([]) : client.findAll(core.class.Status, hulyQuery({ _id: { $in: [...statusIds] } })).pipe(
|
|
177714
|
-
Effect_exports.map(
|
|
177872
|
+
Effect_exports.map(uniqueStatusDocs)
|
|
177715
177873
|
);
|
|
177716
177874
|
var getTaskTypes = (client, taskTypeIds) => taskTypeIds.length === 0 ? Effect_exports.succeed([]) : client.findAll(task.class.TaskType, hulyQuery({ _id: { $in: [...taskTypeIds] } })).pipe(
|
|
177717
177875
|
Effect_exports.map((result) => [...result])
|
|
@@ -177743,7 +177901,11 @@ var projectTypeSummary = (data) => ({
|
|
|
177743
177901
|
statusCount: uniqueStatusIds(data.projectType).length,
|
|
177744
177902
|
isDefaultClassic: isDefaultClassicProjectType(data.projectType)
|
|
177745
177903
|
});
|
|
177746
|
-
var statusTaskTypeIds = (projectType, statusId) =>
|
|
177904
|
+
var statusTaskTypeIds = (projectType, statusId) => uniqueTaskTypeRefs(
|
|
177905
|
+
uniqueProjectStatuses(projectType.statuses).filter((status) => status._id === statusId).map(
|
|
177906
|
+
(status) => status.taskType
|
|
177907
|
+
)
|
|
177908
|
+
);
|
|
177747
177909
|
var statusSummary = (projectType, status) => ({
|
|
177748
177910
|
id: IssueStatusId.make(status._id),
|
|
177749
177911
|
name: status.name,
|
|
@@ -177757,7 +177919,7 @@ var taskTypeSummary = (projectType, taskType) => ({
|
|
|
177757
177919
|
projectTypeName: projectType.name,
|
|
177758
177920
|
kind: taskType.kind,
|
|
177759
177921
|
issueClass: taskType.ofClass,
|
|
177760
|
-
statusCount: taskType.statuses.length
|
|
177922
|
+
statusCount: uniqueStatusRefs(taskType.statuses).length
|
|
177761
177923
|
});
|
|
177762
177924
|
var projectTypeDetail = (data) => ({
|
|
177763
177925
|
...projectTypeSummary(data),
|
|
@@ -177769,7 +177931,7 @@ var projectTypeDetail = (data) => ({
|
|
|
177769
177931
|
taskTypeStatuses: data.taskTypes.map((taskType) => ({
|
|
177770
177932
|
taskTypeId: TaskTypeId.make(taskType._id),
|
|
177771
177933
|
taskTypeName: taskType.name,
|
|
177772
|
-
statusIds: taskType.statuses.map((statusId) => IssueStatusId.make(statusId))
|
|
177934
|
+
statusIds: uniqueStatusRefs(taskType.statuses).map((statusId) => IssueStatusId.make(statusId))
|
|
177773
177935
|
}))
|
|
177774
177936
|
});
|
|
177775
177937
|
var listAllProjectTypes = (client) => client.findAll(
|
|
@@ -177809,7 +177971,12 @@ var resolveStatusClass = (taskTypes) => {
|
|
|
177809
177971
|
const statusClass = statusClasses.at(0);
|
|
177810
177972
|
return statusClasses.length === 1 && statusClass !== void 0 ? Effect_exports.succeed(statusClass) : Effect_exports.fail(new HulyError({ message: "Target task types do not share one issue status class." }));
|
|
177811
177973
|
};
|
|
177812
|
-
var replaceOrAppendProjectStatus = (statuses, statusId, taskTypeId) => statuses.some((status) => status._id === statusId && status.taskType === taskTypeId) ? statuses : [...statuses, { _id: statusId, taskType: taskTypeId }];
|
|
177974
|
+
var replaceOrAppendProjectStatus = (statuses, statusId, taskTypeId) => statuses.some((status) => status._id === statusId && status.taskType === taskTypeId) ? [...statuses] : [...statuses, { _id: statusId, taskType: taskTypeId }];
|
|
177975
|
+
var sameStatusRefList = (left3, right3) => left3.length === right3.length && left3.every((value3, index) => value3 === right3[index]);
|
|
177976
|
+
var sameProjectStatusList = (left3, right3) => left3.length === right3.length && left3.every((value3, index) => {
|
|
177977
|
+
const rightValue = right3[index];
|
|
177978
|
+
return sameProjectStatus(value3, rightValue);
|
|
177979
|
+
});
|
|
177813
177980
|
var listProjectTypes = (_params) => Effect_exports.gen(function* () {
|
|
177814
177981
|
const client = yield* HulyClient;
|
|
177815
177982
|
const projectTypes = yield* listAllProjectTypes(client);
|
|
@@ -177842,29 +178009,42 @@ var createTaskType = (params) => Effect_exports.gen(function* () {
|
|
|
177842
178009
|
const workflowData = yield* loadWorkflowData(client, projectType);
|
|
177843
178010
|
const allProjectTaskTypes = yield* getTaskTypesByProjectType(client, projectType._id);
|
|
177844
178011
|
const existing = existingTaskTypeByName(allProjectTaskTypes, params.name);
|
|
178012
|
+
const normalizedProjectStatuses = uniqueProjectStatuses(projectType.statuses);
|
|
177845
178013
|
if (existing !== void 0) {
|
|
178014
|
+
const existingTaskTypeStatuses = uniqueStatusRefs(existing.statuses);
|
|
178015
|
+
const taskTypeChanged = !sameStatusRefList(existingTaskTypeStatuses, existing.statuses);
|
|
177846
178016
|
const projectTypeTasks = projectType.tasks.includes(existing._id) ? projectType.tasks : [...projectType.tasks, existing._id];
|
|
177847
|
-
const existingProjectStatuses =
|
|
178017
|
+
const existingProjectStatuses = existingTaskTypeStatuses.reduce(
|
|
177848
178018
|
(statuses, statusId) => replaceOrAppendProjectStatus(statuses, statusId, existing._id),
|
|
177849
|
-
|
|
178019
|
+
normalizedProjectStatuses
|
|
177850
178020
|
);
|
|
177851
|
-
const projectTypeChanged = projectTypeTasks.length !== projectType.tasks.length || existingProjectStatuses
|
|
178021
|
+
const projectTypeChanged = projectTypeTasks.length !== projectType.tasks.length || !sameProjectStatusList(existingProjectStatuses, projectType.statuses);
|
|
178022
|
+
if (taskTypeChanged) {
|
|
178023
|
+
yield* client.updateDoc(
|
|
178024
|
+
task.class.TaskType,
|
|
178025
|
+
core.space.Model,
|
|
178026
|
+
existing._id,
|
|
178027
|
+
{ statuses: [...existingTaskTypeStatuses] }
|
|
178028
|
+
);
|
|
178029
|
+
}
|
|
177852
178030
|
if (projectTypeChanged) {
|
|
177853
178031
|
yield* client.updateDoc(
|
|
177854
178032
|
task.class.ProjectType,
|
|
177855
178033
|
core.space.Model,
|
|
177856
178034
|
projectType._id,
|
|
177857
|
-
{ tasks: projectTypeTasks, statuses: existingProjectStatuses }
|
|
178035
|
+
{ tasks: projectTypeTasks, statuses: [...existingProjectStatuses] }
|
|
177858
178036
|
);
|
|
177859
178037
|
}
|
|
177860
178038
|
const result2 = {
|
|
177861
|
-
created: projectTypeChanged,
|
|
178039
|
+
created: taskTypeChanged || projectTypeChanged,
|
|
177862
178040
|
projectType: projectTypeSummary({
|
|
177863
178041
|
projectType: { ...projectType, tasks: projectTypeTasks, statuses: existingProjectStatuses },
|
|
177864
|
-
taskTypes: workflowData.taskTypes.some((taskType) => taskType._id === existing._id) ? workflowData.taskTypes
|
|
178042
|
+
taskTypes: workflowData.taskTypes.some((taskType) => taskType._id === existing._id) ? workflowData.taskTypes.map(
|
|
178043
|
+
(taskType) => taskType._id === existing._id ? { ...taskType, statuses: existingTaskTypeStatuses } : taskType
|
|
178044
|
+
) : [...workflowData.taskTypes, { ...existing, statuses: existingTaskTypeStatuses }],
|
|
177865
178045
|
statuses: workflowData.statuses
|
|
177866
178046
|
}),
|
|
177867
|
-
taskType: taskTypeSummary(projectType, existing),
|
|
178047
|
+
taskType: taskTypeSummary(projectType, { ...existing, statuses: existingTaskTypeStatuses }),
|
|
177868
178048
|
affectedTaskTypeIds: [TaskTypeId.make(existing._id)],
|
|
177869
178049
|
warning: WORKFLOW_WARNING
|
|
177870
178050
|
};
|
|
@@ -177879,6 +178059,7 @@ var createTaskType = (params) => Effect_exports.gen(function* () {
|
|
|
177879
178059
|
const taskTypeId = (0, import_core38.generateId)();
|
|
177880
178060
|
const targetClassId = `${taskTypeId}:type:mixin`;
|
|
177881
178061
|
const targetClassRef = toRef(targetClassId);
|
|
178062
|
+
const templateStatusIds = uniqueStatusRefs(template.statuses);
|
|
177882
178063
|
yield* client.createDoc(
|
|
177883
178064
|
core.class.Mixin,
|
|
177884
178065
|
core.space.Model,
|
|
@@ -177907,7 +178088,7 @@ var createTaskType = (params) => Effect_exports.gen(function* () {
|
|
|
177907
178088
|
kind: template.kind,
|
|
177908
178089
|
ofClass: template.ofClass,
|
|
177909
178090
|
targetClass: targetClassRef,
|
|
177910
|
-
statuses:
|
|
178091
|
+
statuses: templateStatusIds,
|
|
177911
178092
|
statusClass: template.statusClass,
|
|
177912
178093
|
statusCategories: [...template.statusCategories],
|
|
177913
178094
|
...template.allowedAsChildOf === void 0 ? {} : { allowedAsChildOf: template.allowedAsChildOf },
|
|
@@ -177922,18 +178103,23 @@ var createTaskType = (params) => Effect_exports.gen(function* () {
|
|
|
177922
178103
|
{
|
|
177923
178104
|
tasks: [...projectType.tasks, taskTypeId],
|
|
177924
178105
|
statuses: [
|
|
177925
|
-
...
|
|
177926
|
-
...
|
|
178106
|
+
...normalizedProjectStatuses,
|
|
178107
|
+
...templateStatusIds.map((statusId) => ({ _id: statusId, taskType: taskTypeId }))
|
|
177927
178108
|
]
|
|
177928
178109
|
}
|
|
177929
178110
|
);
|
|
178111
|
+
const createdProjectStatuses = [
|
|
178112
|
+
...normalizedProjectStatuses,
|
|
178113
|
+
...templateStatusIds.map((statusId) => ({ _id: statusId, taskType: taskTypeId }))
|
|
178114
|
+
];
|
|
177930
178115
|
const createdTaskType = {
|
|
177931
178116
|
...template,
|
|
177932
178117
|
_id: taskTypeId,
|
|
177933
178118
|
parent: projectType._id,
|
|
177934
178119
|
name: params.name,
|
|
177935
178120
|
kind: template.kind,
|
|
177936
|
-
targetClass: targetClassRef
|
|
178121
|
+
targetClass: targetClassRef,
|
|
178122
|
+
statuses: templateStatusIds
|
|
177937
178123
|
};
|
|
177938
178124
|
const result = {
|
|
177939
178125
|
created: true,
|
|
@@ -177941,10 +178127,7 @@ var createTaskType = (params) => Effect_exports.gen(function* () {
|
|
|
177941
178127
|
projectType: {
|
|
177942
178128
|
...projectType,
|
|
177943
178129
|
tasks: [...projectType.tasks, taskTypeId],
|
|
177944
|
-
statuses:
|
|
177945
|
-
...projectType.statuses,
|
|
177946
|
-
...template.statuses.map((statusId) => ({ _id: statusId, taskType: taskTypeId }))
|
|
177947
|
-
]
|
|
178130
|
+
statuses: createdProjectStatuses
|
|
177948
178131
|
},
|
|
177949
178132
|
taskTypes: [...workflowData.taskTypes, createdTaskType],
|
|
177950
178133
|
statuses: workflowData.statuses
|
|
@@ -177959,6 +178142,7 @@ var createIssueStatus = (params) => Effect_exports.gen(function* () {
|
|
|
177959
178142
|
const client = yield* HulyClient;
|
|
177960
178143
|
const projectType = yield* resolveProjectType(client, params.projectType);
|
|
177961
178144
|
const workflowData = yield* loadWorkflowData(client, projectType);
|
|
178145
|
+
const normalizedProjectStatuses = uniqueProjectStatuses(projectType.statuses);
|
|
177962
178146
|
const targetTaskTypes = params.taskType === void 0 ? workflowData.taskTypes : [yield* resolveTaskType(workflowData.taskTypes, params.taskType)];
|
|
177963
178147
|
const statusClass = yield* resolveStatusClass(targetTaskTypes);
|
|
177964
178148
|
const statusesByName = yield* getRecoverableStatusesByName(client, params.name);
|
|
@@ -177982,28 +178166,33 @@ var createIssueStatus = (params) => Effect_exports.gen(function* () {
|
|
|
177982
178166
|
statusId
|
|
177983
178167
|
);
|
|
177984
178168
|
}
|
|
177985
|
-
const
|
|
178169
|
+
const taskTypesNeedingStatusUpdate = targetTaskTypes.filter((taskType) => {
|
|
178170
|
+
const normalizedStatuses = uniqueStatusRefs(taskType.statuses);
|
|
178171
|
+
return !normalizedStatuses.includes(statusId) || !sameStatusRefList(normalizedStatuses, taskType.statuses);
|
|
178172
|
+
});
|
|
177986
178173
|
yield* Effect_exports.all(
|
|
177987
|
-
|
|
177988
|
-
(taskType)
|
|
178174
|
+
taskTypesNeedingStatusUpdate.map((taskType) => {
|
|
178175
|
+
const normalizedStatuses = uniqueStatusRefs(taskType.statuses);
|
|
178176
|
+
const updatedStatuses = normalizedStatuses.includes(statusId) ? normalizedStatuses : [...normalizedStatuses, statusId];
|
|
178177
|
+
return client.updateDoc(
|
|
177989
178178
|
task.class.TaskType,
|
|
177990
178179
|
core.space.Model,
|
|
177991
178180
|
taskType._id,
|
|
177992
|
-
{ statuses: [...
|
|
177993
|
-
)
|
|
177994
|
-
)
|
|
178181
|
+
{ statuses: [...updatedStatuses] }
|
|
178182
|
+
);
|
|
178183
|
+
})
|
|
177995
178184
|
);
|
|
177996
178185
|
const updatedProjectStatuses = targetTaskTypes.reduce(
|
|
177997
178186
|
(statuses, taskType) => replaceOrAppendProjectStatus(statuses, statusId, taskType._id),
|
|
177998
|
-
|
|
178187
|
+
normalizedProjectStatuses
|
|
177999
178188
|
);
|
|
178000
|
-
const projectTypeChanged = updatedProjectStatuses
|
|
178189
|
+
const projectTypeChanged = !sameProjectStatusList(updatedProjectStatuses, projectType.statuses);
|
|
178001
178190
|
if (projectTypeChanged) {
|
|
178002
178191
|
yield* client.updateDoc(
|
|
178003
178192
|
task.class.ProjectType,
|
|
178004
178193
|
core.space.Model,
|
|
178005
178194
|
projectType._id,
|
|
178006
|
-
{ statuses: updatedProjectStatuses }
|
|
178195
|
+
{ statuses: [...updatedProjectStatuses] }
|
|
178007
178196
|
);
|
|
178008
178197
|
}
|
|
178009
178198
|
const statusDoc = existingStatus ?? {
|
|
@@ -178017,7 +178206,7 @@ var createIssueStatus = (params) => Effect_exports.gen(function* () {
|
|
|
178017
178206
|
category: CATEGORY_TO_REF[params.category]
|
|
178018
178207
|
};
|
|
178019
178208
|
const result = {
|
|
178020
|
-
created: existingStatus === void 0 ||
|
|
178209
|
+
created: existingStatus === void 0 || taskTypesNeedingStatusUpdate.length > 0 || projectTypeChanged,
|
|
178021
178210
|
projectType: projectTypeSummary({
|
|
178022
178211
|
projectType: { ...projectType, statuses: updatedProjectStatuses },
|
|
178023
178212
|
taskTypes: workflowData.taskTypes,
|
|
@@ -178064,7 +178253,7 @@ var taskManagementTools = [
|
|
|
178064
178253
|
},
|
|
178065
178254
|
{
|
|
178066
178255
|
name: "create_issue_status",
|
|
178067
|
-
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.`,
|
|
178068
178257
|
category: CATEGORY22,
|
|
178069
178258
|
inputSchema: createIssueStatusParamsJsonSchema,
|
|
178070
178259
|
annotations: { idempotentHint: true },
|
|
@@ -190246,6 +190435,37 @@ var McpServerService = class _McpServerService extends Context_exports.Tag("@hul
|
|
|
190246
190435
|
}
|
|
190247
190436
|
};
|
|
190248
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
|
+
|
|
190249
190469
|
// src/index.ts
|
|
190250
190470
|
var getTransportType = Config_exports.string("MCP_TRANSPORT").pipe(
|
|
190251
190471
|
Config_exports.withDefault("stdio"),
|
|
@@ -190273,6 +190493,9 @@ var getLazyEnvs = Config_exports.string("LAZY_ENVS").pipe(
|
|
|
190273
190493
|
Config_exports.withDefault("false"),
|
|
190274
190494
|
Effect_exports.map((v) => v.toLowerCase() === "true")
|
|
190275
190495
|
);
|
|
190496
|
+
var restoreConsoleRedirect = (redirect) => Effect_exports.sync(() => {
|
|
190497
|
+
redirect?.restore();
|
|
190498
|
+
});
|
|
190276
190499
|
var buildCombinedClientLayer = () => {
|
|
190277
190500
|
const configLayer = HulyConfigService.layer;
|
|
190278
190501
|
const hulyClientLayer = HulyClient.layer.pipe(
|
|
@@ -190364,8 +190587,7 @@ var buildAppLayer = (transport, httpPort, httpHost, mcpAuthToken, autoExit, auth
|
|
|
190364
190587
|
const mcpServerLayer = McpServerService.layer(mcpServerConfig).pipe(Layer_exports.provide(TelemetryService.layer));
|
|
190365
190588
|
return Layer_exports.merge(mcpServerLayer, HttpServerFactoryService.defaultLayer);
|
|
190366
190589
|
};
|
|
190367
|
-
var
|
|
190368
|
-
const transport = yield* getTransportType;
|
|
190590
|
+
var runConfiguredServer = (transport) => Effect_exports.gen(function* () {
|
|
190369
190591
|
const httpPort = yield* getHttpPort;
|
|
190370
190592
|
const httpHost = yield* getHttpHost;
|
|
190371
190593
|
const mcpAuthToken = transport === "http" ? Option_exports.map(yield* getMcpAuthToken, Redacted_exports.value).pipe(Option_exports.getOrUndefined) : void 0;
|
|
@@ -190399,6 +190621,13 @@ var main = Effect_exports.gen(function* () {
|
|
|
190399
190621
|
Effect_exports.scoped
|
|
190400
190622
|
);
|
|
190401
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
|
+
});
|
|
190402
190631
|
var isMainModule = (() => {
|
|
190403
190632
|
if (typeof require !== "undefined" && require.main === module) return true;
|
|
190404
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
|
}
|