@cat-factory/integrations 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +68 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +84 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/modules/datadog/DatadogClient.d.ts +54 -0
  7. package/dist/modules/datadog/DatadogClient.d.ts.map +1 -0
  8. package/dist/modules/datadog/DatadogClient.js +132 -0
  9. package/dist/modules/datadog/DatadogClient.js.map +1 -0
  10. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts +30 -0
  11. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts.map +1 -0
  12. package/dist/modules/datadog/DatadogReleaseHealthProvider.js +101 -0
  13. package/dist/modules/datadog/DatadogReleaseHealthProvider.js.map +1 -0
  14. package/dist/modules/datadog/datadog.logic.d.ts +37 -0
  15. package/dist/modules/datadog/datadog.logic.d.ts.map +1 -0
  16. package/dist/modules/datadog/datadog.logic.js +90 -0
  17. package/dist/modules/datadog/datadog.logic.js.map +1 -0
  18. package/dist/modules/documents/ConfluenceProvider.d.ts +29 -0
  19. package/dist/modules/documents/ConfluenceProvider.d.ts.map +1 -0
  20. package/dist/modules/documents/ConfluenceProvider.js +180 -0
  21. package/dist/modules/documents/ConfluenceProvider.js.map +1 -0
  22. package/dist/modules/documents/DocumentConnectionService.d.ts +30 -0
  23. package/dist/modules/documents/DocumentConnectionService.d.ts.map +1 -0
  24. package/dist/modules/documents/DocumentConnectionService.js +69 -0
  25. package/dist/modules/documents/DocumentConnectionService.js.map +1 -0
  26. package/dist/modules/documents/DocumentImportService.d.ts +34 -0
  27. package/dist/modules/documents/DocumentImportService.d.ts.map +1 -0
  28. package/dist/modules/documents/DocumentImportService.js +83 -0
  29. package/dist/modules/documents/DocumentImportService.js.map +1 -0
  30. package/dist/modules/documents/DocumentLinkService.d.ts +31 -0
  31. package/dist/modules/documents/DocumentLinkService.d.ts.map +1 -0
  32. package/dist/modules/documents/DocumentLinkService.js +75 -0
  33. package/dist/modules/documents/DocumentLinkService.js.map +1 -0
  34. package/dist/modules/documents/DocumentPlannerService.d.ts +23 -0
  35. package/dist/modules/documents/DocumentPlannerService.d.ts.map +1 -0
  36. package/dist/modules/documents/DocumentPlannerService.js +96 -0
  37. package/dist/modules/documents/DocumentPlannerService.js.map +1 -0
  38. package/dist/modules/documents/GitHubDocsProvider.d.ts +42 -0
  39. package/dist/modules/documents/GitHubDocsProvider.d.ts.map +1 -0
  40. package/dist/modules/documents/GitHubDocsProvider.js +86 -0
  41. package/dist/modules/documents/GitHubDocsProvider.js.map +1 -0
  42. package/dist/modules/documents/NotionProvider.d.ts +32 -0
  43. package/dist/modules/documents/NotionProvider.d.ts.map +1 -0
  44. package/dist/modules/documents/NotionProvider.js +221 -0
  45. package/dist/modules/documents/NotionProvider.js.map +1 -0
  46. package/dist/modules/documents/confluence.logic.d.ts +37 -0
  47. package/dist/modules/documents/confluence.logic.d.ts.map +1 -0
  48. package/dist/modules/documents/confluence.logic.js +133 -0
  49. package/dist/modules/documents/confluence.logic.js.map +1 -0
  50. package/dist/modules/documents/documents.logic.d.ts +22 -0
  51. package/dist/modules/documents/documents.logic.d.ts.map +1 -0
  52. package/dist/modules/documents/documents.logic.js +138 -0
  53. package/dist/modules/documents/documents.logic.js.map +1 -0
  54. package/dist/modules/documents/github-docs.logic.d.ts +52 -0
  55. package/dist/modules/documents/github-docs.logic.d.ts.map +1 -0
  56. package/dist/modules/documents/github-docs.logic.js +94 -0
  57. package/dist/modules/documents/github-docs.logic.js.map +1 -0
  58. package/dist/modules/documents/notion.logic.d.ts +31 -0
  59. package/dist/modules/documents/notion.logic.d.ts.map +1 -0
  60. package/dist/modules/documents/notion.logic.js +142 -0
  61. package/dist/modules/documents/notion.logic.js.map +1 -0
  62. package/dist/modules/email/EmailConnectionService.d.ts +34 -0
  63. package/dist/modules/email/EmailConnectionService.d.ts.map +1 -0
  64. package/dist/modules/email/EmailConnectionService.js +82 -0
  65. package/dist/modules/email/EmailConnectionService.js.map +1 -0
  66. package/dist/modules/email/adapters.d.ts +39 -0
  67. package/dist/modules/email/adapters.d.ts.map +1 -0
  68. package/dist/modules/email/adapters.js +79 -0
  69. package/dist/modules/email/adapters.js.map +1 -0
  70. package/dist/modules/environments/EnvironmentConnectionService.d.ts +42 -0
  71. package/dist/modules/environments/EnvironmentConnectionService.d.ts.map +1 -0
  72. package/dist/modules/environments/EnvironmentConnectionService.js +120 -0
  73. package/dist/modules/environments/EnvironmentConnectionService.js.map +1 -0
  74. package/dist/modules/environments/EnvironmentProvisioningService.d.ts +56 -0
  75. package/dist/modules/environments/EnvironmentProvisioningService.d.ts.map +1 -0
  76. package/dist/modules/environments/EnvironmentProvisioningService.js +153 -0
  77. package/dist/modules/environments/EnvironmentProvisioningService.js.map +1 -0
  78. package/dist/modules/environments/EnvironmentTeardownService.d.ts +24 -0
  79. package/dist/modules/environments/EnvironmentTeardownService.d.ts.map +1 -0
  80. package/dist/modules/environments/EnvironmentTeardownService.js +54 -0
  81. package/dist/modules/environments/EnvironmentTeardownService.js.map +1 -0
  82. package/dist/modules/environments/HttpEnvironmentProvider.d.ts +30 -0
  83. package/dist/modules/environments/HttpEnvironmentProvider.d.ts.map +1 -0
  84. package/dist/modules/environments/HttpEnvironmentProvider.js +316 -0
  85. package/dist/modules/environments/HttpEnvironmentProvider.js.map +1 -0
  86. package/dist/modules/environments/environments.logic.d.ts +50 -0
  87. package/dist/modules/environments/environments.logic.d.ts.map +1 -0
  88. package/dist/modules/environments/environments.logic.js +257 -0
  89. package/dist/modules/environments/environments.logic.js.map +1 -0
  90. package/dist/modules/github/GitHubInstallationService.d.ts +66 -0
  91. package/dist/modules/github/GitHubInstallationService.d.ts.map +1 -0
  92. package/dist/modules/github/GitHubInstallationService.js +143 -0
  93. package/dist/modules/github/GitHubInstallationService.js.map +1 -0
  94. package/dist/modules/github/GitHubService.d.ts +29 -0
  95. package/dist/modules/github/GitHubService.d.ts.map +1 -0
  96. package/dist/modules/github/GitHubService.js +61 -0
  97. package/dist/modules/github/GitHubService.js.map +1 -0
  98. package/dist/modules/github/GitHubSyncService.d.ts +97 -0
  99. package/dist/modules/github/GitHubSyncService.d.ts.map +1 -0
  100. package/dist/modules/github/GitHubSyncService.js +241 -0
  101. package/dist/modules/github/GitHubSyncService.js.map +1 -0
  102. package/dist/modules/github/RepoProvisioningService.d.ts +26 -0
  103. package/dist/modules/github/RepoProvisioningService.d.ts.map +1 -0
  104. package/dist/modules/github/RepoProvisioningService.js +36 -0
  105. package/dist/modules/github/RepoProvisioningService.js.map +1 -0
  106. package/dist/modules/github/WebhookService.d.ts +28 -0
  107. package/dist/modules/github/WebhookService.d.ts.map +1 -0
  108. package/dist/modules/github/WebhookService.js +156 -0
  109. package/dist/modules/github/WebhookService.js.map +1 -0
  110. package/dist/modules/github/projection.logic.d.ts +95 -0
  111. package/dist/modules/github/projection.logic.d.ts.map +1 -0
  112. package/dist/modules/github/projection.logic.js +94 -0
  113. package/dist/modules/github/projection.logic.js.map +1 -0
  114. package/dist/modules/github/provisioning.logic.d.ts +11 -0
  115. package/dist/modules/github/provisioning.logic.d.ts.map +1 -0
  116. package/dist/modules/github/provisioning.logic.js +18 -0
  117. package/dist/modules/github/provisioning.logic.js.map +1 -0
  118. package/dist/modules/incident/incident.logic.d.ts +16 -0
  119. package/dist/modules/incident/incident.logic.d.ts.map +1 -0
  120. package/dist/modules/incident/incident.logic.js +23 -0
  121. package/dist/modules/incident/incident.logic.js.map +1 -0
  122. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts +26 -0
  123. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts.map +1 -0
  124. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js +84 -0
  125. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js.map +1 -0
  126. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts +27 -0
  127. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts.map +1 -0
  128. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js +65 -0
  129. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js.map +1 -0
  130. package/dist/modules/providers/ApiKeyService.d.ts +73 -0
  131. package/dist/modules/providers/ApiKeyService.d.ts.map +1 -0
  132. package/dist/modules/providers/ApiKeyService.js +122 -0
  133. package/dist/modules/providers/ApiKeyService.js.map +1 -0
  134. package/dist/modules/providers/LocalModelEndpointService.d.ts +52 -0
  135. package/dist/modules/providers/LocalModelEndpointService.d.ts.map +1 -0
  136. package/dist/modules/providers/LocalModelEndpointService.js +131 -0
  137. package/dist/modules/providers/LocalModelEndpointService.js.map +1 -0
  138. package/dist/modules/providers/PersonalSubscriptionService.d.ts +94 -0
  139. package/dist/modules/providers/PersonalSubscriptionService.d.ts.map +1 -0
  140. package/dist/modules/providers/PersonalSubscriptionService.js +218 -0
  141. package/dist/modules/providers/PersonalSubscriptionService.js.map +1 -0
  142. package/dist/modules/providers/ProviderSubscriptionService.d.ts +75 -0
  143. package/dist/modules/providers/ProviderSubscriptionService.d.ts.map +1 -0
  144. package/dist/modules/providers/ProviderSubscriptionService.js +130 -0
  145. package/dist/modules/providers/ProviderSubscriptionService.js.map +1 -0
  146. package/dist/modules/providers/localModelUrl.d.ts +7 -0
  147. package/dist/modules/providers/localModelUrl.d.ts.map +1 -0
  148. package/dist/modules/providers/localModelUrl.js +67 -0
  149. package/dist/modules/providers/localModelUrl.js.map +1 -0
  150. package/dist/modules/providers/providers.logic.d.ts +23 -0
  151. package/dist/modules/providers/providers.logic.d.ts.map +1 -0
  152. package/dist/modules/providers/providers.logic.js +46 -0
  153. package/dist/modules/providers/providers.logic.js.map +1 -0
  154. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts +51 -0
  155. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts.map +1 -0
  156. package/dist/modules/runners/HttpRunnerPoolProvider.js +304 -0
  157. package/dist/modules/runners/HttpRunnerPoolProvider.js.map +1 -0
  158. package/dist/modules/runners/RunnerPoolConnectionService.d.ts +47 -0
  159. package/dist/modules/runners/RunnerPoolConnectionService.d.ts.map +1 -0
  160. package/dist/modules/runners/RunnerPoolConnectionService.js +98 -0
  161. package/dist/modules/runners/RunnerPoolConnectionService.js.map +1 -0
  162. package/dist/modules/runners/RunnerPoolTransport.d.ts +11 -0
  163. package/dist/modules/runners/RunnerPoolTransport.d.ts.map +1 -0
  164. package/dist/modules/runners/RunnerPoolTransport.js +61 -0
  165. package/dist/modules/runners/RunnerPoolTransport.js.map +1 -0
  166. package/dist/modules/runners/runners.logic.d.ts +16 -0
  167. package/dist/modules/runners/runners.logic.d.ts.map +1 -0
  168. package/dist/modules/runners/runners.logic.js +52 -0
  169. package/dist/modules/runners/runners.logic.js.map +1 -0
  170. package/dist/modules/slack/SlackApiClient.d.ts +67 -0
  171. package/dist/modules/slack/SlackApiClient.d.ts.map +1 -0
  172. package/dist/modules/slack/SlackApiClient.js +132 -0
  173. package/dist/modules/slack/SlackApiClient.js.map +1 -0
  174. package/dist/modules/slack/SlackConnectionService.d.ts +41 -0
  175. package/dist/modules/slack/SlackConnectionService.d.ts.map +1 -0
  176. package/dist/modules/slack/SlackConnectionService.js +136 -0
  177. package/dist/modules/slack/SlackConnectionService.js.map +1 -0
  178. package/dist/modules/slack/SlackMemberMappingService.d.ts +17 -0
  179. package/dist/modules/slack/SlackMemberMappingService.d.ts.map +1 -0
  180. package/dist/modules/slack/SlackMemberMappingService.js +28 -0
  181. package/dist/modules/slack/SlackMemberMappingService.js.map +1 -0
  182. package/dist/modules/slack/SlackNotificationChannel.d.ts +45 -0
  183. package/dist/modules/slack/SlackNotificationChannel.d.ts.map +1 -0
  184. package/dist/modules/slack/SlackNotificationChannel.js +84 -0
  185. package/dist/modules/slack/SlackNotificationChannel.js.map +1 -0
  186. package/dist/modules/slack/SlackSettingsService.d.ts +16 -0
  187. package/dist/modules/slack/SlackSettingsService.d.ts.map +1 -0
  188. package/dist/modules/slack/SlackSettingsService.js +41 -0
  189. package/dist/modules/slack/SlackSettingsService.js.map +1 -0
  190. package/dist/modules/slack/slack.logic.d.ts +55 -0
  191. package/dist/modules/slack/slack.logic.d.ts.map +1 -0
  192. package/dist/modules/slack/slack.logic.js +149 -0
  193. package/dist/modules/slack/slack.logic.js.map +1 -0
  194. package/dist/modules/tasks/GitHubIssuesProvider.d.ts +50 -0
  195. package/dist/modules/tasks/GitHubIssuesProvider.d.ts.map +1 -0
  196. package/dist/modules/tasks/GitHubIssuesProvider.js +92 -0
  197. package/dist/modules/tasks/GitHubIssuesProvider.js.map +1 -0
  198. package/dist/modules/tasks/JiraProvider.d.ts +29 -0
  199. package/dist/modules/tasks/JiraProvider.d.ts.map +1 -0
  200. package/dist/modules/tasks/JiraProvider.js +114 -0
  201. package/dist/modules/tasks/JiraProvider.js.map +1 -0
  202. package/dist/modules/tasks/TaskConnectionService.d.ts +30 -0
  203. package/dist/modules/tasks/TaskConnectionService.d.ts.map +1 -0
  204. package/dist/modules/tasks/TaskConnectionService.js +69 -0
  205. package/dist/modules/tasks/TaskConnectionService.js.map +1 -0
  206. package/dist/modules/tasks/TaskImportService.d.ts +34 -0
  207. package/dist/modules/tasks/TaskImportService.d.ts.map +1 -0
  208. package/dist/modules/tasks/TaskImportService.js +96 -0
  209. package/dist/modules/tasks/TaskImportService.js.map +1 -0
  210. package/dist/modules/tasks/TaskLinkService.d.ts +30 -0
  211. package/dist/modules/tasks/TaskLinkService.d.ts.map +1 -0
  212. package/dist/modules/tasks/TaskLinkService.js +56 -0
  213. package/dist/modules/tasks/TaskLinkService.js.map +1 -0
  214. package/dist/modules/tasks/github-issues.logic.d.ts +35 -0
  215. package/dist/modules/tasks/github-issues.logic.d.ts.map +1 -0
  216. package/dist/modules/tasks/github-issues.logic.js +67 -0
  217. package/dist/modules/tasks/github-issues.logic.js.map +1 -0
  218. package/dist/modules/tasks/jira.logic.d.ts +28 -0
  219. package/dist/modules/tasks/jira.logic.d.ts.map +1 -0
  220. package/dist/modules/tasks/jira.logic.js +151 -0
  221. package/dist/modules/tasks/jira.logic.js.map +1 -0
  222. package/dist/modules/tasks/tasks.logic.d.ts +12 -0
  223. package/dist/modules/tasks/tasks.logic.d.ts.map +1 -0
  224. package/dist/modules/tasks/tasks.logic.js +17 -0
  225. package/dist/modules/tasks/tasks.logic.js.map +1 -0
  226. package/dist/modules/tracker/TicketTrackerService.d.ts +45 -0
  227. package/dist/modules/tracker/TicketTrackerService.d.ts.map +1 -0
  228. package/dist/modules/tracker/TicketTrackerService.js +52 -0
  229. package/dist/modules/tracker/TicketTrackerService.js.map +1 -0
  230. package/dist/modules/tracker/base64.d.ts +2 -0
  231. package/dist/modules/tracker/base64.d.ts.map +1 -0
  232. package/dist/modules/tracker/base64.js +18 -0
  233. package/dist/modules/tracker/base64.js.map +1 -0
  234. package/dist/modules/tracker/github.create.logic.d.ts +16 -0
  235. package/dist/modules/tracker/github.create.logic.d.ts.map +1 -0
  236. package/dist/modules/tracker/github.create.logic.js +25 -0
  237. package/dist/modules/tracker/github.create.logic.js.map +1 -0
  238. package/dist/modules/tracker/jira.create.logic.d.ts +31 -0
  239. package/dist/modules/tracker/jira.create.logic.d.ts.map +1 -0
  240. package/dist/modules/tracker/jira.create.logic.js +59 -0
  241. package/dist/modules/tracker/jira.create.logic.js.map +1 -0
  242. package/package.json +36 -0
@@ -0,0 +1,37 @@
1
+ import type { DocumentSearchResult, DocumentSourceDescriptor } from '@cat-factory/kernel';
2
+ /** What the connect UI renders, and which credentials the provider needs. */
3
+ export declare const CONFLUENCE_DESCRIPTOR: DocumentSourceDescriptor;
4
+ /**
5
+ * Build the CQL for a free-text page search: match the term anywhere in a page's
6
+ * text, newest first. Confluence's `text ~` is a fuzzy/word search, which is
7
+ * exactly what a "find a page" box wants.
8
+ */
9
+ export declare function buildConfluenceSearchCql(query: string): string;
10
+ /**
11
+ * Map a Confluence search response into lean hits. The endpoint nests the page
12
+ * under `content` (search API) or returns it flat (content/search API); we read
13
+ * either. URLs are resolved against the response's `base`, falling back to the
14
+ * site's `/wiki` base when absent.
15
+ */
16
+ export declare function parseConfluenceSearchResults(json: unknown, fallbackBase: string): DocumentSearchResult[];
17
+ /** Drop a trailing slash and a trailing `/wiki` so we can build paths uniformly. */
18
+ export declare function normalizeBaseUrl(baseUrl: string): string;
19
+ /**
20
+ * Resolve a Confluence page id from raw user input: a bare numeric id, a modern
21
+ * `/wiki/spaces/…/pages/<id>/…` URL, or a legacy `?pageId=<id>` URL.
22
+ */
23
+ export declare function parseConfluenceRef(input: string): string | null;
24
+ /**
25
+ * Validate a (normalized) Confluence base URL before it is stored and later
26
+ * fetched. Delegates to the shared Atlassian guard (`https`-only, no embedded
27
+ * credentials, no internal/private hosts), throwing {@link ValidationError} on
28
+ * anything unsafe.
29
+ */
30
+ export declare function assertSafeConfluenceBaseUrl(baseUrl: string): void;
31
+ /**
32
+ * Convert Confluence storage-format XHTML into the lightweight Markdown the
33
+ * generic planner/excerpt logic consumes: headings become `#`/`##`/`###`, list
34
+ * items become `- `, and block boundaries become newlines.
35
+ */
36
+ export declare function confluenceStorageToMarkdown(html: string): string;
37
+ //# sourceMappingURL=confluence.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confluence.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/confluence.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AASzF,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,EAAE,wBAuBnC,CAAA;AAOD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9D;AAYD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,MAAM,GACnB,oBAAoB,EAAE,CAkBxB;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ/D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjE;AAaD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWhE"}
@@ -0,0 +1,133 @@
1
+ import { assertSafeAtlassianBaseUrl, normalizeAtlassianBaseUrl } from '@cat-factory/kernel';
2
+ // Confluence-specific pure logic, kept out of the worker so it is unit-testable
3
+ // without a live site: parsing a page id out of user input, validating/securing
4
+ // the site base URL, and converting storage-format XHTML into the lightweight
5
+ // Markdown the generic planner consumes. The fetch itself lives in the worker's
6
+ // ConfluenceProvider.
7
+ /** What the connect UI renders, and which credentials the provider needs. */
8
+ export const CONFLUENCE_DESCRIPTOR = {
9
+ source: 'confluence',
10
+ label: 'Confluence',
11
+ icon: 'i-lucide-book-open',
12
+ credentialFields: [
13
+ {
14
+ key: 'baseUrl',
15
+ label: 'Site URL',
16
+ placeholder: 'https://your-team.atlassian.net',
17
+ help: 'e.g. https://your-team.atlassian.net',
18
+ },
19
+ { key: 'accountEmail', label: 'Account email', placeholder: 'you@company.com' },
20
+ {
21
+ key: 'apiToken',
22
+ label: 'API token',
23
+ secret: true,
24
+ placeholder: 'Paste a Confluence API token',
25
+ help: 'Create one at id.atlassian.com → Security → API tokens',
26
+ },
27
+ ],
28
+ refLabel: 'Page URL or ID',
29
+ refPlaceholder: 'https://…/pages/12345/Title or 12345',
30
+ searchable: true,
31
+ };
32
+ /** Escape a user string for embedding inside a CQL double-quoted literal. */
33
+ function escapeCql(query) {
34
+ return query.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
35
+ }
36
+ /**
37
+ * Build the CQL for a free-text page search: match the term anywhere in a page's
38
+ * text, newest first. Confluence's `text ~` is a fuzzy/word search, which is
39
+ * exactly what a "find a page" box wants.
40
+ */
41
+ export function buildConfluenceSearchCql(query) {
42
+ return `type = page AND text ~ "${escapeCql(query.trim())}" ORDER BY lastmodified DESC`;
43
+ }
44
+ /**
45
+ * Map a Confluence search response into lean hits. The endpoint nests the page
46
+ * under `content` (search API) or returns it flat (content/search API); we read
47
+ * either. URLs are resolved against the response's `base`, falling back to the
48
+ * site's `/wiki` base when absent.
49
+ */
50
+ export function parseConfluenceSearchResults(json, fallbackBase) {
51
+ const body = (json ?? {});
52
+ const base = body._links?.base ?? `${fallbackBase.replace(/\/+$/, '')}/wiki`;
53
+ const out = [];
54
+ for (const row of Array.isArray(body.results) ? body.results : []) {
55
+ const content = row.content ?? row;
56
+ const id = content.id;
57
+ if (!id)
58
+ continue;
59
+ const webui = row._links?.webui ?? '';
60
+ out.push({
61
+ source: 'confluence',
62
+ externalId: id,
63
+ title: content.title ?? '(untitled)',
64
+ url: webui ? `${base}${webui}` : `${base}/pages/${id}`,
65
+ excerpt: '',
66
+ });
67
+ }
68
+ return out;
69
+ }
70
+ /** Drop a trailing slash and a trailing `/wiki` so we can build paths uniformly. */
71
+ export function normalizeBaseUrl(baseUrl) {
72
+ return normalizeAtlassianBaseUrl(baseUrl);
73
+ }
74
+ /**
75
+ * Resolve a Confluence page id from raw user input: a bare numeric id, a modern
76
+ * `/wiki/spaces/…/pages/<id>/…` URL, or a legacy `?pageId=<id>` URL.
77
+ */
78
+ export function parseConfluenceRef(input) {
79
+ const trimmed = input.trim();
80
+ if (/^\d+$/.test(trimmed))
81
+ return trimmed;
82
+ const pageIdParam = trimmed.match(/[?&]pageId=(\d+)/);
83
+ if (pageIdParam)
84
+ return pageIdParam[1];
85
+ const pathMatch = trimmed.match(/\/pages\/(?:[a-z-]+\/)?(\d+)/i);
86
+ if (pathMatch)
87
+ return pathMatch[1];
88
+ return null;
89
+ }
90
+ /**
91
+ * Validate a (normalized) Confluence base URL before it is stored and later
92
+ * fetched. Delegates to the shared Atlassian guard (`https`-only, no embedded
93
+ * credentials, no internal/private hosts), throwing {@link ValidationError} on
94
+ * anything unsafe.
95
+ */
96
+ export function assertSafeConfluenceBaseUrl(baseUrl) {
97
+ assertSafeAtlassianBaseUrl(baseUrl);
98
+ }
99
+ /** Decode the handful of XHTML entities Confluence storage format emits. */
100
+ function decodeEntities(text) {
101
+ return text
102
+ .replace(/&nbsp;/gi, ' ')
103
+ .replace(/&amp;/gi, '&')
104
+ .replace(/&lt;/gi, '<')
105
+ .replace(/&gt;/gi, '>')
106
+ .replace(/&quot;/gi, '"')
107
+ .replace(/&#3?9;|&apos;/gi, "'");
108
+ }
109
+ /**
110
+ * Convert Confluence storage-format XHTML into the lightweight Markdown the
111
+ * generic planner/excerpt logic consumes: headings become `#`/`##`/`###`, list
112
+ * items become `- `, and block boundaries become newlines.
113
+ */
114
+ export function confluenceStorageToMarkdown(html) {
115
+ const withMarkers = html
116
+ .replace(/<h1\b[^>]*>([\s\S]*?)<\/h1>/gi, (_m, c) => `\n# ${stripTags(c)}\n`)
117
+ .replace(/<h2\b[^>]*>([\s\S]*?)<\/h2>/gi, (_m, c) => `\n## ${stripTags(c)}\n`)
118
+ .replace(/<h[3-6]\b[^>]*>([\s\S]*?)<\/h[3-6]>/gi, (_m, c) => `\n### ${stripTags(c)}\n`)
119
+ .replace(/<li\b[^>]*>([\s\S]*?)<\/li>/gi, (_m, c) => `\n- ${stripTags(c)}\n`)
120
+ .replace(/<\s*(br|\/p|\/div)\s*\/?>/gi, '\n');
121
+ return decodeEntities(stripTags(withMarkers))
122
+ .replace(/[ \t]+\n/g, '\n')
123
+ .replace(/\n{3,}/g, '\n\n')
124
+ .trim();
125
+ }
126
+ /** Strip any remaining tags and collapse intra-line whitespace. */
127
+ function stripTags(html) {
128
+ return html
129
+ .replace(/<[^>]+>/g, ' ')
130
+ .replace(/[ \t]+/g, ' ')
131
+ .trim();
132
+ }
133
+ //# sourceMappingURL=confluence.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confluence.logic.js","sourceRoot":"","sources":["../../../src/modules/documents/confluence.logic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { DocumentSourceKind } from '@cat-factory/kernel';
2
+ import type { DocumentBoardPlan } from '@cat-factory/kernel';
3
+ import type { DocumentSourceProvider, DocumentSourceRegistry } from '@cat-factory/kernel';
4
+ import { buildExcerpt, markdownToText, MapSourceRegistry } from '@cat-factory/kernel';
5
+ export { buildExcerpt, markdownToText };
6
+ /** A trivial in-memory provider registry built from the wired providers. */
7
+ export declare class MapDocumentSourceRegistry extends MapSourceRegistry<DocumentSourceKind, DocumentSourceProvider> implements DocumentSourceRegistry {
8
+ }
9
+ /**
10
+ * Deterministic fallback planner: map the document's heading outline onto the
11
+ * board. h1 → a service frame, h2 → a module within it, h3 → a task within the
12
+ * current module (or directly in the frame). Used whenever no LLM is configured,
13
+ * and as the safety net when an LLM response can't be parsed.
14
+ */
15
+ export declare function planFromHeadings(source: DocumentSourceKind, externalId: string, title: string, body: string): DocumentBoardPlan;
16
+ /**
17
+ * Coerce an LLM's parsed JSON into a well-formed {@link DocumentBoardPlan},
18
+ * dropping anything malformed. Returns null when nothing usable remains, so the
19
+ * caller can fall back to the heading parser.
20
+ */
21
+ export declare function coercePlan(source: DocumentSourceKind, externalId: string, parsed: unknown): DocumentBoardPlan | null;
22
+ //# sourceMappingURL=documents.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/documents.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAmC,MAAM,qBAAqB,CAAA;AAC7F,OAAO,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAKrF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAA;AAmBvC,4EAA4E;AAC5E,qBAAa,yBACX,SAAQ,iBAAiB,CAAC,kBAAkB,EAAE,sBAAsB,CACpE,YAAW,sBAAsB;CAAG;AAmBtC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,iBAAiB,CAiCnB;AAiBD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,iBAAiB,GAAG,IAAI,CAiC1B"}
@@ -0,0 +1,138 @@
1
+ import { buildExcerpt, markdownToText, MapSourceRegistry } from '@cat-factory/kernel';
2
+ // `markdownToText`/`buildExcerpt` now live in the shared markdown helpers (also
3
+ // used by the task-source integration); re-exported here so existing
4
+ // `documentsLogic.*` consumers are unchanged.
5
+ export { buildExcerpt, markdownToText };
6
+ // Source-agnostic helpers shared by every document source: deriving a plain-text
7
+ // excerpt from a Markdown body, the deterministic heading-based planner, and
8
+ // coercion of an LLM's JSON into a well-formed board plan. Providers normalize
9
+ // their page bodies to lightweight Markdown so these stay independent of any one
10
+ // source's format. Keeping them pure makes the planner deterministic and
11
+ // trivially testable without a live source or an LLM.
12
+ const BLOCK_TYPES = [
13
+ 'frontend',
14
+ 'service',
15
+ 'api',
16
+ 'database',
17
+ 'queue',
18
+ 'integration',
19
+ 'external',
20
+ ];
21
+ /** A trivial in-memory provider registry built from the wired providers. */
22
+ export class MapDocumentSourceRegistry extends MapSourceRegistry {
23
+ }
24
+ /** Extract `#`/`##`/`###` headings (clamped to 1–3), in document order. */
25
+ function extractHeadings(markdown) {
26
+ const headings = [];
27
+ const re = /^[ \t]*(#{1,6})[ \t]+(.+?)[ \t]*#*$/gm;
28
+ let m;
29
+ while ((m = re.exec(markdown)) !== null) {
30
+ const text = m[2].trim();
31
+ if (text)
32
+ headings.push({ level: Math.min(m[1].length, 3), text });
33
+ }
34
+ return headings;
35
+ }
36
+ /**
37
+ * Deterministic fallback planner: map the document's heading outline onto the
38
+ * board. h1 → a service frame, h2 → a module within it, h3 → a task within the
39
+ * current module (or directly in the frame). Used whenever no LLM is configured,
40
+ * and as the safety net when an LLM response can't be parsed.
41
+ */
42
+ export function planFromHeadings(source, externalId, title, body) {
43
+ const headings = extractHeadings(body);
44
+ const frames = [];
45
+ let frame = null;
46
+ let module = null;
47
+ const ensureFrame = () => {
48
+ if (!frame) {
49
+ frame = { type: 'service', title, modules: [], tasks: [] };
50
+ frames.push(frame);
51
+ }
52
+ return frame;
53
+ };
54
+ for (const heading of headings) {
55
+ if (heading.level === 1) {
56
+ frame = { type: 'service', title: heading.text, modules: [], tasks: [] };
57
+ frames.push(frame);
58
+ module = null;
59
+ }
60
+ else if (heading.level === 2) {
61
+ module = { name: heading.text, tasks: [] };
62
+ ensureFrame().modules.push(module);
63
+ }
64
+ else {
65
+ const task = { title: heading.text };
66
+ if (module)
67
+ module.tasks.push(task);
68
+ else
69
+ ensureFrame().tasks.push(task);
70
+ }
71
+ }
72
+ if (frames.length === 0) {
73
+ frames.push({ type: 'service', title, modules: [], tasks: [] });
74
+ }
75
+ return { source, externalId, planner: 'headings', frames };
76
+ }
77
+ function asString(value) {
78
+ return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined;
79
+ }
80
+ function coerceTask(value) {
81
+ if (typeof value !== 'object' || value === null)
82
+ return null;
83
+ const obj = value;
84
+ const title = asString(obj.title);
85
+ if (!title)
86
+ return null;
87
+ const task = { title };
88
+ const description = asString(obj.description);
89
+ if (description)
90
+ task.description = description;
91
+ return task;
92
+ }
93
+ /**
94
+ * Coerce an LLM's parsed JSON into a well-formed {@link DocumentBoardPlan},
95
+ * dropping anything malformed. Returns null when nothing usable remains, so the
96
+ * caller can fall back to the heading parser.
97
+ */
98
+ export function coercePlan(source, externalId, parsed) {
99
+ const root = parsed;
100
+ const rawFrames = Array.isArray(root?.frames) ? root.frames : [];
101
+ const frames = [];
102
+ for (const raw of rawFrames) {
103
+ if (typeof raw !== 'object' || raw === null)
104
+ continue;
105
+ const obj = raw;
106
+ const title = asString(obj.title);
107
+ if (!title)
108
+ continue;
109
+ const type = BLOCK_TYPES.includes(obj.type)
110
+ ? obj.type
111
+ : 'service';
112
+ const modules = [];
113
+ for (const rawModule of Array.isArray(obj.modules) ? obj.modules : []) {
114
+ if (typeof rawModule !== 'object' || rawModule === null)
115
+ continue;
116
+ const mod = rawModule;
117
+ const name = asString(mod.name);
118
+ if (!name)
119
+ continue;
120
+ const tasks = (Array.isArray(mod.tasks) ? mod.tasks : [])
121
+ .map(coerceTask)
122
+ .filter((t) => t !== null);
123
+ modules.push({ name, tasks });
124
+ }
125
+ const tasks = (Array.isArray(obj.tasks) ? obj.tasks : [])
126
+ .map(coerceTask)
127
+ .filter((t) => t !== null);
128
+ const frame = { type, title, modules, tasks };
129
+ const description = asString(obj.description);
130
+ if (description)
131
+ frame.description = description;
132
+ frames.push(frame);
133
+ }
134
+ if (frames.length === 0)
135
+ return null;
136
+ return { source, externalId, planner: 'llm', frames };
137
+ }
138
+ //# sourceMappingURL=documents.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.logic.js","sourceRoot":"","sources":["../../../src/modules/documents/documents.logic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { DocumentSourceDescriptor } from '@cat-factory/kernel';
2
+ /**
3
+ * What the connect UI renders. GitHub docs piggyback on the workspace's existing
4
+ * GitHub App installation, so there are NO credential fields — the connect form
5
+ * is just a confirmation, and `normalizeConnection` accepts an empty bag.
6
+ */
7
+ export declare const GITHUB_DOCS_DESCRIPTOR: DocumentSourceDescriptor;
8
+ /** The parts of a GitHub doc external id (`owner/repo:path`). */
9
+ export interface GitHubDocExternalId {
10
+ owner: string;
11
+ repo: string;
12
+ /** Path relative to the repo root, e.g. `docs/architecture.md`. */
13
+ path: string;
14
+ }
15
+ /** Build the canonical `owner/repo:path` external id from its parts. */
16
+ export declare function githubDocExternalId(id: GitHubDocExternalId): string;
17
+ /**
18
+ * Resolve a GitHub repo-doc reference from raw user input into the canonical
19
+ * `owner/repo:path` external id. Accepts:
20
+ * - a blob URL: `https://github.com/octo/repo/blob/main/docs/x.md`
21
+ * - a raw URL: `https://raw.githubusercontent.com/octo/repo/main/docs/x.md`
22
+ * - the shorthand `octo/repo:docs/x.md`
23
+ * The branch/ref in a URL is dropped — the provider reads the default branch — so
24
+ * the external id (and thus a re-import's identity) is branch-stable. Returns
25
+ * null when nothing parses. Owner/repo/path are kept verbatim (case-preserving).
26
+ *
27
+ * KNOWN LIMITATION: a URL whose branch name itself contains a slash
28
+ * (`…/blob/feature/x/README.md`) is ambiguous — the branch/path boundary cannot
29
+ * be recovered from the URL alone, so the first segment after `blob/` (or the
30
+ * ref slot of a raw URL) is assumed to be the whole ref and the rest the path.
31
+ * For files on a slash-named branch, use the unambiguous `owner/repo:path`
32
+ * shorthand instead. (The default branch is what the provider actually reads.)
33
+ */
34
+ export declare function parseGitHubDocRef(input: string): string | null;
35
+ /**
36
+ * Split a stored `owner/repo:path` external id back into its parts. Returns null
37
+ * if the id is malformed (defensive — ids are produced by
38
+ * {@link parseGitHubDocRef}, but a stale/hand-edited row should not throw).
39
+ */
40
+ export declare function parseGitHubDocExternalId(externalId: string): GitHubDocExternalId | null;
41
+ /** The canonical web URL for a doc external id (default branch via `HEAD`). */
42
+ export declare function githubDocUrl(id: GitHubDocExternalId): string;
43
+ /** A human title for a doc: its file base name (e.g. `architecture.md`). */
44
+ export declare function githubDocTitle(path: string): string;
45
+ /**
46
+ * Build a GitHub code-search query scoped to one account. GitHub's code-search
47
+ * API rejects unscoped queries, so we append an `org:`/`user:` qualifier chosen
48
+ * from the installation's target type. The free text is trimmed and the account
49
+ * login is taken verbatim (GitHub logins have no special search chars).
50
+ */
51
+ export declare function buildGitHubCodeSearchQuery(query: string, account: string, targetType: 'Organization' | 'User'): string;
52
+ //# sourceMappingURL=github-docs.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-docs.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/github-docs.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAWnE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,wBASpC,CAAA;AAMD,iEAAiE;AACjE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;CACb;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,mBAAmB,GAAG,MAAM,CAEnE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW9D;AAOD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAIvF;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,EAAE,EAAE,mBAAmB,GAAG,MAAM,CAE5D;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,cAAc,GAAG,MAAM,GAClC,MAAM,CAGR"}
@@ -0,0 +1,94 @@
1
+ // GitHub repo-doc document-source pure logic, kept out of the worker so it is
2
+ // unit-testable without a live API: parsing a file reference out of user input
3
+ // and round-tripping the `owner/repo:path` external id the provider stores. Like
4
+ // the GitHub-issues task source, the provider reuses the workspace's installed
5
+ // GitHub App, so this source needs no credentials of its own. A repo doc is a
6
+ // single Markdown/text file (a README, an RFC under `docs/`, an architecture
7
+ // note) linked to a task as context; the file body is already Markdown-ish, so
8
+ // there is no body-conversion step here.
9
+ /**
10
+ * What the connect UI renders. GitHub docs piggyback on the workspace's existing
11
+ * GitHub App installation, so there are NO credential fields — the connect form
12
+ * is just a confirmation, and `normalizeConnection` accepts an empty bag.
13
+ */
14
+ export const GITHUB_DOCS_DESCRIPTOR = {
15
+ source: 'github',
16
+ label: 'GitHub Docs',
17
+ icon: 'i-lucide-file-code-2',
18
+ credentialFields: [],
19
+ refLabel: 'File URL or owner/repo:path',
20
+ refPlaceholder: 'octo/repo:docs/architecture.md or https://github.com/octo/repo/blob/main/README.md',
21
+ searchable: true,
22
+ };
23
+ // An owner/repo segment: letters, digits, '.', '_' and '-'. Mirrors the GitHub
24
+ // issues source's segment grammar.
25
+ const SEG = '[A-Za-z0-9._-]+';
26
+ /** Build the canonical `owner/repo:path` external id from its parts. */
27
+ export function githubDocExternalId(id) {
28
+ return `${id.owner}/${id.repo}:${id.path}`;
29
+ }
30
+ /**
31
+ * Resolve a GitHub repo-doc reference from raw user input into the canonical
32
+ * `owner/repo:path` external id. Accepts:
33
+ * - a blob URL: `https://github.com/octo/repo/blob/main/docs/x.md`
34
+ * - a raw URL: `https://raw.githubusercontent.com/octo/repo/main/docs/x.md`
35
+ * - the shorthand `octo/repo:docs/x.md`
36
+ * The branch/ref in a URL is dropped — the provider reads the default branch — so
37
+ * the external id (and thus a re-import's identity) is branch-stable. Returns
38
+ * null when nothing parses. Owner/repo/path are kept verbatim (case-preserving).
39
+ *
40
+ * KNOWN LIMITATION: a URL whose branch name itself contains a slash
41
+ * (`…/blob/feature/x/README.md`) is ambiguous — the branch/path boundary cannot
42
+ * be recovered from the URL alone, so the first segment after `blob/` (or the
43
+ * ref slot of a raw URL) is assumed to be the whole ref and the rest the path.
44
+ * For files on a slash-named branch, use the unambiguous `owner/repo:path`
45
+ * shorthand instead. (The default branch is what the provider actually reads.)
46
+ */
47
+ export function parseGitHubDocRef(input) {
48
+ const trimmed = input.trim();
49
+ const blob = trimmed.match(new RegExp(`github\\.com/(${SEG})/(${SEG})/blob/[^/]+/(.+)$`));
50
+ if (blob)
51
+ return `${blob[1]}/${blob[2]}:${stripQuery(blob[3])}`;
52
+ const raw = trimmed.match(new RegExp(`raw\\.githubusercontent\\.com/(${SEG})/(${SEG})/[^/]+/(.+)$`));
53
+ if (raw)
54
+ return `${raw[1]}/${raw[2]}:${stripQuery(raw[3])}`;
55
+ const short = trimmed.match(new RegExp(`^(${SEG})/(${SEG}):(.+)$`));
56
+ if (short)
57
+ return `${short[1]}/${short[2]}:${short[3].replace(/^\/+/, '')}`;
58
+ return null;
59
+ }
60
+ /** Drop any `?query`/`#hash` and leading slashes from a URL path tail. */
61
+ function stripQuery(path) {
62
+ return path.split(/[?#]/)[0].replace(/^\/+/, '');
63
+ }
64
+ /**
65
+ * Split a stored `owner/repo:path` external id back into its parts. Returns null
66
+ * if the id is malformed (defensive — ids are produced by
67
+ * {@link parseGitHubDocRef}, but a stale/hand-edited row should not throw).
68
+ */
69
+ export function parseGitHubDocExternalId(externalId) {
70
+ const m = externalId.match(new RegExp(`^(${SEG})/(${SEG}):(.+)$`));
71
+ if (!m)
72
+ return null;
73
+ return { owner: m[1], repo: m[2], path: m[3] };
74
+ }
75
+ /** The canonical web URL for a doc external id (default branch via `HEAD`). */
76
+ export function githubDocUrl(id) {
77
+ return `https://github.com/${id.owner}/${id.repo}/blob/HEAD/${id.path}`;
78
+ }
79
+ /** A human title for a doc: its file base name (e.g. `architecture.md`). */
80
+ export function githubDocTitle(path) {
81
+ const base = path.split('/').filter(Boolean).pop();
82
+ return base && base.length > 0 ? base : path;
83
+ }
84
+ /**
85
+ * Build a GitHub code-search query scoped to one account. GitHub's code-search
86
+ * API rejects unscoped queries, so we append an `org:`/`user:` qualifier chosen
87
+ * from the installation's target type. The free text is trimmed and the account
88
+ * login is taken verbatim (GitHub logins have no special search chars).
89
+ */
90
+ export function buildGitHubCodeSearchQuery(query, account, targetType) {
91
+ const qualifier = targetType === 'Organization' ? 'org' : 'user';
92
+ return `${query.trim()} ${qualifier}:${account}`;
93
+ }
94
+ //# sourceMappingURL=github-docs.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-docs.logic.js","sourceRoot":"","sources":["../../../src/modules/documents/github-docs.logic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { DocumentSearchResult, DocumentSourceDescriptor } from '@cat-factory/kernel';
2
+ /** What the connect UI renders, and which credentials the provider needs. */
3
+ export declare const NOTION_DESCRIPTOR: DocumentSourceDescriptor;
4
+ /**
5
+ * Map a Notion `/v1/search` response into lean hits, keeping only pages (the API
6
+ * also returns databases). The page title is read from its `properties` exactly
7
+ * as the single-page fetch does, so list + import titles agree.
8
+ */
9
+ export declare function parseNotionSearchResults(json: unknown): DocumentSearchResult[];
10
+ /** Format 32 hex chars as a canonical dashed Notion/UUID id. */
11
+ export declare function formatNotionId(hex32: string): string;
12
+ /**
13
+ * Resolve a Notion page id from raw user input: a bare id (dashed UUID or 32 hex
14
+ * chars), or any Notion URL whose last path segment ends in the id. Returns the
15
+ * canonical dashed id, or null if none is found.
16
+ */
17
+ export declare function parseNotionRef(input: string): string | null;
18
+ /** The subset of a Notion block we read; the type key holds the rich text. */
19
+ export interface NotionBlock {
20
+ type?: string;
21
+ [key: string]: unknown;
22
+ }
23
+ /**
24
+ * Convert a Notion page's top-level blocks into the lightweight Markdown the
25
+ * generic planner/excerpt logic consumes: headings become `#`/`##`/`###`, list
26
+ * items / to-dos become `- `, and other text blocks become plain lines.
27
+ */
28
+ export declare function notionBlocksToMarkdown(blocks: NotionBlock[]): string;
29
+ /** Extract a page title from a Notion page object's `properties`. */
30
+ export declare function notionPageTitle(properties: Record<string, unknown> | undefined): string;
31
+ //# sourceMappingURL=notion.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/notion.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAQzF,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,EAAE,wBAgB/B,CAAA;AAWD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,oBAAoB,EAAE,CAgB9E;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAQD,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAcD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAkCpE;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAavF"}