@hiver/connector-agent 4.21.2 → 4.22.0-slackM2-beta.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 (71) hide show
  1. package/app/hig-slack/HigSlackSection.d.ts +3 -0
  2. package/app/hig-slack/HigSlackSection.d.ts.map +1 -1
  3. package/constants/tracking-events.d.ts +4 -0
  4. package/constants/tracking-events.d.ts.map +1 -1
  5. package/features/slack/api/__tests__/errors.test.d.ts +2 -0
  6. package/features/slack/api/__tests__/errors.test.d.ts.map +1 -0
  7. package/features/slack/api/__tests__/links.test.d.ts +2 -0
  8. package/features/slack/api/__tests__/links.test.d.ts.map +1 -0
  9. package/features/slack/api/conversations.d.ts +6 -2
  10. package/features/slack/api/conversations.d.ts.map +1 -1
  11. package/features/slack/api/errors.d.ts +37 -0
  12. package/features/slack/api/errors.d.ts.map +1 -0
  13. package/features/slack/api/index.d.ts +2 -0
  14. package/features/slack/api/index.d.ts.map +1 -1
  15. package/features/slack/api/linked-conv.d.ts +11 -2
  16. package/features/slack/api/linked-conv.d.ts.map +1 -1
  17. package/features/slack/api/links.d.ts +93 -0
  18. package/features/slack/api/links.d.ts.map +1 -0
  19. package/features/slack/api/members.d.ts +2 -2
  20. package/features/slack/api/members.d.ts.map +1 -1
  21. package/features/slack/api/messages.d.ts +1 -1
  22. package/features/slack/api/messages.d.ts.map +1 -1
  23. package/features/slack/components/LinkExistingModal/ChannelPicker.d.ts +23 -0
  24. package/features/slack/components/LinkExistingModal/ChannelPicker.d.ts.map +1 -0
  25. package/features/slack/components/LinkExistingModal/index.d.ts +31 -0
  26. package/features/slack/components/LinkExistingModal/index.d.ts.map +1 -0
  27. package/features/slack/components/LinkExistingModal/style.d.ts +21 -0
  28. package/features/slack/components/LinkExistingModal/style.d.ts.map +1 -0
  29. package/features/slack/components/LinkedConversationPanel/Composer.d.ts.map +1 -1
  30. package/features/slack/components/LinkedConversationPanel/LinkedChannelHeader.d.ts +10 -3
  31. package/features/slack/components/LinkedConversationPanel/LinkedChannelHeader.d.ts.map +1 -1
  32. package/features/slack/components/LinkedConversationPanel/MessageItem.d.ts.map +1 -1
  33. package/features/slack/components/LinkedConversationPanel/ThreadDetailView.d.ts.map +1 -1
  34. package/features/slack/components/LinkedConversationPanel/index.d.ts +18 -1
  35. package/features/slack/components/LinkedConversationPanel/index.d.ts.map +1 -1
  36. package/features/slack/components/SlackConversationTab.d.ts.map +1 -1
  37. package/features/slack/components/SlackLinkList.d.ts +23 -0
  38. package/features/slack/components/SlackLinkList.d.ts.map +1 -0
  39. package/features/slack/components/StartModal/index.d.ts +8 -2
  40. package/features/slack/components/StartModal/index.d.ts.map +1 -1
  41. package/features/slack/components/style.d.ts.map +1 -1
  42. package/features/slack/constants/api.d.ts +6 -0
  43. package/features/slack/constants/api.d.ts.map +1 -1
  44. package/features/slack/context.d.ts +18 -0
  45. package/features/slack/context.d.ts.map +1 -1
  46. package/features/slack/hooks/__tests__/useMarkLinkRead.test.d.ts +2 -0
  47. package/features/slack/hooks/__tests__/useMarkLinkRead.test.d.ts.map +1 -0
  48. package/features/slack/hooks/useMarkLinkRead.d.ts +33 -0
  49. package/features/slack/hooks/useMarkLinkRead.d.ts.map +1 -0
  50. package/features/slack/hooks/useSlackLinks.d.ts +32 -0
  51. package/features/slack/hooks/useSlackLinks.d.ts.map +1 -0
  52. package/features/slack/link-scope.d.ts +7 -0
  53. package/features/slack/link-scope.d.ts.map +1 -0
  54. package/features/slack/types/wire.d.ts +87 -0
  55. package/features/slack/types/wire.d.ts.map +1 -1
  56. package/features/slack/utils/__tests__/join-notices.test.d.ts +2 -0
  57. package/features/slack/utils/__tests__/join-notices.test.d.ts.map +1 -0
  58. package/features/slack/utils/__tests__/slack-thread-url.test.d.ts +2 -0
  59. package/features/slack/utils/__tests__/slack-thread-url.test.d.ts.map +1 -0
  60. package/features/slack/utils/join-notices.d.ts +3 -0
  61. package/features/slack/utils/join-notices.d.ts.map +1 -0
  62. package/features/slack/utils/slack-thread-url.d.ts +26 -0
  63. package/features/slack/utils/slack-thread-url.d.ts.map +1 -0
  64. package/index.d.ts +3 -0
  65. package/index.d.ts.map +1 -1
  66. package/index.es.js +13763 -12726
  67. package/index.umd.js +664 -648
  68. package/main-dev.d.ts.map +1 -1
  69. package/package.json +1 -1
  70. package/testing/mocks/handlers/slack.d.ts +22 -12
  71. package/testing/mocks/handlers/slack.d.ts.map +1 -1
@@ -5,6 +5,9 @@ export type HigSlackSectionProps = SlackContextData & {
5
5
  /** Host hook (M-HIG-2) for the linked-state "View all" link — wired to
6
6
  * activating the Slack tab. The section itself stays panel-free. */
7
7
  onViewAll?: () => void;
8
+ /** Multi-link (M2): clicking a link row should open the Slack tab ON
9
+ * that item. Falls back to `onViewAll` when the host doesn't wire it. */
10
+ onOpenLink?: (linkId: string) => void;
8
11
  theme?: ConnectorThemeConfig;
9
12
  };
10
13
  /** Body-only surface: same props, no self-owned accordion shell. */
@@ -1 +1 @@
1
- {"version":3,"file":"HigSlackSection.d.ts","sourceRoot":"","sources":["../../../src/app/hig-slack/HigSlackSection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAkC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AASjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAyBpE,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IACpD;yEACqE;IACrE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,oBAAoB,CAAC;CAC9B,CAAC;AAEF,oEAAoE;AACpE,MAAM,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAoQ5D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAIpD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAI5D,CAAC"}
1
+ {"version":3,"file":"HigSlackSection.d.ts","sourceRoot":"","sources":["../../../src/app/hig-slack/HigSlackSection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAkC,MAAM,OAAO,CAAC;AAc3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAUjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAyBpE,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IACpD;yEACqE;IACrE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;8EAC0E;IAC1E,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,KAAK,CAAC,EAAE,oBAAoB,CAAC;CAC9B,CAAC;AAEF,oEAAoE;AACpE,MAAM,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAiX5D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAIpD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAI5D,CAAC"}
@@ -58,4 +58,8 @@ export declare const SLACK_EXISTING_CHANNEL_LINKED = "slack_existing_channel_lin
58
58
  export declare const SLACK_NEW_CHANNEL_LINKED = "slack_new_channel_linked";
59
59
  export declare const SLACK_REPLY_SENT = "slack_reply_sent";
60
60
  export declare const SLACK_OLDER_MESSAGES_LOADED = "slack_older_messages_loaded";
61
+ export declare const SLACK_LINK_EXISTING_CLICKED = "slack_link_existing_clicked";
62
+ export declare const SLACK_EXISTING_THREAD_LINKED = "slack_existing_thread_linked";
63
+ export declare const SLACK_CONVERSATION_UNLINKED = "slack_conversation_unlinked";
64
+ export declare const SLACK_LINK_SWITCHED = "slack_link_switched";
61
65
  //# sourceMappingURL=tracking-events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracking-events.d.ts","sourceRoot":"","sources":["../../src/constants/tracking-events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tracking-events.d.ts","sourceRoot":"","sources":["../../src/constants/tracking-events.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AACrE,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAC7E,eAAO,MAAM,gCAAgC,qCAAqC,CAAC;AACnF,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AACvE,eAAO,MAAM,6BAA6B,4CAA4C,CAAC;AACvF,eAAO,MAAM,4BAA4B,2CAA2C,CAAC;AACrF,eAAO,MAAM,wBAAwB,kCAAkC,CAAC;AACxE,eAAO,MAAM,yBAAyB,wCAAwC,CAAC;AAC/E,eAAO,MAAM,uBAAuB,sCAAsC,CAAC;AAC3E,eAAO,MAAM,0BAA0B,yCAAyC,CAAC;AACjF,eAAO,MAAM,yBAAyB,wCAAwC,CAAC;AAC/E,eAAO,MAAM,uBAAuB,sCAAsC,CAAC;AAC3E,eAAO,MAAM,oBAAoB,mCAAmC,CAAC;AACrE,eAAO,MAAM,2BAA2B,0CAA0C,CAAC;AACnF,eAAO,MAAM,yBAAyB,wCAAwC,CAAC;AAC/E,eAAO,MAAM,mCAAmC,yBAAyB,CAAC;AAC1E,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AACzE,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AACzE,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AACzE,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AACvE,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AACzE,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AACzE,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAChE,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAC9D,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAClD,eAAO,MAAM,wBAAwB,mCAAmC,CAAC;AACzE,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AAKrE,eAAO,MAAM,0BAA0B,yCAAyC,CAAC;AAKjF,eAAO,MAAM,8BAA8B,6CAA6C,CAAC;AAGzF,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAC7E,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAInD,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAIzE,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAGzE,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAE3E,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAEzE,eAAO,MAAM,mBAAmB,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/api/__tests__/errors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=links.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.test.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/api/__tests__/links.test.ts"],"names":[],"mappings":""}
@@ -8,6 +8,10 @@ import { ExternalConversation, SlackOlderPage, SlackThreadGroup, StartExistingCh
8
8
  export interface SlackPageParams {
9
9
  beforeTs?: string;
10
10
  pageSize?: number;
11
+ /** Multi-link selector (M2): scope the read to one link row. Omitted ⇒
12
+ * backend serves the most recently linked item (flag-off compat shim).
13
+ * Query-param casing is snake_case on the wire (`link_id`). */
14
+ linkId?: string;
11
15
  }
12
16
  export declare const startExistingChannel: (payload: StartExistingChannelRequest) => Promise<StartResponse>;
13
17
  export declare const startNewChannel: (payload: StartNewChannelRequest) => Promise<StartResponse>;
@@ -18,7 +22,7 @@ export declare const getExternalConversation: (hiverConvId: string, page?: Slack
18
22
  * backwards into older history. Returns older thread replies (thread mode)
19
23
  * or older thread roots (channel mode); the caller merges + dedupes.
20
24
  */
21
- export declare const getExternalConversationPage: (hiverConvId: string, beforeTs: string, pageSize?: number) => Promise<SlackOlderPage>;
25
+ export declare const getExternalConversationPage: (hiverConvId: string, beforeTs: string, pageSize?: number, linkId?: string) => Promise<SlackOlderPage>;
22
26
  /**
23
27
  * Channel mode (B4): lazily fetch a single thread's full messages
24
28
  * (root + replies) when the user drills into it. The list view only
@@ -31,7 +35,7 @@ export declare const getThread: (hiverConvId: string, threadTs: string, page?: S
31
35
  * page's nextCursor as `beforeTs`. Returns the older replies window (the
32
36
  * thread root is omitted from `messages` — it stays pinned in page 0).
33
37
  */
34
- export declare const getThreadPage: (hiverConvId: string, threadTs: string, beforeTs: string, pageSize?: number) => Promise<SlackOlderPage>;
38
+ export declare const getThreadPage: (hiverConvId: string, threadTs: string, beforeTs: string, pageSize?: number, linkId?: string) => Promise<SlackOlderPage>;
35
39
  export declare const getExternalConversationsByTarget: (params: {
36
40
  channelId: string;
37
41
  externalThreadTs?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/conversations.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,oBAAoB,EAEpB,cAAc,EAGd,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,aAAa,EACd,MAAM,6BAA6B,CAAC;AAErC;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgED,eAAO,MAAM,oBAAoB,YAAmB,2BAA2B,KAAG,OAAO,CAAC,aAAa,CAQtG,CAAC;AAEF,eAAO,MAAM,eAAe,YAAmB,sBAAsB,KAAG,OAAO,CAAC,aAAa,CAQ5F,CAAC;AAeF,eAAO,MAAM,uBAAuB,gBACrB,MAAM,SACZ,eAAe,KACrB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CA0BrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,gBACzB,MAAM,YACT,MAAM,aACL,MAAM,KAChB,OAAO,CAAC,cAAc,CASxB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,gBACP,MAAM,YACT,MAAM,SACT,eAAe,KACrB,OAAO,CAAC,gBAAgB,CAQ1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,gBACX,MAAM,YACT,MAAM,YACN,MAAM,aACL,MAAM,KAChB,OAAO,CAAC,cAAc,CAQxB,CAAC;AAEF,eAAO,MAAM,gCAAgC,WAAkB;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,KAAG,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAUrC,CAAC"}
1
+ {"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/conversations.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,oBAAoB,EAEpB,cAAc,EAGd,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,aAAa,EACd,MAAM,6BAA6B,CAAC;AAErC;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;oEAEgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAiED,eAAO,MAAM,oBAAoB,YAAmB,2BAA2B,KAAG,OAAO,CAAC,aAAa,CAQtG,CAAC;AAEF,eAAO,MAAM,eAAe,YAAmB,sBAAsB,KAAG,OAAO,CAAC,aAAa,CAQ5F,CAAC;AAeF,eAAO,MAAM,uBAAuB,gBACrB,MAAM,SACZ,eAAe,KACrB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CA0BrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,gBACzB,MAAM,YACT,MAAM,aACL,MAAM,WACR,MAAM,KACd,OAAO,CAAC,cAAc,CASxB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,gBACP,MAAM,YACT,MAAM,SACT,eAAe,KACrB,OAAO,CAAC,gBAAgB,CAQ1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,gBACX,MAAM,YACT,MAAM,YACN,MAAM,aACL,MAAM,WACR,MAAM,KACd,OAAO,CAAC,cAAc,CAQxB,CAAC;AAEF,eAAO,MAAM,gCAAgC,WAAkB;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,KAAG,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAUrC,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Central Slack error taxonomy (M2). Every mapped backend error returns
3
+ * `{ detail: { reason: '<code>', … } }` — switch on `detail.reason`,
4
+ * NEVER on HTTP status alone: two different 409s exist now
5
+ * (already-linked vs cap-reached).
6
+ *
7
+ * One historical wrinkle: the pre-M2 already-linked 409 returned only
8
+ * `{ existingLinkId }` with NO reason key (the backend is adding
9
+ * `reason: 'slack_target_already_linked'` alongside it). We therefore
10
+ * treat "409 with an existingLinkId" as already-linked even when the
11
+ * reason is absent, so the client works against both backend versions.
12
+ *
13
+ * Shapes are read defensively (detail-nested first, then top-level)
14
+ * because the agent controller serialises FastAPI HTTPException as
15
+ * `{ detail: { reason } }` while the generic user-tier resolver returns
16
+ * a top-level `reason` — same duality isSlackAuthError already handles.
17
+ */
18
+ export type SlackErrorReason = 'slack_invalid_auth' | 'hiver_conv_not_linked' | 'slack_target_already_linked' | 'slack_link_cap_reached' | 'slack_api_error' | 'workspace_connector_missing' | 'user_slack_auth_missing';
19
+ export interface ParsedSlackError {
20
+ status?: number;
21
+ reason?: SlackErrorReason | string;
22
+ /** Slack's own error code when reason === 'slack_api_error'
23
+ * (e.g. 'name_taken', 'not_in_channel'). */
24
+ code?: string;
25
+ /** Set on the already-linked 409 — the linkId of the existing row,
26
+ * so the UI can switch straight to that item. */
27
+ existingLinkId?: string;
28
+ message?: string;
29
+ }
30
+ export declare const parseSlackError: (err: unknown) => ParsedSlackError;
31
+ export declare const isSlackErrorReason: (err: unknown, reason: SlackErrorReason) => boolean;
32
+ /** 404 for an unknown / stale linkId — the item was unlinked elsewhere.
33
+ * Correct handling: refetch the links list; the item is gone. */
34
+ export declare const isStaleLinkError: (err: unknown) => boolean;
35
+ export declare const isLinkCapReachedError: (err: unknown) => boolean;
36
+ export declare const isTargetAlreadyLinkedError: (err: unknown) => boolean;
37
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,MAAM,gBAAgB,GACxB,oBAAoB,GACpB,uBAAuB,GACvB,6BAA6B,GAC7B,wBAAwB,GACxB,iBAAiB,GACjB,6BAA6B,GAC7B,yBAAyB,CAAC;AAE9B,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACnC;iDAC6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;sDACkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAeD,eAAO,MAAM,eAAe,QAAS,OAAO,KAAG,gBAiB9C,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAS,OAAO,UAAU,gBAAgB,KAAG,OACpC,CAAC;AAEzC;kEACkE;AAClE,eAAO,MAAM,gBAAgB,QAAS,OAAO,KAAG,OAG/C,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAS,OAAO,KAAG,OAA4D,CAAC;AAElH,eAAO,MAAM,0BAA0B,QAAS,OAAO,KAAG,OACF,CAAC"}
@@ -1,4 +1,6 @@
1
1
  export { getExternalConversation, getExternalConversationPage, getExternalConversationsByTarget, getThreadPage, startExistingChannel, startNewChannel } from './conversations';
2
2
  export { postMessage } from './messages';
3
3
  export { getChannelMembers } from './members';
4
+ export { getLinkPreview, getLinks, linkExistingChannel, linkExistingThread, markLinkRead, unlinkConversation } from './links';
5
+ export { parseSlackError } from './errors';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,aAAa,EACb,oBAAoB,EACpB,eAAe,EAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,aAAa,EACb,oBAAoB,EACpB,eAAe,EAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EACL,cAAc,EACd,QAAQ,EACR,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC"}
@@ -52,7 +52,16 @@ export declare function backedOffInterval(baseMs: number, failureCount: number):
52
52
  * exponentially up to MAX_POLL_BACKOFF_MS and snaps back to base on
53
53
  * the first success (see `backedOffInterval`).
54
54
  */
55
- export declare function useLinkedConversation(hiverConvId: string, enabled?: boolean, refetchIntervalMs?: number): import('@tanstack/react-query').UseQueryResult<ExternalConversation | null, Error>;
55
+ /**
56
+ * Query-key builders (M2). The linkId lands in the key ONLY when
57
+ * provided, so flag-off single-link surfaces keep today's exact key
58
+ * shape — and the cache-patching call sites (Composer optimistic writes,
59
+ * MessageItem delete invalidation) build keys through these helpers
60
+ * instead of hand-rolled arrays, so reads and writes can't drift apart.
61
+ */
62
+ export declare const linkedConvQueryKey: (hiverConvId: string, linkId?: string) => string[];
63
+ export declare const threadQueryKey: (hiverConvId: string, threadTs: string | null, linkId?: string) => (string | null)[];
64
+ export declare function useLinkedConversation(hiverConvId: string, enabled?: boolean, refetchIntervalMs?: number, linkId?: string): import('@tanstack/react-query').UseQueryResult<ExternalConversation | null, Error>;
56
65
  /**
57
66
  * Channel mode (B4): lazily fetch a single thread's messages (root +
58
67
  * replies) when the user drills into it from the channel list. Enabled
@@ -61,5 +70,5 @@ export declare function useLinkedConversation(hiverConvId: string, enabled?: boo
61
70
  * `useLinkedConversation`, pauses when the surface is inactive (`isActive`
62
71
  * false) and backs off while the endpoint is failing.
63
72
  */
64
- export declare function useThread(hiverConvId: string, threadTs: string | null, isActive?: boolean): import('@tanstack/react-query').UseQueryResult<SlackThreadGroup, Error>;
73
+ export declare function useThread(hiverConvId: string, threadTs: string | null, isActive?: boolean, linkId?: string): import('@tanstack/react-query').UseQueryResult<SlackThreadGroup, Error>;
65
74
  //# sourceMappingURL=linked-conv.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"linked-conv.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/linked-conv.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE1F;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAG9E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,UAAO,EACd,iBAAiB,GAAE,MAAqC,sFA+BzD;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,UAAO,2EAWtF"}
1
+ {"version":3,"file":"linked-conv.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/linked-conv.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE1F;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAG9E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,gBAAiB,MAAM,WAAW,MAAM,aACyB,CAAC;AAEjG,eAAO,MAAM,cAAc,gBAAiB,MAAM,YAAY,MAAM,GAAG,IAAI,WAAW,MAAM,sBACc,CAAC;AAE3G,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,UAAO,EACd,iBAAiB,GAAE,MAAqC,EACxD,MAAM,CAAC,EAAE,MAAM,sFA+BhB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,UAAO,EAAE,MAAM,CAAC,EAAE,MAAM,2EAcvG"}
@@ -0,0 +1,93 @@
1
+ import { LinkExistingChannelRequest, LinkExistingThreadRequest, SlackLink, SlackLinkPreview, SlackLinksResponse, StartResponse } from '../types/wire';
2
+ /**
3
+ * Poll cadence for the links list (the switcher payload). The endpoint is
4
+ * declared safe to poll — it never mutates read state — and it's the ONLY
5
+ * background poll for non-selected links: their unread counts and
6
+ * lastActivityTs ride this query, while message polling stays scoped to
7
+ * the one selected link (decision D8). Kept as a named constant so the
8
+ * cadence is tunable without touching call sites.
9
+ */
10
+ export declare const LINKS_POLL_INTERVAL_MS = 5000;
11
+ /**
12
+ * Last-resort cap when the server omits `cap`/`remainingSlots` (should not
13
+ * happen per contract). The SERVER value always wins when present —
14
+ * decision D6: never trust a hardcoded 4.
15
+ */
16
+ export declare const FALLBACK_LINK_CAP = 4;
17
+ /** Query key for the links list — exported so mutations (link, unlink,
18
+ * mark-read) and M2-C's optimistic unread updates target one shape. */
19
+ export declare const linksQueryKey: (hiverConvId: string) => readonly ["slack", "links", string];
20
+ interface RawSlackLink extends Omit<SlackLink, 'channelName' | 'parentExternalId' | 'threadTs' | 'lastActivityTs' | 'unreadCount'> {
21
+ channelName?: string | null;
22
+ parentExternalId?: string | null;
23
+ threadTs?: string | null;
24
+ lastActivityTs?: string | null;
25
+ unreadCount?: number;
26
+ }
27
+ interface RawLinksResponse {
28
+ links?: RawSlackLink[] | null;
29
+ totalUnreadCount?: number;
30
+ cap?: number;
31
+ remainingSlots?: number;
32
+ }
33
+ export declare const normaliseLinksResponse: (body: RawLinksResponse | undefined) => SlackLinksResponse;
34
+ /**
35
+ * Display label for a link. `channelName` can legitimately be null on
36
+ * older links until first read — fall back to a kind-appropriate
37
+ * placeholder instead of an empty string (TC-012).
38
+ */
39
+ export declare const linkDisplayName: (link: Pick<SlackLink, "channelName" | "targetKind">) => string;
40
+ /**
41
+ * Cold-open selection rule (decision D9): the item with the most recent
42
+ * activity wins; items with no cached activity rank last and tie-break by
43
+ * most recently linked. This is deliberately NOT the backend's
44
+ * omitted-linkId fallback (most recently LINKED) — a different rule the
45
+ * contract tells us not to lean on.
46
+ */
47
+ export declare const pickDefaultLink: (links: SlackLink[]) => SlackLink | null;
48
+ export declare const getLinks: (hiverConvId: string) => Promise<SlackLinksResponse>;
49
+ /**
50
+ * The switcher query: every link on the conversation with unread + cap
51
+ * info, polled at LINKS_POLL_INTERVAL_MS with the shared exponential
52
+ * backoff. Pass `refetchIntervalMs: 0` for surfaces that are mounted but
53
+ * hidden (same `isActive` convention as useLinkedConversation).
54
+ */
55
+ export declare function useLinks(hiverConvId: string, enabled?: boolean, refetchIntervalMs?: number): import('@tanstack/react-query').UseQueryResult<SlackLinksResponse, Error>;
56
+ /**
57
+ * Unlink one item. 204; frees a cap slot. Nothing happens on Slack —
58
+ * the channel/thread and all history survive (say so in confirm copy).
59
+ * Anyone with access to the conversation may unlink.
60
+ */
61
+ export declare const unlinkConversation: (hiverConvId: string, linkId: string) => Promise<void>;
62
+ /**
63
+ * Mark one item read — clears its per-viewer unreadCount. Call ONLY when
64
+ * the rep actually views the item (opens it, or it's the cold-open
65
+ * default in view); never from a background poll or prefetch. Omitting
66
+ * `lastReadTs` marks up to the newest message the backend knows about,
67
+ * which is what we want in almost every case.
68
+ */
69
+ export declare const markLinkRead: (hiverConvId: string, linkId: string, lastReadTs?: string) => Promise<void>;
70
+ /**
71
+ * Attach an existing Slack thread. Posts `messageText` into the thread
72
+ * (always — no silent attach), then links it. Response shape is identical
73
+ * to /start/existing-channel so the success path reuses that handling;
74
+ * `externalConversationId` IS the new linkId.
75
+ */
76
+ export declare const linkExistingThread: (payload: LinkExistingThreadRequest) => Promise<StartResponse>;
77
+ /**
78
+ * Attach an existing Slack channel (posts `messageText` top-level, then
79
+ * links the whole channel → renders in channel mode like a started one).
80
+ */
81
+ export declare const linkExistingChannel: (payload: LinkExistingChannelRequest) => Promise<StartResponse>;
82
+ /**
83
+ * Fetch preview meta for a pasted thread permalink before linking
84
+ * (GET /link-preview — the real endpoint that closed the D1 gap). The
85
+ * RAW URL travels as `preview_link` (snake_case query, per the casing
86
+ * rule); the BACKEND parses it and returns canonical channelId/threadTs
87
+ * — those, not any client-side parse, feed /link/existing-thread. The
88
+ * client-side parser remains only as a pre-flight validity gate so
89
+ * obviously-invalid input never hits the network.
90
+ */
91
+ export declare const getLinkPreview: (previewLink: string) => Promise<SlackLinkPreview>;
92
+ export {};
93
+ //# sourceMappingURL=links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/links.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACd,MAAM,6BAA6B,CAAC;AAErC;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;wEACwE;AACxE,eAAO,MAAM,aAAa,gBAAiB,MAAM,wCAA6C,CAAC;AAE/F,UAAU,YACR,SAAQ,IAAI,CAAC,SAAS,EAAE,aAAa,GAAG,kBAAkB,GAAG,UAAU,GAAG,gBAAgB,GAAG,aAAa,CAAC;IAC3G,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,gBAAgB;IACxB,KAAK,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAWD,eAAO,MAAM,sBAAsB,SAAU,gBAAgB,GAAG,SAAS,KAAG,kBAS3E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,SAAU,IAAI,CAAC,SAAS,EAAE,aAAa,GAAG,YAAY,CAAC,KAAG,MACC,CAAC;AAExF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,UAAW,SAAS,EAAE,KAAG,SAAS,GAAG,IAShE,CAAC;AAEF,eAAO,MAAM,QAAQ,gBAAuB,MAAM,KAAG,OAAO,CAAC,kBAAkB,CAM9E,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,UAAO,EAAE,iBAAiB,GAAE,MAA+B,6EAW/G;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,gBAAuB,MAAM,UAAU,MAAM,KAAG,OAAO,CAAC,IAAI,CAK1F,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,gBAAuB,MAAM,UAAU,MAAM,eAAe,MAAM,KAAG,OAAO,CAAC,IAAI,CAMzG,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAmB,yBAAyB,KAAG,OAAO,CAAC,aAAa,CAQlG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,YAAmB,0BAA0B,KAAG,OAAO,CAAC,aAAa,CAQpG,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,gBAAuB,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAOlF,CAAC"}
@@ -1,10 +1,10 @@
1
1
  import { ChannelMember } from '../types/wire';
2
- export declare const getChannelMembers: (hiverConvId?: string, channelId?: string) => Promise<ChannelMember[]>;
2
+ export declare const getChannelMembers: (hiverConvId?: string, channelId?: string, linkId?: string) => Promise<ChannelMember[]>;
3
3
  /**
4
4
  * Cached channel-members query. Used by the linked-conv panel to
5
5
  * resolve `<@USER_ID>` mention tokens to display names, and by the
6
6
  * composer's @-mention picker — same queryKey → one shared fetch.
7
7
  * Names are stable, so a long staleTime avoids refetch churn.
8
8
  */
9
- export declare function useChannelMembers(hiverConvId: string, enabled?: boolean): import('@tanstack/react-query').UseQueryResult<ChannelMember[], Error>;
9
+ export declare function useChannelMembers(hiverConvId: string, enabled?: boolean, linkId?: string): import('@tanstack/react-query').UseQueryResult<ChannelMember[], Error>;
10
10
  //# sourceMappingURL=members.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"members.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/members.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,eAAO,MAAM,iBAAiB,iBAAwB,MAAM,cAAc,MAAM,KAAG,OAAO,CAAC,aAAa,EAAE,CAgBzG,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,UAAO,0EAQpE"}
1
+ {"version":3,"file":"members.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/members.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,eAAO,MAAM,iBAAiB,iBACd,MAAM,cACR,MAAM,WACT,MAAM,KACd,OAAO,CAAC,aAAa,EAAE,CAmBzB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,UAAO,EAAE,MAAM,CAAC,EAAE,MAAM,0EAWrF"}
@@ -6,5 +6,5 @@ export declare const postMessage: (payload: PostMessageRequest) => Promise<Slack
6
6
  * returns 204. `hiver_conv_id` resolves the linked channel/thread the
7
7
  * message lives in.
8
8
  */
9
- export declare const deleteMessage: (externalMessageId: string, hiverConvId: string) => Promise<void>;
9
+ export declare const deleteMessage: (externalMessageId: string, hiverConvId: string, linkId?: string) => Promise<void>;
10
10
  //# sourceMappingURL=messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/messages.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAqBpF,eAAO,MAAM,WAAW,YAAmB,kBAAkB,KAAG,OAAO,CAAC,YAAY,CAOnF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,sBAA6B,MAAM,eAAe,MAAM,KAAG,OAAO,CAAC,IAAI,CAWhG,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/api/messages.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAqBpF,eAAO,MAAM,WAAW,YAAmB,kBAAkB,KAAG,OAAO,CAAC,YAAY,CAOnF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,sBAA6B,MAAM,eAAe,MAAM,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,CAYjH,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { FC } from 'react';
2
+ import { SlackChannel } from '../../types/wire';
3
+ interface ChannelPickerProps {
4
+ channels: SlackChannel[];
5
+ isLoading: boolean;
6
+ isWarming: boolean;
7
+ value: string | null;
8
+ onChange: (channelId: string) => void;
9
+ }
10
+ /**
11
+ * Channel tab — Figma M2 1719:109242. A search box sitting directly above an
12
+ * inline, always-visible results list (NOT a MUI Autocomplete popper): the
13
+ * list is part of the same bordered card as the search input, capped to a
14
+ * scrollable window (dev note on both Figma boards: max ~3 rows visible).
15
+ *
16
+ * Note: Figma's row shows a member count under the channel name, but
17
+ * `GET /channels` (useSlackChannels) doesn't return one — the wire type
18
+ * (`SlackChannel`) only has `isPrivate`/`isMember`, so that line is omitted
19
+ * here rather than fabricated.
20
+ */
21
+ export declare const ChannelPicker: FC<ChannelPickerProps>;
22
+ export {};
23
+ //# sourceMappingURL=ChannelPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelPicker.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkExistingModal/ChannelPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAqB,MAAM,OAAO,CAAC;AAS9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA6IhD,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { FC } from 'react';
2
+ interface LinkExistingModalProps {
3
+ open: boolean;
4
+ onClose: () => void;
5
+ /** Fired on success with the NEW link's id (externalConversationId)
6
+ * so the parent can select/open it. */
7
+ onLinked?: (linkId: string) => void;
8
+ /** 409 slack_target_already_linked: the parent switches to the
9
+ * existing item instead of surfacing an error. */
10
+ onAlreadyLinked?: (existingLinkId: string) => void;
11
+ /** Links currently on the conversation — analytics metadata only
12
+ * (PRD: linked count 0–3 at the moment of linking). */
13
+ linkedCount?: number;
14
+ }
15
+ /**
16
+ * M2 "Link Slack Conversation" modal (Figma M2 1705:92605 / 1719:109242).
17
+ * Two tabs:
18
+ * Thread — paste a Slack thread permalink → Fetch → preview card
19
+ * (first message, channel, member count, type) → link.
20
+ * Channel — search the workspace channel directory → pick → link.
21
+ *
22
+ * Both link endpoints ALWAYS post before linking; per product decision
23
+ * D2 the modal has no compose box and sends `messageText: ''`.
24
+ * Preview rides GET /link-preview (the real endpoint that closed the D1
25
+ * gap): the raw pasted URL goes up as `preview_link`, the response's
26
+ * canonical channelId/threadTs feed /link/existing-thread, and
27
+ * `viewerCanAccess: false` blocks linking with an access error.
28
+ */
29
+ export declare const LinkExistingModal: FC<LinkExistingModalProps>;
30
+ export {};
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkExistingModal/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAyB,MAAM,OAAO,CAAC;AAsClD,UAAU,sBAAsB;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;4CACwC;IACxC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC;uDACmD;IACnD,eAAe,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD;4DACwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAyUxD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { BoxProps, StackProps } from '@hiver/hiver-ui-kit';
2
+ import { StyledComponent } from '@emotion/styled';
3
+ /**
4
+ * LinkExistingModal-only chrome (Figma 1705:92605 not-fetched /
5
+ * 1705:86410 fetched). The shared StartModal primitives stay untouched —
6
+ * these three exist because the link modal's layout differs from the
7
+ * start modal's: the field group sits inside its own bordered card, the
8
+ * footer carries a hairline divider, and the content area keeps a fixed
9
+ * minimum height so the not-yet-fetched state doesn't collapse.
10
+ */
11
+ /** Bordered rounded card wrapping the tab's field group (label + URL
12
+ * input + fetched preview on the Thread tab). Radius matches the
13
+ * TabTrack's 12px rather than any t.radius step. */
14
+ export declare const FieldGroupCard: StyledComponent<BoxProps>;
15
+ /** Gives the tab content a stable, ample footprint: before a preview is
16
+ * fetched the card is short, and without this the modal collapses to
17
+ * hug it. The card grows into this space once a preview loads. */
18
+ export declare const TabPanel: StyledComponent<BoxProps>;
19
+ /** ModalFooter + the hairline divider above the actions. */
20
+ export declare const DividedFooter: StyledComponent<StackProps>;
21
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkExistingModal/style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKvD;;;;;;;GAOG;AAEH;;qDAEqD;AACrD,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,QAAQ,CAMpD,CAAC;AAEF;;mEAEmE;AACnE,eAAO,MAAM,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAI9C,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,UAAU,CAGrD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/Composer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,EAAE,EAA+E,MAAM,OAAO,CAAC;AAgFvH,UAAU,aAAa;IACrB;oEACgE;IAChE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAChD;wEACoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;oDACgD;IAChD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;4CAEwC;IACxC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC;;;wEAGoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAijBtC,CAAC"}
1
+ {"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/Composer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,EAAE,EAA+E,MAAM,OAAO,CAAC;AAoFvH,UAAU,aAAa;IACrB;oEACgE;IAChE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAChD;wEACoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;oDACgD;IAChD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;4CAEwC;IACxC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC;;;wEAGoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CA+jBtC,CAAC"}
@@ -7,14 +7,21 @@ interface LinkedChannelHeaderProps {
7
7
  * present, the additive `URL:` row renders a blue, truncated link opening in
8
8
  * a new tab. Absent → `Channel:`-only Phase-1 layout. */
9
9
  channelUrl?: string;
10
+ /** Multi-link (M2): render a "← Back" row above the meta rows, returning to
11
+ * the links list. Absent (flag off / single link) → no back affordance. */
12
+ onBack?: () => void;
13
+ /** Multi-link (M2): render the kebab (⋮) menu with the Unlink action.
14
+ * Absent → no kebab (flag off). */
15
+ onUnlink?: () => void;
10
16
  }
11
17
  /**
12
18
  * HIG-only top content band (Figma 679:621193) pinned above the linked panel.
13
19
  * Phase 1 renders a `Channel:` (gray label) + `#<name>` (dark value) row; Phase 2
14
20
  * adds an additive `URL:` row (blue, truncated link opening Slack in a new tab)
15
- * whenever a `channelUrl` is supplied. The bottom hairline lives on
16
- * `ChannelHeaderBand`. Purely presentational — gated by `showChannelHeader` at
17
- * the call site.
21
+ * whenever a `channelUrl` is supplied. M2 (multi-link) adds an optional "← Back"
22
+ * row (returns to the links list, Figma M2 1699:30955) and a kebab menu with
23
+ * Unlink on the Channel row (Figma M2 1767:108199). The bottom hairline lives on
24
+ * `ChannelHeaderBand`. Gated by `showChannelHeader` at the call site.
18
25
  */
19
26
  export declare const LinkedChannelHeader: FC<LinkedChannelHeaderProps>;
20
27
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"LinkedChannelHeader.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/LinkedChannelHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAM3B,UAAU,wBAAwB;IAChC;sFACkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB;;8DAE0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAYD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CA4C5D,CAAC"}
1
+ {"version":3,"file":"LinkedChannelHeader.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/LinkedChannelHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAwB,MAAM,OAAO,CAAC;AAOjD,UAAU,wBAAwB;IAChC;sFACkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB;;8DAE0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;gFAC4E;IAC5E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;wCACoC;IACpC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAYD;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAyH5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/MessageItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,EAAE,EAA8C,MAAM,OAAO,CAAC;AAYtF,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,6BAA6B,CAAC;AAiB/E,UAAU,gBAAgB;IACxB,OAAO,EAAE,YAAY,CAAC;IACtB;wEACoE;IACpE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;4DAGwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;kCAE8B;IAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;2EACuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;gDAE4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;yEAEqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;yEAGqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;yDACqD;IACrD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAkDD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAwQ5C,CAAC"}
1
+ {"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/MessageItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,EAAE,EAA8C,MAAM,OAAO,CAAC;AAatF,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,6BAA6B,CAAC;AAiB/E,UAAU,gBAAgB;IACxB,OAAO,EAAE,YAAY,CAAC;IACtB;wEACoE;IACpE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;4DAGwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;kCAE8B;IAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;2EACuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;gDAE4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;yEAEqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;yEAGqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;yDACqD;IACrD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAkDD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA0Q5C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadDetailView.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/ThreadDetailView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,SAAS,EAAyC,MAAM,OAAO,CAAC;AA0F7E,UAAU,qBAAqB;IAC7B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;0EACsE;IACtE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;qEAEiE;IACjE,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CA0KtD,CAAC"}
1
+ {"version":3,"file":"ThreadDetailView.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/ThreadDetailView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,SAAS,EAAyC,MAAM,OAAO,CAAC;AA4F7E,UAAU,qBAAqB;IAC7B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;0EACsE;IACtE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;qEAEiE;IACjE,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAiLtD,CAAC"}
@@ -23,5 +23,22 @@ import { FC } from 'react';
23
23
  * The 50-entry trim flag (`isTrimmed`) renders a muted footer at
24
24
  * the top of the scroll list when the cache hit the M1 cap.
25
25
  */
26
- export declare const LinkedConversationPanel: FC;
26
+ export interface LinkedConversationPanelProps {
27
+ /** Multi-link (M2): pin the panel to ONE link row. Every read/write in
28
+ * the subtree is scoped to it (via LinkScopeProvider). Undefined =
29
+ * flag-off single-link mode — today's behavior, byte-identical keys. */
30
+ linkId?: string;
31
+ /** Multi-link: "← Back" in the channel band returns to the links list. */
32
+ onBack?: () => void;
33
+ /** Multi-link: fired after a successful unlink so the parent can drop
34
+ * the selection and fall back to the list. */
35
+ onUnlinked?: () => void;
36
+ }
37
+ /**
38
+ * Public surface. Wraps the panel subtree in LinkScopeProvider so deep
39
+ * call sites (Composer cache patches, MessageItem delete, the thread
40
+ * drill-in) read the SAME linkId this panel is pinned to without prop
41
+ * threading. Flag-off callers mount it prop-less — nothing changes.
42
+ */
43
+ export declare const LinkedConversationPanel: FC<LinkedConversationPanelProps>;
27
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAA8D,MAAM,OAAO,CAAC;AA+BvF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,uBAAuB,EAAE,EAmhBrC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/LinkedConversationPanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAA8D,MAAM,OAAO,CAAC;AAqCvF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;6EAEyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;mDAC+C;IAC/C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AA8kBD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,4BAA4B,CAIpE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SlackConversationTab.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/components/SlackConversationTab.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAoC,MAAM,OAAO,CAAC;AAwB7D,UAAU,yBAAyB;IACjC;;oDAEgD;IAChD,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC;AAuCD,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAmN9D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"SlackConversationTab.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/components/SlackConversationTab.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAA4C,MAAM,OAAO,CAAC;AAkCrE,UAAU,yBAAyB;IACjC;;oDAEgD;IAChD,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC;AA0CD,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAmZ9D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { FC } from 'react';
2
+ import { SlackLink } from '../types/wire';
3
+ interface SlackLinkListProps {
4
+ links: SlackLink[];
5
+ /** Server-authoritative cap info (never hardcode 4 — decision D6). */
6
+ cap: number;
7
+ remainingSlots: number;
8
+ onOpen: (linkId: string) => void;
9
+ onStartNew: () => void;
10
+ onLinkExisting: () => void;
11
+ }
12
+ /**
13
+ * Multi-link switcher — the HIG Slack tab's landing view (Figma M2
14
+ * 1673:23178): one card per linked Slack conversation with its unread
15
+ * count, then "+ Start new" + "Link existing" CTAs. Both CTAs disable
16
+ * at zero remaining slots with the server-cap limit message.
17
+ *
18
+ * Purely presentational — the parent (SlackConversationTab) owns the
19
+ * links query, selection state, and the two modals.
20
+ */
21
+ export declare const SlackLinkList: FC<SlackLinkListProps>;
22
+ export {};
23
+ //# sourceMappingURL=SlackLinkList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlackLinkList.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/components/SlackLinkList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAM3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,UAAU,kBAAkB;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AA+BD;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAyFhD,CAAC"}
@@ -3,8 +3,14 @@ interface StartModalProps {
3
3
  open: boolean;
4
4
  onClose: () => void;
5
5
  /** Called after a successful start, with the linked channel id so
6
- * the parent can transition to the linked-conv view. */
7
- onStarted?: (channelId: string) => void;
6
+ * the parent can transition to the linked-conv view. M2 adds the new
7
+ * link row's id (`externalConversationId`) as a second arg so the
8
+ * multi-link tab can select the exact item without waiting a poll. */
9
+ onStarted?: (channelId: string, linkId?: string) => void;
10
+ /** Multi-link (M2): 409 slack_target_already_linked → the parent
11
+ * switches to the existing item (Figma M2 "switch to that tab").
12
+ * Absent (flag off) → the M1 silent-adopt behavior is preserved. */
13
+ onAlreadyLinked?: (existingLinkId: string) => void;
8
14
  }
9
15
  /**
10
16
  * UI-2 — shared shell for the "Start new" flow. Two tabs:
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/StartModal/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAqD,MAAM,OAAO,CAAC;AAkC9E,UAAU,eAAe;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;6DACyD;IACzD,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAID;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAkP1C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/slack/components/StartModal/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAqD,MAAM,OAAO,CAAC;AAmC9E,UAAU,eAAe;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;2EAGuE;IACvE,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD;;yEAEqE;IACrE,eAAe,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAID;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA2P1C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/components/style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,QAAQ,CAOpD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAAC,UAAU,CAO3D,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAAe,CAAC,QAAQ,CAM7D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,eAAe,CAAC,QAAQ,CAQrD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,UAAU,CAatD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,WAAW,CAqBtD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAAC,WAAW,CA4B3D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAAe,CAAC,WAAW,CAexD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,QAAQ,CASnD,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAAe,CAAC,QAAQ,CAa/C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,QAAQ,CASpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAAC,eAAe,CAiB7D,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAAe,CAAC,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAIhF,CAAC"}
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/components/style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,QAAQ,CAOpD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAAC,UAAU,CAO3D,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAAe,CAAC,QAAQ,CAM7D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,eAAe,CAAC,QAAQ,CAQrD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,UAAU,CAatD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,WAAW,CAqBtD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAAe,CAAC,WAAW,CA4B3D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAAe,CAAC,WAAW,CAkBxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,QAAQ,CASnD,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAAe,CAAC,QAAQ,CAa/C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,QAAQ,CASpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAAC,eAAe,CAiB7D,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAAe,CAAC,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAIhF,CAAC"}
@@ -7,6 +7,12 @@ export declare const SLACK_MESSAGE_BY_ID_API: string;
7
7
  export declare const SLACK_EXTERNAL_CONVERSATION_API: string;
8
8
  export declare const SLACK_THREAD_API: string;
9
9
  export declare const SLACK_EXTERNAL_CONVERSATIONS_BY_TARGET_API: string;
10
+ export declare const SLACK_LINKS_API: string;
11
+ export declare const SLACK_LINK_BY_ID_API: string;
12
+ export declare const SLACK_LINK_READ_API: string;
13
+ export declare const SLACK_LINK_EXISTING_THREAD_API: string;
14
+ export declare const SLACK_LINK_EXISTING_CHANNEL_API: string;
15
+ export declare const SLACK_LINK_PREVIEW_API: string;
10
16
  export declare const SLACK_CHANNEL_MEMBERS_API: string;
11
17
  export declare const SLACK_CHANNELS_API: string;
12
18
  export declare const SLACK_WORKSPACE_USERS_API: string;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/constants/api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,yBAAyB,CAAC;AACrD,eAAO,MAAM,gBAAgB,+BAA4B,CAAC;AAE1D,eAAO,MAAM,gCAAgC,EAAE,MAAqD,CAAC;AACrG,eAAO,MAAM,2BAA2B,EAAE,MAAgD,CAAC;AAE3F,eAAO,MAAM,kBAAkB,EAAE,MAAuC,CAAC;AAGzE,eAAO,MAAM,uBAAuB,EAAE,MAA0D,CAAC;AAEjG,eAAO,MAAM,+BAA+B,EAAE,MAAiE,CAAC;AAGhH,eAAO,MAAM,gBAAgB,EAAE,MAAmF,CAAC;AACnH,eAAO,MAAM,0CAA0C,EAAE,MAA+D,CAAC;AAEzH,eAAO,MAAM,yBAAyB,EAAE,MAA8C,CAAC;AAMvF,eAAO,MAAM,kBAAkB,EAAE,MAAuC,CAAC;AASzE,eAAO,MAAM,yBAAyB,EAAE,MAAoC,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/features/slack/constants/api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,yBAAyB,CAAC;AACrD,eAAO,MAAM,gBAAgB,+BAA4B,CAAC;AAE1D,eAAO,MAAM,gCAAgC,EAAE,MAAqD,CAAC;AACrG,eAAO,MAAM,2BAA2B,EAAE,MAAgD,CAAC;AAE3F,eAAO,MAAM,kBAAkB,EAAE,MAAuC,CAAC;AAGzE,eAAO,MAAM,uBAAuB,EAAE,MAA0D,CAAC;AAEjG,eAAO,MAAM,+BAA+B,EAAE,MAAiE,CAAC;AAGhH,eAAO,MAAM,gBAAgB,EAAE,MAAmF,CAAC;AACnH,eAAO,MAAM,0CAA0C,EAAE,MAA+D,CAAC;AAKzH,eAAO,MAAM,eAAe,EAAE,MAAwE,CAAC;AAEvG,eAAO,MAAM,oBAAoB,EAAE,MAAgF,CAAC;AAGpH,eAAO,MAAM,mBAAmB,EAAE,MAAqF,CAAC;AAGxH,eAAO,MAAM,8BAA8B,EAAE,MAAmD,CAAC;AACjG,eAAO,MAAM,+BAA+B,EAAE,MAAoD,CAAC;AAMnG,eAAO,MAAM,sBAAsB,EAAE,MAA2C,CAAC;AAEjF,eAAO,MAAM,yBAAyB,EAAE,MAA8C,CAAC;AAMvF,eAAO,MAAM,kBAAkB,EAAE,MAAuC,CAAC;AASzE,eAAO,MAAM,yBAAyB,EAAE,MAAoC,CAAC"}