@firfi/huly-mcp 0.15.1 → 0.16.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.
Files changed (3) hide show
  1. package/README.md +4 -2
  2. package/dist/index.cjs +1461 -968
  3. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -151353,864 +151353,1215 @@ var InvalidContentTypeError = class extends Schema_exports.TaggedError()(
151353
151353
  }
151354
151354
  };
151355
151355
 
151356
- // src/huly/errors-generic-associations.ts
151357
- var CandidateSchema = Schema_exports.Struct({
151358
- id: AssociationId,
151359
- name: Schema_exports.optional(Schema_exports.String),
151360
- sourceClass: Schema_exports.optional(Schema_exports.String),
151361
- targetClass: Schema_exports.optional(Schema_exports.String)
151356
+ // src/domain/schemas/generic-associations.ts
151357
+ var AssociationIdentifier = NonEmptyString2.pipe(Schema_exports.brand("AssociationIdentifier"));
151358
+ var AssociationName = NonEmptyString2.pipe(Schema_exports.brand("AssociationName"));
151359
+ var AssociationRoleName = NonEmptyString2.pipe(Schema_exports.brand("AssociationRoleName"));
151360
+ var RelationIdentifier = NonEmptyString2.pipe(Schema_exports.brand("RelationIdentifier"));
151361
+ var ListRelationsWarning = NonEmptyString2.pipe(Schema_exports.brand("ListRelationsWarning"));
151362
+ var CardinalityValues = [
151363
+ "one-to-one",
151364
+ "one-to-many",
151365
+ "many-to-many"
151366
+ ];
151367
+ var CardinalitySchema = Schema_exports.Literal(...CardinalityValues).annotations({
151368
+ description: `Association cardinality: ${enumValuesDescription(CardinalityValues)}`
151362
151369
  });
151363
- var formatCandidates = (candidates) => candidates.map((candidate) => {
151364
- const name = candidate.name === void 0 ? "" : `${candidate.name} `;
151365
- const classes = candidate.sourceClass === void 0 || candidate.targetClass === void 0 ? "" : ` ${candidate.sourceClass} -> ${candidate.targetClass}`;
151366
- return `${name}(${candidate.id}${classes})`;
151367
- }).join("; ");
151368
- var AssociationNotFoundError = class extends Schema_exports.TaggedError()(
151369
- "AssociationNotFoundError",
151370
- {
151371
- identifier: Schema_exports.String
151372
- }
151373
- ) {
151374
- get message() {
151375
- return `Association '${this.identifier}' not found. Call list_associations to discover valid association IDs.`;
151376
- }
151377
- };
151378
- var AssociationIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151379
- "AssociationIdentifierAmbiguousError",
151380
- {
151381
- identifier: Schema_exports.String,
151382
- candidates: Schema_exports.Array(CandidateSchema)
151383
- }
151384
- ) {
151385
- get message() {
151386
- return `Association '${this.identifier}' matched multiple definitions: ${formatCandidates(this.candidates)}. Call list_associations with sourceClass and targetClass to choose one.`;
151387
- }
151388
- };
151389
- var RelationNotFoundError = class extends Schema_exports.TaggedError()(
151390
- "RelationNotFoundError",
151391
- {
151392
- identifier: Schema_exports.String
151393
- }
151394
- ) {
151395
- get message() {
151396
- return `Relation '${this.identifier}' not found.`;
151397
- }
151398
- };
151399
- var RelationIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151400
- "RelationIdentifierAmbiguousError",
151401
- {
151402
- identifier: Schema_exports.String,
151403
- relationIds: Schema_exports.Array(RelationId)
151404
- }
151405
- ) {
151406
- get message() {
151407
- return `Relation selector '${this.identifier}' matched multiple relations: ${this.relationIds.join(", ")}. Delete by relation ID instead.`;
151408
- }
151409
- };
151410
- var RelationMutationUnsupportedError = class extends Schema_exports.TaggedError()(
151411
- "RelationMutationUnsupportedError",
151412
- {
151413
- associationId: Schema_exports.optional(AssociationId),
151414
- reason: Schema_exports.String
151415
- }
151416
- ) {
151417
- get message() {
151418
- const id = this.associationId === void 0 ? "" : ` for association '${this.associationId}'`;
151419
- return `Generic relation mutation${id} is not supported: ${this.reason}. Call list_associations with writableOnly=true to discover writable associations.`;
151420
- }
151421
- };
151422
- var RelationEndpointClassMismatchError = class extends Schema_exports.TaggedError()(
151423
- "RelationEndpointClassMismatchError",
151424
- {
151425
- field: Schema_exports.String,
151426
- expectedClass: Schema_exports.String,
151427
- actualClass: Schema_exports.String
151428
- }
151429
- ) {
151430
- get message() {
151431
- return `Relation endpoint '${this.field}' has class '${this.actualClass}', expected '${this.expectedClass}'.`;
151432
- }
151433
- };
151434
- var GenericObjectIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151435
- "GenericObjectIdentifierAmbiguousError",
151436
- {
151437
- field: Schema_exports.String,
151438
- identifier: Schema_exports.String,
151439
- candidates: Schema_exports.Array(Schema_exports.Struct({
151440
- id: DocId,
151441
- class: ObjectClassName,
151442
- display: Schema_exports.String
151443
- }))
151444
- }
151445
- ) {
151446
- get message() {
151447
- const candidates = this.candidates.map((candidate) => `${candidate.display} (${candidate.id}, ${candidate.class})`).join("; ");
151448
- return `Object locator '${this.field}' for '${this.identifier}' is ambiguous. Use a raw locator with one of these IDs: ${candidates}`;
151449
- }
151450
- };
151451
- var GenericObjectLocatorInvalidError = class extends Schema_exports.TaggedError()(
151452
- "GenericObjectLocatorInvalidError",
151453
- {
151454
- field: Schema_exports.String,
151455
- reason: Schema_exports.String
151456
- }
151457
- ) {
151458
- get message() {
151459
- return `Object locator '${this.field}' is invalid: ${this.reason}`;
151460
- }
151461
- };
151462
- var GenericObjectNotFoundError = class extends Schema_exports.TaggedError()(
151463
- "GenericObjectNotFoundError",
151464
- {
151465
- field: Schema_exports.String,
151466
- identifier: Schema_exports.String,
151467
- class: Schema_exports.optional(Schema_exports.String)
151468
- }
151469
- ) {
151470
- get message() {
151471
- const classHint = this.class === void 0 ? "" : ` with class '${this.class}'`;
151472
- return `Object locator '${this.field}' for '${this.identifier}'${classHint} not found.`;
151473
- }
151474
- };
151475
-
151476
- // src/huly/errors-labels.ts
151477
- var TagNotFoundError = class extends Schema_exports.TaggedError()(
151478
- "TagNotFoundError",
151479
- {
151480
- identifier: Schema_exports.String
151481
- }
151482
- ) {
151483
- get message() {
151484
- return `Tag/label '${this.identifier}' not found`;
151485
- }
151486
- };
151487
- var TagCategoryNotFoundError = class extends Schema_exports.TaggedError()(
151488
- "TagCategoryNotFoundError",
151489
- {
151490
- identifier: Schema_exports.String
151491
- }
151492
- ) {
151493
- get message() {
151494
- return `Tag category '${this.identifier}' not found`;
151495
- }
151496
- };
151497
-
151498
- // src/domain/schemas/leads.ts
151499
- var FunnelReference = NonEmptyString2.pipe(Schema_exports.brand("FunnelReference"));
151500
- var FunnelIdentifier = DocId.pipe(Schema_exports.brand("FunnelIdentifier"));
151501
- var CanonicalLeadIdentifier = Schema_exports.Trim.pipe(
151502
- Schema_exports.pattern(/^LEAD-\d+$/, {
151503
- message: () => "Expected lead identifier like 'LEAD-1'"
151370
+ var RelationDirectionValues = ["source-to-target", "target-to-source", "either"];
151371
+ var RelationDirectionSchema = Schema_exports.Literal(...RelationDirectionValues);
151372
+ var DefaultRelationDirection = "source-to-target";
151373
+ var relationDirectionDescription = `Relation traversal direction: ${enumValuesDescription(RelationDirectionValues)}. Defaults to ${DefaultRelationDirection}.`;
151374
+ var RelationIfExistsSchema = Schema_exports.Literal("return_existing", "fail");
151375
+ var AssociationIfExistsSchema = Schema_exports.Literal("return_existing", "fail");
151376
+ var RawObjectLocatorSchema = Schema_exports.Struct({
151377
+ kind: Schema_exports.Literal("raw"),
151378
+ id: DocId.annotations({
151379
+ description: "Raw Huly document _id"
151504
151380
  }),
151505
- Schema_exports.brand("LeadIdentifier")
151506
- );
151507
- var leadIdentifierPattern = /^(?:LEAD-)?(\d+)$/i;
151508
- var LeadIdentifier = Schema_exports.transformOrFail(Schema_exports.String, CanonicalLeadIdentifier, {
151509
- strict: true,
151510
- decode: (input, _options, ast) => {
151511
- const match16 = leadIdentifierPattern.exec(input.trim());
151512
- return match16 !== null ? ParseResult_exports.succeed(`LEAD-${match16[1]}`) : ParseResult_exports.fail(new ParseResult_exports.Type(ast, input, "Expected lead identifier like 'LEAD-1'"));
151513
- },
151514
- encode: ParseResult_exports.succeed
151515
- }).annotations({
151516
- jsonSchema: {
151517
- type: "string",
151518
- pattern: "^LEAD-[0-9]+$"
151519
- }
151381
+ class: Schema_exports.optional(ObjectClassName.annotations({
151382
+ description: "Raw Huly document class, such as tracker:class:Issue. Required unless the association side determines the expected class."
151383
+ }))
151520
151384
  });
151521
- var FunnelSummarySchema = Schema_exports.Struct({
151522
- identifier: FunnelIdentifier,
151523
- name: Schema_exports.String,
151524
- description: Schema_exports.optional(Schema_exports.String),
151525
- archived: Schema_exports.Boolean
151526
- }).annotations({
151527
- title: "FunnelSummary",
151528
- description: "Sales funnel summary"
151385
+ var IssueObjectLocatorSchema = Schema_exports.Struct({
151386
+ kind: Schema_exports.Literal("issue"),
151387
+ issue: IssueIdentifier.annotations({
151388
+ description: "Issue identifier, such as HULY-123, or a numeric issue number when project is also provided."
151389
+ }),
151390
+ project: Schema_exports.optional(ProjectIdentifier.annotations({
151391
+ description: "Project identifier. Optional when issue already includes a project prefix like HULY-123."
151392
+ }))
151529
151393
  });
151530
- var LeadSummarySchema = Schema_exports.Struct({
151531
- identifier: LeadIdentifier,
151532
- title: Schema_exports.String,
151533
- status: StatusName,
151534
- assignee: Schema_exports.optional(PersonName),
151535
- customer: Schema_exports.optional(Schema_exports.String),
151536
- modifiedOn: Schema_exports.optional(Timestamp)
151537
- }).annotations({
151538
- title: "LeadSummary",
151539
- description: "Lead summary for list operations"
151394
+ var DocumentObjectLocatorSchema = Schema_exports.Struct({
151395
+ kind: Schema_exports.Literal("document"),
151396
+ document: DocumentIdentifier.annotations({
151397
+ description: "Document title or ID"
151398
+ }),
151399
+ teamspace: Schema_exports.optional(TeamspaceIdentifier.annotations({
151400
+ description: "Teamspace name or ID. If omitted, document title matches must be unique across the workspace."
151401
+ }))
151540
151402
  });
151541
- var LeadDetailSchema = Schema_exports.Struct({
151542
- identifier: LeadIdentifier,
151543
- title: Schema_exports.String,
151544
- description: Schema_exports.optional(Schema_exports.String),
151545
- status: StatusName,
151546
- assignee: Schema_exports.optional(PersonName),
151547
- customer: Schema_exports.optional(Schema_exports.String),
151548
- funnel: FunnelIdentifier,
151549
- funnelName: Schema_exports.String,
151550
- modifiedOn: Schema_exports.optional(Timestamp),
151551
- createdOn: Schema_exports.optional(Timestamp)
151552
- }).annotations({
151553
- title: "LeadDetail",
151554
- description: "Full lead with all fields"
151403
+ var GenericObjectLocatorSchema = Schema_exports.Union(
151404
+ RawObjectLocatorSchema,
151405
+ IssueObjectLocatorSchema,
151406
+ DocumentObjectLocatorSchema
151407
+ ).annotations({
151408
+ title: "GenericObjectLocator",
151409
+ description: "Explicit locator for a Huly document endpoint. Use raw for known _id values, issue for tracker issues, or document for Huly documents. Card locators are intentionally not included until a robust card resolver is available."
151555
151410
  });
151556
- var ListFunnelsParamsSchema = Schema_exports.Struct({
151557
- includeArchived: Schema_exports.optional(Schema_exports.Boolean.annotations({
151558
- description: "Include archived funnels in results (default: false, showing only active)"
151559
- })),
151560
- limit: Schema_exports.optional(
151561
- LimitParam.annotations({
151562
- description: "Maximum number of funnels to return (default: 50)"
151563
- })
151564
- )
151565
- }).annotations({
151566
- title: "ListFunnelsParams",
151567
- description: "Parameters for listing funnels"
151411
+ var ResolvedObjectSummarySchema = Schema_exports.Struct({
151412
+ id: DocId,
151413
+ class: ObjectClassName,
151414
+ display: NonEmptyString2,
151415
+ locatorKind: Schema_exports.Literal("raw", "issue", "document"),
151416
+ warning: Schema_exports.optional(Schema_exports.String)
151568
151417
  });
151569
- var ListLeadsParamsBase = Schema_exports.Struct({
151570
- funnel: FunnelReference.annotations({
151571
- description: "Funnel ID returned by list_funnels, or funnel name for convenience lookup."
151418
+ var AssociationSummarySchema = Schema_exports.Struct({
151419
+ associationId: AssociationId,
151420
+ name: Schema_exports.optional(AssociationName),
151421
+ label: Schema_exports.optional(NonEmptyString2),
151422
+ description: Schema_exports.optional(Schema_exports.String),
151423
+ sourceClass: ObjectClassName,
151424
+ sourceClassLabel: Schema_exports.optional(NonEmptyString2.annotations({
151425
+ description: "Best-effort human display label for sourceClass when the class is known to this server"
151426
+ })),
151427
+ targetClass: ObjectClassName,
151428
+ targetClassLabel: Schema_exports.optional(NonEmptyString2.annotations({
151429
+ description: "Best-effort human display label for targetClass when the class is known to this server"
151430
+ })),
151431
+ sourceRole: Schema_exports.optional(AssociationRoleName),
151432
+ targetRole: Schema_exports.optional(AssociationRoleName),
151433
+ relationClass: Schema_exports.optional(ObjectClassName),
151434
+ cardinality: CardinalitySchema,
151435
+ symmetric: Schema_exports.Boolean,
151436
+ system: Schema_exports.Boolean,
151437
+ canListRelations: Schema_exports.Boolean,
151438
+ canCreateRelation: Schema_exports.Boolean,
151439
+ canDeleteRelation: Schema_exports.Boolean,
151440
+ unsupportedReason: Schema_exports.optional(Schema_exports.String)
151441
+ });
151442
+ var RelationSummarySchema = Schema_exports.Struct({
151443
+ relationId: RelationId,
151444
+ associationId: AssociationId,
151445
+ associationName: Schema_exports.optional(AssociationName),
151446
+ source: ResolvedObjectSummarySchema,
151447
+ target: ResolvedObjectSummarySchema,
151448
+ createdOn: Schema_exports.optional(Timestamp),
151449
+ modifiedOn: Schema_exports.optional(Timestamp)
151450
+ });
151451
+ var ListAssociationsParamsSchema = Schema_exports.Struct({
151452
+ association: Schema_exports.optional(AssociationIdentifier.annotations({
151453
+ description: "Association _id, source/target role name, or stable association name"
151454
+ })),
151455
+ sourceClass: Schema_exports.optional(ObjectClassName.annotations({
151456
+ description: "Only return associations whose source class matches this Huly class ID"
151457
+ })),
151458
+ targetClass: Schema_exports.optional(ObjectClassName.annotations({
151459
+ description: "Only return associations whose target class matches this Huly class ID"
151460
+ })),
151461
+ writableOnly: Schema_exports.optional(Schema_exports.Boolean.annotations({
151462
+ description: "Only return associations whose relation create/delete path has been validated and allowlisted"
151463
+ })),
151464
+ includeSystem: Schema_exports.optional(Schema_exports.Boolean.annotations({
151465
+ description: "Include internal/system associations. Defaults to false."
151466
+ })),
151467
+ limit: Schema_exports.optional(LimitParam.annotations({
151468
+ description: "Maximum number of associations to return (default: 50)"
151469
+ }))
151470
+ }).annotations({
151471
+ title: "ListAssociationsParams",
151472
+ description: "Parameters for listing generic Huly association definitions"
151473
+ });
151474
+ var ListAssociationsResultSchema = Schema_exports.Struct({
151475
+ associations: Schema_exports.Array(AssociationSummarySchema),
151476
+ total: Schema_exports.Number
151477
+ });
151478
+ var CreateAssociationParamsSchema = Schema_exports.Struct({
151479
+ sourceClass: ObjectClassName.annotations({
151480
+ description: "Source Huly class ID, such as tracker:class:Issue. core:class:* system classes are rejected."
151572
151481
  }),
151573
- status: Schema_exports.optional(StatusName.annotations({
151574
- description: "Filter by status name"
151482
+ targetClass: ObjectClassName.annotations({
151483
+ description: "Target Huly class ID, such as tracker:class:Issue. core:class:* system classes are rejected."
151484
+ }),
151485
+ sourceRole: AssociationRoleName.annotations({
151486
+ description: "Role name stored on the source side of the association."
151487
+ }),
151488
+ targetRole: AssociationRoleName.annotations({
151489
+ description: "Role name stored on the target side of the association."
151490
+ }),
151491
+ cardinality: CardinalitySchema,
151492
+ automationOnly: Schema_exports.optional(Schema_exports.Boolean.annotations({
151493
+ description: "Whether Huly automation-only UI paths should own relation writes for this association. Defaults to false."
151575
151494
  })),
151576
- assignee: Schema_exports.optional(PersonRefInput.annotations({
151577
- description: "Filter by assignee email or display name"
151495
+ ifExists: Schema_exports.optional(AssociationIfExistsSchema.annotations({
151496
+ description: "return_existing (default) returns an identical existing association; fail reports an existing association as an error"
151497
+ }))
151498
+ }).annotations({
151499
+ title: "CreateAssociationParams",
151500
+ description: "Parameters for idempotently creating a Huly association definition in the model space. The created association can then be used with create_relation."
151501
+ });
151502
+ var CreateAssociationResultSchema = Schema_exports.Struct({
151503
+ association: AssociationSummarySchema,
151504
+ created: Schema_exports.Boolean,
151505
+ existing: Schema_exports.Boolean
151506
+ });
151507
+ var DeleteAssociationParamsSchema = Schema_exports.Struct({
151508
+ association: AssociationIdentifier.annotations({
151509
+ description: "Association _id or unambiguous name returned by list_associations. Deleting a missing association is a successful no-op."
151510
+ })
151511
+ }).annotations({
151512
+ title: "DeleteAssociationParams",
151513
+ description: "Parameters for idempotently deleting a Huly association definition. The association must have zero concrete relations."
151514
+ });
151515
+ var DeleteAssociationResultSchema = Schema_exports.Struct({
151516
+ association: AssociationIdentifier,
151517
+ associationId: Schema_exports.optional(AssociationId),
151518
+ deleted: Schema_exports.Boolean,
151519
+ relationCount: Schema_exports.Number,
151520
+ reason: Schema_exports.optional(Schema_exports.Literal("not_found", "deleted"))
151521
+ });
151522
+ var ListRelationsParamsBaseSchema = Schema_exports.Struct({
151523
+ association: Schema_exports.optional(AssociationIdentifier.annotations({
151524
+ description: "Association _id or name. If omitted, relations are listed only across supported visible associations."
151578
151525
  })),
151579
- titleSearch: Schema_exports.optional(Schema_exports.String.annotations({
151580
- description: "Search leads by title substring (case-insensitive)"
151526
+ source: Schema_exports.optional(GenericObjectLocatorSchema.annotations({
151527
+ description: "Optional source endpoint filter"
151581
151528
  })),
151582
- limit: Schema_exports.optional(
151583
- LimitParam.annotations({
151584
- description: "Maximum number of leads to return (default: 50)"
151585
- })
151529
+ target: Schema_exports.optional(GenericObjectLocatorSchema.annotations({
151530
+ description: "Optional target endpoint filter"
151531
+ })),
151532
+ direction: Schema_exports.optional(RelationDirectionSchema.annotations({
151533
+ description: relationDirectionDescription
151534
+ })),
151535
+ limit: Schema_exports.optional(LimitParam.annotations({
151536
+ description: "Maximum number of relations to return (default: 50)"
151537
+ }))
151538
+ }).annotations({
151539
+ title: "ListRelationsParams",
151540
+ description: "Parameters for listing concrete Huly relation instances"
151541
+ });
151542
+ var ListRelationsParamsSchema = ListRelationsParamsBaseSchema.pipe(
151543
+ Schema_exports.filter(
151544
+ (params) => params.association === void 0 && params.source === void 0 && params.target === void 0 ? "Provide at least one of association, source, or target to avoid broad workspace scans." : void 0
151586
151545
  )
151546
+ ).annotations({
151547
+ title: "ListRelationsParams",
151548
+ description: "Parameters for listing concrete Huly relation instances"
151587
151549
  });
151588
- var ListLeadsParamsSchema = ListLeadsParamsBase.annotations({
151589
- title: "ListLeadsParams",
151590
- description: "Parameters for listing leads in a funnel"
151550
+ var ListRelationsResultSchema = Schema_exports.Struct({
151551
+ relations: Schema_exports.Array(RelationSummarySchema),
151552
+ total: Schema_exports.Number,
151553
+ warnings: Schema_exports.optional(
151554
+ Schema_exports.NonEmptyArray(ListRelationsWarning).annotations({
151555
+ description: "Non-fatal warnings about result completeness or resolution. Treat these as guidance for narrowing a follow-up call."
151556
+ })
151557
+ )
151591
151558
  });
151592
- var GetLeadParamsSchema = Schema_exports.Struct({
151593
- funnel: FunnelReference.annotations({
151594
- description: "Funnel ID returned by list_funnels, or funnel name for convenience lookup."
151559
+ var CreateRelationParamsSchema = Schema_exports.Struct({
151560
+ association: AssociationIdentifier.annotations({
151561
+ description: "Association _id or unambiguous name returned by list_associations"
151595
151562
  }),
151596
- identifier: LeadIdentifier.annotations({
151597
- description: "Lead identifier (e.g., 'LEAD-1')"
151563
+ source: GenericObjectLocatorSchema.annotations({
151564
+ description: "Source endpoint document"
151565
+ }),
151566
+ target: GenericObjectLocatorSchema.annotations({
151567
+ description: "Target endpoint document"
151568
+ }),
151569
+ direction: Schema_exports.optional(RelationDirectionSchema.annotations({
151570
+ description: relationDirectionDescription
151571
+ })),
151572
+ ifExists: Schema_exports.optional(RelationIfExistsSchema.annotations({
151573
+ description: "return_existing (default) returns an existing relation; fail reports an existing relation as an error"
151574
+ }))
151575
+ }).annotations({
151576
+ title: "CreateRelationParams",
151577
+ description: "Parameters for idempotently creating a concrete generic relation"
151578
+ });
151579
+ var CreateRelationResultSchema = Schema_exports.Struct({
151580
+ relationId: RelationId,
151581
+ associationId: AssociationId,
151582
+ source: ResolvedObjectSummarySchema,
151583
+ target: ResolvedObjectSummarySchema,
151584
+ created: Schema_exports.Boolean,
151585
+ existing: Schema_exports.Boolean
151586
+ });
151587
+ var DeleteRelationByIdParamsSchema = Schema_exports.Struct({
151588
+ relation: RelationIdentifier.annotations({
151589
+ description: "Concrete relation _id to delete"
151598
151590
  })
151599
151591
  }).annotations({
151600
- title: "GetLeadParams",
151601
- description: "Parameters for getting a single lead"
151592
+ title: "DeleteRelationByIdParams",
151593
+ description: "Delete one concrete relation by its relation ID."
151602
151594
  });
151603
- var listFunnelsParamsJsonSchema = JSONSchema_exports.make(ListFunnelsParamsSchema);
151604
- var listLeadsParamsJsonSchema = JSONSchema_exports.make(ListLeadsParamsSchema);
151605
- var getLeadParamsJsonSchema = JSONSchema_exports.make(GetLeadParamsSchema);
151606
- var parseListFunnelsParams = Schema_exports.decodeUnknown(ListFunnelsParamsSchema);
151607
- var parseListLeadsParams = Schema_exports.decodeUnknown(ListLeadsParamsSchema);
151608
- var parseGetLeadParams = Schema_exports.decodeUnknown(GetLeadParamsSchema);
151609
- var parseLeadDetail = Schema_exports.decodeUnknown(LeadDetailSchema);
151610
- var parseLeadSummary = Schema_exports.decodeUnknown(LeadSummarySchema);
151595
+ var DeleteRelationByTripleParamsSchema = Schema_exports.Struct({
151596
+ association: AssociationIdentifier.annotations({
151597
+ description: "Association _id or unambiguous name"
151598
+ }),
151599
+ source: GenericObjectLocatorSchema.annotations({
151600
+ description: "Source endpoint"
151601
+ }),
151602
+ target: GenericObjectLocatorSchema.annotations({
151603
+ description: "Target endpoint"
151604
+ }),
151605
+ direction: Schema_exports.optional(RelationDirectionSchema.annotations({
151606
+ description: relationDirectionDescription
151607
+ }))
151608
+ }).annotations({
151609
+ title: "DeleteRelationByTripleParams",
151610
+ description: "Delete one concrete relation by exact association + source + target triple."
151611
+ });
151612
+ var DeleteRelationParamsSchema = Schema_exports.Union(
151613
+ DeleteRelationByIdParamsSchema,
151614
+ DeleteRelationByTripleParamsSchema
151615
+ ).annotations({
151616
+ title: "DeleteRelationParams",
151617
+ description: "Parameters for idempotently deleting one concrete generic relation. Provide either relation, or the full association + source + target triple."
151618
+ });
151619
+ var DeleteRelationResultSchema = Schema_exports.Struct({
151620
+ relationId: Schema_exports.optional(RelationId),
151621
+ associationId: Schema_exports.optional(AssociationId),
151622
+ deleted: Schema_exports.Boolean,
151623
+ reason: Schema_exports.optional(Schema_exports.Literal("not_found", "deleted"))
151624
+ });
151625
+ var listAssociationsParamsJsonSchema = JSONSchema_exports.make(ListAssociationsParamsSchema);
151626
+ var createAssociationParamsJsonSchema = JSONSchema_exports.make(CreateAssociationParamsSchema);
151627
+ var deleteAssociationParamsJsonSchema = JSONSchema_exports.make(DeleteAssociationParamsSchema);
151628
+ var listRelationsParamsJsonSchema = {
151629
+ ...JSONSchema_exports.make(ListRelationsParamsBaseSchema),
151630
+ anyOf: [
151631
+ { required: ["association"] },
151632
+ { required: ["source"] },
151633
+ { required: ["target"] }
151634
+ ]
151635
+ };
151636
+ var createRelationParamsJsonSchema = JSONSchema_exports.make(CreateRelationParamsSchema);
151637
+ var deleteRelationParamsJsonSchema = {
151638
+ ...JSONSchema_exports.make(DeleteRelationParamsSchema),
151639
+ type: "object"
151640
+ };
151641
+ var strictParseOptions = { onExcessProperty: "error" };
151642
+ var parseListAssociationsParams = Schema_exports.decodeUnknown(ListAssociationsParamsSchema, strictParseOptions);
151643
+ var parseCreateAssociationParams = Schema_exports.decodeUnknown(CreateAssociationParamsSchema, strictParseOptions);
151644
+ var parseDeleteAssociationParams = Schema_exports.decodeUnknown(DeleteAssociationParamsSchema, strictParseOptions);
151645
+ var parseListRelationsParams = Schema_exports.decodeUnknown(ListRelationsParamsSchema, strictParseOptions);
151646
+ var parseCreateRelationParams = Schema_exports.decodeUnknown(CreateRelationParamsSchema, strictParseOptions);
151647
+ var parseDeleteRelationParams = Schema_exports.decodeUnknown(DeleteRelationParamsSchema, strictParseOptions);
151611
151648
 
151612
- // src/huly/errors-leads.ts
151613
- var FunnelNotFoundError = class extends Schema_exports.TaggedError()(
151614
- "FunnelNotFoundError",
151649
+ // src/huly/errors-generic-associations.ts
151650
+ var CandidateSchema = Schema_exports.Struct({
151651
+ id: AssociationId,
151652
+ name: Schema_exports.optional(AssociationName),
151653
+ sourceClass: Schema_exports.optional(ObjectClassName),
151654
+ targetClass: Schema_exports.optional(ObjectClassName)
151655
+ });
151656
+ var formatCandidates = (candidates) => candidates.map((candidate) => {
151657
+ const name = candidate.name === void 0 ? "" : `${candidate.name} `;
151658
+ const classes = candidate.sourceClass === void 0 || candidate.targetClass === void 0 ? "" : ` ${candidate.sourceClass} -> ${candidate.targetClass}`;
151659
+ return `${name}(${candidate.id}${classes})`;
151660
+ }).join("; ");
151661
+ var AssociationNotFoundError = class extends Schema_exports.TaggedError()(
151662
+ "AssociationNotFoundError",
151615
151663
  {
151616
- identifier: FunnelReference
151664
+ identifier: Schema_exports.String
151617
151665
  }
151618
151666
  ) {
151619
151667
  get message() {
151620
- return `Funnel '${this.identifier}' not found`;
151668
+ return `Association '${this.identifier}' not found. Call list_associations to discover valid association IDs.`;
151621
151669
  }
151622
151670
  };
151623
- var LeadNotFoundError = class extends Schema_exports.TaggedError()(
151624
- "LeadNotFoundError",
151671
+ var AssociationIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151672
+ "AssociationIdentifierAmbiguousError",
151625
151673
  {
151626
- identifier: LeadIdentifier,
151627
- funnel: FunnelIdentifier
151674
+ identifier: Schema_exports.String,
151675
+ candidates: Schema_exports.Array(CandidateSchema)
151628
151676
  }
151629
151677
  ) {
151630
151678
  get message() {
151631
- return `Lead '${this.identifier}' not found in funnel '${this.funnel}'`;
151679
+ return `Association '${this.identifier}' matched multiple definitions: ${formatCandidates(this.candidates)}. Call list_associations with sourceClass and targetClass to choose one.`;
151632
151680
  }
151633
151681
  };
151634
-
151635
- // src/huly/errors-messaging.ts
151636
- var MIN_AMBIGUOUS_DM_MATCHES = 2;
151637
- var ChannelNotFoundError = class extends Schema_exports.TaggedError()(
151638
- "ChannelNotFoundError",
151682
+ var RelationNotFoundError = class extends Schema_exports.TaggedError()(
151683
+ "RelationNotFoundError",
151639
151684
  {
151640
151685
  identifier: Schema_exports.String
151641
151686
  }
151642
151687
  ) {
151643
151688
  get message() {
151644
- return `Channel '${this.identifier}' not found`;
151689
+ return `Relation '${this.identifier}' not found.`;
151645
151690
  }
151646
151691
  };
151647
- var DirectMessageNotFoundError = class extends Schema_exports.TaggedError()(
151648
- "DirectMessageNotFoundError",
151692
+ var RelationIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151693
+ "RelationIdentifierAmbiguousError",
151649
151694
  {
151650
- identifier: Schema_exports.String
151695
+ identifier: Schema_exports.String,
151696
+ relationIds: Schema_exports.Array(RelationId)
151651
151697
  }
151652
151698
  ) {
151653
151699
  get message() {
151654
- return `Direct message '${this.identifier}' not found`;
151700
+ return `Relation selector '${this.identifier}' matched multiple relations: ${this.relationIds.join(", ")}. Delete by relation ID instead.`;
151655
151701
  }
151656
151702
  };
151657
- var DirectMessageIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151658
- "DirectMessageIdentifierAmbiguousError",
151703
+ var RelationMutationUnsupportedError = class extends Schema_exports.TaggedError()(
151704
+ "RelationMutationUnsupportedError",
151659
151705
  {
151660
- identifier: Schema_exports.String,
151661
- matches: Schema_exports.Number.pipe(Schema_exports.int(), Schema_exports.greaterThanOrEqualTo(MIN_AMBIGUOUS_DM_MATCHES))
151706
+ associationId: Schema_exports.optional(AssociationId),
151707
+ reason: Schema_exports.String
151662
151708
  }
151663
151709
  ) {
151664
151710
  get message() {
151665
- return `Direct message '${this.identifier}' is ambiguous (${this.matches} matches); use the DM _id`;
151711
+ const id = this.associationId === void 0 ? "" : ` for association '${this.associationId}'`;
151712
+ return `Generic relation mutation${id} is not supported: ${this.reason}. Call list_associations with writableOnly=true to discover writable associations.`;
151666
151713
  }
151667
151714
  };
151668
- var CannotDirectMessageSelfError = class extends Schema_exports.TaggedError()(
151669
- "CannotDirectMessageSelfError",
151715
+ var AssociationSystemClassUnsupportedError = class extends Schema_exports.TaggedError()(
151716
+ "AssociationSystemClassUnsupportedError",
151670
151717
  {
151671
- identifier: Schema_exports.String
151718
+ className: ObjectClassName,
151719
+ operation: Schema_exports.Literal("create_association", "delete_association", "create_relation", "delete_relation")
151672
151720
  }
151673
151721
  ) {
151674
151722
  get message() {
151675
- return `Cannot start a direct-message conversation with yourself ('${this.identifier}')`;
151723
+ return `${this.operation} does not support core system class '${this.className}' in generic association writes.`;
151676
151724
  }
151677
151725
  };
151678
- var PersonNotAnEmployeeError = class extends Schema_exports.TaggedError()(
151679
- "PersonNotAnEmployeeError",
151726
+ var AssociationConflictError = class extends Schema_exports.TaggedError()(
151727
+ "AssociationConflictError",
151680
151728
  {
151681
- identifier: Schema_exports.String
151729
+ associationId: AssociationId,
151730
+ reason: Schema_exports.String
151682
151731
  }
151683
151732
  ) {
151684
151733
  get message() {
151685
- return `Person '${this.identifier}' is not a workspace member (no Huly account) and cannot receive direct messages`;
151734
+ return `Association '${this.associationId}' already exists but conflicts with the requested definition: ${this.reason}.`;
151686
151735
  }
151687
151736
  };
151688
- var MessageNotFoundError = class extends Schema_exports.TaggedError()(
151689
- "MessageNotFoundError",
151737
+ var AssociationInUseError = class extends Schema_exports.TaggedError()(
151738
+ "AssociationInUseError",
151690
151739
  {
151691
- messageId: Schema_exports.String,
151692
- channel: Schema_exports.String
151740
+ associationId: AssociationId,
151741
+ relationCount: Schema_exports.Number,
151742
+ sampleRelationIds: Schema_exports.Array(RelationId)
151693
151743
  }
151694
151744
  ) {
151695
151745
  get message() {
151696
- return `Message '${this.messageId}' not found in channel '${this.channel}'`;
151746
+ const sample2 = this.sampleRelationIds.length === 0 ? "" : ` Sample relation IDs: ${this.sampleRelationIds.join(", ")}.`;
151747
+ return `Association '${this.associationId}' cannot be deleted because ${this.relationCount} relation(s) still reference it. Delete those relations first.${sample2}`;
151697
151748
  }
151698
151749
  };
151699
- var ThreadReplyNotFoundError = class extends Schema_exports.TaggedError()(
151700
- "ThreadReplyNotFoundError",
151750
+ var RelationCardinalityViolationError = class extends Schema_exports.TaggedError()(
151751
+ "RelationCardinalityViolationError",
151701
151752
  {
151702
- replyId: Schema_exports.String,
151703
- messageId: Schema_exports.String
151753
+ associationId: AssociationId,
151754
+ cardinality: CardinalitySchema,
151755
+ reason: Schema_exports.String
151704
151756
  }
151705
151757
  ) {
151706
151758
  get message() {
151707
- return `Thread reply '${this.replyId}' not found on message '${this.messageId}'`;
151759
+ return `Relation violates ${this.cardinality} cardinality for association '${this.associationId}': ${this.reason}.`;
151708
151760
  }
151709
151761
  };
151710
- var ActivityMessageNotFoundError = class extends Schema_exports.TaggedError()(
151711
- "ActivityMessageNotFoundError",
151762
+ var RelationDirectionAmbiguousError = class extends Schema_exports.TaggedError()(
151763
+ "RelationDirectionAmbiguousError",
151712
151764
  {
151713
- messageId: Schema_exports.String
151765
+ associationId: AssociationId,
151766
+ reason: Schema_exports.String
151714
151767
  }
151715
151768
  ) {
151716
151769
  get message() {
151717
- return `Activity message '${this.messageId}' not found`;
151770
+ return `Relation direction is ambiguous for association '${this.associationId}': ${this.reason}. Use source-to-target or target-to-source.`;
151718
151771
  }
151719
151772
  };
151720
- var ReactionNotFoundError = class extends Schema_exports.TaggedError()(
151721
- "ReactionNotFoundError",
151773
+ var RelationEndpointClassMismatchError = class extends Schema_exports.TaggedError()(
151774
+ "RelationEndpointClassMismatchError",
151722
151775
  {
151723
- messageId: Schema_exports.String,
151724
- emoji: Schema_exports.String
151776
+ field: Schema_exports.String,
151777
+ expectedClass: Schema_exports.String,
151778
+ actualClass: Schema_exports.String
151725
151779
  }
151726
151780
  ) {
151727
151781
  get message() {
151728
- return `Reaction '${this.emoji}' not found on message '${this.messageId}'`;
151782
+ return `Relation endpoint '${this.field}' has class '${this.actualClass}', expected '${this.expectedClass}'.`;
151729
151783
  }
151730
151784
  };
151731
- var SavedMessageNotFoundError = class extends Schema_exports.TaggedError()(
151732
- "SavedMessageNotFoundError",
151785
+ var GenericObjectIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151786
+ "GenericObjectIdentifierAmbiguousError",
151733
151787
  {
151734
- messageId: Schema_exports.String
151788
+ field: Schema_exports.String,
151789
+ identifier: Schema_exports.String,
151790
+ candidates: Schema_exports.Array(Schema_exports.Struct({
151791
+ id: DocId,
151792
+ class: ObjectClassName,
151793
+ display: Schema_exports.String
151794
+ }))
151735
151795
  }
151736
151796
  ) {
151737
151797
  get message() {
151738
- return `Saved message for '${this.messageId}' not found`;
151798
+ const candidates = this.candidates.map((candidate) => `${candidate.display} (${candidate.id}, ${candidate.class})`).join("; ");
151799
+ return `Object locator '${this.field}' for '${this.identifier}' is ambiguous. Use a raw locator with one of these IDs: ${candidates}`;
151800
+ }
151801
+ };
151802
+ var GenericObjectLocatorInvalidError = class extends Schema_exports.TaggedError()(
151803
+ "GenericObjectLocatorInvalidError",
151804
+ {
151805
+ field: Schema_exports.String,
151806
+ reason: Schema_exports.String
151807
+ }
151808
+ ) {
151809
+ get message() {
151810
+ return `Object locator '${this.field}' is invalid: ${this.reason}`;
151811
+ }
151812
+ };
151813
+ var GenericObjectNotFoundError = class extends Schema_exports.TaggedError()(
151814
+ "GenericObjectNotFoundError",
151815
+ {
151816
+ field: Schema_exports.String,
151817
+ identifier: Schema_exports.String,
151818
+ class: Schema_exports.optional(Schema_exports.String)
151819
+ }
151820
+ ) {
151821
+ get message() {
151822
+ const classHint = this.class === void 0 ? "" : ` with class '${this.class}'`;
151823
+ return `Object locator '${this.field}' for '${this.identifier}'${classHint} not found.`;
151739
151824
  }
151740
151825
  };
151741
151826
 
151742
- // src/huly/errors-notifications.ts
151743
- var NotificationNotFoundError = class extends Schema_exports.TaggedError()(
151744
- "NotificationNotFoundError",
151827
+ // src/huly/errors-labels.ts
151828
+ var TagNotFoundError = class extends Schema_exports.TaggedError()(
151829
+ "TagNotFoundError",
151745
151830
  {
151746
- notificationId: Schema_exports.String
151831
+ identifier: Schema_exports.String
151747
151832
  }
151748
151833
  ) {
151749
151834
  get message() {
151750
- return `Notification '${this.notificationId}' not found`;
151835
+ return `Tag/label '${this.identifier}' not found`;
151751
151836
  }
151752
151837
  };
151753
- var NotificationContextNotFoundError = class extends Schema_exports.TaggedError()(
151754
- "NotificationContextNotFoundError",
151838
+ var TagCategoryNotFoundError = class extends Schema_exports.TaggedError()(
151839
+ "TagCategoryNotFoundError",
151755
151840
  {
151756
- contextId: Schema_exports.String
151841
+ identifier: Schema_exports.String
151757
151842
  }
151758
151843
  ) {
151759
151844
  get message() {
151760
- return `Notification context '${this.contextId}' not found`;
151845
+ return `Tag category '${this.identifier}' not found`;
151761
151846
  }
151762
151847
  };
151763
151848
 
151764
- // src/domain/schemas/processes.ts
151765
- var ProcessId = DocId.pipe(Schema_exports.brand("ProcessId"));
151766
- var ProcessIdentifier = NonEmptyString2.pipe(Schema_exports.brand("ProcessIdentifier"));
151767
- var ProcessExecutionId = DocId.pipe(Schema_exports.brand("ProcessExecutionId"));
151768
- var ProcessStateId = DocId.pipe(Schema_exports.brand("ProcessStateId"));
151769
- var ProcessTransitionId = DocId.pipe(Schema_exports.brand("ProcessTransitionId"));
151770
- var ProcessCardIdentifier = NonEmptyString2.pipe(Schema_exports.brand("ProcessCardIdentifier"));
151771
- var ProcessMasterTagIdentifier = NonEmptyString2.pipe(Schema_exports.brand("ProcessMasterTagIdentifier"));
151772
- var ProcessExecutionStatusSchema = Schema_exports.Literal("active", "done", "cancelled");
151773
- var ProcessCandidateSchema = Schema_exports.Struct({
151774
- id: ProcessId,
151775
- name: NonEmptyString2,
151776
- masterTagId: MasterTagId,
151777
- masterTagName: Schema_exports.optional(NonEmptyString2)
151849
+ // src/domain/schemas/leads.ts
151850
+ var FunnelReference = NonEmptyString2.pipe(Schema_exports.brand("FunnelReference"));
151851
+ var FunnelIdentifier = DocId.pipe(Schema_exports.brand("FunnelIdentifier"));
151852
+ var CanonicalLeadIdentifier = Schema_exports.Trim.pipe(
151853
+ Schema_exports.pattern(/^LEAD-\d+$/, {
151854
+ message: () => "Expected lead identifier like 'LEAD-1'"
151855
+ }),
151856
+ Schema_exports.brand("LeadIdentifier")
151857
+ );
151858
+ var leadIdentifierPattern = /^(?:LEAD-)?(\d+)$/i;
151859
+ var LeadIdentifier = Schema_exports.transformOrFail(Schema_exports.String, CanonicalLeadIdentifier, {
151860
+ strict: true,
151861
+ decode: (input, _options, ast) => {
151862
+ const match16 = leadIdentifierPattern.exec(input.trim());
151863
+ return match16 !== null ? ParseResult_exports.succeed(`LEAD-${match16[1]}`) : ParseResult_exports.fail(new ParseResult_exports.Type(ast, input, "Expected lead identifier like 'LEAD-1'"));
151864
+ },
151865
+ encode: ParseResult_exports.succeed
151866
+ }).annotations({
151867
+ jsonSchema: {
151868
+ type: "string",
151869
+ pattern: "^LEAD-[0-9]+$"
151870
+ }
151778
151871
  });
151779
- var ProcessSummarySchema = Schema_exports.Struct({
151780
- id: ProcessId,
151781
- name: NonEmptyString2,
151872
+ var FunnelSummarySchema = Schema_exports.Struct({
151873
+ identifier: FunnelIdentifier,
151874
+ name: Schema_exports.String,
151782
151875
  description: Schema_exports.optional(Schema_exports.String),
151783
- masterTagId: MasterTagId,
151784
- masterTagName: Schema_exports.optional(NonEmptyString2),
151785
- autoStart: Schema_exports.Boolean,
151786
- automationOnly: Schema_exports.Boolean,
151787
- parallelExecutionForbidden: Schema_exports.Boolean,
151788
- stateCount: Schema_exports.NonNegativeInt,
151789
- transitionCount: Schema_exports.NonNegativeInt
151790
- });
151791
- var ProcessStateSummarySchema = Schema_exports.Struct({
151792
- id: ProcessStateId,
151793
- title: NonEmptyString2
151794
- });
151795
- var ProcessTransitionSummarySchema = Schema_exports.Struct({
151796
- id: ProcessTransitionId,
151797
- fromStateId: Schema_exports.optional(ProcessStateId),
151798
- fromStateTitle: Schema_exports.optional(NonEmptyString2),
151799
- toStateId: ProcessStateId,
151800
- toStateTitle: Schema_exports.optional(NonEmptyString2),
151801
- triggerId: NonEmptyString2,
151802
- actionCount: Schema_exports.NonNegativeInt
151876
+ archived: Schema_exports.Boolean
151877
+ }).annotations({
151878
+ title: "FunnelSummary",
151879
+ description: "Sales funnel summary"
151803
151880
  });
151804
- var ProcessDetailSchema = ProcessSummarySchema.pipe(
151805
- Schema_exports.extend(Schema_exports.Struct({
151806
- initialStateId: Schema_exports.optional(ProcessStateId),
151807
- states: Schema_exports.Array(ProcessStateSummarySchema),
151808
- transitions: Schema_exports.Array(ProcessTransitionSummarySchema)
151809
- }))
151810
- );
151811
- var ProcessExecutionSummarySchema = Schema_exports.Struct({
151812
- id: ProcessExecutionId,
151813
- processId: ProcessId,
151814
- processName: Schema_exports.optional(NonEmptyString2),
151815
- cardId: CardId,
151816
- cardTitle: Schema_exports.optional(NonEmptyString2),
151817
- currentStateId: ProcessStateId,
151818
- currentStateTitle: Schema_exports.optional(NonEmptyString2),
151819
- status: ProcessExecutionStatusSchema,
151820
- errorCount: Schema_exports.NonNegativeInt,
151821
- hasError: Schema_exports.Boolean,
151822
- hasParent: Schema_exports.Boolean,
151823
- parentExecutionId: Schema_exports.optional(ProcessExecutionId),
151881
+ var LeadSummarySchema = Schema_exports.Struct({
151882
+ identifier: LeadIdentifier,
151883
+ title: Schema_exports.String,
151884
+ status: StatusName,
151885
+ assignee: Schema_exports.optional(PersonName),
151886
+ customer: Schema_exports.optional(Schema_exports.String),
151824
151887
  modifiedOn: Schema_exports.optional(Timestamp)
151825
- });
151826
- var ListProcessesParamsSchema = Schema_exports.Struct({
151827
- masterTag: Schema_exports.optional(ProcessMasterTagIdentifier.annotations({
151828
- description: "Optional master tag/card type ID or display label. Use this when you only want workflows attached to one Huly card/document type."
151829
- })),
151830
- limit: Schema_exports.optional(LimitParam.annotations({
151831
- description: "Maximum number of process definitions to return (default: 50, maximum: 200)."
151832
- }))
151833
151888
  }).annotations({
151834
- title: "ListProcessesParams",
151835
- description: "Parameters for listing Huly Process workflow definitions."
151889
+ title: "LeadSummary",
151890
+ description: "Lead summary for list operations"
151836
151891
  });
151837
- var GetProcessParamsSchema = Schema_exports.Struct({
151838
- process: ProcessIdentifier.annotations({
151839
- description: "Process/workflow ID or exact display name. Ambiguous names fail with candidate IDs instead of guessing."
151840
- })
151892
+ var LeadDetailSchema = Schema_exports.Struct({
151893
+ identifier: LeadIdentifier,
151894
+ title: Schema_exports.String,
151895
+ description: Schema_exports.optional(Schema_exports.String),
151896
+ status: StatusName,
151897
+ assignee: Schema_exports.optional(PersonName),
151898
+ customer: Schema_exports.optional(Schema_exports.String),
151899
+ funnel: FunnelIdentifier,
151900
+ funnelName: Schema_exports.String,
151901
+ modifiedOn: Schema_exports.optional(Timestamp),
151902
+ createdOn: Schema_exports.optional(Timestamp)
151841
151903
  }).annotations({
151842
- title: "GetProcessParams",
151843
- description: "Parameters for retrieving one Huly Process workflow definition."
151904
+ title: "LeadDetail",
151905
+ description: "Full lead with all fields"
151844
151906
  });
151845
- var ListExecutionsParamsSchema = Schema_exports.Struct({
151846
- process: Schema_exports.optional(ProcessIdentifier.annotations({
151847
- description: "Optional process/workflow ID or exact display name. Ambiguous names fail with candidate IDs instead of guessing."
151848
- })),
151849
- card: Schema_exports.optional(ProcessCardIdentifier.annotations({
151850
- description: "Optional card/document ID or exact title. If a title matches multiple cards, the call fails with candidates."
151851
- })),
151852
- status: Schema_exports.optional(ProcessExecutionStatusSchema.annotations({
151853
- description: "Optional execution status filter: active, done, or cancelled."
151907
+ var ListFunnelsParamsSchema = Schema_exports.Struct({
151908
+ includeArchived: Schema_exports.optional(Schema_exports.Boolean.annotations({
151909
+ description: "Include archived funnels in results (default: false, showing only active)"
151854
151910
  })),
151855
- limit: Schema_exports.optional(LimitParam.annotations({
151856
- description: "Maximum number of executions to return (default: 50, maximum: 200)."
151857
- }))
151911
+ limit: Schema_exports.optional(
151912
+ LimitParam.annotations({
151913
+ description: "Maximum number of funnels to return (default: 50)"
151914
+ })
151915
+ )
151858
151916
  }).annotations({
151859
- title: "ListExecutionsParams",
151860
- description: "Parameters for listing read-only Huly Process workflow executions."
151917
+ title: "ListFunnelsParams",
151918
+ description: "Parameters for listing funnels"
151861
151919
  });
151862
- var StartProcessParamsSchema = Schema_exports.Struct({
151863
- process: ProcessIdentifier.annotations({
151864
- description: "Process/workflow ID or exact display name. Ambiguous names fail with candidate IDs instead of guessing."
151920
+ var ListLeadsParamsBase = Schema_exports.Struct({
151921
+ funnel: FunnelReference.annotations({
151922
+ description: "Funnel ID returned by list_funnels, or funnel name for convenience lookup."
151865
151923
  }),
151866
- card: ProcessCardIdentifier.annotations({
151867
- description: "Card/document ID or exact title to attach the new execution to. If a title matches multiple cards, the call fails with candidates."
151868
- })
151869
- }).annotations({
151870
- title: "StartProcessParams",
151871
- description: "Parameters for starting a Huly Process workflow execution on a card/document."
151924
+ status: Schema_exports.optional(StatusName.annotations({
151925
+ description: "Filter by status name"
151926
+ })),
151927
+ assignee: Schema_exports.optional(PersonRefInput.annotations({
151928
+ description: "Filter by assignee email or display name"
151929
+ })),
151930
+ titleSearch: Schema_exports.optional(Schema_exports.String.annotations({
151931
+ description: "Search leads by title substring (case-insensitive)"
151932
+ })),
151933
+ limit: Schema_exports.optional(
151934
+ LimitParam.annotations({
151935
+ description: "Maximum number of leads to return (default: 50)"
151936
+ })
151937
+ )
151872
151938
  });
151873
- var CancelExecutionParamsSchema = Schema_exports.Struct({
151874
- execution: ProcessExecutionId.annotations({
151875
- description: "Process execution ID to cancel. Already-cancelled executions return cancelled=false; completed executions fail without mutation."
151939
+ var ListLeadsParamsSchema = ListLeadsParamsBase.annotations({
151940
+ title: "ListLeadsParams",
151941
+ description: "Parameters for listing leads in a funnel"
151942
+ });
151943
+ var GetLeadParamsSchema = Schema_exports.Struct({
151944
+ funnel: FunnelReference.annotations({
151945
+ description: "Funnel ID returned by list_funnels, or funnel name for convenience lookup."
151946
+ }),
151947
+ identifier: LeadIdentifier.annotations({
151948
+ description: "Lead identifier (e.g., 'LEAD-1')"
151876
151949
  })
151877
151950
  }).annotations({
151878
- title: "CancelExecutionParams",
151879
- description: "Parameters for cancelling an active Huly Process workflow execution."
151880
- });
151881
- var ListProcessesResultSchema = Schema_exports.Struct({
151882
- processes: Schema_exports.Array(ProcessSummarySchema),
151883
- total: Schema_exports.NonNegativeInt
151884
- });
151885
- var ListExecutionsResultSchema = Schema_exports.Struct({
151886
- executions: Schema_exports.Array(ProcessExecutionSummarySchema),
151887
- total: Schema_exports.NonNegativeInt
151888
- });
151889
- var StartProcessResultSchema = Schema_exports.Struct({
151890
- executionId: ProcessExecutionId,
151891
- processId: ProcessId,
151892
- processName: Schema_exports.optional(NonEmptyString2),
151893
- cardId: CardId,
151894
- cardTitle: Schema_exports.optional(NonEmptyString2),
151895
- currentStateId: ProcessStateId,
151896
- currentStateTitle: Schema_exports.optional(NonEmptyString2),
151897
- status: Schema_exports.Literal("active")
151898
- });
151899
- var CancelExecutionResultSchema = Schema_exports.Struct({
151900
- executionId: ProcessExecutionId,
151901
- status: Schema_exports.Literal("cancelled"),
151902
- cancelled: Schema_exports.Boolean
151951
+ title: "GetLeadParams",
151952
+ description: "Parameters for getting a single lead"
151903
151953
  });
151904
- var listProcessesParamsJsonSchema = JSONSchema_exports.make(ListProcessesParamsSchema);
151905
- var getProcessParamsJsonSchema = JSONSchema_exports.make(GetProcessParamsSchema);
151906
- var listExecutionsParamsJsonSchema = JSONSchema_exports.make(ListExecutionsParamsSchema);
151907
- var startProcessParamsJsonSchema = JSONSchema_exports.make(StartProcessParamsSchema);
151908
- var cancelExecutionParamsJsonSchema = JSONSchema_exports.make(CancelExecutionParamsSchema);
151909
- var parseListProcessesParams = Schema_exports.decodeUnknown(ListProcessesParamsSchema);
151910
- var parseGetProcessParams = Schema_exports.decodeUnknown(GetProcessParamsSchema);
151911
- var parseListExecutionsParams = Schema_exports.decodeUnknown(ListExecutionsParamsSchema);
151912
- var parseStartProcessParams = Schema_exports.decodeUnknown(StartProcessParamsSchema);
151913
- var parseCancelExecutionParams = Schema_exports.decodeUnknown(CancelExecutionParamsSchema);
151954
+ var listFunnelsParamsJsonSchema = JSONSchema_exports.make(ListFunnelsParamsSchema);
151955
+ var listLeadsParamsJsonSchema = JSONSchema_exports.make(ListLeadsParamsSchema);
151956
+ var getLeadParamsJsonSchema = JSONSchema_exports.make(GetLeadParamsSchema);
151957
+ var parseListFunnelsParams = Schema_exports.decodeUnknown(ListFunnelsParamsSchema);
151958
+ var parseListLeadsParams = Schema_exports.decodeUnknown(ListLeadsParamsSchema);
151959
+ var parseGetLeadParams = Schema_exports.decodeUnknown(GetLeadParamsSchema);
151960
+ var parseLeadDetail = Schema_exports.decodeUnknown(LeadDetailSchema);
151961
+ var parseLeadSummary = Schema_exports.decodeUnknown(LeadSummarySchema);
151914
151962
 
151915
- // src/huly/errors-processes.ts
151916
- var candidateList = (candidates) => candidates.map(
151917
- (candidate) => candidate.masterTagName === void 0 ? `${candidate.name} (${candidate.id}, masterTag ${candidate.masterTagId})` : `${candidate.name} (${candidate.id}, ${candidate.masterTagName})`
151918
- ).join("; ");
151919
- var ProcessNotFoundError = class extends Schema_exports.TaggedError()(
151920
- "ProcessNotFoundError",
151963
+ // src/huly/errors-leads.ts
151964
+ var FunnelNotFoundError = class extends Schema_exports.TaggedError()(
151965
+ "FunnelNotFoundError",
151921
151966
  {
151922
- identifier: Schema_exports.String,
151923
- candidates: Schema_exports.Array(ProcessCandidateSchema)
151967
+ identifier: FunnelReference
151924
151968
  }
151925
151969
  ) {
151926
151970
  get message() {
151927
- const suffix = this.candidates.length === 0 ? "" : ` Available processes: ${candidateList(this.candidates)}`;
151928
- return `Process '${this.identifier}' not found.${suffix}`;
151971
+ return `Funnel '${this.identifier}' not found`;
151929
151972
  }
151930
151973
  };
151931
- var ProcessIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151932
- "ProcessIdentifierAmbiguousError",
151974
+ var LeadNotFoundError = class extends Schema_exports.TaggedError()(
151975
+ "LeadNotFoundError",
151933
151976
  {
151934
- identifier: Schema_exports.String,
151935
- candidates: Schema_exports.Array(ProcessCandidateSchema)
151977
+ identifier: LeadIdentifier,
151978
+ funnel: FunnelIdentifier
151936
151979
  }
151937
151980
  ) {
151938
151981
  get message() {
151939
- return `Process name '${this.identifier}' is ambiguous. Use one of these process IDs: ${candidateList(this.candidates)}`;
151982
+ return `Lead '${this.identifier}' not found in funnel '${this.funnel}'`;
151940
151983
  }
151941
151984
  };
151942
- var ProcessMasterTagNotFoundError = class extends Schema_exports.TaggedError()(
151943
- "ProcessMasterTagNotFoundError",
151985
+
151986
+ // src/huly/errors-messaging.ts
151987
+ var MIN_AMBIGUOUS_DM_MATCHES = 2;
151988
+ var ChannelNotFoundError = class extends Schema_exports.TaggedError()(
151989
+ "ChannelNotFoundError",
151944
151990
  {
151945
151991
  identifier: Schema_exports.String
151946
151992
  }
151947
151993
  ) {
151948
151994
  get message() {
151949
- return `Process master tag/card type '${this.identifier}' not found`;
151995
+ return `Channel '${this.identifier}' not found`;
151950
151996
  }
151951
151997
  };
151952
- var ProcessMasterTagAmbiguousError = class extends Schema_exports.TaggedError()(
151953
- "ProcessMasterTagAmbiguousError",
151998
+ var DirectMessageNotFoundError = class extends Schema_exports.TaggedError()(
151999
+ "DirectMessageNotFoundError",
151954
152000
  {
151955
- identifier: Schema_exports.String,
151956
- candidates: Schema_exports.Array(Schema_exports.Struct({
151957
- id: MasterTagId,
151958
- name: NonEmptyString2
151959
- }))
152001
+ identifier: Schema_exports.String
151960
152002
  }
151961
152003
  ) {
151962
152004
  get message() {
151963
- const candidates = this.candidates.map((candidate) => `${candidate.name} (${candidate.id})`).join("; ");
151964
- return `Process master tag/card type '${this.identifier}' is ambiguous. Use one of these IDs: ${candidates}`;
152005
+ return `Direct message '${this.identifier}' not found`;
151965
152006
  }
151966
152007
  };
151967
- var ProcessCardIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
151968
- "ProcessCardIdentifierAmbiguousError",
152008
+ var DirectMessageIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
152009
+ "DirectMessageIdentifierAmbiguousError",
151969
152010
  {
151970
152011
  identifier: Schema_exports.String,
151971
- candidates: Schema_exports.Array(Schema_exports.Struct({
151972
- id: CardId,
151973
- title: NonEmptyString2
151974
- }))
152012
+ matches: Schema_exports.Number.pipe(Schema_exports.int(), Schema_exports.greaterThanOrEqualTo(MIN_AMBIGUOUS_DM_MATCHES))
151975
152013
  }
151976
152014
  ) {
151977
152015
  get message() {
151978
- const candidates = this.candidates.map((candidate) => `${candidate.title} (${candidate.id})`).join("; ");
151979
- return `Card/document title '${this.identifier}' is ambiguous. Use one of these card IDs: ${candidates}`;
152016
+ return `Direct message '${this.identifier}' is ambiguous (${this.matches} matches); use the DM _id`;
151980
152017
  }
151981
152018
  };
151982
- var ProcessCardNotFoundError = class extends Schema_exports.TaggedError()(
151983
- "ProcessCardNotFoundError",
152019
+ var CannotDirectMessageSelfError = class extends Schema_exports.TaggedError()(
152020
+ "CannotDirectMessageSelfError",
151984
152021
  {
151985
152022
  identifier: Schema_exports.String
151986
152023
  }
151987
152024
  ) {
151988
152025
  get message() {
151989
- return `Card/document '${this.identifier}' not found`;
151990
- }
151991
- };
151992
- var ProcessInitialStateNotFoundError = class extends Schema_exports.TaggedError()(
151993
- "ProcessInitialStateNotFoundError",
151994
- {
151995
- processId: ProcessId,
151996
- processName: NonEmptyString2
151997
- }
151998
- ) {
151999
- get message() {
152000
- return `Process '${this.processName}' (${this.processId}) has no initial transition from null`;
152001
- }
152002
- };
152003
- var ProcessParallelExecutionForbiddenError = class extends Schema_exports.TaggedError()(
152004
- "ProcessParallelExecutionForbiddenError",
152005
- {
152006
- processId: ProcessId,
152007
- cardId: CardId,
152008
- activeExecutionId: ProcessExecutionId
152009
- }
152010
- ) {
152011
- get message() {
152012
- return `Process '${this.processId}' already has active execution '${this.activeExecutionId}' for card '${this.cardId}'`;
152026
+ return `Cannot start a direct-message conversation with yourself ('${this.identifier}')`;
152013
152027
  }
152014
152028
  };
152015
- var ProcessExecutionNotFoundError = class extends Schema_exports.TaggedError()(
152016
- "ProcessExecutionNotFoundError",
152029
+ var PersonNotAnEmployeeError = class extends Schema_exports.TaggedError()(
152030
+ "PersonNotAnEmployeeError",
152017
152031
  {
152018
- executionId: ProcessExecutionId
152032
+ identifier: Schema_exports.String
152019
152033
  }
152020
152034
  ) {
152021
152035
  get message() {
152022
- return `Process execution '${this.executionId}' not found`;
152036
+ return `Person '${this.identifier}' is not a workspace member (no Huly account) and cannot receive direct messages`;
152023
152037
  }
152024
152038
  };
152025
- var ProcessExecutionNotCancellableError = class extends Schema_exports.TaggedError()(
152026
- "ProcessExecutionNotCancellableError",
152039
+ var MessageNotFoundError = class extends Schema_exports.TaggedError()(
152040
+ "MessageNotFoundError",
152027
152041
  {
152028
- executionId: ProcessExecutionId,
152029
- status: Schema_exports.Literal("done")
152042
+ messageId: Schema_exports.String,
152043
+ channel: Schema_exports.String
152030
152044
  }
152031
152045
  ) {
152032
152046
  get message() {
152033
- return `Process execution '${this.executionId}' is completed and cannot be cancelled`;
152047
+ return `Message '${this.messageId}' not found in channel '${this.channel}'`;
152034
152048
  }
152035
152049
  };
152036
-
152037
- // src/huly/errors-test-management.ts
152038
- var TestProjectNotFoundError = class extends Schema_exports.TaggedError()(
152039
- "TestProjectNotFoundError",
152050
+ var ThreadReplyNotFoundError = class extends Schema_exports.TaggedError()(
152051
+ "ThreadReplyNotFoundError",
152040
152052
  {
152041
- identifier: Schema_exports.String
152053
+ replyId: Schema_exports.String,
152054
+ messageId: Schema_exports.String
152042
152055
  }
152043
152056
  ) {
152044
152057
  get message() {
152045
- return `Test project '${this.identifier}' not found`;
152058
+ return `Thread reply '${this.replyId}' not found on message '${this.messageId}'`;
152046
152059
  }
152047
152060
  };
152048
- var TestSuiteNotFoundError = class extends Schema_exports.TaggedError()(
152049
- "TestSuiteNotFoundError",
152061
+ var ActivityMessageNotFoundError = class extends Schema_exports.TaggedError()(
152062
+ "ActivityMessageNotFoundError",
152050
152063
  {
152051
- identifier: Schema_exports.String
152064
+ messageId: Schema_exports.String
152052
152065
  }
152053
152066
  ) {
152054
152067
  get message() {
152055
- return `Test suite '${this.identifier}' not found`;
152068
+ return `Activity message '${this.messageId}' not found`;
152056
152069
  }
152057
152070
  };
152058
- var TestCaseNotFoundError = class extends Schema_exports.TaggedError()(
152059
- "TestCaseNotFoundError",
152071
+ var ReactionNotFoundError = class extends Schema_exports.TaggedError()(
152072
+ "ReactionNotFoundError",
152060
152073
  {
152061
- identifier: Schema_exports.String
152074
+ messageId: Schema_exports.String,
152075
+ emoji: Schema_exports.String
152062
152076
  }
152063
152077
  ) {
152064
152078
  get message() {
152065
- return `Test case '${this.identifier}' not found`;
152079
+ return `Reaction '${this.emoji}' not found on message '${this.messageId}'`;
152066
152080
  }
152067
152081
  };
152068
- var TestPlanNotFoundError = class extends Schema_exports.TaggedError()(
152069
- "TestPlanNotFoundError",
152082
+ var SavedMessageNotFoundError = class extends Schema_exports.TaggedError()(
152083
+ "SavedMessageNotFoundError",
152070
152084
  {
152071
- identifier: Schema_exports.String
152085
+ messageId: Schema_exports.String
152072
152086
  }
152073
152087
  ) {
152074
152088
  get message() {
152075
- return `Test plan '${this.identifier}' not found`;
152089
+ return `Saved message for '${this.messageId}' not found`;
152076
152090
  }
152077
152091
  };
152078
- var TestRunNotFoundError = class extends Schema_exports.TaggedError()(
152079
- "TestRunNotFoundError",
152092
+
152093
+ // src/huly/errors-notifications.ts
152094
+ var NotificationNotFoundError = class extends Schema_exports.TaggedError()(
152095
+ "NotificationNotFoundError",
152080
152096
  {
152081
- identifier: Schema_exports.String
152097
+ notificationId: Schema_exports.String
152082
152098
  }
152083
152099
  ) {
152084
152100
  get message() {
152085
- return `Test run '${this.identifier}' not found`;
152101
+ return `Notification '${this.notificationId}' not found`;
152086
152102
  }
152087
152103
  };
152088
- var TestResultNotFoundError = class extends Schema_exports.TaggedError()(
152089
- "TestResultNotFoundError",
152104
+ var NotificationContextNotFoundError = class extends Schema_exports.TaggedError()(
152105
+ "NotificationContextNotFoundError",
152090
152106
  {
152091
- identifier: Schema_exports.String
152107
+ contextId: Schema_exports.String
152092
152108
  }
152093
152109
  ) {
152094
152110
  get message() {
152095
- return `Test result '${this.identifier}' not found`;
152096
- }
152097
- };
152098
- var TestPlanItemNotFoundError = class extends Schema_exports.TaggedError()(
152099
- "TestPlanItemNotFoundError",
152100
- {
152101
- identifier: Schema_exports.String,
152102
- plan: Schema_exports.String
152103
- }
152104
- ) {
152105
- get message() {
152106
- return `Test plan item '${this.identifier}' not found in plan '${this.plan}'`;
152111
+ return `Notification context '${this.contextId}' not found`;
152107
152112
  }
152108
152113
  };
152109
152114
 
152110
- // src/huly/errors-tracker.ts
152111
- var IssueNotFoundError = class extends Schema_exports.TaggedError()(
152112
- "IssueNotFoundError",
152115
+ // src/domain/schemas/processes.ts
152116
+ var ProcessId = DocId.pipe(Schema_exports.brand("ProcessId"));
152117
+ var ProcessIdentifier = NonEmptyString2.pipe(Schema_exports.brand("ProcessIdentifier"));
152118
+ var ProcessExecutionId = DocId.pipe(Schema_exports.brand("ProcessExecutionId"));
152119
+ var ProcessStateId = DocId.pipe(Schema_exports.brand("ProcessStateId"));
152120
+ var ProcessTransitionId = DocId.pipe(Schema_exports.brand("ProcessTransitionId"));
152121
+ var ProcessCardIdentifier = NonEmptyString2.pipe(Schema_exports.brand("ProcessCardIdentifier"));
152122
+ var ProcessMasterTagIdentifier = NonEmptyString2.pipe(Schema_exports.brand("ProcessMasterTagIdentifier"));
152123
+ var ProcessExecutionStatusSchema = Schema_exports.Literal("active", "done", "cancelled");
152124
+ var ProcessCandidateSchema = Schema_exports.Struct({
152125
+ id: ProcessId,
152126
+ name: NonEmptyString2,
152127
+ masterTagId: MasterTagId,
152128
+ masterTagName: Schema_exports.optional(NonEmptyString2)
152129
+ });
152130
+ var ProcessSummarySchema = Schema_exports.Struct({
152131
+ id: ProcessId,
152132
+ name: NonEmptyString2,
152133
+ description: Schema_exports.optional(Schema_exports.String),
152134
+ masterTagId: MasterTagId,
152135
+ masterTagName: Schema_exports.optional(NonEmptyString2),
152136
+ autoStart: Schema_exports.Boolean,
152137
+ automationOnly: Schema_exports.Boolean,
152138
+ parallelExecutionForbidden: Schema_exports.Boolean,
152139
+ stateCount: Schema_exports.NonNegativeInt,
152140
+ transitionCount: Schema_exports.NonNegativeInt
152141
+ });
152142
+ var ProcessStateSummarySchema = Schema_exports.Struct({
152143
+ id: ProcessStateId,
152144
+ title: NonEmptyString2
152145
+ });
152146
+ var ProcessTransitionSummarySchema = Schema_exports.Struct({
152147
+ id: ProcessTransitionId,
152148
+ fromStateId: Schema_exports.optional(ProcessStateId),
152149
+ fromStateTitle: Schema_exports.optional(NonEmptyString2),
152150
+ toStateId: ProcessStateId,
152151
+ toStateTitle: Schema_exports.optional(NonEmptyString2),
152152
+ triggerId: NonEmptyString2,
152153
+ actionCount: Schema_exports.NonNegativeInt
152154
+ });
152155
+ var ProcessDetailSchema = ProcessSummarySchema.pipe(
152156
+ Schema_exports.extend(Schema_exports.Struct({
152157
+ initialStateId: Schema_exports.optional(ProcessStateId),
152158
+ states: Schema_exports.Array(ProcessStateSummarySchema),
152159
+ transitions: Schema_exports.Array(ProcessTransitionSummarySchema)
152160
+ }))
152161
+ );
152162
+ var ProcessExecutionSummarySchema = Schema_exports.Struct({
152163
+ id: ProcessExecutionId,
152164
+ processId: ProcessId,
152165
+ processName: Schema_exports.optional(NonEmptyString2),
152166
+ cardId: CardId,
152167
+ cardTitle: Schema_exports.optional(NonEmptyString2),
152168
+ currentStateId: ProcessStateId,
152169
+ currentStateTitle: Schema_exports.optional(NonEmptyString2),
152170
+ status: ProcessExecutionStatusSchema,
152171
+ errorCount: Schema_exports.NonNegativeInt,
152172
+ hasError: Schema_exports.Boolean,
152173
+ hasParent: Schema_exports.Boolean,
152174
+ parentExecutionId: Schema_exports.optional(ProcessExecutionId),
152175
+ modifiedOn: Schema_exports.optional(Timestamp)
152176
+ });
152177
+ var ListProcessesParamsSchema = Schema_exports.Struct({
152178
+ masterTag: Schema_exports.optional(ProcessMasterTagIdentifier.annotations({
152179
+ description: "Optional master tag/card type ID or display label. Use this when you only want workflows attached to one Huly card/document type."
152180
+ })),
152181
+ limit: Schema_exports.optional(LimitParam.annotations({
152182
+ description: "Maximum number of process definitions to return (default: 50, maximum: 200)."
152183
+ }))
152184
+ }).annotations({
152185
+ title: "ListProcessesParams",
152186
+ description: "Parameters for listing Huly Process workflow definitions."
152187
+ });
152188
+ var GetProcessParamsSchema = Schema_exports.Struct({
152189
+ process: ProcessIdentifier.annotations({
152190
+ description: "Process/workflow ID or exact display name. Ambiguous names fail with candidate IDs instead of guessing."
152191
+ })
152192
+ }).annotations({
152193
+ title: "GetProcessParams",
152194
+ description: "Parameters for retrieving one Huly Process workflow definition."
152195
+ });
152196
+ var ListExecutionsParamsSchema = Schema_exports.Struct({
152197
+ process: Schema_exports.optional(ProcessIdentifier.annotations({
152198
+ description: "Optional process/workflow ID or exact display name. Ambiguous names fail with candidate IDs instead of guessing."
152199
+ })),
152200
+ card: Schema_exports.optional(ProcessCardIdentifier.annotations({
152201
+ description: "Optional card/document ID or exact title. If a title matches multiple cards, the call fails with candidates."
152202
+ })),
152203
+ status: Schema_exports.optional(ProcessExecutionStatusSchema.annotations({
152204
+ description: "Optional execution status filter: active, done, or cancelled."
152205
+ })),
152206
+ limit: Schema_exports.optional(LimitParam.annotations({
152207
+ description: "Maximum number of executions to return (default: 50, maximum: 200)."
152208
+ }))
152209
+ }).annotations({
152210
+ title: "ListExecutionsParams",
152211
+ description: "Parameters for listing read-only Huly Process workflow executions."
152212
+ });
152213
+ var StartProcessParamsSchema = Schema_exports.Struct({
152214
+ process: ProcessIdentifier.annotations({
152215
+ description: "Process/workflow ID or exact display name. Ambiguous names fail with candidate IDs instead of guessing."
152216
+ }),
152217
+ card: ProcessCardIdentifier.annotations({
152218
+ description: "Card/document ID or exact title to attach the new execution to. If a title matches multiple cards, the call fails with candidates."
152219
+ })
152220
+ }).annotations({
152221
+ title: "StartProcessParams",
152222
+ description: "Parameters for starting a Huly Process workflow execution on a card/document."
152223
+ });
152224
+ var CancelExecutionParamsSchema = Schema_exports.Struct({
152225
+ execution: ProcessExecutionId.annotations({
152226
+ description: "Process execution ID to cancel. Already-cancelled executions return cancelled=false; completed executions fail without mutation."
152227
+ })
152228
+ }).annotations({
152229
+ title: "CancelExecutionParams",
152230
+ description: "Parameters for cancelling an active Huly Process workflow execution."
152231
+ });
152232
+ var ListProcessesResultSchema = Schema_exports.Struct({
152233
+ processes: Schema_exports.Array(ProcessSummarySchema),
152234
+ total: Schema_exports.NonNegativeInt
152235
+ });
152236
+ var ListExecutionsResultSchema = Schema_exports.Struct({
152237
+ executions: Schema_exports.Array(ProcessExecutionSummarySchema),
152238
+ total: Schema_exports.NonNegativeInt
152239
+ });
152240
+ var StartProcessResultSchema = Schema_exports.Struct({
152241
+ executionId: ProcessExecutionId,
152242
+ processId: ProcessId,
152243
+ processName: Schema_exports.optional(NonEmptyString2),
152244
+ cardId: CardId,
152245
+ cardTitle: Schema_exports.optional(NonEmptyString2),
152246
+ currentStateId: ProcessStateId,
152247
+ currentStateTitle: Schema_exports.optional(NonEmptyString2),
152248
+ status: Schema_exports.Literal("active")
152249
+ });
152250
+ var CancelExecutionResultSchema = Schema_exports.Struct({
152251
+ executionId: ProcessExecutionId,
152252
+ status: Schema_exports.Literal("cancelled"),
152253
+ cancelled: Schema_exports.Boolean
152254
+ });
152255
+ var listProcessesParamsJsonSchema = JSONSchema_exports.make(ListProcessesParamsSchema);
152256
+ var getProcessParamsJsonSchema = JSONSchema_exports.make(GetProcessParamsSchema);
152257
+ var listExecutionsParamsJsonSchema = JSONSchema_exports.make(ListExecutionsParamsSchema);
152258
+ var startProcessParamsJsonSchema = JSONSchema_exports.make(StartProcessParamsSchema);
152259
+ var cancelExecutionParamsJsonSchema = JSONSchema_exports.make(CancelExecutionParamsSchema);
152260
+ var parseListProcessesParams = Schema_exports.decodeUnknown(ListProcessesParamsSchema);
152261
+ var parseGetProcessParams = Schema_exports.decodeUnknown(GetProcessParamsSchema);
152262
+ var parseListExecutionsParams = Schema_exports.decodeUnknown(ListExecutionsParamsSchema);
152263
+ var parseStartProcessParams = Schema_exports.decodeUnknown(StartProcessParamsSchema);
152264
+ var parseCancelExecutionParams = Schema_exports.decodeUnknown(CancelExecutionParamsSchema);
152265
+
152266
+ // src/huly/errors-processes.ts
152267
+ var candidateList = (candidates) => candidates.map(
152268
+ (candidate) => candidate.masterTagName === void 0 ? `${candidate.name} (${candidate.id}, masterTag ${candidate.masterTagId})` : `${candidate.name} (${candidate.id}, ${candidate.masterTagName})`
152269
+ ).join("; ");
152270
+ var ProcessNotFoundError = class extends Schema_exports.TaggedError()(
152271
+ "ProcessNotFoundError",
152113
152272
  {
152114
152273
  identifier: Schema_exports.String,
152115
- project: Schema_exports.String
152274
+ candidates: Schema_exports.Array(ProcessCandidateSchema)
152116
152275
  }
152117
152276
  ) {
152118
152277
  get message() {
152119
- return `Issue '${this.identifier}' not found in project '${this.project}'`;
152278
+ const suffix = this.candidates.length === 0 ? "" : ` Available processes: ${candidateList(this.candidates)}`;
152279
+ return `Process '${this.identifier}' not found.${suffix}`;
152120
152280
  }
152121
152281
  };
152122
- var ProjectNotFoundError = class extends Schema_exports.TaggedError()(
152123
- "ProjectNotFoundError",
152282
+ var ProcessIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
152283
+ "ProcessIdentifierAmbiguousError",
152124
152284
  {
152125
- identifier: Schema_exports.String
152285
+ identifier: Schema_exports.String,
152286
+ candidates: Schema_exports.Array(ProcessCandidateSchema)
152126
152287
  }
152127
152288
  ) {
152128
152289
  get message() {
152129
- return `Project '${this.identifier}' not found`;
152290
+ return `Process name '${this.identifier}' is ambiguous. Use one of these process IDs: ${candidateList(this.candidates)}`;
152130
152291
  }
152131
152292
  };
152132
- var InvalidStatusError = class extends Schema_exports.TaggedError()(
152133
- "InvalidStatusError",
152293
+ var ProcessMasterTagNotFoundError = class extends Schema_exports.TaggedError()(
152294
+ "ProcessMasterTagNotFoundError",
152134
152295
  {
152135
- status: Schema_exports.String,
152136
- project: Schema_exports.String
152296
+ identifier: Schema_exports.String
152137
152297
  }
152138
152298
  ) {
152139
152299
  get message() {
152140
- return `Invalid status '${this.status}' for project '${this.project}'`;
152300
+ return `Process master tag/card type '${this.identifier}' not found`;
152141
152301
  }
152142
152302
  };
152143
- var CommentNotFoundError = class extends Schema_exports.TaggedError()(
152144
- "CommentNotFoundError",
152303
+ var ProcessMasterTagAmbiguousError = class extends Schema_exports.TaggedError()(
152304
+ "ProcessMasterTagAmbiguousError",
152145
152305
  {
152146
- commentId: Schema_exports.String,
152147
- issueIdentifier: Schema_exports.String,
152148
- project: Schema_exports.String
152306
+ identifier: Schema_exports.String,
152307
+ candidates: Schema_exports.Array(Schema_exports.Struct({
152308
+ id: MasterTagId,
152309
+ name: NonEmptyString2
152310
+ }))
152149
152311
  }
152150
152312
  ) {
152151
152313
  get message() {
152152
- return `Comment '${this.commentId}' not found on issue '${this.issueIdentifier}' in project '${this.project}'`;
152314
+ const candidates = this.candidates.map((candidate) => `${candidate.name} (${candidate.id})`).join("; ");
152315
+ return `Process master tag/card type '${this.identifier}' is ambiguous. Use one of these IDs: ${candidates}`;
152153
152316
  }
152154
152317
  };
152155
- var MilestoneNotFoundError = class extends Schema_exports.TaggedError()(
152156
- "MilestoneNotFoundError",
152318
+ var ProcessCardIdentifierAmbiguousError = class extends Schema_exports.TaggedError()(
152319
+ "ProcessCardIdentifierAmbiguousError",
152157
152320
  {
152158
152321
  identifier: Schema_exports.String,
152159
- project: Schema_exports.String
152322
+ candidates: Schema_exports.Array(Schema_exports.Struct({
152323
+ id: CardId,
152324
+ title: NonEmptyString2
152325
+ }))
152160
152326
  }
152161
152327
  ) {
152162
152328
  get message() {
152163
- return `Milestone '${this.identifier}' not found in project '${this.project}'`;
152329
+ const candidates = this.candidates.map((candidate) => `${candidate.title} (${candidate.id})`).join("; ");
152330
+ return `Card/document title '${this.identifier}' is ambiguous. Use one of these card IDs: ${candidates}`;
152164
152331
  }
152165
152332
  };
152166
- var ComponentNotFoundError = class extends Schema_exports.TaggedError()(
152167
- "ComponentNotFoundError",
152333
+ var ProcessCardNotFoundError = class extends Schema_exports.TaggedError()(
152334
+ "ProcessCardNotFoundError",
152168
152335
  {
152169
- identifier: Schema_exports.String,
152170
- project: Schema_exports.String
152336
+ identifier: Schema_exports.String
152171
152337
  }
152172
152338
  ) {
152173
152339
  get message() {
152174
- return `Component '${this.identifier}' not found in project '${this.project}'`;
152340
+ return `Card/document '${this.identifier}' not found`;
152175
152341
  }
152176
152342
  };
152177
- var IssueTemplateNotFoundError = class extends Schema_exports.TaggedError()(
152178
- "IssueTemplateNotFoundError",
152343
+ var ProcessInitialStateNotFoundError = class extends Schema_exports.TaggedError()(
152344
+ "ProcessInitialStateNotFoundError",
152179
152345
  {
152180
- identifier: Schema_exports.String,
152181
- project: Schema_exports.String
152346
+ processId: ProcessId,
152347
+ processName: NonEmptyString2
152182
152348
  }
152183
152349
  ) {
152184
152350
  get message() {
152185
- return `Issue template '${this.identifier}' not found in project '${this.project}'`;
152351
+ return `Process '${this.processName}' (${this.processId}) has no initial transition from null`;
152186
152352
  }
152187
152353
  };
152188
- var TemplateChildNotFoundError = class extends Schema_exports.TaggedError()(
152189
- "TemplateChildNotFoundError",
152354
+ var ProcessParallelExecutionForbiddenError = class extends Schema_exports.TaggedError()(
152355
+ "ProcessParallelExecutionForbiddenError",
152190
152356
  {
152191
- childId: Schema_exports.String,
152192
- template: Schema_exports.String,
152193
- project: Schema_exports.String
152357
+ processId: ProcessId,
152358
+ cardId: CardId,
152359
+ activeExecutionId: ProcessExecutionId
152194
152360
  }
152195
152361
  ) {
152196
152362
  get message() {
152197
- return `Child template '${this.childId}' not found in template '${this.template}' of project '${this.project}'`;
152363
+ return `Process '${this.processId}' already has active execution '${this.activeExecutionId}' for card '${this.cardId}'`;
152198
152364
  }
152199
152365
  };
152200
-
152201
- // src/huly/errors.ts
152202
- var HulyDomainError = Schema_exports.Union(
152203
- HulyError,
152204
- NoUpdateFieldsError,
152205
- HulyConnectionError,
152206
- HulyAuthError,
152207
- IssueNotFoundError,
152208
- ProjectNotFoundError,
152209
- InvalidStatusError,
152210
- PersonIdentifierAmbiguousError,
152211
- PersonNotFoundError,
152212
- OrganizationNotFoundError,
152213
- OrganizationIdentifierAmbiguousError,
152366
+ var ProcessExecutionNotFoundError = class extends Schema_exports.TaggedError()(
152367
+ "ProcessExecutionNotFoundError",
152368
+ {
152369
+ executionId: ProcessExecutionId
152370
+ }
152371
+ ) {
152372
+ get message() {
152373
+ return `Process execution '${this.executionId}' not found`;
152374
+ }
152375
+ };
152376
+ var ProcessExecutionNotCancellableError = class extends Schema_exports.TaggedError()(
152377
+ "ProcessExecutionNotCancellableError",
152378
+ {
152379
+ executionId: ProcessExecutionId,
152380
+ status: Schema_exports.Literal("done")
152381
+ }
152382
+ ) {
152383
+ get message() {
152384
+ return `Process execution '${this.executionId}' is completed and cannot be cancelled`;
152385
+ }
152386
+ };
152387
+
152388
+ // src/huly/errors-test-management.ts
152389
+ var TestProjectNotFoundError = class extends Schema_exports.TaggedError()(
152390
+ "TestProjectNotFoundError",
152391
+ {
152392
+ identifier: Schema_exports.String
152393
+ }
152394
+ ) {
152395
+ get message() {
152396
+ return `Test project '${this.identifier}' not found`;
152397
+ }
152398
+ };
152399
+ var TestSuiteNotFoundError = class extends Schema_exports.TaggedError()(
152400
+ "TestSuiteNotFoundError",
152401
+ {
152402
+ identifier: Schema_exports.String
152403
+ }
152404
+ ) {
152405
+ get message() {
152406
+ return `Test suite '${this.identifier}' not found`;
152407
+ }
152408
+ };
152409
+ var TestCaseNotFoundError = class extends Schema_exports.TaggedError()(
152410
+ "TestCaseNotFoundError",
152411
+ {
152412
+ identifier: Schema_exports.String
152413
+ }
152414
+ ) {
152415
+ get message() {
152416
+ return `Test case '${this.identifier}' not found`;
152417
+ }
152418
+ };
152419
+ var TestPlanNotFoundError = class extends Schema_exports.TaggedError()(
152420
+ "TestPlanNotFoundError",
152421
+ {
152422
+ identifier: Schema_exports.String
152423
+ }
152424
+ ) {
152425
+ get message() {
152426
+ return `Test plan '${this.identifier}' not found`;
152427
+ }
152428
+ };
152429
+ var TestRunNotFoundError = class extends Schema_exports.TaggedError()(
152430
+ "TestRunNotFoundError",
152431
+ {
152432
+ identifier: Schema_exports.String
152433
+ }
152434
+ ) {
152435
+ get message() {
152436
+ return `Test run '${this.identifier}' not found`;
152437
+ }
152438
+ };
152439
+ var TestResultNotFoundError = class extends Schema_exports.TaggedError()(
152440
+ "TestResultNotFoundError",
152441
+ {
152442
+ identifier: Schema_exports.String
152443
+ }
152444
+ ) {
152445
+ get message() {
152446
+ return `Test result '${this.identifier}' not found`;
152447
+ }
152448
+ };
152449
+ var TestPlanItemNotFoundError = class extends Schema_exports.TaggedError()(
152450
+ "TestPlanItemNotFoundError",
152451
+ {
152452
+ identifier: Schema_exports.String,
152453
+ plan: Schema_exports.String
152454
+ }
152455
+ ) {
152456
+ get message() {
152457
+ return `Test plan item '${this.identifier}' not found in plan '${this.plan}'`;
152458
+ }
152459
+ };
152460
+
152461
+ // src/huly/errors-tracker.ts
152462
+ var IssueNotFoundError = class extends Schema_exports.TaggedError()(
152463
+ "IssueNotFoundError",
152464
+ {
152465
+ identifier: Schema_exports.String,
152466
+ project: Schema_exports.String
152467
+ }
152468
+ ) {
152469
+ get message() {
152470
+ return `Issue '${this.identifier}' not found in project '${this.project}'`;
152471
+ }
152472
+ };
152473
+ var ProjectNotFoundError = class extends Schema_exports.TaggedError()(
152474
+ "ProjectNotFoundError",
152475
+ {
152476
+ identifier: Schema_exports.String
152477
+ }
152478
+ ) {
152479
+ get message() {
152480
+ return `Project '${this.identifier}' not found`;
152481
+ }
152482
+ };
152483
+ var InvalidStatusError = class extends Schema_exports.TaggedError()(
152484
+ "InvalidStatusError",
152485
+ {
152486
+ status: Schema_exports.String,
152487
+ project: Schema_exports.String
152488
+ }
152489
+ ) {
152490
+ get message() {
152491
+ return `Invalid status '${this.status}' for project '${this.project}'`;
152492
+ }
152493
+ };
152494
+ var CommentNotFoundError = class extends Schema_exports.TaggedError()(
152495
+ "CommentNotFoundError",
152496
+ {
152497
+ commentId: Schema_exports.String,
152498
+ issueIdentifier: Schema_exports.String,
152499
+ project: Schema_exports.String
152500
+ }
152501
+ ) {
152502
+ get message() {
152503
+ return `Comment '${this.commentId}' not found on issue '${this.issueIdentifier}' in project '${this.project}'`;
152504
+ }
152505
+ };
152506
+ var MilestoneNotFoundError = class extends Schema_exports.TaggedError()(
152507
+ "MilestoneNotFoundError",
152508
+ {
152509
+ identifier: Schema_exports.String,
152510
+ project: Schema_exports.String
152511
+ }
152512
+ ) {
152513
+ get message() {
152514
+ return `Milestone '${this.identifier}' not found in project '${this.project}'`;
152515
+ }
152516
+ };
152517
+ var ComponentNotFoundError = class extends Schema_exports.TaggedError()(
152518
+ "ComponentNotFoundError",
152519
+ {
152520
+ identifier: Schema_exports.String,
152521
+ project: Schema_exports.String
152522
+ }
152523
+ ) {
152524
+ get message() {
152525
+ return `Component '${this.identifier}' not found in project '${this.project}'`;
152526
+ }
152527
+ };
152528
+ var IssueTemplateNotFoundError = class extends Schema_exports.TaggedError()(
152529
+ "IssueTemplateNotFoundError",
152530
+ {
152531
+ identifier: Schema_exports.String,
152532
+ project: Schema_exports.String
152533
+ }
152534
+ ) {
152535
+ get message() {
152536
+ return `Issue template '${this.identifier}' not found in project '${this.project}'`;
152537
+ }
152538
+ };
152539
+ var TemplateChildNotFoundError = class extends Schema_exports.TaggedError()(
152540
+ "TemplateChildNotFoundError",
152541
+ {
152542
+ childId: Schema_exports.String,
152543
+ template: Schema_exports.String,
152544
+ project: Schema_exports.String
152545
+ }
152546
+ ) {
152547
+ get message() {
152548
+ return `Child template '${this.childId}' not found in template '${this.template}' of project '${this.project}'`;
152549
+ }
152550
+ };
152551
+
152552
+ // src/huly/errors.ts
152553
+ var HulyDomainError = Schema_exports.Union(
152554
+ HulyError,
152555
+ NoUpdateFieldsError,
152556
+ HulyConnectionError,
152557
+ HulyAuthError,
152558
+ IssueNotFoundError,
152559
+ ProjectNotFoundError,
152560
+ InvalidStatusError,
152561
+ PersonIdentifierAmbiguousError,
152562
+ PersonNotFoundError,
152563
+ OrganizationNotFoundError,
152564
+ OrganizationIdentifierAmbiguousError,
152214
152565
  InvalidContactProviderError,
152215
152566
  FileUploadError,
152216
152567
  InvalidFileDataError,
@@ -152274,9 +152625,14 @@ var HulyDomainError = Schema_exports.Union(
152274
152625
  ProcessExecutionNotCancellableError,
152275
152626
  AssociationNotFoundError,
152276
152627
  AssociationIdentifierAmbiguousError,
152628
+ AssociationSystemClassUnsupportedError,
152629
+ AssociationConflictError,
152630
+ AssociationInUseError,
152277
152631
  RelationNotFoundError,
152278
152632
  RelationIdentifierAmbiguousError,
152279
152633
  RelationMutationUnsupportedError,
152634
+ RelationCardinalityViolationError,
152635
+ RelationDirectionAmbiguousError,
152280
152636
  RelationEndpointClassMismatchError,
152281
152637
  GenericObjectIdentifierAmbiguousError,
152282
152638
  GenericObjectLocatorInvalidError,
@@ -172203,7 +172559,7 @@ var PostHog = class extends PostHogBackendClient {
172203
172559
  };
172204
172560
 
172205
172561
  // src/version.ts
172206
- var VERSION = true ? "0.15.1" : "0.0.0-dev";
172562
+ var VERSION = true ? "0.16.0" : "0.0.0-dev";
172207
172563
 
172208
172564
  // src/telemetry/posthog.ts
172209
172565
  var POSTHOG_API_KEY = "phc_TGfFqCGdnF0p68wuFzd5WSw1IsBvOJW0YgoMJDyZPjm";
@@ -172387,9 +172743,14 @@ var INVALID_PARAMS_TAGS = /* @__PURE__ */ new Set([
172387
172743
  "ProcessCardNotFoundError",
172388
172744
  "AssociationNotFoundError",
172389
172745
  "AssociationIdentifierAmbiguousError",
172746
+ "AssociationSystemClassUnsupportedError",
172747
+ "AssociationConflictError",
172748
+ "AssociationInUseError",
172390
172749
  "RelationNotFoundError",
172391
172750
  "RelationIdentifierAmbiguousError",
172392
172751
  "RelationMutationUnsupportedError",
172752
+ "RelationCardinalityViolationError",
172753
+ "RelationDirectionAmbiguousError",
172393
172754
  "RelationEndpointClassMismatchError",
172394
172755
  "GenericObjectIdentifierAmbiguousError",
172395
172756
  "GenericObjectLocatorInvalidError",
@@ -175851,352 +176212,116 @@ var deleteEvent = (params) => Effect_exports.gen(function* () {
175851
176212
  return yield* new EventNotFoundError({ eventId: params.eventId });
175852
176213
  }
175853
176214
  yield* client.removeDoc(
175854
- calendar.class.Event,
175855
- event.space,
175856
- event._id
175857
- );
175858
- return { eventId: EventId.make(params.eventId), deleted: true };
175859
- });
175860
-
175861
- // src/mcp/tools/calendar.ts
175862
- var CATEGORY3 = "calendar";
175863
- var calendarTools = [
175864
- {
175865
- name: "list_events",
175866
- description: "List calendar events. Returns events sorted by date. Supports filtering by date range.",
175867
- category: CATEGORY3,
175868
- inputSchema: listEventsParamsJsonSchema,
175869
- handler: createToolHandler(
175870
- "list_events",
175871
- parseListEventsParams,
175872
- listEvents
175873
- )
175874
- },
175875
- {
175876
- name: "list_calendars",
175877
- description: "List writable, non-hidden calendars that can be used as create_event or create_recurring_event targets. Use this before creating events when you need to choose a target calendarId explicitly.",
175878
- category: CATEGORY3,
175879
- inputSchema: listCalendarsParamsJsonSchema,
175880
- handler: createToolHandler(
175881
- "list_calendars",
175882
- parseListCalendarsParams,
175883
- listCalendars
175884
- )
175885
- },
175886
- {
175887
- name: "get_event",
175888
- description: "Retrieve full details for a calendar event including description. Use this to view event content and metadata.",
175889
- category: CATEGORY3,
175890
- inputSchema: getEventParamsJsonSchema,
175891
- handler: createToolHandler(
175892
- "get_event",
175893
- parseGetEventParams,
175894
- getEvent
175895
- )
175896
- },
175897
- {
175898
- name: "create_event",
175899
- description: "Create a new calendar event. Description supports markdown formatting. Optional calendarId targets a specific calendar; when omitted, the event uses the authenticated user's primary personal calendar. Returns the created event ID.",
175900
- category: CATEGORY3,
175901
- inputSchema: createEventParamsJsonSchema,
175902
- handler: createToolHandler(
175903
- "create_event",
175904
- parseCreateEventParams,
175905
- createEvent
175906
- )
175907
- },
175908
- {
175909
- name: "update_event",
175910
- description: "Update fields on an existing calendar event. Only provided fields are modified. Description updates support markdown.",
175911
- category: CATEGORY3,
175912
- inputSchema: updateEventParamsJsonSchema,
175913
- handler: createToolHandler(
175914
- "update_event",
175915
- parseUpdateEventParams,
175916
- updateEvent
175917
- )
175918
- },
175919
- {
175920
- name: "delete_event",
175921
- description: "Permanently delete a calendar event. This action cannot be undone.",
175922
- category: CATEGORY3,
175923
- inputSchema: deleteEventParamsJsonSchema,
175924
- handler: createToolHandler(
175925
- "delete_event",
175926
- parseDeleteEventParams,
175927
- deleteEvent
175928
- )
175929
- },
175930
- {
175931
- name: "list_recurring_events",
175932
- description: "List recurring event definitions. Returns recurring events sorted by modification date (newest first).",
175933
- category: CATEGORY3,
175934
- inputSchema: listRecurringEventsParamsJsonSchema,
175935
- handler: createToolHandler(
175936
- "list_recurring_events",
175937
- parseListRecurringEventsParams,
175938
- listRecurringEvents
175939
- )
175940
- },
175941
- {
175942
- name: "create_recurring_event",
175943
- description: "Create a new recurring calendar event with RFC5545 RRULE rules. Description supports markdown. Optional calendarId targets a specific calendar; when omitted, the event uses the authenticated user's primary personal calendar. Returns the created event ID.",
175944
- category: CATEGORY3,
175945
- inputSchema: createRecurringEventParamsJsonSchema,
175946
- handler: createToolHandler(
175947
- "create_recurring_event",
175948
- parseCreateRecurringEventParams,
175949
- createRecurringEvent
175950
- )
175951
- },
175952
- {
175953
- name: "list_event_instances",
175954
- description: "List instances of a recurring event. Returns instances sorted by date. Supports filtering by date range. Use includeParticipants=true to fetch full participant info (extra lookups).",
175955
- category: CATEGORY3,
175956
- inputSchema: listEventInstancesParamsJsonSchema,
175957
- handler: createToolHandler(
175958
- "list_event_instances",
175959
- parseListEventInstancesParams,
175960
- listEventInstances
175961
- )
175962
- }
175963
- ];
175964
-
175965
- // src/domain/schemas/generic-associations.ts
175966
- var AssociationIdentifier = NonEmptyString2.pipe(Schema_exports.brand("AssociationIdentifier"));
175967
- var RelationIdentifier = NonEmptyString2.pipe(Schema_exports.brand("RelationIdentifier"));
175968
- var ListRelationsWarning = NonEmptyString2.pipe(Schema_exports.brand("ListRelationsWarning"));
175969
- var CardinalityValues = [
175970
- "one-to-one",
175971
- "one-to-many",
175972
- "many-to-many"
175973
- ];
175974
- var CardinalitySchema = Schema_exports.Literal(...CardinalityValues).annotations({
175975
- description: `Association cardinality: ${enumValuesDescription(CardinalityValues)}`
175976
- });
175977
- var RelationDirectionValues = ["source-to-target", "target-to-source", "either"];
175978
- var RelationDirectionSchema = Schema_exports.Literal(...RelationDirectionValues);
175979
- var DefaultRelationDirection = "source-to-target";
175980
- var relationDirectionDescription = `Relation traversal direction: ${enumValuesDescription(RelationDirectionValues)}. Defaults to ${DefaultRelationDirection}.`;
175981
- var RelationIfExistsSchema = Schema_exports.Literal("return_existing", "fail");
175982
- var RawObjectLocatorSchema = Schema_exports.Struct({
175983
- kind: Schema_exports.Literal("raw"),
175984
- id: DocId.annotations({
175985
- description: "Raw Huly document _id"
175986
- }),
175987
- class: Schema_exports.optional(ObjectClassName.annotations({
175988
- description: "Raw Huly document class, such as tracker:class:Issue. Required unless the association side determines the expected class."
175989
- }))
175990
- });
175991
- var IssueObjectLocatorSchema = Schema_exports.Struct({
175992
- kind: Schema_exports.Literal("issue"),
175993
- issue: IssueIdentifier.annotations({
175994
- description: "Issue identifier, such as HULY-123, or a numeric issue number when project is also provided."
175995
- }),
175996
- project: Schema_exports.optional(ProjectIdentifier.annotations({
175997
- description: "Project identifier. Optional when issue already includes a project prefix like HULY-123."
175998
- }))
175999
- });
176000
- var DocumentObjectLocatorSchema = Schema_exports.Struct({
176001
- kind: Schema_exports.Literal("document"),
176002
- document: DocumentIdentifier.annotations({
176003
- description: "Document title or ID"
176004
- }),
176005
- teamspace: Schema_exports.optional(TeamspaceIdentifier.annotations({
176006
- description: "Teamspace name or ID. If omitted, document title matches must be unique across the workspace."
176007
- }))
176008
- });
176009
- var GenericObjectLocatorSchema = Schema_exports.Union(
176010
- RawObjectLocatorSchema,
176011
- IssueObjectLocatorSchema,
176012
- DocumentObjectLocatorSchema
176013
- ).annotations({
176014
- title: "GenericObjectLocator",
176015
- description: "Explicit locator for a Huly document endpoint. Use raw for known _id values, issue for tracker issues, or document for Huly documents. Card locators are intentionally not included until a robust card resolver is available."
176016
- });
176017
- var ResolvedObjectSummarySchema = Schema_exports.Struct({
176018
- id: DocId,
176019
- class: ObjectClassName,
176020
- display: NonEmptyString2,
176021
- locatorKind: Schema_exports.Literal("raw", "issue", "document"),
176022
- warning: Schema_exports.optional(Schema_exports.String)
176023
- });
176024
- var AssociationSummarySchema = Schema_exports.Struct({
176025
- associationId: AssociationId,
176026
- name: Schema_exports.optional(NonEmptyString2),
176027
- label: Schema_exports.optional(NonEmptyString2),
176028
- description: Schema_exports.optional(Schema_exports.String),
176029
- sourceClass: ObjectClassName,
176030
- sourceClassLabel: Schema_exports.optional(NonEmptyString2.annotations({
176031
- description: "Best-effort human display label for sourceClass when the class is known to this server"
176032
- })),
176033
- targetClass: ObjectClassName,
176034
- targetClassLabel: Schema_exports.optional(NonEmptyString2.annotations({
176035
- description: "Best-effort human display label for targetClass when the class is known to this server"
176036
- })),
176037
- sourceRole: Schema_exports.optional(NonEmptyString2),
176038
- targetRole: Schema_exports.optional(NonEmptyString2),
176039
- relationClass: Schema_exports.optional(ObjectClassName),
176040
- cardinality: CardinalitySchema,
176041
- symmetric: Schema_exports.Boolean,
176042
- system: Schema_exports.Boolean,
176043
- canListRelations: Schema_exports.Boolean,
176044
- canCreateRelation: Schema_exports.Boolean,
176045
- canDeleteRelation: Schema_exports.Boolean,
176046
- unsupportedReason: Schema_exports.optional(Schema_exports.String)
176047
- });
176048
- var RelationSummarySchema = Schema_exports.Struct({
176049
- relationId: RelationId,
176050
- associationId: AssociationId,
176051
- associationName: Schema_exports.optional(NonEmptyString2),
176052
- source: ResolvedObjectSummarySchema,
176053
- target: ResolvedObjectSummarySchema,
176054
- createdOn: Schema_exports.optional(Timestamp),
176055
- modifiedOn: Schema_exports.optional(Timestamp)
176056
- });
176057
- var ListAssociationsParamsSchema = Schema_exports.Struct({
176058
- association: Schema_exports.optional(AssociationIdentifier.annotations({
176059
- description: "Association _id, source/target role name, or stable association name"
176060
- })),
176061
- sourceClass: Schema_exports.optional(ObjectClassName.annotations({
176062
- description: "Only return associations whose source class matches this Huly class ID"
176063
- })),
176064
- targetClass: Schema_exports.optional(ObjectClassName.annotations({
176065
- description: "Only return associations whose target class matches this Huly class ID"
176066
- })),
176067
- writableOnly: Schema_exports.optional(Schema_exports.Boolean.annotations({
176068
- description: "Only return associations whose relation create/delete path has been validated and allowlisted"
176069
- })),
176070
- includeSystem: Schema_exports.optional(Schema_exports.Boolean.annotations({
176071
- description: "Include internal/system associations. Defaults to false."
176072
- })),
176073
- limit: Schema_exports.optional(LimitParam.annotations({
176074
- description: "Maximum number of associations to return (default: 50)"
176075
- }))
176076
- }).annotations({
176077
- title: "ListAssociationsParams",
176078
- description: "Parameters for listing generic Huly association definitions"
176079
- });
176080
- var ListAssociationsResultSchema = Schema_exports.Struct({
176081
- associations: Schema_exports.Array(AssociationSummarySchema),
176082
- total: Schema_exports.Number
176083
- });
176084
- var ListRelationsParamsBaseSchema = Schema_exports.Struct({
176085
- association: Schema_exports.optional(AssociationIdentifier.annotations({
176086
- description: "Association _id or name. If omitted, relations are listed only across supported visible associations."
176087
- })),
176088
- source: Schema_exports.optional(GenericObjectLocatorSchema.annotations({
176089
- description: "Optional source endpoint filter"
176090
- })),
176091
- target: Schema_exports.optional(GenericObjectLocatorSchema.annotations({
176092
- description: "Optional target endpoint filter"
176093
- })),
176094
- direction: Schema_exports.optional(RelationDirectionSchema.annotations({
176095
- description: relationDirectionDescription
176096
- })),
176097
- limit: Schema_exports.optional(LimitParam.annotations({
176098
- description: "Maximum number of relations to return (default: 50)"
176099
- }))
176100
- }).annotations({
176101
- title: "ListRelationsParams",
176102
- description: "Parameters for listing concrete Huly relation instances"
176103
- });
176104
- var ListRelationsParamsSchema = ListRelationsParamsBaseSchema.pipe(
176105
- Schema_exports.filter(
176106
- (params) => params.association === void 0 && params.source === void 0 && params.target === void 0 ? "Provide at least one of association, source, or target to avoid broad workspace scans." : void 0
176107
- )
176108
- ).annotations({
176109
- title: "ListRelationsParams",
176110
- description: "Parameters for listing concrete Huly relation instances"
176111
- });
176112
- var ListRelationsResultSchema = Schema_exports.Struct({
176113
- relations: Schema_exports.Array(RelationSummarySchema),
176114
- total: Schema_exports.Number,
176115
- warnings: Schema_exports.optional(
176116
- Schema_exports.NonEmptyArray(ListRelationsWarning).annotations({
176117
- description: "Non-fatal warnings about result completeness or resolution. Treat these as guidance for narrowing a follow-up call."
176118
- })
176119
- )
176120
- });
176121
- var CreateRelationParamsSchema = Schema_exports.Struct({
176122
- association: AssociationIdentifier.annotations({
176123
- description: "Association _id or unambiguous name returned by list_associations"
176124
- }),
176125
- source: GenericObjectLocatorSchema.annotations({
176126
- description: "Source endpoint document"
176127
- }),
176128
- target: GenericObjectLocatorSchema.annotations({
176129
- description: "Target endpoint document"
176130
- }),
176131
- ifExists: Schema_exports.optional(RelationIfExistsSchema.annotations({
176132
- description: "return_existing (default) returns an existing relation; fail reports an existing relation as an error"
176133
- }))
176134
- }).annotations({
176135
- title: "CreateRelationParams",
176136
- description: "Parameters for idempotently creating a concrete generic relation"
176137
- });
176138
- var CreateRelationResultSchema = Schema_exports.Struct({
176139
- relationId: RelationId,
176140
- associationId: AssociationId,
176141
- source: ResolvedObjectSummarySchema,
176142
- target: ResolvedObjectSummarySchema,
176143
- created: Schema_exports.Boolean,
176144
- existing: Schema_exports.Boolean
176145
- });
176146
- var DeleteRelationByIdParamsSchema = Schema_exports.Struct({
176147
- relation: RelationIdentifier.annotations({
176148
- description: "Concrete relation _id to delete"
176149
- })
176150
- }).annotations({
176151
- title: "DeleteRelationByIdParams",
176152
- description: "Delete one concrete relation by its relation ID."
176153
- });
176154
- var DeleteRelationByTripleParamsSchema = Schema_exports.Struct({
176155
- association: AssociationIdentifier.annotations({
176156
- description: "Association _id or unambiguous name"
176157
- }),
176158
- source: GenericObjectLocatorSchema.annotations({
176159
- description: "Source endpoint"
176160
- }),
176161
- target: GenericObjectLocatorSchema.annotations({
176162
- description: "Target endpoint"
176163
- })
176164
- }).annotations({
176165
- title: "DeleteRelationByTripleParams",
176166
- description: "Delete one concrete relation by exact association + source + target triple."
176167
- });
176168
- var DeleteRelationParamsSchema = Schema_exports.Union(
176169
- DeleteRelationByIdParamsSchema,
176170
- DeleteRelationByTripleParamsSchema
176171
- ).annotations({
176172
- title: "DeleteRelationParams",
176173
- description: "Parameters for idempotently deleting one concrete generic relation. Provide either relation, or the full association + source + target triple."
176174
- });
176175
- var DeleteRelationResultSchema = Schema_exports.Struct({
176176
- relationId: Schema_exports.optional(RelationId),
176177
- associationId: Schema_exports.optional(AssociationId),
176178
- deleted: Schema_exports.Boolean,
176179
- reason: Schema_exports.optional(Schema_exports.Literal("not_found", "deleted"))
176180
- });
176181
- var listAssociationsParamsJsonSchema = JSONSchema_exports.make(ListAssociationsParamsSchema);
176182
- var listRelationsParamsJsonSchema = {
176183
- ...JSONSchema_exports.make(ListRelationsParamsBaseSchema),
176184
- anyOf: [
176185
- { required: ["association"] },
176186
- { required: ["source"] },
176187
- { required: ["target"] }
176188
- ]
176189
- };
176190
- var createRelationParamsJsonSchema = JSONSchema_exports.make(CreateRelationParamsSchema);
176191
- var deleteRelationParamsJsonSchema = {
176192
- ...JSONSchema_exports.make(DeleteRelationParamsSchema),
176193
- type: "object"
176194
- };
176195
- var strictParseOptions = { onExcessProperty: "error" };
176196
- var parseListAssociationsParams = Schema_exports.decodeUnknown(ListAssociationsParamsSchema, strictParseOptions);
176197
- var parseListRelationsParams = Schema_exports.decodeUnknown(ListRelationsParamsSchema, strictParseOptions);
176198
- var parseCreateRelationParams = Schema_exports.decodeUnknown(CreateRelationParamsSchema, strictParseOptions);
176199
- var parseDeleteRelationParams = Schema_exports.decodeUnknown(DeleteRelationParamsSchema, strictParseOptions);
176215
+ calendar.class.Event,
176216
+ event.space,
176217
+ event._id
176218
+ );
176219
+ return { eventId: EventId.make(params.eventId), deleted: true };
176220
+ });
176221
+
176222
+ // src/mcp/tools/calendar.ts
176223
+ var CATEGORY3 = "calendar";
176224
+ var calendarTools = [
176225
+ {
176226
+ name: "list_events",
176227
+ description: "List calendar events. Returns events sorted by date. Supports filtering by date range.",
176228
+ category: CATEGORY3,
176229
+ inputSchema: listEventsParamsJsonSchema,
176230
+ handler: createToolHandler(
176231
+ "list_events",
176232
+ parseListEventsParams,
176233
+ listEvents
176234
+ )
176235
+ },
176236
+ {
176237
+ name: "list_calendars",
176238
+ description: "List writable, non-hidden calendars that can be used as create_event or create_recurring_event targets. Use this before creating events when you need to choose a target calendarId explicitly.",
176239
+ category: CATEGORY3,
176240
+ inputSchema: listCalendarsParamsJsonSchema,
176241
+ handler: createToolHandler(
176242
+ "list_calendars",
176243
+ parseListCalendarsParams,
176244
+ listCalendars
176245
+ )
176246
+ },
176247
+ {
176248
+ name: "get_event",
176249
+ description: "Retrieve full details for a calendar event including description. Use this to view event content and metadata.",
176250
+ category: CATEGORY3,
176251
+ inputSchema: getEventParamsJsonSchema,
176252
+ handler: createToolHandler(
176253
+ "get_event",
176254
+ parseGetEventParams,
176255
+ getEvent
176256
+ )
176257
+ },
176258
+ {
176259
+ name: "create_event",
176260
+ description: "Create a new calendar event. Description supports markdown formatting. Optional calendarId targets a specific calendar; when omitted, the event uses the authenticated user's primary personal calendar. Returns the created event ID.",
176261
+ category: CATEGORY3,
176262
+ inputSchema: createEventParamsJsonSchema,
176263
+ handler: createToolHandler(
176264
+ "create_event",
176265
+ parseCreateEventParams,
176266
+ createEvent
176267
+ )
176268
+ },
176269
+ {
176270
+ name: "update_event",
176271
+ description: "Update fields on an existing calendar event. Only provided fields are modified. Description updates support markdown.",
176272
+ category: CATEGORY3,
176273
+ inputSchema: updateEventParamsJsonSchema,
176274
+ handler: createToolHandler(
176275
+ "update_event",
176276
+ parseUpdateEventParams,
176277
+ updateEvent
176278
+ )
176279
+ },
176280
+ {
176281
+ name: "delete_event",
176282
+ description: "Permanently delete a calendar event. This action cannot be undone.",
176283
+ category: CATEGORY3,
176284
+ inputSchema: deleteEventParamsJsonSchema,
176285
+ handler: createToolHandler(
176286
+ "delete_event",
176287
+ parseDeleteEventParams,
176288
+ deleteEvent
176289
+ )
176290
+ },
176291
+ {
176292
+ name: "list_recurring_events",
176293
+ description: "List recurring event definitions. Returns recurring events sorted by modification date (newest first).",
176294
+ category: CATEGORY3,
176295
+ inputSchema: listRecurringEventsParamsJsonSchema,
176296
+ handler: createToolHandler(
176297
+ "list_recurring_events",
176298
+ parseListRecurringEventsParams,
176299
+ listRecurringEvents
176300
+ )
176301
+ },
176302
+ {
176303
+ name: "create_recurring_event",
176304
+ description: "Create a new recurring calendar event with RFC5545 RRULE rules. Description supports markdown. Optional calendarId targets a specific calendar; when omitted, the event uses the authenticated user's primary personal calendar. Returns the created event ID.",
176305
+ category: CATEGORY3,
176306
+ inputSchema: createRecurringEventParamsJsonSchema,
176307
+ handler: createToolHandler(
176308
+ "create_recurring_event",
176309
+ parseCreateRecurringEventParams,
176310
+ createRecurringEvent
176311
+ )
176312
+ },
176313
+ {
176314
+ name: "list_event_instances",
176315
+ description: "List instances of a recurring event. Returns instances sorted by date. Supports filtering by date range. Use includeParticipants=true to fetch full participant info (extra lookups).",
176316
+ category: CATEGORY3,
176317
+ inputSchema: listEventInstancesParamsJsonSchema,
176318
+ handler: createToolHandler(
176319
+ "list_event_instances",
176320
+ parseListEventInstancesParams,
176321
+ listEventInstances
176322
+ )
176323
+ }
176324
+ ];
176200
176325
 
176201
176326
  // src/domain/schemas/projects.ts
176202
176327
  var ProjectSummarySchema = Schema_exports.Struct({
@@ -182115,7 +182240,6 @@ var documentTools = [
182115
182240
 
182116
182241
  // src/huly/operations/generic-associations.ts
182117
182242
  var import_core35 = __toESM(require_lib4(), 1);
182118
- var WRITE_UNSUPPORTED_REASON = "no generic association relation write path has been live-validated for this workspace";
182119
182243
  var ASSOCIATION_DISCOVERY_LIMIT = 200;
182120
182244
  var ASSOCIATION_DISCOVERY_LIMIT_WARNING = ListRelationsWarning.make(
182121
182245
  `Association discovery reached the local ${ASSOCIATION_DISCOVERY_LIMIT}-association cap for at least one endpoint orientation. Huly did not indicate whether more matching associations exist, so list_relations may omit older matching associations; pass a specific association from list_associations to avoid this discovery cap.`
@@ -182131,8 +182255,7 @@ var VISIBLE_ASSOCIATION_FILTERS = {
182131
182255
  sourceClass: void 0,
182132
182256
  targetClass: void 0
182133
182257
  };
182134
- var associationName = (association) => association.nameA === association.nameB ? association.nameA : `${association.nameA} -> ${association.nameB}`;
182135
- var optionalNonEmpty = (value3) => value3 === void 0 ? void 0 : NonEmptyString2.make(value3);
182258
+ var associationName = (association) => association.nameA === association.nameB ? AssociationName.make(association.nameA) : AssociationName.make(`${association.nameA} -> ${association.nameB}`);
182136
182259
  var classLabelEntry = (classRef2, label) => [
182137
182260
  ObjectClassName.make(classRef2),
182138
182261
  NonEmptyString2.make(label)
@@ -182150,7 +182273,19 @@ var KNOWN_CLASS_LABELS = new Map([
182150
182273
  classLabelEntry(tracker.class.Milestone, "Milestone")
182151
182274
  ]);
182152
182275
  var classLabel = (classRef2) => KNOWN_CLASS_LABELS.get(classRef2);
182153
- var isSystemAssociation = (association) => String(association.classA).startsWith("core:class:") || String(association.classB).startsWith("core:class:");
182276
+ var isSystemClassName = (className) => className.startsWith("core:class:");
182277
+ var isSystemAssociation = (association) => isSystemClassName(String(association.classA)) || isSystemClassName(String(association.classB));
182278
+ var associationAutomationOnly = (association) => association.automationOnly === true;
182279
+ var relationWriteUnsupportedReason = (association) => {
182280
+ if (isSystemAssociation(association)) {
182281
+ return "association uses a core:class:* system class";
182282
+ }
182283
+ if (associationAutomationOnly(association)) {
182284
+ return "association is automation-only";
182285
+ }
182286
+ return void 0;
182287
+ };
182288
+ var isRelationWritableAssociation = (association) => relationWriteUnsupportedReason(association) === void 0;
182154
182289
  var isSymmetric = (association) => association.classA === association.classB && association.nameA === association.nameB;
182155
182290
  var ASSOCIATION_CARDINALITY = {
182156
182291
  "1:1": "one-to-one",
@@ -182160,33 +182295,39 @@ var ASSOCIATION_CARDINALITY = {
182160
182295
  var exactCardinalityMapping = (value3) => value3;
182161
182296
  exactCardinalityMapping(true);
182162
182297
  var cardinality = (type) => ASSOCIATION_CARDINALITY[type];
182298
+ var SDK_CARDINALITY = {
182299
+ "one-to-one": "1:1",
182300
+ "one-to-many": "1:N",
182301
+ "many-to-many": "N:N"
182302
+ };
182163
182303
  var toAssociationSummary = (association) => {
182164
182304
  const sourceClass = ObjectClassName.make(association.classA);
182165
182305
  const targetClass = ObjectClassName.make(association.classB);
182306
+ const unsupportedReason = relationWriteUnsupportedReason(association);
182166
182307
  return {
182167
182308
  associationId: AssociationId.make(association._id),
182168
- name: optionalNonEmpty(associationName(association)),
182309
+ name: associationName(association),
182169
182310
  sourceClass,
182170
182311
  sourceClassLabel: classLabel(sourceClass),
182171
182312
  targetClass,
182172
182313
  targetClassLabel: classLabel(targetClass),
182173
- sourceRole: NonEmptyString2.make(association.nameA),
182174
- targetRole: NonEmptyString2.make(association.nameB),
182314
+ sourceRole: AssociationRoleName.make(association.nameA),
182315
+ targetRole: AssociationRoleName.make(association.nameB),
182175
182316
  relationClass: ObjectClassName.make(core.class.Relation),
182176
182317
  cardinality: cardinality(association.type),
182177
182318
  symmetric: isSymmetric(association),
182178
182319
  system: isSystemAssociation(association),
182179
182320
  canListRelations: true,
182180
- canCreateRelation: false,
182181
- canDeleteRelation: false,
182182
- unsupportedReason: WRITE_UNSUPPORTED_REASON
182321
+ canCreateRelation: unsupportedReason === void 0,
182322
+ canDeleteRelation: unsupportedReason === void 0,
182323
+ ...unsupportedReason === void 0 ? {} : { unsupportedReason }
182183
182324
  };
182184
182325
  };
182185
182326
  var toCandidate = (association) => ({
182186
182327
  id: AssociationId.make(association._id),
182187
182328
  name: associationName(association),
182188
- sourceClass: association.classA,
182189
- targetClass: association.classB
182329
+ sourceClass: ObjectClassName.make(association.classA),
182330
+ targetClass: ObjectClassName.make(association.classB)
182190
182331
  });
182191
182332
  var matchesAssociationIdentifier = (association, identifier2) => {
182192
182333
  const normalized = identifier2.trim().toLowerCase();
@@ -182203,7 +182344,7 @@ var associationListFiltersFromParams = (params) => ({
182203
182344
  });
182204
182345
  var associationMatchesFilters = (association, filters) => (filters.includeSystem || !isSystemAssociation(association)) && (filters.sourceClass === void 0 || association.classA === String(filters.sourceClass)) && (filters.targetClass === void 0 || association.classB === String(filters.targetClass));
182205
182346
  var filterVisible = (associations, filters) => associations.filter(
182206
- (association) => associationMatchesFilters(association, filters) && !filters.writableOnly
182347
+ (association) => associationMatchesFilters(association, filters) && (!filters.writableOnly || isRelationWritableAssociation(association))
182207
182348
  );
182208
182349
  var listAssociationDocs = (client, params) => {
182209
182350
  const query = {};
@@ -182300,6 +182441,155 @@ var resolveAssociation = (client, identifier2, filters) => Effect_exports.gen(fu
182300
182441
  }
182301
182442
  return candidates[0];
182302
182443
  });
182444
+ var rejectSystemClass = (className, operation) => isSystemClassName(String(className)) ? Effect_exports.fail(new AssociationSystemClassUnsupportedError({ className, operation })) : Effect_exports.void;
182445
+ var systemClassInAssociation = (association) => {
182446
+ if (isSystemClassName(String(association.classA))) {
182447
+ return ObjectClassName.make(association.classA);
182448
+ }
182449
+ if (isSystemClassName(String(association.classB))) {
182450
+ return ObjectClassName.make(association.classB);
182451
+ }
182452
+ return void 0;
182453
+ };
182454
+ var ensureRelationMutationSupported = (association, operation) => {
182455
+ const systemClass = systemClassInAssociation(association);
182456
+ if (systemClass !== void 0) {
182457
+ return Effect_exports.fail(new AssociationSystemClassUnsupportedError({ className: systemClass, operation }));
182458
+ }
182459
+ if (associationAutomationOnly(association)) {
182460
+ return Effect_exports.fail(
182461
+ new RelationMutationUnsupportedError({
182462
+ associationId: AssociationId.make(association._id),
182463
+ reason: "association is automation-only"
182464
+ })
182465
+ );
182466
+ }
182467
+ return Effect_exports.void;
182468
+ };
182469
+ var exactAssociationQuery = (params) => ({
182470
+ classA: toClassRef(params.sourceClass),
182471
+ classB: toClassRef(params.targetClass),
182472
+ nameA: params.sourceRole,
182473
+ nameB: params.targetRole
182474
+ });
182475
+ var createdAssociationSummaryInput = (id, params) => ({
182476
+ _id: id,
182477
+ classA: toClassRef(params.sourceClass),
182478
+ classB: toClassRef(params.targetClass),
182479
+ nameA: params.sourceRole,
182480
+ nameB: params.targetRole,
182481
+ type: SDK_CARDINALITY[params.cardinality],
182482
+ automationOnly: params.automationOnly ?? false
182483
+ });
182484
+ var createAssociation = (params) => Effect_exports.gen(function* () {
182485
+ const client = yield* HulyClient;
182486
+ yield* rejectSystemClass(params.sourceClass, "create_association");
182487
+ yield* rejectSystemClass(params.targetClass, "create_association");
182488
+ const existing = yield* client.findOne(
182489
+ core.class.Association,
182490
+ hulyQuery(exactAssociationQuery(params))
182491
+ );
182492
+ if (existing !== void 0) {
182493
+ if (params.ifExists === "fail") {
182494
+ return yield* new AssociationConflictError({
182495
+ associationId: AssociationId.make(existing._id),
182496
+ reason: "ifExists=fail was requested"
182497
+ });
182498
+ }
182499
+ if (cardinality(existing.type) !== params.cardinality) {
182500
+ return yield* new AssociationConflictError({
182501
+ associationId: AssociationId.make(existing._id),
182502
+ reason: `existing cardinality is ${cardinality(existing.type)}, requested ${params.cardinality}`
182503
+ });
182504
+ }
182505
+ if (associationAutomationOnly(existing) !== (params.automationOnly ?? false)) {
182506
+ return yield* new AssociationConflictError({
182507
+ associationId: AssociationId.make(existing._id),
182508
+ reason: `existing automationOnly is ${associationAutomationOnly(existing)}, requested ${params.automationOnly ?? false}`
182509
+ });
182510
+ }
182511
+ return {
182512
+ association: toAssociationSummary(existing),
182513
+ created: false,
182514
+ existing: true
182515
+ };
182516
+ }
182517
+ const attributes = {
182518
+ classA: toClassRef(params.sourceClass),
182519
+ classB: toClassRef(params.targetClass),
182520
+ nameA: params.sourceRole,
182521
+ nameB: params.targetRole,
182522
+ type: SDK_CARDINALITY[params.cardinality],
182523
+ automationOnly: params.automationOnly ?? false
182524
+ };
182525
+ const associationId = yield* client.createDoc(
182526
+ core.class.Association,
182527
+ toRef(core.space.Model),
182528
+ attributes
182529
+ );
182530
+ return {
182531
+ association: toAssociationSummary(createdAssociationSummaryInput(associationId, params)),
182532
+ created: true,
182533
+ existing: false
182534
+ };
182535
+ });
182536
+ var ensureAssociationDeletionSupported = (association) => {
182537
+ const systemClass = systemClassInAssociation(association);
182538
+ return systemClass === void 0 ? Effect_exports.void : Effect_exports.fail(
182539
+ new AssociationSystemClassUnsupportedError({
182540
+ className: systemClass,
182541
+ operation: "delete_association"
182542
+ })
182543
+ );
182544
+ };
182545
+ var countAssociationRelations = (client, association) => Effect_exports.map(
182546
+ client.findAll(
182547
+ core.class.Relation,
182548
+ hulyQuery({
182549
+ association: toRef(association._id)
182550
+ }),
182551
+ { limit: 5 }
182552
+ ),
182553
+ (relations) => ({
182554
+ total: Math.max(relations.total, relations.length),
182555
+ sampleRelationIds: relations.map((relation) => RelationId.make(relation._id))
182556
+ })
182557
+ );
182558
+ var deleteAssociation = (params) => Effect_exports.gen(function* () {
182559
+ const client = yield* HulyClient;
182560
+ const association = yield* resolveAssociation(
182561
+ client,
182562
+ params.association,
182563
+ MUTATION_ASSOCIATION_FILTERS
182564
+ ).pipe(
182565
+ Effect_exports.catchTag("AssociationNotFoundError", () => Effect_exports.succeed(void 0))
182566
+ );
182567
+ if (association === void 0) {
182568
+ return {
182569
+ association: params.association,
182570
+ deleted: false,
182571
+ relationCount: 0,
182572
+ reason: "not_found"
182573
+ };
182574
+ }
182575
+ yield* ensureAssociationDeletionSupported(association);
182576
+ const relationUsage = yield* countAssociationRelations(client, association);
182577
+ if (relationUsage.total > 0) {
182578
+ return yield* new AssociationInUseError({
182579
+ associationId: AssociationId.make(association._id),
182580
+ relationCount: relationUsage.total,
182581
+ sampleRelationIds: relationUsage.sampleRelationIds
182582
+ });
182583
+ }
182584
+ yield* client.removeDoc(core.class.Association, association.space, association._id);
182585
+ return {
182586
+ association: params.association,
182587
+ associationId: AssociationId.make(association._id),
182588
+ deleted: true,
182589
+ relationCount: 0,
182590
+ reason: "deleted"
182591
+ };
182592
+ });
182303
182593
  var listAssociations = (params) => Effect_exports.gen(function* () {
182304
182594
  const client = yield* HulyClient;
182305
182595
  if (params.association !== void 0) {
@@ -182514,7 +182804,7 @@ var resolveRelationEndpointFromCache = (docsByClass, id, className) => {
182514
182804
  var relationToSummary = (association, relation, docsByClass) => ({
182515
182805
  relationId: RelationId.make(relation._id),
182516
182806
  associationId: AssociationId.make(association._id),
182517
- associationName: optionalNonEmpty(associationName(association)),
182807
+ associationName: associationName(association),
182518
182808
  source: resolveRelationEndpointFromCache(docsByClass, relation.docA, association.classA),
182519
182809
  target: resolveRelationEndpointFromCache(docsByClass, relation.docB, association.classB),
182520
182810
  createdOn: relation.createdOn,
@@ -182752,21 +183042,182 @@ var listRelations = (params) => Effect_exports.gen(function* () {
182752
183042
  total: summaries.length
182753
183043
  };
182754
183044
  });
183045
+ var resolveRelationWriteEndpoints = (client, association, params) => Effect_exports.gen(function* () {
183046
+ const direction = params.direction ?? DefaultRelationDirection;
183047
+ if (direction === "source-to-target") {
183048
+ const source2 = yield* resolveGenericObject(client, params.source, association.classA, "source");
183049
+ const target2 = yield* resolveGenericObject(client, params.target, association.classB, "target");
183050
+ return { docA: source2, docB: target2, source: source2, target: target2 };
183051
+ }
183052
+ if (direction === "target-to-source") {
183053
+ const source2 = yield* resolveGenericObject(client, params.source, association.classB, "source");
183054
+ const target2 = yield* resolveGenericObject(client, params.target, association.classA, "target");
183055
+ return { docA: target2, docB: source2, source: source2, target: target2 };
183056
+ }
183057
+ const source = yield* resolveGenericObject(client, params.source, void 0, "source");
183058
+ const target = yield* resolveGenericObject(client, params.target, void 0, "target");
183059
+ const matchesForward = String(source.class) === association.classA && String(target.class) === association.classB;
183060
+ const matchesReverse = String(source.class) === association.classB && String(target.class) === association.classA;
183061
+ if (matchesForward && matchesReverse) {
183062
+ return yield* new RelationDirectionAmbiguousError({
183063
+ associationId: AssociationId.make(association._id),
183064
+ reason: "both endpoints match both sides of the association"
183065
+ });
183066
+ }
183067
+ if (matchesForward) {
183068
+ return { docA: source, docB: target, source, target };
183069
+ }
183070
+ if (matchesReverse) {
183071
+ return { docA: target, docB: source, source, target };
183072
+ }
183073
+ yield* validateEitherEndpointClasses(association, source, target);
183074
+ return yield* new RelationEndpointClassMismatchError({
183075
+ field: "source",
183076
+ expectedClass: `${association.classA} or ${association.classB}`,
183077
+ actualClass: source.class
183078
+ });
183079
+ });
183080
+ var exactRelationQuery = (association, endpoints) => ({
183081
+ association: toRef(association._id),
183082
+ docA: toRef(endpoints.docA.id),
183083
+ docB: toRef(endpoints.docB.id)
183084
+ });
183085
+ var findExactRelations = (client, association, endpoints, limit) => Effect_exports.map(
183086
+ client.findAll(
183087
+ core.class.Relation,
183088
+ hulyQuery(exactRelationQuery(association, endpoints)),
183089
+ { limit }
183090
+ ),
183091
+ (relations) => [...relations]
183092
+ );
183093
+ var findCardinalityConflict = (client, association, endpoints) => Effect_exports.gen(function* () {
183094
+ if (association.type === "N:N") {
183095
+ return void 0;
183096
+ }
183097
+ const docBConflict = yield* client.findOne(
183098
+ core.class.Relation,
183099
+ hulyQuery({
183100
+ association: toRef(association._id),
183101
+ docB: toRef(endpoints.docB.id)
183102
+ })
183103
+ );
183104
+ if (docBConflict !== void 0) {
183105
+ return docBConflict;
183106
+ }
183107
+ if (association.type === "1:1") {
183108
+ return yield* client.findOne(
183109
+ core.class.Relation,
183110
+ hulyQuery({
183111
+ association: toRef(association._id),
183112
+ docA: toRef(endpoints.docA.id)
183113
+ })
183114
+ );
183115
+ }
183116
+ return void 0;
183117
+ });
183118
+ var enforceCardinality = (client, association, endpoints) => Effect_exports.gen(function* () {
183119
+ const conflict = yield* findCardinalityConflict(client, association, endpoints);
183120
+ if (conflict === void 0) {
183121
+ return;
183122
+ }
183123
+ const reason = association.type === "1:1" ? "one-to-one associations allow each endpoint to appear in only one relation" : "one-to-many associations allow each target-side endpoint to appear in only one relation";
183124
+ return yield* new RelationCardinalityViolationError({
183125
+ associationId: AssociationId.make(association._id),
183126
+ cardinality: cardinality(association.type),
183127
+ reason
183128
+ });
183129
+ });
182755
183130
  var createRelation = (params) => Effect_exports.gen(function* () {
182756
183131
  const client = yield* HulyClient;
182757
183132
  const association = yield* resolveAssociation(client, params.association, MUTATION_ASSOCIATION_FILTERS);
182758
- return yield* new RelationMutationUnsupportedError({
183133
+ yield* ensureRelationMutationSupported(association, "create_relation");
183134
+ const endpoints = yield* resolveRelationWriteEndpoints(client, association, params);
183135
+ const exact = yield* findExactRelations(client, association, endpoints, 1);
183136
+ const existing = exact.at(0);
183137
+ if (existing !== void 0) {
183138
+ if (params.ifExists === "fail") {
183139
+ return yield* new RelationCardinalityViolationError({
183140
+ associationId: AssociationId.make(association._id),
183141
+ cardinality: cardinality(association.type),
183142
+ reason: `relation '${existing._id}' already exists`
183143
+ });
183144
+ }
183145
+ return {
183146
+ relationId: RelationId.make(existing._id),
183147
+ associationId: AssociationId.make(association._id),
183148
+ source: endpoints.source,
183149
+ target: endpoints.target,
183150
+ created: false,
183151
+ existing: true
183152
+ };
183153
+ }
183154
+ yield* enforceCardinality(client, association, endpoints);
183155
+ const relationId = yield* client.createDoc(
183156
+ core.class.Relation,
183157
+ toRef(core.space.Workspace),
183158
+ {
183159
+ association: toRef(association._id),
183160
+ docA: toRef(endpoints.docA.id),
183161
+ docB: toRef(endpoints.docB.id)
183162
+ }
183163
+ );
183164
+ return {
183165
+ relationId: RelationId.make(relationId),
182759
183166
  associationId: AssociationId.make(association._id),
182760
- reason: WRITE_UNSUPPORTED_REASON
182761
- });
183167
+ source: endpoints.source,
183168
+ target: endpoints.target,
183169
+ created: true,
183170
+ existing: false
183171
+ };
182762
183172
  });
182763
183173
  var deleteRelation = (params) => Effect_exports.gen(function* () {
182764
183174
  const client = yield* HulyClient;
182765
- const association = "association" in params ? yield* resolveAssociation(client, params.association, MUTATION_ASSOCIATION_FILTERS) : void 0;
182766
- return yield* new RelationMutationUnsupportedError({
182767
- associationId: association === void 0 ? void 0 : AssociationId.make(association._id),
182768
- reason: WRITE_UNSUPPORTED_REASON
182769
- });
183175
+ if ("relation" in params) {
183176
+ const existing = yield* client.findOne(
183177
+ core.class.Relation,
183178
+ hulyQuery({ _id: toRef(params.relation) })
183179
+ );
183180
+ if (existing === void 0) {
183181
+ return {
183182
+ relationId: RelationId.make(params.relation),
183183
+ deleted: false,
183184
+ reason: "not_found"
183185
+ };
183186
+ }
183187
+ const association2 = yield* resolveAssociation(client, existing.association, MUTATION_ASSOCIATION_FILTERS);
183188
+ yield* ensureRelationMutationSupported(association2, "delete_relation");
183189
+ yield* client.removeDoc(core.class.Relation, existing.space, existing._id);
183190
+ return {
183191
+ relationId: RelationId.make(existing._id),
183192
+ associationId: AssociationId.make(association2._id),
183193
+ deleted: true,
183194
+ reason: "deleted"
183195
+ };
183196
+ }
183197
+ const association = yield* resolveAssociation(client, params.association, MUTATION_ASSOCIATION_FILTERS);
183198
+ yield* ensureRelationMutationSupported(association, "delete_relation");
183199
+ const endpoints = yield* resolveRelationWriteEndpoints(client, association, params);
183200
+ const matches = yield* findExactRelations(client, association, endpoints, 2);
183201
+ if (matches.length === 0) {
183202
+ return {
183203
+ associationId: AssociationId.make(association._id),
183204
+ deleted: false,
183205
+ reason: "not_found"
183206
+ };
183207
+ }
183208
+ if (matches.length > 1) {
183209
+ return yield* new RelationIdentifierAmbiguousError({
183210
+ identifier: `${params.association}/${endpoints.docA.id}/${endpoints.docB.id}`,
183211
+ relationIds: matches.map((relation) => RelationId.make(relation._id))
183212
+ });
183213
+ }
183214
+ yield* client.removeDoc(core.class.Relation, matches[0].space, matches[0]._id);
183215
+ return {
183216
+ relationId: RelationId.make(matches[0]._id),
183217
+ associationId: AssociationId.make(association._id),
183218
+ deleted: true,
183219
+ reason: "deleted"
183220
+ };
182770
183221
  });
182771
183222
 
182772
183223
  // src/mcp/tools/generic-associations.ts
@@ -182784,6 +183235,42 @@ var genericAssociationTools = [
182784
183235
  ListAssociationsResultSchema
182785
183236
  )
182786
183237
  },
183238
+ {
183239
+ name: "create_association",
183240
+ description: "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.",
183241
+ category: CATEGORY11,
183242
+ inputSchema: createAssociationParamsJsonSchema,
183243
+ annotations: {
183244
+ readOnlyHint: false,
183245
+ destructiveHint: false,
183246
+ idempotentHint: true,
183247
+ openWorldHint: false
183248
+ },
183249
+ handler: createEncodedToolHandler(
183250
+ "create_association",
183251
+ parseCreateAssociationParams,
183252
+ createAssociation,
183253
+ CreateAssociationResultSchema
183254
+ )
183255
+ },
183256
+ {
183257
+ name: "delete_association",
183258
+ description: "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.",
183259
+ category: CATEGORY11,
183260
+ inputSchema: deleteAssociationParamsJsonSchema,
183261
+ annotations: {
183262
+ readOnlyHint: false,
183263
+ destructiveHint: true,
183264
+ idempotentHint: true,
183265
+ openWorldHint: false
183266
+ },
183267
+ handler: createEncodedToolHandler(
183268
+ "delete_association",
183269
+ parseDeleteAssociationParams,
183270
+ deleteAssociation,
183271
+ DeleteAssociationResultSchema
183272
+ )
183273
+ },
182787
183274
  {
182788
183275
  name: "list_relations",
182789
183276
  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.",
@@ -182798,7 +183285,7 @@ var genericAssociationTools = [
182798
183285
  },
182799
183286
  {
182800
183287
  name: "create_relation",
182801
- description: "Idempotently create one concrete relation between two resolved documents. Only succeeds for associations where list_associations reports canCreateRelation=true; otherwise it fails clearly. This build currently reports no generic associations as writable until a write allowlist is live-validated.",
183288
+ 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.",
182802
183289
  category: CATEGORY11,
182803
183290
  inputSchema: createRelationParamsJsonSchema,
182804
183291
  annotations: {
@@ -182816,9 +183303,15 @@ var genericAssociationTools = [
182816
183303
  },
182817
183304
  {
182818
183305
  name: "delete_relation",
182819
- description: "Idempotently delete one concrete relation by relation ID or by exact association/source/target triple. Only succeeds for associations where list_associations reports canDeleteRelation=true; otherwise it fails clearly. This build currently reports no generic associations as writable until a write allowlist is live-validated.",
183306
+ 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.",
182820
183307
  category: CATEGORY11,
182821
183308
  inputSchema: deleteRelationParamsJsonSchema,
183309
+ annotations: {
183310
+ readOnlyHint: false,
183311
+ destructiveHint: true,
183312
+ idempotentHint: true,
183313
+ openWorldHint: false
183314
+ },
182822
183315
  handler: createEncodedToolHandler(
182823
183316
  "delete_relation",
182824
183317
  parseDeleteRelationParams,