crewly 1.20.162 → 1.20.164

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 (132) hide show
  1. package/config/roles/orchestrator/prompt.md +2 -0
  2. package/config/roles/team-leader/prompt.md +2 -0
  3. package/config/roles/team-leader/tl-addon.md +2 -0
  4. package/config/skills/agent/core/project-tickets/SKILL.md +4 -0
  5. package/config/skills/orchestrator/set-team-lead/SKILL.md +58 -0
  6. package/config/skills/orchestrator/set-team-lead/execute.sh +46 -0
  7. package/config/skills/orchestrator/set-team-lead/execute.test.sh +77 -0
  8. package/dist/backend/backend/src/constants.d.ts +31 -1
  9. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  10. package/dist/backend/backend/src/constants.js +39 -2
  11. package/dist/backend/backend/src/constants.js.map +1 -1
  12. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +1 -1
  13. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
  14. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +6 -1
  15. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
  16. package/dist/backend/backend/src/controllers/team/team.controller.d.ts +15 -0
  17. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  18. package/dist/backend/backend/src/controllers/team/team.controller.js +110 -15
  19. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  20. package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
  21. package/dist/backend/backend/src/controllers/team/team.routes.js +3 -1
  22. package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
  23. package/dist/backend/backend/src/index.d.ts.map +1 -1
  24. package/dist/backend/backend/src/index.js +9 -15
  25. package/dist/backend/backend/src/index.js.map +1 -1
  26. package/dist/backend/backend/src/models/Team.d.ts.map +1 -1
  27. package/dist/backend/backend/src/models/Team.js +5 -9
  28. package/dist/backend/backend/src/models/Team.js.map +1 -1
  29. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/agent/agent-registration.service.js +20 -28
  31. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  32. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts +26 -0
  33. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/agent/idle-detection.service.js +43 -0
  35. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  36. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +18 -6
  37. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +21 -23
  39. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  40. package/dist/backend/backend/src/services/chat-v2/huddle-leader.d.ts +23 -0
  41. package/dist/backend/backend/src/services/chat-v2/huddle-leader.d.ts.map +1 -0
  42. package/dist/backend/backend/src/services/chat-v2/huddle-leader.js +37 -0
  43. package/dist/backend/backend/src/services/chat-v2/huddle-leader.js.map +1 -0
  44. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  45. package/dist/backend/backend/src/services/core/storage.service.js +3 -0
  46. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  47. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +28 -7
  48. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
  49. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +51 -14
  50. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
  51. package/dist/backend/backend/src/services/project-tickets/ticket-assignee-waker.d.ts +70 -0
  52. package/dist/backend/backend/src/services/project-tickets/ticket-assignee-waker.d.ts.map +1 -0
  53. package/dist/backend/backend/src/services/project-tickets/ticket-assignee-waker.js +64 -0
  54. package/dist/backend/backend/src/services/project-tickets/ticket-assignee-waker.js.map +1 -0
  55. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts +24 -0
  56. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts.map +1 -1
  57. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js +38 -1
  58. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js.map +1 -1
  59. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts +14 -2
  60. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts.map +1 -1
  61. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js +33 -3
  62. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js.map +1 -1
  63. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +13 -2
  64. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
  65. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +43 -12
  66. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
  67. package/dist/backend/backend/src/services/slack/slack-instance-registry.service.js +2 -2
  68. package/dist/backend/backend/src/services/slack/slack-instance-registry.service.js.map +1 -1
  69. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +10 -1
  70. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  71. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +19 -8
  72. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  73. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts.map +1 -1
  74. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js +4 -3
  75. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js.map +1 -1
  76. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.d.ts +4 -3
  77. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.d.ts.map +1 -1
  78. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.js +6 -7
  79. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.js.map +1 -1
  80. package/dist/backend/backend/src/services/wiki/wiki-owner.resolver.d.ts.map +1 -1
  81. package/dist/backend/backend/src/services/wiki/wiki-owner.resolver.js +2 -1
  82. package/dist/backend/backend/src/services/wiki/wiki-owner.resolver.js.map +1 -1
  83. package/dist/backend/backend/src/types/index.d.ts +3 -2
  84. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  85. package/dist/backend/backend/src/types/index.js.map +1 -1
  86. package/dist/backend/backend/src/utils/defaultPrompts.d.ts.map +1 -1
  87. package/dist/backend/backend/src/utils/defaultPrompts.js +8 -0
  88. package/dist/backend/backend/src/utils/defaultPrompts.js.map +1 -1
  89. package/dist/backend/backend/src/utils/member-default-model.utils.d.ts +5 -5
  90. package/dist/backend/backend/src/utils/member-default-model.utils.d.ts.map +1 -1
  91. package/dist/backend/backend/src/utils/member-default-model.utils.js +4 -4
  92. package/dist/backend/backend/src/utils/member-default-model.utils.js.map +1 -1
  93. package/dist/backend/backend/src/utils/team.utils.d.ts +129 -18
  94. package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -1
  95. package/dist/backend/backend/src/utils/team.utils.js +240 -28
  96. package/dist/backend/backend/src/utils/team.utils.js.map +1 -1
  97. package/dist/backend/build-info.json +2 -2
  98. package/dist/cli/backend/src/constants.d.ts +31 -1
  99. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  100. package/dist/cli/backend/src/constants.js +39 -2
  101. package/dist/cli/backend/src/constants.js.map +1 -1
  102. package/dist/cli/backend/src/models/Team.d.ts.map +1 -1
  103. package/dist/cli/backend/src/models/Team.js +5 -9
  104. package/dist/cli/backend/src/models/Team.js.map +1 -1
  105. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  106. package/dist/cli/backend/src/services/agent/agent-registration.service.js +20 -28
  107. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  108. package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts +18 -6
  109. package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  110. package/dist/cli/backend/src/services/ai/prompt-builder.service.js +21 -23
  111. package/dist/cli/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  112. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  113. package/dist/cli/backend/src/services/core/storage.service.js +3 -0
  114. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  115. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +10 -1
  116. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  117. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +19 -8
  118. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  119. package/dist/cli/backend/src/types/index.d.ts +3 -2
  120. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  121. package/dist/cli/backend/src/types/index.js.map +1 -1
  122. package/dist/cli/backend/src/utils/member-default-model.utils.d.ts +5 -5
  123. package/dist/cli/backend/src/utils/member-default-model.utils.d.ts.map +1 -1
  124. package/dist/cli/backend/src/utils/member-default-model.utils.js +4 -4
  125. package/dist/cli/backend/src/utils/member-default-model.utils.js.map +1 -1
  126. package/dist/cli/backend/src/utils/team.utils.d.ts +129 -18
  127. package/dist/cli/backend/src/utils/team.utils.d.ts.map +1 -1
  128. package/dist/cli/backend/src/utils/team.utils.js +240 -28
  129. package/dist/cli/backend/src/utils/team.utils.js.map +1 -1
  130. package/frontend/dist/assets/{index-64c8a616.js → index-9153caca.js} +263 -263
  131. package/frontend/dist/index.html +1 -1
  132. package/package.json +1 -1
@@ -13,7 +13,7 @@
13
13
  * @module utils/member-default-model
14
14
  */
15
15
  import { MEMBER_MODEL_DEFAULT_CONSTANTS, ORCHESTRATOR_SESSION_NAME, RUNTIME_TYPES } from '../constants.js';
16
- import { pickTeamLead } from './team.utils.js';
16
+ import { isTeamLead, pickTeamLead } from './team.utils.js';
17
17
  /**
18
18
  * The model reviewed members get when they have none, after the env override.
19
19
  *
@@ -32,15 +32,15 @@ export function reviewedMemberDefaultModel(env = process.env) {
32
32
  /**
33
33
  * Whether someone other than the member reviews its work: a parent member
34
34
  * that exists in the team, or a team lead who is not the member itself.
35
- * Members that lead (team-leader / tech-lead role, or a delegating member
36
- * with no parent) never count as reviewed.
35
+ * Members that lead (a lead by the team-lead rule in `utils/team.utils`, or a
36
+ * delegating member with no parent) never count as reviewed.
37
37
  *
38
38
  * @param team - The member's team
39
39
  * @param member - The member
40
40
  * @returns True when the member has a reviewer above it
41
41
  */
42
42
  export function memberHasReviewer(team, member) {
43
- if (MEMBER_MODEL_DEFAULT_CONSTANTS.LEAD_ROLES.includes(member.role))
43
+ if (isTeamLead(team, member))
44
44
  return false;
45
45
  const members = team.members ?? [];
46
46
  const parent = member.parentMemberId ? members.find((m) => m.id === member.parentMemberId) : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"member-default-model.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/member-default-model.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE3G,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM/C;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7E,MAAM,GAAG,GAAG,GAAG,CAAC,8BAA8B,CAAC,YAAY,CAAC,CAAC;IAC7D,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,8BAA8B,CAAC,6BAA6B,CAAC;IAC3F,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA2C,EAAE,MAAkB;IAC/F,IAAK,8BAA8B,CAAC,UAAgC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACzG,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,IAAI,MAAM,IAAI,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IACxE,MAAM,IAAI,GAAG,YAAY,CAAC,IAAY,CAAC,CAAC;IACxC,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAA2C,EAC3C,MAAkB,EAClB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,aAAa,CAAC,WAAW,CAAC,KAAK,aAAa,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IACjG,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,IAAI,MAAM,CAAC,WAAW,KAAK,yBAAyB;QAAE,OAAO,IAAI,CAAC;IACpG,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAA2C,EAC3C,MAAkB,EAClB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IAC1C,OAAO,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;AAC/D,CAAC"}
1
+ {"version":3,"file":"member-default-model.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/member-default-model.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE3G,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM3D;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7E,MAAM,GAAG,GAAG,GAAG,CAAC,8BAA8B,CAAC,YAAY,CAAC,CAAC;IAC7D,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,8BAA8B,CAAC,6BAA6B,CAAC;IAC3F,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAsE,EAAE,MAAkB;IAC1H,IAAI,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,IAAI,MAAM,IAAI,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IACxE,MAAM,IAAI,GAAG,YAAY,CAAC,IAAY,CAAC,CAAC;IACxC,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAsE,EACtE,MAAkB,EAClB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,aAAa,CAAC,WAAW,CAAC,KAAK,aAAa,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IACjG,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,IAAI,MAAM,CAAC,WAAW,KAAK,yBAAyB;QAAE,OAAO,IAAI,CAAC;IACpG,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAsE,EACtE,MAAkB,EAClB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IAC1C,OAAO,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;AAC/D,CAAC"}
@@ -2,33 +2,105 @@
2
2
  * Team utility helpers
3
3
  *
4
4
  * Shared, dependency-free helpers operating on the `Team` / `TeamMember`
5
- * shape. These are extracted here so multiple call sites (chat-v2 mention
6
- * resolver, mission OKR reminder service, …) can share a single canonical
7
- * implementation instead of drifting over time.
5
+ * shape. Every module that needs to know who leads a team asks here — the
6
+ * one rule (specs/2026-09-30-team-lead-rule.md):
7
+ *
8
+ * 1. the team's explicit `leaderIds` (or the deprecated `leaderId`), when
9
+ * at least one of them is still a member;
10
+ * 2. otherwise every member whose role is in
11
+ * {@link TEAM_LEAD_CONSTANTS.LEAD_ROLES} (`team-leader`, `tech-lead`).
12
+ *
13
+ * `canDelegate` is NOT part of the rule. It stays a separate "delegation
14
+ * authority" flag for the hierarchy (sub-leads with subordinates) and is the
15
+ * last-resort routing fallback of {@link pickTeamLead}. A rule lead always
16
+ * counts as able to delegate (see {@link canMemberDelegate}).
8
17
  *
9
18
  * @module utils/team.utils
10
19
  */
20
+ import { TEAM_LEAD_CONSTANTS } from '../constants.js';
11
21
  import type { Team, TeamMember } from '../types/index.js';
22
+ /** The team fields the lead rule reads. */
23
+ export type TeamLeadSource = {
24
+ members?: Array<Pick<TeamMember, 'id' | 'role'>>;
25
+ leaderIds?: string[];
26
+ leaderId?: string;
27
+ };
28
+ /** How {@link setTeamLead} changes the leads. */
29
+ export type SetTeamLeadMode = (typeof TEAM_LEAD_CONSTANTS.SET_LEAD_MODES)[number];
30
+ /**
31
+ * Whether a role is a lead role (used only when the team names no lead).
32
+ *
33
+ * @param role - Member role
34
+ * @returns True for `team-leader` / `tech-lead`
35
+ */
36
+ export declare function isLeadRole(role: string | undefined | null): boolean;
12
37
  /**
13
- * Choose the TL (Team Lead) responder for a team.
14
- *
15
- * Resolution rules (ordered, first match wins):
16
- * 1. Hierarchy TL: `hierarchyLevel === 1 && canDelegate === true`.
17
- * 2. Any delegator: `canDelegate === true` regardless of level. Covers
18
- * teams that were imported before hierarchy fields were added but
19
- * already have a flagged TL.
20
- * 3. Role-tagged TL: `role === 'team-leader'` so role-based teams that
21
- * didn't fill in `canDelegate` still resolve correctly.
22
- * 4. First member: deterministic last resort — better to dispatch to
23
- * _someone_ than silently drop a `@team` ping. Tests cover this
24
- * case. **Emits a warn-log (#332)** so operators see when team
25
- * hierarchy data is incomplete — silent rule-4 hits were
26
- * previously invisible.
38
+ * The ids of the members who lead a team — THE lead rule.
39
+ *
40
+ * @param team - Team
41
+ * @returns Lead member ids (explicit ones, else lead-role members); empty when the team has no lead
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * getTeamLeadIds({ members: [{ id: 'o', role: 'tech-lead' }, { id: 'n', role: 'developer' }] }); // ['o']
46
+ * getTeamLeadIds({ leaderIds: ['n'], members: [...] }); // ['n']
47
+ * ```
48
+ */
49
+ export declare function getTeamLeadIds(team: TeamLeadSource): string[];
50
+ /**
51
+ * Whether a member leads its team (see {@link getTeamLeadIds}).
52
+ *
53
+ * @param team - The member's team
54
+ * @param member - The member
55
+ * @returns True for a team lead
56
+ */
57
+ export declare function isTeamLead(team: TeamLeadSource, member: Pick<TeamMember, 'id'>): boolean;
58
+ /**
59
+ * The lead members of a team, in rule order.
60
+ *
61
+ * @param team - Team
62
+ * @returns Lead members (may be empty)
63
+ */
64
+ export declare function getTeamLeads(team: Team): TeamMember[];
65
+ /**
66
+ * Whether a member may delegate: a team lead by the rule, or a member the
67
+ * hierarchy flagged with `canDelegate` (a sub-lead of its subordinates).
68
+ * This is what lead-only prompt modules (TL addon, TL soul overlay, TL
69
+ * skills) and delegation checks key on, so a lead set by the rule gets them
70
+ * on its next wake without a separate flag.
71
+ *
72
+ * @param team - The member's team
73
+ * @param member - The member
74
+ * @returns True when the member may delegate
75
+ */
76
+ export declare function canMemberDelegate(team: TeamLeadSource, member: Pick<TeamMember, 'id' | 'canDelegate'>): boolean;
77
+ /**
78
+ * The members a delegating member directs: its `subordinateIds` (or the
79
+ * members naming it as parent); for a rule lead with neither, every other
80
+ * member that is not itself a lead and reports to nobody else.
81
+ *
82
+ * @param team - The member's team
83
+ * @param member - The member
84
+ * @returns Subordinate members (may be empty)
85
+ */
86
+ export declare function getLeadSubordinates(team: Team, member: TeamMember): TeamMember[];
87
+ /**
88
+ * Choose the ONE member to route "the team lead" traffic to.
89
+ *
90
+ * Resolution (first match wins):
91
+ * 1. A lead by the rule ({@link getTeamLeadIds}); among several, the one
92
+ * the hierarchy marks as top (`hierarchyLevel === 1 && canDelegate`),
93
+ * else the first.
94
+ * 2. Legacy routing fallback — a member flagged `canDelegate` (hierarchy
95
+ * data imported without `leaderIds` or a lead role). Not a lead by the
96
+ * rule; kept so escalations of such teams still reach someone.
97
+ * 3. First member — better to dispatch to _someone_ than silently drop a
98
+ * `@team` ping. **Emits a warn-log (#332)**.
27
99
  *
28
100
  * Returns `null` only when the team has no members at all.
29
101
  *
30
102
  * @param team - The matched team.
31
- * @returns The TL to dispatch to, or `null` when the team has no members.
103
+ * @returns The member to dispatch to, or `null` when the team has no members.
32
104
  *
33
105
  * @example
34
106
  * ```typescript
@@ -37,4 +109,43 @@ import type { Team, TeamMember } from '../types/index.js';
37
109
  * ```
38
110
  */
39
111
  export declare function pickTeamLead(team: Team): TeamMember | null;
112
+ /**
113
+ * Store the lead rule's answer on the team (idempotent migration, run on
114
+ * every load and save): a team with no usable explicit leads but with
115
+ * lead-role members gets `leaderIds` = those members; `leaderId` always
116
+ * mirrors `leaderIds[0]` for back-compat. The rule's answer never changes —
117
+ * only where it is stored. Dangling explicit ids (members since removed)
118
+ * are dropped when at least one explicit lead remains.
119
+ *
120
+ * @param team - Team (mutated)
121
+ * @returns True when the team changed
122
+ */
123
+ export declare function normalizeTeamLeaderIds(team: {
124
+ members?: Array<Pick<TeamMember, 'id' | 'role'>>;
125
+ leaderIds?: string[];
126
+ leaderId?: string;
127
+ }): boolean;
128
+ /**
129
+ * Make a member a lead of its team (`POST /api/teams/:id/lead`, the
130
+ * `set-team-lead` skill, the dashboard "Make lead" toggle).
131
+ *
132
+ * - `set` (default): the member becomes THE lead. Former leads lose the
133
+ * lead's delegation flag, and members that reported to a former lead now
134
+ * report to the new one.
135
+ * - `add`: the member joins the existing leads.
136
+ *
137
+ * The lead gets `canDelegate = true` (so the in-process delegation guard and
138
+ * hierarchy views agree) and `hierarchyLevel = 1` on hierarchical teams.
139
+ *
140
+ * @param team - Team (mutated)
141
+ * @param memberId - Member to make lead
142
+ * @param mode - `set` or `add`
143
+ * @returns The lead ids before and after
144
+ * @throws Error when the member is not on the team or is the orchestrator
145
+ */
146
+ export declare function setTeamLead(team: Team, memberId: string, mode?: SetTeamLeadMode): {
147
+ before: string[];
148
+ after: string[];
149
+ changed: boolean;
150
+ };
40
151
  //# sourceMappingURL=team.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"team.utils.d.ts","sourceRoot":"","sources":["../../../../../backend/src/utils/team.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAK1D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAyB1D"}
1
+ {"version":3,"file":"team.utils.d.ts","sourceRoot":"","sources":["../../../../../backend/src/utils/team.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkB1D,2CAA2C;AAC3C,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,iDAAiD;AACjD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,mBAAmB,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAElF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEnE;AAeD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAI7D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,OAAO,CAExF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,EAAE,CAIrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,aAAa,CAAC,GAAG,OAAO,CAE/G;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,CAkBhF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAwB1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAqBnJ;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,eAAuB,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAkChJ"}
@@ -2,34 +2,156 @@
2
2
  * Team utility helpers
3
3
  *
4
4
  * Shared, dependency-free helpers operating on the `Team` / `TeamMember`
5
- * shape. These are extracted here so multiple call sites (chat-v2 mention
6
- * resolver, mission OKR reminder service, …) can share a single canonical
7
- * implementation instead of drifting over time.
5
+ * shape. Every module that needs to know who leads a team asks here — the
6
+ * one rule (specs/2026-09-30-team-lead-rule.md):
7
+ *
8
+ * 1. the team's explicit `leaderIds` (or the deprecated `leaderId`), when
9
+ * at least one of them is still a member;
10
+ * 2. otherwise every member whose role is in
11
+ * {@link TEAM_LEAD_CONSTANTS.LEAD_ROLES} (`team-leader`, `tech-lead`).
12
+ *
13
+ * `canDelegate` is NOT part of the rule. It stays a separate "delegation
14
+ * authority" flag for the hierarchy (sub-leads with subordinates) and is the
15
+ * last-resort routing fallback of {@link pickTeamLead}. A rule lead always
16
+ * counts as able to delegate (see {@link canMemberDelegate}).
8
17
  *
9
18
  * @module utils/team.utils
10
19
  */
20
+ import { TEAM_LEAD_CONSTANTS } from '../constants.js';
11
21
  import { LoggerService } from '../services/core/logger.service.js';
12
- const logger = LoggerService.getInstance().createComponentLogger('TeamUtils');
13
22
  /**
14
- * Choose the TL (Team Lead) responder for a team.
15
- *
16
- * Resolution rules (ordered, first match wins):
17
- * 1. Hierarchy TL: `hierarchyLevel === 1 && canDelegate === true`.
18
- * 2. Any delegator: `canDelegate === true` regardless of level. Covers
19
- * teams that were imported before hierarchy fields were added but
20
- * already have a flagged TL.
21
- * 3. Role-tagged TL: `role === 'team-leader'` so role-based teams that
22
- * didn't fill in `canDelegate` still resolve correctly.
23
- * 4. First member: deterministic last resort — better to dispatch to
24
- * _someone_ than silently drop a `@team` ping. Tests cover this
25
- * case. **Emits a warn-log (#332)** so operators see when team
26
- * hierarchy data is incomplete — silent rule-4 hits were
27
- * previously invisible.
23
+ * The component logger, created on first use: this module is imported by
24
+ * storage and the Team model, and suites that mock LoggerService must be
25
+ * able to load it without a working logger.
26
+ *
27
+ * @returns The logger, or null when none is available
28
+ */
29
+ function teamLogger() {
30
+ try {
31
+ return LoggerService.getInstance()?.createComponentLogger('TeamUtils') ?? null;
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ /**
38
+ * Whether a role is a lead role (used only when the team names no lead).
39
+ *
40
+ * @param role - Member role
41
+ * @returns True for `team-leader` / `tech-lead`
42
+ */
43
+ export function isLeadRole(role) {
44
+ return TEAM_LEAD_CONSTANTS.LEAD_ROLES.includes(String(role ?? ''));
45
+ }
46
+ /**
47
+ * The explicit lead ids a team stores (`leaderIds`, else the legacy
48
+ * `leaderId`), limited to ids that are still members.
49
+ *
50
+ * @param team - Team
51
+ * @returns Explicit lead ids, in stored order (may be empty)
52
+ */
53
+ function explicitLeadIds(team) {
54
+ const memberIds = new Set((team.members ?? []).map((m) => m.id));
55
+ const stored = team.leaderIds && team.leaderIds.length > 0 ? team.leaderIds : team.leaderId ? [team.leaderId] : [];
56
+ return [...new Set(stored)].filter((id) => memberIds.has(id));
57
+ }
58
+ /**
59
+ * The ids of the members who lead a team — THE lead rule.
60
+ *
61
+ * @param team - Team
62
+ * @returns Lead member ids (explicit ones, else lead-role members); empty when the team has no lead
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * getTeamLeadIds({ members: [{ id: 'o', role: 'tech-lead' }, { id: 'n', role: 'developer' }] }); // ['o']
67
+ * getTeamLeadIds({ leaderIds: ['n'], members: [...] }); // ['n']
68
+ * ```
69
+ */
70
+ export function getTeamLeadIds(team) {
71
+ const explicit = explicitLeadIds(team);
72
+ if (explicit.length > 0)
73
+ return explicit;
74
+ return (team.members ?? []).filter((m) => isLeadRole(m.role)).map((m) => m.id);
75
+ }
76
+ /**
77
+ * Whether a member leads its team (see {@link getTeamLeadIds}).
78
+ *
79
+ * @param team - The member's team
80
+ * @param member - The member
81
+ * @returns True for a team lead
82
+ */
83
+ export function isTeamLead(team, member) {
84
+ return getTeamLeadIds(team).includes(member.id);
85
+ }
86
+ /**
87
+ * The lead members of a team, in rule order.
88
+ *
89
+ * @param team - Team
90
+ * @returns Lead members (may be empty)
91
+ */
92
+ export function getTeamLeads(team) {
93
+ const ids = getTeamLeadIds(team);
94
+ const members = team.members ?? [];
95
+ return ids.map((id) => members.find((m) => m.id === id)).filter((m) => !!m);
96
+ }
97
+ /**
98
+ * Whether a member may delegate: a team lead by the rule, or a member the
99
+ * hierarchy flagged with `canDelegate` (a sub-lead of its subordinates).
100
+ * This is what lead-only prompt modules (TL addon, TL soul overlay, TL
101
+ * skills) and delegation checks key on, so a lead set by the rule gets them
102
+ * on its next wake without a separate flag.
103
+ *
104
+ * @param team - The member's team
105
+ * @param member - The member
106
+ * @returns True when the member may delegate
107
+ */
108
+ export function canMemberDelegate(team, member) {
109
+ return member.canDelegate === true || isTeamLead(team, member);
110
+ }
111
+ /**
112
+ * The members a delegating member directs: its `subordinateIds` (or the
113
+ * members naming it as parent); for a rule lead with neither, every other
114
+ * member that is not itself a lead and reports to nobody else.
115
+ *
116
+ * @param team - The member's team
117
+ * @param member - The member
118
+ * @returns Subordinate members (may be empty)
119
+ */
120
+ export function getLeadSubordinates(team, member) {
121
+ const members = team.members ?? [];
122
+ const explicit = new Set([
123
+ ...(member.subordinateIds ?? []),
124
+ ...members.filter((m) => m.parentMemberId === member.id).map((m) => m.id),
125
+ ]);
126
+ explicit.delete(member.id);
127
+ if (explicit.size > 0)
128
+ return members.filter((m) => explicit.has(m.id));
129
+ if (!isTeamLead(team, member))
130
+ return [];
131
+ const leadIds = new Set(getTeamLeadIds(team));
132
+ const memberIds = new Set(members.map((m) => m.id));
133
+ return members.filter((m) => m.id !== member.id &&
134
+ !leadIds.has(m.id) &&
135
+ m.role !== 'orchestrator' &&
136
+ (!m.parentMemberId || m.parentMemberId === member.id || !memberIds.has(m.parentMemberId)));
137
+ }
138
+ /**
139
+ * Choose the ONE member to route "the team lead" traffic to.
140
+ *
141
+ * Resolution (first match wins):
142
+ * 1. A lead by the rule ({@link getTeamLeadIds}); among several, the one
143
+ * the hierarchy marks as top (`hierarchyLevel === 1 && canDelegate`),
144
+ * else the first.
145
+ * 2. Legacy routing fallback — a member flagged `canDelegate` (hierarchy
146
+ * data imported without `leaderIds` or a lead role). Not a lead by the
147
+ * rule; kept so escalations of such teams still reach someone.
148
+ * 3. First member — better to dispatch to _someone_ than silently drop a
149
+ * `@team` ping. **Emits a warn-log (#332)**.
28
150
  *
29
151
  * Returns `null` only when the team has no members at all.
30
152
  *
31
153
  * @param team - The matched team.
32
- * @returns The TL to dispatch to, or `null` when the team has no members.
154
+ * @returns The member to dispatch to, or `null` when the team has no members.
33
155
  *
34
156
  * @example
35
157
  * ```typescript
@@ -41,26 +163,116 @@ export function pickTeamLead(team) {
41
163
  const members = team.members ?? [];
42
164
  if (members.length === 0)
43
165
  return null;
166
+ const leads = getTeamLeads(team);
167
+ if (leads.length > 0) {
168
+ return leads.find((m) => m.hierarchyLevel === 1 && m.canDelegate === true) ?? leads[0];
169
+ }
44
170
  const hierarchyTl = members.find((m) => m.hierarchyLevel === 1 && m.canDelegate === true);
45
171
  if (hierarchyTl)
46
172
  return hierarchyTl;
47
173
  const anyDelegator = members.find((m) => m.canDelegate === true);
48
174
  if (anyDelegator)
49
175
  return anyDelegator;
50
- const roleTl = members.find((m) => m.role === 'team-leader');
51
- if (roleTl)
52
- return roleTl;
53
- // Issue #332: rule-4 fallback — emit a warn so the missing hierarchy
54
- // data surfaces in observability instead of being invisible. The
55
- // resolver still returns a member so `@team` pings don't silently
56
- // drop, but the team owner should fix the underlying hierarchy gap.
57
- logger.warn('pickTeamLead falling back to first member — team has no canDelegate / team-leader marker', {
176
+ // Issue #332: rule-3 fallback — emit a warn so the missing lead surfaces
177
+ // in observability instead of being invisible.
178
+ teamLogger()?.warn('pickTeamLead falling back to first member — team has no lead (set one with set-team-lead)', {
58
179
  teamId: team.id,
59
180
  teamName: team.name,
60
181
  chosenMemberId: members[0].id,
61
182
  memberCount: members.length,
62
- reason: 'no TL markers — falling back to first member',
183
+ reason: 'no leaderIds and no team-leader / tech-lead member',
63
184
  });
64
185
  return members[0];
65
186
  }
187
+ /**
188
+ * Store the lead rule's answer on the team (idempotent migration, run on
189
+ * every load and save): a team with no usable explicit leads but with
190
+ * lead-role members gets `leaderIds` = those members; `leaderId` always
191
+ * mirrors `leaderIds[0]` for back-compat. The rule's answer never changes —
192
+ * only where it is stored. Dangling explicit ids (members since removed)
193
+ * are dropped when at least one explicit lead remains.
194
+ *
195
+ * @param team - Team (mutated)
196
+ * @returns True when the team changed
197
+ */
198
+ export function normalizeTeamLeaderIds(team) {
199
+ const ids = getTeamLeadIds(team);
200
+ if (ids.length === 0) {
201
+ // Nothing the rule can use (no member matches). Keep what is stored and
202
+ // only keep the two fields in sync, as before the rule existed.
203
+ if (team.leaderIds && team.leaderIds.length > 0) {
204
+ if (team.leaderId === team.leaderIds[0])
205
+ return false;
206
+ team.leaderId = team.leaderIds[0];
207
+ return true;
208
+ }
209
+ if (team.leaderId && !team.leaderIds) {
210
+ team.leaderIds = [team.leaderId];
211
+ return true;
212
+ }
213
+ return false;
214
+ }
215
+ const same = team.leaderIds?.length === ids.length && ids.every((id, i) => team.leaderIds?.[i] === id) && team.leaderId === ids[0];
216
+ if (same)
217
+ return false;
218
+ team.leaderIds = ids;
219
+ team.leaderId = ids[0];
220
+ return true;
221
+ }
222
+ /**
223
+ * Make a member a lead of its team (`POST /api/teams/:id/lead`, the
224
+ * `set-team-lead` skill, the dashboard "Make lead" toggle).
225
+ *
226
+ * - `set` (default): the member becomes THE lead. Former leads lose the
227
+ * lead's delegation flag, and members that reported to a former lead now
228
+ * report to the new one.
229
+ * - `add`: the member joins the existing leads.
230
+ *
231
+ * The lead gets `canDelegate = true` (so the in-process delegation guard and
232
+ * hierarchy views agree) and `hierarchyLevel = 1` on hierarchical teams.
233
+ *
234
+ * @param team - Team (mutated)
235
+ * @param memberId - Member to make lead
236
+ * @param mode - `set` or `add`
237
+ * @returns The lead ids before and after
238
+ * @throws Error when the member is not on the team or is the orchestrator
239
+ */
240
+ export function setTeamLead(team, memberId, mode = 'set') {
241
+ const members = team.members ?? [];
242
+ const lead = members.find((m) => m.id === memberId);
243
+ if (!lead)
244
+ throw new Error(`Member ${memberId} is not on team ${team.name}`);
245
+ if (lead.role === 'orchestrator')
246
+ throw new Error('The orchestrator cannot lead a team');
247
+ const before = getTeamLeadIds(team);
248
+ const after = mode === 'add' ? [...new Set([...before, memberId])] : [memberId];
249
+ const former = new Set(before.filter((id) => !after.includes(id)));
250
+ team.leaderIds = after;
251
+ team.leaderId = after[0];
252
+ lead.canDelegate = true;
253
+ if (team.hierarchical)
254
+ lead.hierarchyLevel = 1;
255
+ if (mode === 'set')
256
+ lead.parentMemberId = undefined;
257
+ for (const m of members) {
258
+ if (m.id === memberId)
259
+ continue;
260
+ if (former.has(m.id)) {
261
+ m.canDelegate = false;
262
+ m.subordinateIds = [];
263
+ if (team.hierarchical) {
264
+ m.hierarchyLevel = 2;
265
+ m.parentMemberId = memberId;
266
+ }
267
+ }
268
+ else if (m.parentMemberId && former.has(m.parentMemberId)) {
269
+ m.parentMemberId = memberId;
270
+ }
271
+ }
272
+ const reports = members.filter((m) => m.parentMemberId === memberId && m.id !== memberId).map((m) => m.id);
273
+ if (reports.length > 0 || lead.subordinateIds)
274
+ lead.subordinateIds = reports;
275
+ const changed = before.length !== after.length || before.some((id, i) => after[i] !== id);
276
+ return { before, after, changed };
277
+ }
66
278
  //# sourceMappingURL=team.utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"team.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/team.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAEnE,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IAC1F,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IACjE,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IAEtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;IAC7D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,qEAAqE;IACrE,iEAAiE;IACjE,kEAAkE;IAClE,oEAAoE;IACpE,MAAM,CAAC,IAAI,CAAC,0FAA0F,EAAE;QACtG,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,QAAQ,EAAE,IAAI,CAAC,IAAI;QACnB,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;QAC7B,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,MAAM,EAAE,8CAA8C;KACvD,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"team.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/team.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAEnE;;;;;;GAMG;AACH,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,OAAO,aAAa,CAAC,WAAW,EAAE,EAAE,qBAAqB,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAYD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAA+B;IACxD,OAAQ,mBAAmB,CAAC,UAAgC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,IAAoB;IAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnH,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,IAAoB;IACjD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACjF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAoB,EAAE,MAA8B;IAC7E,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAoB,EAAE,MAA8C;IACpG,OAAO,MAAM,CAAC,WAAW,KAAK,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAU,EAAE,MAAkB;IAChE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS;QAC/B,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;QAChC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1E,CAAC,CAAC;IACH,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxE,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC,MAAM,CACnB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE;QAClB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,CAAC,CAAC,IAAI,KAAK,cAAc;QACzB,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,cAAc,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAC5F,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IAC1F,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IACjE,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IAEtC,yEAAyE;IACzE,+CAA+C;IAC/C,UAAU,EAAE,EAAE,IAAI,CAAC,2FAA2F,EAAE;QAC9G,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,QAAQ,EAAE,IAAI,CAAC,IAAI;QACnB,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;QAC7B,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,MAAM,EAAE,oDAAoD;KAC7D,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAmG;IACxI,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,wEAAwE;QACxE,gEAAgE;QAChE,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChD,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;YACtD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACnI,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IACvB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;IACrB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,WAAW,CAAC,IAAU,EAAE,QAAgB,EAAE,OAAwB,KAAK;IACrF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,QAAQ,mBAAmB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7E,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAEzF,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEnE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACvB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACxB,IAAI,IAAI,CAAC,YAAY;QAAE,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;IAC/C,IAAI,IAAI,KAAK,KAAK;QAAE,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAEpD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,EAAE,KAAK,QAAQ;YAAE,SAAS;QAChC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YACrB,CAAC,CAAC,WAAW,GAAG,KAAK,CAAC;YACtB,CAAC,CAAC,cAAc,GAAG,EAAE,CAAC;YACtB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC;gBACrB,CAAC,CAAC,cAAc,GAAG,QAAQ,CAAC;YAC9B,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,CAAC,cAAc,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC;YAC5D,CAAC,CAAC,cAAc,GAAG,QAAQ,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3G,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc;QAAE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;IAE7E,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1F,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC"}