crewly 1.16.0 → 1.17.1

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 (200) hide show
  1. package/README.md +33 -1
  2. package/config/roles/orchestrator/prompt.md +20 -5
  3. package/config/skills/agent/core/calendar-create/SKILL.md +62 -0
  4. package/config/skills/agent/core/calendar-create/execute.sh +91 -0
  5. package/config/skills/agent/core/calendar-create/execute.test.sh +80 -0
  6. package/config/skills/agent/core/calendar-list/SKILL.md +58 -0
  7. package/config/skills/agent/core/calendar-list/execute.sh +88 -0
  8. package/config/skills/agent/core/calendar-list/execute.test.sh +71 -0
  9. package/config/skills/agent/core/gmail-read/SKILL.md +61 -0
  10. package/config/skills/agent/core/gmail-read/execute.sh +62 -0
  11. package/config/skills/agent/core/gmail-read/execute.test.sh +68 -0
  12. package/config/skills/agent/core/gmail-search/SKILL.md +64 -0
  13. package/config/skills/agent/core/gmail-search/execute.sh +70 -0
  14. package/config/skills/agent/core/gmail-search/execute.test.sh +67 -0
  15. package/config/skills/agent/core/gmail-send/SKILL.md +69 -0
  16. package/config/skills/agent/core/gmail-send/execute.sh +114 -0
  17. package/config/skills/agent/core/gmail-send/execute.test.sh +83 -0
  18. package/config/skills/orchestrator/list-missions/SKILL.md +47 -0
  19. package/config/skills/orchestrator/list-missions/execute.sh +34 -0
  20. package/config/skills/orchestrator/list-missions/execute.test.sh +33 -0
  21. package/config/slack-master-app-manifest.json +64 -0
  22. package/dist/backend/backend/src/constants.d.ts +125 -0
  23. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  24. package/dist/backend/backend/src/constants.js +125 -0
  25. package/dist/backend/backend/src/constants.js.map +1 -1
  26. package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
  27. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +3 -1
  28. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
  29. package/dist/backend/backend/src/controllers/google/google.controller.d.ts +100 -0
  30. package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -0
  31. package/dist/backend/backend/src/controllers/google/google.controller.js +293 -0
  32. package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -0
  33. package/dist/backend/backend/src/controllers/google/google.routes.d.ts +26 -0
  34. package/dist/backend/backend/src/controllers/google/google.routes.d.ts.map +1 -0
  35. package/dist/backend/backend/src/controllers/google/google.routes.js +38 -0
  36. package/dist/backend/backend/src/controllers/google/google.routes.js.map +1 -0
  37. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  38. package/dist/backend/backend/src/controllers/slack/slack.controller.js +209 -2
  39. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  40. package/dist/backend/backend/src/index.d.ts.map +1 -1
  41. package/dist/backend/backend/src/index.js +58 -8
  42. package/dist/backend/backend/src/index.js.map +1 -1
  43. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  44. package/dist/backend/backend/src/routes/api.routes.js +4 -0
  45. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  46. package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts +8 -0
  47. package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/cloud/cloud-initializer.js +25 -0
  49. package/dist/backend/backend/src/services/cloud/cloud-initializer.js.map +1 -1
  50. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
  51. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
  52. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +1 -0
  53. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
  54. package/dist/backend/backend/src/services/core/crewly-home.utils.d.ts +49 -0
  55. package/dist/backend/backend/src/services/core/crewly-home.utils.d.ts.map +1 -1
  56. package/dist/backend/backend/src/services/core/crewly-home.utils.js +86 -0
  57. package/dist/backend/backend/src/services/core/crewly-home.utils.js.map +1 -1
  58. package/dist/backend/backend/src/services/google/calendar.service.d.ts +98 -0
  59. package/dist/backend/backend/src/services/google/calendar.service.d.ts.map +1 -0
  60. package/dist/backend/backend/src/services/google/calendar.service.js +125 -0
  61. package/dist/backend/backend/src/services/google/calendar.service.js.map +1 -0
  62. package/dist/backend/backend/src/services/google/gmail.service.d.ts +165 -0
  63. package/dist/backend/backend/src/services/google/gmail.service.d.ts.map +1 -0
  64. package/dist/backend/backend/src/services/google/gmail.service.js +296 -0
  65. package/dist/backend/backend/src/services/google/gmail.service.js.map +1 -0
  66. package/dist/backend/backend/src/services/google/google-api.client.d.ts +44 -0
  67. package/dist/backend/backend/src/services/google/google-api.client.d.ts.map +1 -0
  68. package/dist/backend/backend/src/services/google/google-api.client.js +104 -0
  69. package/dist/backend/backend/src/services/google/google-api.client.js.map +1 -0
  70. package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts +159 -0
  71. package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts.map +1 -0
  72. package/dist/backend/backend/src/services/google/google-workspace-token.service.js +274 -0
  73. package/dist/backend/backend/src/services/google/google-workspace-token.service.js.map +1 -0
  74. package/dist/backend/backend/src/services/memory/mission-context.service.d.ts.map +1 -1
  75. package/dist/backend/backend/src/services/memory/mission-context.service.js +2 -1
  76. package/dist/backend/backend/src/services/memory/mission-context.service.js.map +1 -1
  77. package/dist/backend/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  78. package/dist/backend/backend/src/services/memory/project-memory.service.js +3 -2
  79. package/dist/backend/backend/src/services/memory/project-memory.service.js.map +1 -1
  80. package/dist/backend/backend/src/services/memory/session-memory.service.d.ts.map +1 -1
  81. package/dist/backend/backend/src/services/memory/session-memory.service.js +2 -1
  82. package/dist/backend/backend/src/services/memory/session-memory.service.js.map +1 -1
  83. package/dist/backend/backend/src/services/project/task.service.d.ts.map +1 -1
  84. package/dist/backend/backend/src/services/project/task.service.js +2 -3
  85. package/dist/backend/backend/src/services/project/task.service.js.map +1 -1
  86. package/dist/backend/backend/src/services/project/ticket-editor.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/project/ticket-editor.service.js +2 -3
  88. package/dist/backend/backend/src/services/project/ticket-editor.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.d.ts +12 -1
  90. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.js +30 -0
  92. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.js.map +1 -1
  93. package/dist/backend/backend/src/services/slack/slack-cloud-config.service.d.ts +186 -0
  94. package/dist/backend/backend/src/services/slack/slack-cloud-config.service.d.ts.map +1 -0
  95. package/dist/backend/backend/src/services/slack/slack-cloud-config.service.js +409 -0
  96. package/dist/backend/backend/src/services/slack/slack-cloud-config.service.js.map +1 -0
  97. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts +95 -1
  98. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  99. package/dist/backend/backend/src/services/slack/slack-initializer.js +284 -4
  100. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  101. package/dist/backend/backend/src/services/slack/slack-instance-registry.service.d.ts +178 -0
  102. package/dist/backend/backend/src/services/slack/slack-instance-registry.service.d.ts.map +1 -0
  103. package/dist/backend/backend/src/services/slack/slack-instance-registry.service.js +392 -0
  104. package/dist/backend/backend/src/services/slack/slack-instance-registry.service.js.map +1 -0
  105. package/dist/backend/backend/src/services/slack/slack.service.d.ts +76 -1
  106. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/slack/slack.service.js +234 -47
  108. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  109. package/dist/backend/backend/src/services/v3/escalation-router.service.d.ts.map +1 -1
  110. package/dist/backend/backend/src/services/v3/escalation-router.service.js +2 -1
  111. package/dist/backend/backend/src/services/v3/escalation-router.service.js.map +1 -1
  112. package/dist/backend/backend/src/services/v3/mission-paths.d.ts +17 -0
  113. package/dist/backend/backend/src/services/v3/mission-paths.d.ts.map +1 -1
  114. package/dist/backend/backend/src/services/v3/mission-paths.js +21 -2
  115. package/dist/backend/backend/src/services/v3/mission-paths.js.map +1 -1
  116. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +4 -0
  117. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -1
  118. package/dist/backend/backend/src/services/v3/mission-reminder.service.js +17 -0
  119. package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -1
  120. package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.d.ts +116 -0
  121. package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.d.ts.map +1 -0
  122. package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.js +254 -0
  123. package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.js.map +1 -0
  124. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  125. package/dist/backend/backend/src/services/v3/request.service.js +2 -1
  126. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  127. package/dist/backend/backend/src/services/v3/task-projection.service.d.ts.map +1 -1
  128. package/dist/backend/backend/src/services/v3/task-projection.service.js +2 -1
  129. package/dist/backend/backend/src/services/v3/task-projection.service.js.map +1 -1
  130. package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts.map +1 -1
  131. package/dist/backend/backend/src/services/v3/trigger-engine.service.js +2 -1
  132. package/dist/backend/backend/src/services/v3/trigger-engine.service.js.map +1 -1
  133. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  134. package/dist/backend/backend/src/services/v3/v3-data.service.js +2 -1
  135. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  136. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts.map +1 -1
  137. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js +6 -1
  138. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js.map +1 -1
  139. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.d.ts.map +1 -1
  140. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js +3 -1
  141. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js.map +1 -1
  142. package/dist/backend/backend/src/types/slack.types.d.ts +141 -2
  143. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  144. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  145. package/dist/backend/backend/src/types/v2/mission.types.d.ts +2 -0
  146. package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
  147. package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
  148. package/dist/backend/build-info.json +2 -2
  149. package/dist/cli/backend/src/constants.d.ts +125 -0
  150. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  151. package/dist/cli/backend/src/constants.js +125 -0
  152. package/dist/cli/backend/src/constants.js.map +1 -1
  153. package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
  154. package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
  155. package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +1 -0
  156. package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
  157. package/dist/cli/backend/src/services/core/crewly-home.utils.d.ts +49 -0
  158. package/dist/cli/backend/src/services/core/crewly-home.utils.d.ts.map +1 -1
  159. package/dist/cli/backend/src/services/core/crewly-home.utils.js +86 -0
  160. package/dist/cli/backend/src/services/core/crewly-home.utils.js.map +1 -1
  161. package/dist/cli/backend/src/services/memory/mission-context.service.d.ts.map +1 -1
  162. package/dist/cli/backend/src/services/memory/mission-context.service.js +2 -1
  163. package/dist/cli/backend/src/services/memory/mission-context.service.js.map +1 -1
  164. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  165. package/dist/cli/backend/src/services/memory/project-memory.service.js +3 -2
  166. package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -1
  167. package/dist/cli/backend/src/services/memory/session-memory.service.d.ts.map +1 -1
  168. package/dist/cli/backend/src/services/memory/session-memory.service.js +2 -1
  169. package/dist/cli/backend/src/services/memory/session-memory.service.js.map +1 -1
  170. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.d.ts +12 -1
  171. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.d.ts.map +1 -1
  172. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.js +30 -0
  173. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.js.map +1 -1
  174. package/dist/cli/backend/src/services/slack/slack.service.d.ts +76 -1
  175. package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
  176. package/dist/cli/backend/src/services/slack/slack.service.js +234 -47
  177. package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
  178. package/dist/cli/backend/src/services/v3/escalation-router.service.d.ts.map +1 -1
  179. package/dist/cli/backend/src/services/v3/escalation-router.service.js +2 -1
  180. package/dist/cli/backend/src/services/v3/escalation-router.service.js.map +1 -1
  181. package/dist/cli/backend/src/services/v3/mission-paths.d.ts +17 -0
  182. package/dist/cli/backend/src/services/v3/mission-paths.d.ts.map +1 -1
  183. package/dist/cli/backend/src/services/v3/mission-paths.js +21 -2
  184. package/dist/cli/backend/src/services/v3/mission-paths.js.map +1 -1
  185. package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -1
  186. package/dist/cli/backend/src/services/v3/request.service.js +2 -1
  187. package/dist/cli/backend/src/services/v3/request.service.js.map +1 -1
  188. package/dist/cli/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  189. package/dist/cli/backend/src/services/v3/v3-data.service.js +2 -1
  190. package/dist/cli/backend/src/services/v3/v3-data.service.js.map +1 -1
  191. package/dist/cli/backend/src/types/slack.types.d.ts +141 -2
  192. package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
  193. package/dist/cli/backend/src/types/slack.types.js.map +1 -1
  194. package/dist/cli/backend/src/types/v2/mission.types.d.ts +2 -0
  195. package/dist/cli/backend/src/types/v2/mission.types.d.ts.map +1 -1
  196. package/dist/cli/backend/src/types/v2/mission.types.js.map +1 -1
  197. package/frontend/dist/assets/{index-019817e2.js → index-c87332bf.js} +273 -273
  198. package/frontend/dist/assets/{index-a56613e7.css → index-f6b4230e.css} +1 -1
  199. package/frontend/dist/index.html +2 -2
  200. package/package.json +1 -1
@@ -6,8 +6,17 @@
6
6
  *
7
7
  * @module services/slack/initializer
8
8
  */
9
- import { SlackConfig } from '../../types/slack.types.js';
9
+ import { SlackCloudConfigService } from './slack-cloud-config.service.js';
10
+ import { SlackInstanceRegistryService } from './slack-instance-registry.service.js';
11
+ import { SlackConfig, SlackCloudConfig } from '../../types/slack.types.js';
10
12
  import type { MessageQueueService } from '../messaging/message-queue.service.js';
13
+ /** Where the active Slack connection's tokens came from. */
14
+ export type SlackSource = 'env' | 'cloud';
15
+ /** A config together with its provenance. */
16
+ export interface ResolvedSlackConfig {
17
+ config: SlackConfig;
18
+ source: SlackSource;
19
+ }
11
20
  /**
12
21
  * Result of initialization attempt
13
22
  */
@@ -38,6 +47,37 @@ export declare function getSlackConfigFromEnv(): SlackConfig | null;
38
47
  * @returns SlackConfig object or null if not configured
39
48
  */
40
49
  export declare function getSlackConfig(): Promise<SlackConfig | null>;
50
+ /**
51
+ * Build (once) the Cloud config service on top of the Cloud client.
52
+ *
53
+ * @returns The process-wide SlackCloudConfigService
54
+ */
55
+ export declare function ensureSlackCloudConfigService(): Promise<SlackCloudConfigService>;
56
+ /**
57
+ * Pick the Slack config to connect with, applying the source precedence:
58
+ *
59
+ * - `CREWLY_SLACK_SOURCE=env` → local tokens only (env / credentials file);
60
+ * - `CREWLY_SLACK_SOURCE=cloud` → the Cloud-owned workspace only;
61
+ * - unset → Cloud when the account has a workspace
62
+ * installed, otherwise local tokens. When both exist Cloud wins and this
63
+ * is logged once so the migration is visible.
64
+ *
65
+ * @returns The config and where it came from, or null when nothing is set up
66
+ */
67
+ export declare function resolveSlackConfig(): Promise<ResolvedSlackConfig | null>;
68
+ /**
69
+ * The source of the live Slack connection.
70
+ *
71
+ * @returns `env`, `cloud`, or null when Slack is not connected
72
+ */
73
+ export declare function getActiveSlackSource(): SlackSource | null;
74
+ /**
75
+ * Record the source of a connection made outside {@link connectSlack}
76
+ * (the manual `/api/slack/connect` route).
77
+ *
78
+ * @param source - The source, or null after a disconnect
79
+ */
80
+ export declare function setActiveSlackSource(source: SlackSource | null): void;
41
81
  /**
42
82
  * Options for Slack initialization
43
83
  */
@@ -70,6 +110,60 @@ export interface SlackInitOptions {
70
110
  * ```
71
111
  */
72
112
  export declare function initializeSlackIfConfigured(options?: SlackInitOptions): Promise<SlackInitResult>;
113
+ /**
114
+ * Connect SlackService with a resolved config and bring up the bridge, team
115
+ * channels and — for the Cloud source — the relay transport, the identities
116
+ * from the Cloud config and the instance registry.
117
+ *
118
+ * @param resolved - Config + source
119
+ * @param options - Init options (message queue)
120
+ * @returns Result object indicating success or failure
121
+ */
122
+ export declare function connectSlack(resolved: ResolvedSlackConfig, options?: SlackInitOptions): Promise<SlackInitResult>;
123
+ /**
124
+ * Build (once) the instance registry service without starting it — the
125
+ * primary toggle needs it even before Slack is connected.
126
+ *
127
+ * @returns The process-wide SlackInstanceRegistryService
128
+ */
129
+ export declare function ensureSlackInstanceRegistry(): Promise<SlackInstanceRegistryService>;
130
+ /**
131
+ * Build (once) and start the instance registry heartbeat. Never throws.
132
+ *
133
+ * @returns The registry service, or null when its dependencies are missing
134
+ */
135
+ export declare function startSlackInstanceRegistry(): Promise<SlackInstanceRegistryService | null>;
136
+ /**
137
+ * Subscribe to Cloud config changes and start the 10-minute refresh (unless
138
+ * `CREWLY_SLACK_SOURCE=env`). Idempotent.
139
+ */
140
+ export declare function watchSlackCloudConfig(): Promise<void>;
141
+ /**
142
+ * React to the Cloud config appearing, rotating or disappearing:
143
+ *
144
+ * - appeared and Slack is not connected → connect with the cloud source;
145
+ * - changed while connected via Cloud → re-initialise with the new token
146
+ * and merge new identities;
147
+ * - removed while connected via Cloud → disconnect.
148
+ *
149
+ * A live self-hosted (`env`) connection is left alone; precedence is only
150
+ * applied at boot so a running socket is never yanked under the owner.
151
+ *
152
+ * @param config - The new Cloud config (null when removed)
153
+ */
154
+ export declare function handleSlackCloudConfigChange(config: SlackCloudConfig | null): Promise<void>;
155
+ /**
156
+ * Called once Cloud is signed in (boot restore or the login route — both
157
+ * happen after the Slack boot path ran): fetch the Cloud config now instead
158
+ * of waiting for the 10-minute tick, connect if a workspace exists and
159
+ * Slack is down, and re-register the instance now that a relay queue may
160
+ * exist. Never throws.
161
+ */
162
+ export declare function refreshSlackCloudConfig(): Promise<void>;
163
+ /**
164
+ * Reset module state (tests).
165
+ */
166
+ export declare function resetSlackInitializerState(): void;
73
167
  /**
74
168
  * Wire and start the Slack team-channel service (one Slack channel + one
75
169
  * chat-v2 huddle per team). Idempotent — safe to call from both the boot
@@ -1 +1 @@
1
- {"version":3,"file":"slack-initializer.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAKjF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,GAAG,IAAI,CAiB1D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqBlE;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CA8B1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAqD5D;AAED;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAUnD"}
1
+ {"version":3,"file":"slack-initializer.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EACL,uBAAuB,EAGxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,4BAA4B,EAG7B,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAKjF,4DAA4D;AAC5D,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,OAAO,CAAC;AAE1C,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;CACrB;AASD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,GAAG,IAAI,CAiB1D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqBlE;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAQtF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAsB9E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,WAAW,GAAG,IAAI,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAErE;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CAc1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CAkC1B;AAoCD;;;;;GAKG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAoBzF;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAW/F;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAS3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,4BAA4B,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCjG;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB7D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CASjD;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAqD5D;AAED;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAanD"}
@@ -9,8 +9,18 @@
9
9
  import { getSlackService } from './slack.service.js';
10
10
  import { getSlackOrchestratorBridge } from './slack-orchestrator-bridge.js';
11
11
  import { loadSlackCredentials } from './slack-credentials.service.js';
12
+ import { SlackCloudConfigService, getSlackCloudConfigService, setSlackCloudConfigService, } from './slack-cloud-config.service.js';
13
+ import { SlackInstanceRegistryService, getSlackInstanceRegistryService, setSlackInstanceRegistryService, } from './slack-instance-registry.service.js';
14
+ import { getSlackAgentIdentityService } from './slack-agent-identity.service.js';
15
+ import { getSlackTeamChannelService } from './slack-team-channel.service.js';
12
16
  import { LoggerService } from '../core/logger.service.js';
13
17
  const logger = LoggerService.getInstance().createComponentLogger('SlackInitializer');
18
+ /** Source of the connection currently held by SlackService (null = none). */
19
+ let activeSource = null;
20
+ /** Unsubscribe for the Cloud config watch. */
21
+ let unsubscribeCloudConfig = null;
22
+ /** Init options captured at boot so a later Cloud-triggered connect gets the queue. */
23
+ let bootOptions;
14
24
  /**
15
25
  * Check if Slack is configured via environment variables
16
26
  *
@@ -69,6 +79,67 @@ export async function getSlackConfig() {
69
79
  }
70
80
  return null;
71
81
  }
82
+ /**
83
+ * Build (once) the Cloud config service on top of the Cloud client.
84
+ *
85
+ * @returns The process-wide SlackCloudConfigService
86
+ */
87
+ export async function ensureSlackCloudConfigService() {
88
+ let service = getSlackCloudConfigService();
89
+ if (!service) {
90
+ const { CloudClientService } = await import('../cloud/cloud-client.service.js');
91
+ service = new SlackCloudConfigService({ cloud: CloudClientService.getInstance() });
92
+ setSlackCloudConfigService(service);
93
+ }
94
+ return service;
95
+ }
96
+ /**
97
+ * Pick the Slack config to connect with, applying the source precedence:
98
+ *
99
+ * - `CREWLY_SLACK_SOURCE=env` → local tokens only (env / credentials file);
100
+ * - `CREWLY_SLACK_SOURCE=cloud` → the Cloud-owned workspace only;
101
+ * - unset → Cloud when the account has a workspace
102
+ * installed, otherwise local tokens. When both exist Cloud wins and this
103
+ * is logged once so the migration is visible.
104
+ *
105
+ * @returns The config and where it came from, or null when nothing is set up
106
+ */
107
+ export async function resolveSlackConfig() {
108
+ const cloudConfigService = await ensureSlackCloudConfigService();
109
+ const mode = cloudConfigService.getSourceMode();
110
+ const local = mode === 'cloud' ? null : await getSlackConfig();
111
+ let cloud = null;
112
+ if (mode !== 'env') {
113
+ await cloudConfigService.loadOrRefresh();
114
+ cloud = cloudConfigService.toSlackConfig();
115
+ }
116
+ if (cloud) {
117
+ if (local) {
118
+ logger.info('Both local Slack tokens and a Cloud-owned workspace are present — using Crewly Cloud. Set CREWLY_SLACK_SOURCE=env to keep the self-hosted app.');
119
+ }
120
+ return { config: cloud, source: 'cloud' };
121
+ }
122
+ if (local)
123
+ return { config: local, source: 'env' };
124
+ return null;
125
+ }
126
+ /**
127
+ * The source of the live Slack connection.
128
+ *
129
+ * @returns `env`, `cloud`, or null when Slack is not connected
130
+ */
131
+ export function getActiveSlackSource() {
132
+ return activeSource;
133
+ }
134
+ /**
135
+ * Record the source of a connection made outside {@link connectSlack}
136
+ * (the manual `/api/slack/connect` route).
137
+ *
138
+ * @param source - The source, or null after a disconnect
139
+ */
140
+ export function setActiveSlackSource(source) {
141
+ activeSource = source;
142
+ }
72
143
  /**
73
144
  * Initialize Slack integration if configured via environment variables
74
145
  * or saved credentials.
@@ -94,14 +165,34 @@ export async function getSlackConfig() {
94
165
  * ```
95
166
  */
96
167
  export async function initializeSlackIfConfigured(options) {
97
- const config = await getSlackConfig();
98
- if (!config) {
168
+ bootOptions = options;
169
+ const resolved = await resolveSlackConfig();
170
+ // Keep watching Cloud: a workspace connected later from Settings (or on
171
+ // another machine) lights this instance up without a restart.
172
+ await watchSlackCloudConfig();
173
+ if (!resolved) {
99
174
  logger.info('Not configured - skipping initialization');
100
175
  return { attempted: false, success: false };
101
176
  }
177
+ return connectSlack(resolved, options);
178
+ }
179
+ /**
180
+ * Connect SlackService with a resolved config and bring up the bridge, team
181
+ * channels and — for the Cloud source — the relay transport, the identities
182
+ * from the Cloud config and the instance registry.
183
+ *
184
+ * @param resolved - Config + source
185
+ * @param options - Init options (message queue)
186
+ * @returns Result object indicating success or failure
187
+ */
188
+ export async function connectSlack(resolved, options) {
189
+ const { config, source } = resolved;
102
190
  try {
103
191
  const slackService = getSlackService();
104
192
  await slackService.initialize(config);
193
+ if (source === 'cloud') {
194
+ await attachSlackCloudTransport();
195
+ }
105
196
  const bridge = getSlackOrchestratorBridge();
106
197
  // Set the message queue service if provided
107
198
  if (options?.messageQueueService) {
@@ -109,15 +200,201 @@ export async function initializeSlackIfConfigured(options) {
109
200
  }
110
201
  await bridge.initialize();
111
202
  await startSlackTeamChannels();
112
- logger.info('Successfully connected');
203
+ if (source === 'cloud') {
204
+ await applyCloudIdentities();
205
+ await startSlackInstanceRegistry();
206
+ }
207
+ activeSource = source;
208
+ logger.info('Successfully connected', { source, transport: slackService.getTransport() });
113
209
  return { attempted: true, success: true };
114
210
  }
115
211
  catch (error) {
116
212
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
117
- logger.error('Failed to initialize', { error: errorMessage });
213
+ logger.error('Failed to initialize', { error: errorMessage, source });
118
214
  return { attempted: true, success: false, error: errorMessage };
119
215
  }
120
216
  }
217
+ /**
218
+ * Route `slack_event` relay messages from CloudSyncService into SlackService
219
+ * (the cloud inbound transport). Non-fatal when Cloud Sync is not running —
220
+ * events simply cannot arrive until it is.
221
+ */
222
+ async function attachSlackCloudTransport() {
223
+ try {
224
+ const { CloudSyncService } = await import('../cloud/cloud-sync.service.js');
225
+ getSlackService().attachCloudTransport(CloudSyncService.getInstance());
226
+ }
227
+ catch (error) {
228
+ logger.warn('Could not attach the Cloud Slack transport — inbound Slack events will not arrive', {
229
+ error: error instanceof Error ? error.message : String(error),
230
+ });
231
+ }
232
+ }
233
+ /**
234
+ * Feed the per-agent identities delivered with the Cloud config into the
235
+ * identity service (installed bot users, tokens included).
236
+ */
237
+ async function applyCloudIdentities() {
238
+ const cloudConfigService = getSlackCloudConfigService();
239
+ const identities = getSlackAgentIdentityService();
240
+ if (!cloudConfigService || !identities)
241
+ return;
242
+ try {
243
+ const added = await identities.applyCloudConfig(cloudConfigService.getAgents());
244
+ if (added > 0)
245
+ logger.info('Agent identities installed from Cloud config', { added });
246
+ }
247
+ catch (error) {
248
+ logger.warn('Could not apply agent identities from Cloud config', {
249
+ error: error instanceof Error ? error.message : String(error),
250
+ });
251
+ }
252
+ }
253
+ /**
254
+ * Build (once) the instance registry service without starting it — the
255
+ * primary toggle needs it even before Slack is connected.
256
+ *
257
+ * @returns The process-wide SlackInstanceRegistryService
258
+ */
259
+ export async function ensureSlackInstanceRegistry() {
260
+ let registry = getSlackInstanceRegistryService();
261
+ if (!registry) {
262
+ const [{ CloudClientService }, { CloudSyncService }, { DeviceIdentityService }, { StorageService }] = await Promise.all([
263
+ import('../cloud/cloud-client.service.js'),
264
+ import('../cloud/cloud-sync.service.js'),
265
+ import('../cloud/device-identity.service.js'),
266
+ import('../core/storage.service.js'),
267
+ ]);
268
+ registry = new SlackInstanceRegistryService({
269
+ cloud: CloudClientService.getInstance(),
270
+ identity: DeviceIdentityService.getInstance(),
271
+ sync: CloudSyncService.getInstance(),
272
+ storage: StorageService.getInstance(),
273
+ getTeamChannels: () => getSlackTeamChannelService(),
274
+ });
275
+ setSlackInstanceRegistryService(registry);
276
+ }
277
+ return registry;
278
+ }
279
+ /**
280
+ * Build (once) and start the instance registry heartbeat. Never throws.
281
+ *
282
+ * @returns The registry service, or null when its dependencies are missing
283
+ */
284
+ export async function startSlackInstanceRegistry() {
285
+ try {
286
+ const registry = await ensureSlackInstanceRegistry();
287
+ await registry.start();
288
+ return registry;
289
+ }
290
+ catch (error) {
291
+ logger.warn('Slack instance registry not started', {
292
+ error: error instanceof Error ? error.message : String(error),
293
+ });
294
+ return null;
295
+ }
296
+ }
297
+ /**
298
+ * Subscribe to Cloud config changes and start the 10-minute refresh (unless
299
+ * `CREWLY_SLACK_SOURCE=env`). Idempotent.
300
+ */
301
+ export async function watchSlackCloudConfig() {
302
+ const cloudConfigService = await ensureSlackCloudConfigService();
303
+ if (cloudConfigService.getSourceMode() === 'env')
304
+ return;
305
+ if (!unsubscribeCloudConfig) {
306
+ unsubscribeCloudConfig = cloudConfigService.onChange((config) => {
307
+ void handleSlackCloudConfigChange(config);
308
+ });
309
+ }
310
+ cloudConfigService.start();
311
+ }
312
+ /**
313
+ * React to the Cloud config appearing, rotating or disappearing:
314
+ *
315
+ * - appeared and Slack is not connected → connect with the cloud source;
316
+ * - changed while connected via Cloud → re-initialise with the new token
317
+ * and merge new identities;
318
+ * - removed while connected via Cloud → disconnect.
319
+ *
320
+ * A live self-hosted (`env`) connection is left alone; precedence is only
321
+ * applied at boot so a running socket is never yanked under the owner.
322
+ *
323
+ * @param config - The new Cloud config (null when removed)
324
+ */
325
+ export async function handleSlackCloudConfigChange(config) {
326
+ const slackService = getSlackService();
327
+ const cloudConfigService = getSlackCloudConfigService();
328
+ if (!cloudConfigService)
329
+ return;
330
+ if (!config) {
331
+ if (activeSource === 'cloud') {
332
+ logger.info('Cloud Slack workspace removed — disconnecting');
333
+ getSlackInstanceRegistryService()?.stop();
334
+ await slackService.disconnect().catch(() => undefined);
335
+ activeSource = null;
336
+ }
337
+ return;
338
+ }
339
+ const slackConfig = cloudConfigService.toSlackConfig();
340
+ if (!slackConfig)
341
+ return;
342
+ if (!slackService.isConnected()) {
343
+ logger.info('Cloud Slack workspace available — connecting', { workspace: config.workspace.slackTeamName });
344
+ await connectSlack({ config: slackConfig, source: 'cloud' }, bootOptions);
345
+ return;
346
+ }
347
+ if (activeSource === 'cloud') {
348
+ if (slackService.getBotToken() !== slackConfig.botToken) {
349
+ logger.info('Cloud Slack bot token rotated — re-initialising');
350
+ await slackService.initialize(slackConfig);
351
+ await attachSlackCloudTransport();
352
+ }
353
+ await applyCloudIdentities();
354
+ }
355
+ }
356
+ /**
357
+ * Called once Cloud is signed in (boot restore or the login route — both
358
+ * happen after the Slack boot path ran): fetch the Cloud config now instead
359
+ * of waiting for the 10-minute tick, connect if a workspace exists and
360
+ * Slack is down, and re-register the instance now that a relay queue may
361
+ * exist. Never throws.
362
+ */
363
+ export async function refreshSlackCloudConfig() {
364
+ try {
365
+ const cloudConfigService = await ensureSlackCloudConfigService();
366
+ if (cloudConfigService.getSourceMode() === 'env')
367
+ return;
368
+ await watchSlackCloudConfig();
369
+ const config = await cloudConfigService.refresh();
370
+ // onChange only fires when the config differs from the cache; a cached
371
+ // config that could not connect at boot needs an explicit nudge.
372
+ if (config && !getSlackService().isConnected()) {
373
+ await handleSlackCloudConfigChange(config);
374
+ }
375
+ else if (activeSource === 'cloud') {
376
+ await getSlackInstanceRegistryService()?.heartbeat();
377
+ }
378
+ }
379
+ catch (error) {
380
+ logger.warn('Cloud Slack config refresh after login failed', {
381
+ error: error instanceof Error ? error.message : String(error),
382
+ });
383
+ }
384
+ }
385
+ /**
386
+ * Reset module state (tests).
387
+ */
388
+ export function resetSlackInitializerState() {
389
+ unsubscribeCloudConfig?.();
390
+ unsubscribeCloudConfig = null;
391
+ activeSource = null;
392
+ bootOptions = undefined;
393
+ getSlackCloudConfigService()?.stop();
394
+ getSlackInstanceRegistryService()?.stop();
395
+ setSlackInstanceRegistryService(null);
396
+ setSlackCloudConfigService(null);
397
+ }
121
398
  /**
122
399
  * Wire and start the Slack team-channel service (one Slack channel + one
123
400
  * chat-v2 huddle per team). Idempotent — safe to call from both the boot
@@ -180,9 +457,12 @@ export async function startSlackTeamChannels() {
180
457
  */
181
458
  export async function shutdownSlack() {
182
459
  try {
460
+ getSlackInstanceRegistryService()?.stop();
461
+ getSlackCloudConfigService()?.stop();
183
462
  const slackService = getSlackService();
184
463
  if (slackService.isConnected()) {
185
464
  await slackService.disconnect();
465
+ activeSource = null;
186
466
  logger.info('Disconnected');
187
467
  }
188
468
  }
@@ -1 +1 @@
1
- {"version":3,"file":"slack-initializer.js","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slack-initializer.js","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Slack Instance Registry Service — tells Crewly Cloud what this instance
3
+ * can handle, so Slack traffic reaches the right machine.
4
+ *
5
+ * Several OSS instances of one Crewly account may run at once (laptop,
6
+ * VPS, …). Cloud receives every Slack event for the account's workspace and
7
+ * routes it by a registry: which instance owns which team channel and which
8
+ * agent sessions, and which instance is the **primary** (DMs to the master
9
+ * bot and unmapped channels). This service keeps that registry fresh:
10
+ *
11
+ * - `PUT /api/cloud/slack/instances/:instanceId` on boot, on every team
12
+ * save (debounced) and every 5 minutes, with the team → channel mapping
13
+ * from `SlackTeamChannelService` and each team's member session names;
14
+ * - `POST /api/cloud/slack/agents/sync` with the team roster on boot and
15
+ * when a team is created, so Cloud provisions the per-agent apps; the
16
+ * returned `installUrls` (agents still needing their one-time install
17
+ * click) are kept for Settings.
18
+ *
19
+ * `instanceId` is the Cloud device id (`DeviceIdentityService`), the relay
20
+ * `queueId` comes from `CloudSyncService`, and `primary` is
21
+ * `CREWLY_SLACK_PRIMARY=1` or the persisted Settings toggle
22
+ * (`~/.crewly/slack-instance.json`).
23
+ *
24
+ * @module services/slack/slack-instance-registry.service
25
+ */
26
+ import type { Team } from '../../types/index.js';
27
+ import type { SlackAgentsSyncResult, SlackInstanceRegistryPayload, SlackPendingInstall, SlackTeamChannelMapping } from '../../types/slack.types.js';
28
+ import type { StorageEvent } from '../core/storage.service.js';
29
+ import { type IdentityCloudClient } from './slack-agent-identity.service.js';
30
+ /** The slice of DeviceIdentityService this service needs. */
31
+ export interface RegistryDeviceIdentity {
32
+ getOrCreateIdentity(): Promise<{
33
+ deviceId: string;
34
+ deviceName: string;
35
+ }>;
36
+ }
37
+ /** The slice of CloudSyncService this service needs. */
38
+ export interface RegistryCloudSync {
39
+ getQueueId(): string | null;
40
+ }
41
+ /** The slice of StorageService this service needs. */
42
+ export interface RegistryStorage {
43
+ getTeams(): Promise<Team[]>;
44
+ onStorageEvent(listener: (event: StorageEvent) => Promise<void> | void): () => void;
45
+ }
46
+ /** The slice of SlackTeamChannelService this service needs. */
47
+ export interface RegistryTeamChannels {
48
+ findByTeamId(teamId: string): SlackTeamChannelMapping | null;
49
+ }
50
+ /** Constructor dependencies. */
51
+ export interface SlackInstanceRegistryServiceDeps {
52
+ cloud: IdentityCloudClient;
53
+ identity: RegistryDeviceIdentity;
54
+ sync: RegistryCloudSync;
55
+ storage: RegistryStorage;
56
+ /** Resolved lazily — the team-channel service is built after Slack connects. */
57
+ getTeamChannels: () => RegistryTeamChannels | null;
58
+ /** Crewly version reported to Cloud; read from package.json when omitted. */
59
+ version?: string;
60
+ /** Settings path; defaults to `<CREWLY_HOME>/slack-instance.json`. */
61
+ settingsPath?: string;
62
+ fetchImpl?: typeof fetch;
63
+ now?: () => number;
64
+ env?: NodeJS.ProcessEnv;
65
+ setInterval?: typeof setInterval;
66
+ clearInterval?: typeof clearInterval;
67
+ setTimeout?: typeof setTimeout;
68
+ clearTimeout?: typeof clearTimeout;
69
+ }
70
+ /**
71
+ * Service — see module docs.
72
+ */
73
+ export declare class SlackInstanceRegistryService {
74
+ private readonly logger;
75
+ private readonly deps;
76
+ private readonly settingsPath;
77
+ private readonly fetchImpl;
78
+ private settings;
79
+ private instanceId;
80
+ private deviceName;
81
+ private version;
82
+ private heartbeatTimer;
83
+ private debounceTimer;
84
+ private unsubscribeStorage;
85
+ private pendingInstalls;
86
+ private lastHeartbeatAt;
87
+ private lastError;
88
+ private started;
89
+ /** Consecutive heartbeats skipped because the relay queue was not registered yet */
90
+ private queueWaitRetries;
91
+ constructor(deps: SlackInstanceRegistryServiceDeps);
92
+ /**
93
+ * Boot: heartbeat + agent sync now, then heartbeat every 5 minutes and on
94
+ * every team save. Idempotent; never throws (Cloud failures are logged).
95
+ */
96
+ start(): Promise<void>;
97
+ /** Undo {@link start}. */
98
+ stop(): void;
99
+ /**
100
+ * React to team lifecycle: every save re-registers (debounced — status
101
+ * writes fire this too); a created team also provisions its agents.
102
+ *
103
+ * @param event - Storage event
104
+ */
105
+ handleStorageEvent(event: StorageEvent): Promise<void>;
106
+ /**
107
+ * Build the registry payload from the current teams, channel mappings
108
+ * and settings.
109
+ *
110
+ * @returns The `PUT /instances/:id` body
111
+ */
112
+ buildPayload(): Promise<SlackInstanceRegistryPayload>;
113
+ /**
114
+ * `PUT /api/cloud/slack/instances/:instanceId`. Skipped (false) when not
115
+ * signed in to Cloud or before the relay queue is registered.
116
+ *
117
+ * @returns True when Cloud accepted the registration
118
+ */
119
+ heartbeat(): Promise<boolean>;
120
+ /**
121
+ * `POST /api/cloud/slack/agents/sync` with every team's roster; keeps the
122
+ * returned pending install links.
123
+ *
124
+ * @returns Cloud's answer, or null when skipped / failed
125
+ */
126
+ syncAgents(): Promise<SlackAgentsSyncResult | null>;
127
+ /**
128
+ * Whether this instance is the account's primary: `CREWLY_SLACK_PRIMARY`
129
+ * (`1`/`true`) wins, otherwise the persisted Settings toggle.
130
+ *
131
+ * @returns True when primary
132
+ */
133
+ isPrimary(): Promise<boolean>;
134
+ /**
135
+ * Persist the Settings toggle and re-register immediately so Cloud moves
136
+ * the flag (it clears `primary` on the account's other instances).
137
+ *
138
+ * @param primary - The new value
139
+ */
140
+ setPrimary(primary: boolean): Promise<void>;
141
+ /**
142
+ * Agents still needing their one-time install click (from the last sync).
143
+ *
144
+ * @returns Copies
145
+ */
146
+ getPendingInstalls(): SlackPendingInstall[];
147
+ /** @returns The Cloud device id once resolved */
148
+ getInstanceId(): string | null;
149
+ /** @returns ISO timestamp of the last accepted heartbeat */
150
+ getLastHeartbeatAt(): string | null;
151
+ /** @returns Last Cloud failure, if the most recent call failed */
152
+ getLastError(): string | null;
153
+ /**
154
+ * Whether Cloud can be reached.
155
+ *
156
+ * @returns True when signed in with a token and url
157
+ */
158
+ isAvailable(): boolean;
159
+ private scheduleHeartbeat;
160
+ private resolveIdentity;
161
+ private resolveVersion;
162
+ private loadSettings;
163
+ private now;
164
+ private cloudRequest;
165
+ }
166
+ /**
167
+ * Install the process-wide instance (composition root).
168
+ *
169
+ * @param service - The service or null
170
+ */
171
+ export declare function setSlackInstanceRegistryService(service: SlackInstanceRegistryService | null): void;
172
+ /**
173
+ * The process-wide instance, or null before wiring.
174
+ *
175
+ * @returns The service or null
176
+ */
177
+ export declare function getSlackInstanceRegistryService(): SlackInstanceRegistryService | null;
178
+ //# sourceMappingURL=slack-instance-registry.service.d.ts.map