patchwork-os 0.2.0-alpha.3 → 0.2.0-alpha.30

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 (298) hide show
  1. package/README.bridge.md +6 -0
  2. package/README.md +40 -15
  3. package/deploy/bootstrap-vps.sh +184 -0
  4. package/deploy/deploy-dashboard.sh +174 -0
  5. package/deploy/deploy-landing.sh +79 -0
  6. package/dist/activationMetrics.d.ts +67 -0
  7. package/dist/activationMetrics.js +255 -0
  8. package/dist/activationMetrics.js.map +1 -0
  9. package/dist/approvalHttp.d.ts +24 -2
  10. package/dist/approvalHttp.js +150 -10
  11. package/dist/approvalHttp.js.map +1 -1
  12. package/dist/approvalQueue.d.ts +16 -1
  13. package/dist/approvalQueue.js +44 -3
  14. package/dist/approvalQueue.js.map +1 -1
  15. package/dist/automation.d.ts +20 -0
  16. package/dist/automation.js +54 -1
  17. package/dist/automation.js.map +1 -1
  18. package/dist/bridge.d.ts +7 -0
  19. package/dist/bridge.js +225 -35
  20. package/dist/bridge.js.map +1 -1
  21. package/dist/bridgeToken.js +57 -19
  22. package/dist/bridgeToken.js.map +1 -1
  23. package/dist/ccPermissions.js +6 -4
  24. package/dist/ccPermissions.js.map +1 -1
  25. package/dist/claudeOrchestrator.d.ts +1 -1
  26. package/dist/claudeOrchestrator.js +14 -8
  27. package/dist/claudeOrchestrator.js.map +1 -1
  28. package/dist/commands/launchd.d.ts +2 -0
  29. package/dist/commands/launchd.js +94 -0
  30. package/dist/commands/launchd.js.map +1 -0
  31. package/dist/commands/recipe.d.ts +258 -0
  32. package/dist/commands/recipe.js +1130 -0
  33. package/dist/commands/recipe.js.map +1 -0
  34. package/dist/commands/recipeInstall.d.ts +72 -0
  35. package/dist/commands/recipeInstall.js +339 -0
  36. package/dist/commands/recipeInstall.js.map +1 -0
  37. package/dist/config.d.ts +14 -1
  38. package/dist/config.js +99 -8
  39. package/dist/config.js.map +1 -1
  40. package/dist/connectors/baseConnector.d.ts +117 -0
  41. package/dist/connectors/baseConnector.js +213 -0
  42. package/dist/connectors/baseConnector.js.map +1 -0
  43. package/dist/connectors/confluence.d.ts +111 -0
  44. package/dist/connectors/confluence.js +406 -0
  45. package/dist/connectors/confluence.js.map +1 -0
  46. package/dist/connectors/datadog.d.ts +116 -0
  47. package/dist/connectors/datadog.js +385 -0
  48. package/dist/connectors/datadog.js.map +1 -0
  49. package/dist/connectors/fixtureLibrary.d.ts +21 -0
  50. package/dist/connectors/fixtureLibrary.js +70 -0
  51. package/dist/connectors/fixtureLibrary.js.map +1 -0
  52. package/dist/connectors/fixtureRecorder.d.ts +1 -0
  53. package/dist/connectors/fixtureRecorder.js +35 -0
  54. package/dist/connectors/fixtureRecorder.js.map +1 -0
  55. package/dist/connectors/github.d.ts +58 -8
  56. package/dist/connectors/github.js +312 -84
  57. package/dist/connectors/github.js.map +1 -1
  58. package/dist/connectors/gmail.d.ts +4 -1
  59. package/dist/connectors/gmail.js +79 -16
  60. package/dist/connectors/gmail.js.map +1 -1
  61. package/dist/connectors/googleCalendar.d.ts +60 -0
  62. package/dist/connectors/googleCalendar.js +345 -0
  63. package/dist/connectors/googleCalendar.js.map +1 -0
  64. package/dist/connectors/hubspot.d.ts +112 -0
  65. package/dist/connectors/hubspot.js +408 -0
  66. package/dist/connectors/hubspot.js.map +1 -0
  67. package/dist/connectors/intercom.d.ts +102 -0
  68. package/dist/connectors/intercom.js +402 -0
  69. package/dist/connectors/intercom.js.map +1 -0
  70. package/dist/connectors/jira.d.ts +98 -0
  71. package/dist/connectors/jira.js +379 -0
  72. package/dist/connectors/jira.js.map +1 -0
  73. package/dist/connectors/linear.d.ts +69 -19
  74. package/dist/connectors/linear.js +170 -129
  75. package/dist/connectors/linear.js.map +1 -1
  76. package/dist/connectors/mcpClient.d.ts +56 -0
  77. package/dist/connectors/mcpClient.js +189 -0
  78. package/dist/connectors/mcpClient.js.map +1 -0
  79. package/dist/connectors/mcpOAuth.d.ts +84 -0
  80. package/dist/connectors/mcpOAuth.js +389 -0
  81. package/dist/connectors/mcpOAuth.js.map +1 -0
  82. package/dist/connectors/mockConnector.d.ts +28 -0
  83. package/dist/connectors/mockConnector.js +81 -0
  84. package/dist/connectors/mockConnector.js.map +1 -0
  85. package/dist/connectors/notion.d.ts +143 -0
  86. package/dist/connectors/notion.js +424 -0
  87. package/dist/connectors/notion.js.map +1 -0
  88. package/dist/connectors/sentry.d.ts +17 -21
  89. package/dist/connectors/sentry.js +115 -131
  90. package/dist/connectors/sentry.js.map +1 -1
  91. package/dist/connectors/slack.d.ts +50 -0
  92. package/dist/connectors/slack.js +324 -0
  93. package/dist/connectors/slack.js.map +1 -0
  94. package/dist/connectors/stripe.d.ts +116 -0
  95. package/dist/connectors/stripe.js +379 -0
  96. package/dist/connectors/stripe.js.map +1 -0
  97. package/dist/connectors/tokenStorage.d.ts +35 -0
  98. package/dist/connectors/tokenStorage.js +459 -0
  99. package/dist/connectors/tokenStorage.js.map +1 -0
  100. package/dist/connectors/zendesk.d.ts +104 -0
  101. package/dist/connectors/zendesk.js +424 -0
  102. package/dist/connectors/zendesk.js.map +1 -0
  103. package/dist/drivers/gemini/index.d.ts +5 -1
  104. package/dist/drivers/gemini/index.js +39 -5
  105. package/dist/drivers/gemini/index.js.map +1 -1
  106. package/dist/drivers/index.d.ts +5 -0
  107. package/dist/drivers/index.js +1 -1
  108. package/dist/drivers/index.js.map +1 -1
  109. package/dist/featureFlags.d.ts +73 -0
  110. package/dist/featureFlags.js +203 -0
  111. package/dist/featureFlags.js.map +1 -0
  112. package/dist/fp/automationInterpreter.js +1 -0
  113. package/dist/fp/automationInterpreter.js.map +1 -1
  114. package/dist/fp/automationProgram.d.ts +1 -1
  115. package/dist/fp/automationProgram.js.map +1 -1
  116. package/dist/fp/policyParser.js +17 -0
  117. package/dist/fp/policyParser.js.map +1 -1
  118. package/dist/index.js +621 -61
  119. package/dist/index.js.map +1 -1
  120. package/dist/installGuard.d.ts +25 -0
  121. package/dist/installGuard.js +48 -0
  122. package/dist/installGuard.js.map +1 -0
  123. package/dist/oauth.d.ts +4 -1
  124. package/dist/oauth.js +50 -14
  125. package/dist/oauth.js.map +1 -1
  126. package/dist/patchworkConfig.d.ts +9 -0
  127. package/dist/patchworkConfig.js.map +1 -1
  128. package/dist/recipes/RecipeOrchestrator.d.ts +40 -0
  129. package/dist/recipes/RecipeOrchestrator.js +51 -0
  130. package/dist/recipes/RecipeOrchestrator.js.map +1 -0
  131. package/dist/recipes/agentExecutor.d.ts +28 -0
  132. package/dist/recipes/agentExecutor.js +42 -0
  133. package/dist/recipes/agentExecutor.js.map +1 -0
  134. package/dist/recipes/chainedRunner.d.ts +140 -0
  135. package/dist/recipes/chainedRunner.js +539 -0
  136. package/dist/recipes/chainedRunner.js.map +1 -0
  137. package/dist/recipes/dependencyGraph.d.ts +39 -0
  138. package/dist/recipes/dependencyGraph.js +199 -0
  139. package/dist/recipes/dependencyGraph.js.map +1 -0
  140. package/dist/recipes/legacyRecipeCompat.d.ts +2 -0
  141. package/dist/recipes/legacyRecipeCompat.js +112 -0
  142. package/dist/recipes/legacyRecipeCompat.js.map +1 -0
  143. package/dist/recipes/manifest.d.ts +47 -0
  144. package/dist/recipes/manifest.js +141 -0
  145. package/dist/recipes/manifest.js.map +1 -0
  146. package/dist/recipes/nestedRecipeStep.d.ts +58 -0
  147. package/dist/recipes/nestedRecipeStep.js +95 -0
  148. package/dist/recipes/nestedRecipeStep.js.map +1 -0
  149. package/dist/recipes/outputRegistry.d.ts +28 -0
  150. package/dist/recipes/outputRegistry.js +52 -0
  151. package/dist/recipes/outputRegistry.js.map +1 -0
  152. package/dist/recipes/scheduler.d.ts +23 -7
  153. package/dist/recipes/scheduler.js +131 -41
  154. package/dist/recipes/scheduler.js.map +1 -1
  155. package/dist/recipes/schema.d.ts +17 -2
  156. package/dist/recipes/schemaGenerator.d.ts +28 -0
  157. package/dist/recipes/schemaGenerator.js +565 -0
  158. package/dist/recipes/schemaGenerator.js.map +1 -0
  159. package/dist/recipes/templateEngine.d.ts +62 -0
  160. package/dist/recipes/templateEngine.js +182 -0
  161. package/dist/recipes/templateEngine.js.map +1 -0
  162. package/dist/recipes/toolRegistry.d.ts +181 -0
  163. package/dist/recipes/toolRegistry.js +300 -0
  164. package/dist/recipes/toolRegistry.js.map +1 -0
  165. package/dist/recipes/tools/calendar.d.ts +6 -0
  166. package/dist/recipes/tools/calendar.js +61 -0
  167. package/dist/recipes/tools/calendar.js.map +1 -0
  168. package/dist/recipes/tools/confluence.d.ts +6 -0
  169. package/dist/recipes/tools/confluence.js +254 -0
  170. package/dist/recipes/tools/confluence.js.map +1 -0
  171. package/dist/recipes/tools/datadog.d.ts +6 -0
  172. package/dist/recipes/tools/datadog.js +239 -0
  173. package/dist/recipes/tools/datadog.js.map +1 -0
  174. package/dist/recipes/tools/diagnostics.d.ts +6 -0
  175. package/dist/recipes/tools/diagnostics.js +36 -0
  176. package/dist/recipes/tools/diagnostics.js.map +1 -0
  177. package/dist/recipes/tools/file.d.ts +6 -0
  178. package/dist/recipes/tools/file.js +170 -0
  179. package/dist/recipes/tools/file.js.map +1 -0
  180. package/dist/recipes/tools/git.d.ts +6 -0
  181. package/dist/recipes/tools/git.js +63 -0
  182. package/dist/recipes/tools/git.js.map +1 -0
  183. package/dist/recipes/tools/github.d.ts +6 -0
  184. package/dist/recipes/tools/github.js +91 -0
  185. package/dist/recipes/tools/github.js.map +1 -0
  186. package/dist/recipes/tools/gmail.d.ts +6 -0
  187. package/dist/recipes/tools/gmail.js +210 -0
  188. package/dist/recipes/tools/gmail.js.map +1 -0
  189. package/dist/recipes/tools/hubspot.d.ts +6 -0
  190. package/dist/recipes/tools/hubspot.js +232 -0
  191. package/dist/recipes/tools/hubspot.js.map +1 -0
  192. package/dist/recipes/tools/index.d.ts +22 -0
  193. package/dist/recipes/tools/index.js +25 -0
  194. package/dist/recipes/tools/index.js.map +1 -0
  195. package/dist/recipes/tools/intercom.d.ts +6 -0
  196. package/dist/recipes/tools/intercom.js +226 -0
  197. package/dist/recipes/tools/intercom.js.map +1 -0
  198. package/dist/recipes/tools/linear.d.ts +6 -0
  199. package/dist/recipes/tools/linear.js +83 -0
  200. package/dist/recipes/tools/linear.js.map +1 -0
  201. package/dist/recipes/tools/notion.d.ts +6 -0
  202. package/dist/recipes/tools/notion.js +278 -0
  203. package/dist/recipes/tools/notion.js.map +1 -0
  204. package/dist/recipes/tools/slack.d.ts +6 -0
  205. package/dist/recipes/tools/slack.js +72 -0
  206. package/dist/recipes/tools/slack.js.map +1 -0
  207. package/dist/recipes/tools/stripe.d.ts +6 -0
  208. package/dist/recipes/tools/stripe.js +265 -0
  209. package/dist/recipes/tools/stripe.js.map +1 -0
  210. package/dist/recipes/tools/zendesk.d.ts +6 -0
  211. package/dist/recipes/tools/zendesk.js +245 -0
  212. package/dist/recipes/tools/zendesk.js.map +1 -0
  213. package/dist/recipes/validation.d.ts +13 -0
  214. package/dist/recipes/validation.js +433 -0
  215. package/dist/recipes/validation.js.map +1 -0
  216. package/dist/recipes/yamlRunner.d.ts +87 -0
  217. package/dist/recipes/yamlRunner.js +693 -409
  218. package/dist/recipes/yamlRunner.js.map +1 -1
  219. package/dist/recipesHttp.d.ts +34 -6
  220. package/dist/recipesHttp.js +285 -15
  221. package/dist/recipesHttp.js.map +1 -1
  222. package/dist/riskTier.js +1 -0
  223. package/dist/riskTier.js.map +1 -1
  224. package/dist/runLog.d.ts +23 -0
  225. package/dist/runLog.js +56 -1
  226. package/dist/runLog.js.map +1 -1
  227. package/dist/schemas/dry-run-plan.v1.json +139 -0
  228. package/dist/schemas/recipe.v1.json +684 -0
  229. package/dist/server.d.ts +32 -1
  230. package/dist/server.js +980 -97
  231. package/dist/server.js.map +1 -1
  232. package/dist/streamableHttp.js +2 -0
  233. package/dist/streamableHttp.js.map +1 -1
  234. package/dist/tools/addLinearComment.d.ts +55 -0
  235. package/dist/tools/addLinearComment.js +72 -0
  236. package/dist/tools/addLinearComment.js.map +1 -0
  237. package/dist/tools/bridgeDoctor.js +2 -2
  238. package/dist/tools/bridgeDoctor.js.map +1 -1
  239. package/dist/tools/createLinearIssue.d.ts +84 -0
  240. package/dist/tools/createLinearIssue.js +146 -0
  241. package/dist/tools/createLinearIssue.js.map +1 -0
  242. package/dist/tools/fetchCalendarEvents.d.ts +94 -0
  243. package/dist/tools/fetchCalendarEvents.js +97 -0
  244. package/dist/tools/fetchCalendarEvents.js.map +1 -0
  245. package/dist/tools/fetchGithubIssue.d.ts +80 -0
  246. package/dist/tools/fetchGithubIssue.js +84 -0
  247. package/dist/tools/fetchGithubIssue.js.map +1 -0
  248. package/dist/tools/fetchGithubPR.d.ts +89 -0
  249. package/dist/tools/fetchGithubPR.js +96 -0
  250. package/dist/tools/fetchGithubPR.js.map +1 -0
  251. package/dist/tools/fetchSlackProfile.d.ts +43 -0
  252. package/dist/tools/fetchSlackProfile.js +46 -0
  253. package/dist/tools/fetchSlackProfile.js.map +1 -0
  254. package/dist/tools/getConnectorStatus.d.ts +58 -0
  255. package/dist/tools/getConnectorStatus.js +56 -0
  256. package/dist/tools/getConnectorStatus.js.map +1 -0
  257. package/dist/tools/github/actions.js +4 -2
  258. package/dist/tools/github/actions.js.map +1 -1
  259. package/dist/tools/github/composite.d.ts +339 -0
  260. package/dist/tools/github/composite.js +343 -0
  261. package/dist/tools/github/composite.js.map +1 -0
  262. package/dist/tools/github/index.d.ts +2 -1
  263. package/dist/tools/github/index.js +2 -1
  264. package/dist/tools/github/index.js.map +1 -1
  265. package/dist/tools/github/issues.js +8 -4
  266. package/dist/tools/github/issues.js.map +1 -1
  267. package/dist/tools/github/pr.d.ts +122 -0
  268. package/dist/tools/github/pr.js +195 -5
  269. package/dist/tools/github/pr.js.map +1 -1
  270. package/dist/tools/index.js +32 -1
  271. package/dist/tools/index.js.map +1 -1
  272. package/dist/tools/searchTools.js +1 -1
  273. package/dist/tools/searchTools.js.map +1 -1
  274. package/dist/tools/slackListChannels.d.ts +65 -0
  275. package/dist/tools/slackListChannels.js +70 -0
  276. package/dist/tools/slackListChannels.js.map +1 -0
  277. package/dist/tools/slackPostMessage.d.ts +57 -0
  278. package/dist/tools/slackPostMessage.js +77 -0
  279. package/dist/tools/slackPostMessage.js.map +1 -0
  280. package/dist/tools/testTraceToSource.js +2 -2
  281. package/dist/tools/testTraceToSource.js.map +1 -1
  282. package/dist/tools/updateLinearIssue.d.ts +89 -0
  283. package/dist/tools/updateLinearIssue.js +117 -0
  284. package/dist/tools/updateLinearIssue.js.map +1 -0
  285. package/dist/transport.d.ts +7 -1
  286. package/dist/transport.js +85 -11
  287. package/dist/transport.js.map +1 -1
  288. package/package.json +5 -2
  289. package/scripts/start-all.sh +56 -19
  290. package/templates/automation-policies/recipe-authoring.json +25 -0
  291. package/templates/automation-policy.example.json +6 -0
  292. package/templates/co.patchwork-os.bridge.plist +34 -0
  293. package/templates/recipes/ctx-loop-test.yaml +75 -0
  294. package/templates/recipes/lint-on-save.yaml +1 -2
  295. package/templates/recipes/morning-brief-slack.yaml +57 -0
  296. package/templates/recipes/morning-brief.yaml +14 -6
  297. package/templates/recipes/project-health-check.yaml +50 -0
  298. package/templates/recipes/sentry-to-linear.yaml +77 -0
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Confluence connector — read/write Confluence pages via Atlassian REST API v2.
3
+ *
4
+ * Auth: API token + email + instance URL (same credential shape as Jira).
5
+ * - Env vars: CONFLUENCE_API_TOKEN, CONFLUENCE_INSTANCE_URL, CONFLUENCE_EMAIL
6
+ * - Stored: getSecretJsonSync("confluence") → ConfluenceTokens
7
+ *
8
+ * Tools: getPage, search, createPage, appendToPage, listSpaces
9
+ *
10
+ * Extends BaseConnector for unified auth, retry, rate-limit, error handling.
11
+ */
12
+ import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus } from "./baseConnector.js";
13
+ export interface ConfluenceTokens {
14
+ accessToken: string;
15
+ email: string;
16
+ instanceUrl: string;
17
+ connected_at: string;
18
+ }
19
+ export interface ConfluencePage {
20
+ id: string;
21
+ title: string;
22
+ status: string;
23
+ spaceId: string;
24
+ parentId?: string;
25
+ version: {
26
+ number: number;
27
+ createdAt: string;
28
+ };
29
+ body?: {
30
+ storage?: {
31
+ value: string;
32
+ representation: "storage";
33
+ };
34
+ };
35
+ _links: {
36
+ webui: string;
37
+ };
38
+ }
39
+ export interface ConfluenceSpace {
40
+ id: string;
41
+ key: string;
42
+ name: string;
43
+ type: string;
44
+ status: string;
45
+ _links: {
46
+ webui: string;
47
+ };
48
+ }
49
+ export interface ConfluenceSearchResult {
50
+ results: Array<{
51
+ content: {
52
+ id: string;
53
+ type: string;
54
+ title: string;
55
+ _links: {
56
+ webui: string;
57
+ };
58
+ };
59
+ excerpt: string;
60
+ url: string;
61
+ lastModified: string;
62
+ }>;
63
+ totalSize: number;
64
+ start: number;
65
+ limit: number;
66
+ }
67
+ export declare class ConfluenceConnector extends BaseConnector {
68
+ readonly providerName = "confluence";
69
+ private tokens;
70
+ protected getOAuthConfig(): null;
71
+ authenticate(): Promise<AuthContext>;
72
+ healthCheck(): Promise<{
73
+ ok: boolean;
74
+ error?: ConnectorError;
75
+ }>;
76
+ normalizeError(error: unknown): ConnectorError;
77
+ getStatus(): ConnectorStatus;
78
+ getPage(pageId: string, includeBody?: boolean): Promise<ConfluencePage | null>;
79
+ search(query: string, limit?: number): Promise<ConfluenceSearchResult>;
80
+ createPage(params: {
81
+ spaceId: string;
82
+ title: string;
83
+ body: string;
84
+ parentId?: string;
85
+ }): Promise<ConfluencePage>;
86
+ appendToPage(pageId: string, content: string): Promise<ConfluencePage>;
87
+ listSpaces(limit?: number): Promise<ConfluenceSpace[]>;
88
+ private buildHeaders;
89
+ }
90
+ export declare function loadTokens(): ConfluenceTokens | null;
91
+ export declare function saveTokens(tokens: ConfluenceTokens): void;
92
+ export declare function clearTokens(): void;
93
+ export declare function getConfluenceConnector(): ConfluenceConnector;
94
+ export { getConfluenceConnector as confluence };
95
+ export interface ConnectorHandlerResult {
96
+ status: number;
97
+ body: string;
98
+ contentType?: string;
99
+ }
100
+ /**
101
+ * POST /connections/confluence/connect { token, email, instanceUrl }
102
+ */
103
+ export declare function handleConfluenceConnect(body: string): Promise<ConnectorHandlerResult>;
104
+ /**
105
+ * POST /connections/confluence/test
106
+ */
107
+ export declare function handleConfluenceTest(): Promise<ConnectorHandlerResult>;
108
+ /**
109
+ * DELETE /connections/confluence
110
+ */
111
+ export declare function handleConfluenceDisconnect(): ConnectorHandlerResult;
@@ -0,0 +1,406 @@
1
+ /**
2
+ * Confluence connector — read/write Confluence pages via Atlassian REST API v2.
3
+ *
4
+ * Auth: API token + email + instance URL (same credential shape as Jira).
5
+ * - Env vars: CONFLUENCE_API_TOKEN, CONFLUENCE_INSTANCE_URL, CONFLUENCE_EMAIL
6
+ * - Stored: getSecretJsonSync("confluence") → ConfluenceTokens
7
+ *
8
+ * Tools: getPage, search, createPage, appendToPage, listSpaces
9
+ *
10
+ * Extends BaseConnector for unified auth, retry, rate-limit, error handling.
11
+ */
12
+ import { BaseConnector, } from "./baseConnector.js";
13
+ import { deleteSecretJsonSync, getSecretJsonSync, storeSecretJsonSync, } from "./tokenStorage.js";
14
+ // Confluence Cloud REST API v2
15
+ const CONFLUENCE_API_V2 = "/wiki/api/v2";
16
+ export class ConfluenceConnector extends BaseConnector {
17
+ providerName = "confluence";
18
+ tokens = null;
19
+ getOAuthConfig() {
20
+ return null;
21
+ }
22
+ async authenticate() {
23
+ const tokens = loadTokens();
24
+ if (!tokens) {
25
+ throw new Error("Confluence not connected. Run: patchwork-os connect confluence or set CONFLUENCE_API_TOKEN");
26
+ }
27
+ this.tokens = tokens;
28
+ return {
29
+ token: tokens.accessToken,
30
+ scopes: ["read:confluence-content.all", "write:confluence-content"],
31
+ };
32
+ }
33
+ async healthCheck() {
34
+ try {
35
+ const result = await this.apiCall(async (token) => {
36
+ const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/spaces?limit=1`;
37
+ const res = await fetch(url, {
38
+ headers: this.buildHeaders(token),
39
+ });
40
+ if (!res.ok)
41
+ throw new Error(`HTTP ${res.status}`);
42
+ return res.json();
43
+ });
44
+ if ("error" in result)
45
+ return { ok: false, error: result.error };
46
+ return { ok: true };
47
+ }
48
+ catch (err) {
49
+ return { ok: false, error: this.normalizeError(err) };
50
+ }
51
+ }
52
+ normalizeError(error) {
53
+ if (error instanceof Response) {
54
+ const s = error.status;
55
+ if (s === 401)
56
+ return {
57
+ code: "auth_expired",
58
+ message: "Confluence authentication expired — reconnect",
59
+ retryable: false,
60
+ suggestedAction: "patchwork-os connect confluence",
61
+ };
62
+ if (s === 403)
63
+ return {
64
+ code: "permission_denied",
65
+ message: "Insufficient Confluence permissions",
66
+ retryable: false,
67
+ };
68
+ if (s === 404)
69
+ return {
70
+ code: "not_found",
71
+ message: "Confluence page or space not found",
72
+ retryable: false,
73
+ };
74
+ if (s === 429)
75
+ return {
76
+ code: "rate_limited",
77
+ message: "Confluence API rate limit exceeded",
78
+ retryable: true,
79
+ suggestedAction: "Wait and retry",
80
+ };
81
+ return {
82
+ code: "provider_error",
83
+ message: `Confluence API error: HTTP ${s}`,
84
+ retryable: s >= 500,
85
+ };
86
+ }
87
+ if (error instanceof Error) {
88
+ if (error.message.includes("ENOTFOUND") ||
89
+ error.message.includes("ECONNREFUSED")) {
90
+ return {
91
+ code: "network_error",
92
+ message: `Cannot connect to Confluence: ${error.message}`,
93
+ retryable: true,
94
+ };
95
+ }
96
+ }
97
+ return {
98
+ code: "provider_error",
99
+ message: error instanceof Error ? error.message : String(error),
100
+ retryable: false,
101
+ };
102
+ }
103
+ getStatus() {
104
+ const tokens = loadTokens();
105
+ return {
106
+ id: "confluence",
107
+ status: tokens ? "connected" : "disconnected",
108
+ lastSync: tokens?.connected_at,
109
+ workspace: tokens?.instanceUrl,
110
+ };
111
+ }
112
+ // ── API Methods ────────────────────────────────────────────────────────────
113
+ async getPage(pageId, includeBody = true) {
114
+ const result = await this.apiCall(async (token) => {
115
+ const bodyParam = includeBody ? "&body-format=storage" : "";
116
+ const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/pages/${pageId}?${bodyParam}`;
117
+ const res = await fetch(url, { headers: this.buildHeaders(token) });
118
+ this.updateRateLimitFromHeaders({
119
+ "x-ratelimit-remaining": res.headers.get("x-ratelimit-remaining") ?? undefined,
120
+ "retry-after": res.headers.get("retry-after") ?? undefined,
121
+ });
122
+ if (res.status === 404)
123
+ return null;
124
+ if (!res.ok)
125
+ throw res;
126
+ return res.json();
127
+ });
128
+ if ("error" in result)
129
+ throw new Error(result.error.message);
130
+ return result.data;
131
+ }
132
+ async search(query, limit = 25) {
133
+ const result = await this.apiCall(async (token) => {
134
+ // Use legacy v1 search which supports full-text CQL
135
+ const cql = encodeURIComponent(`text ~ "${query}" AND type = page`);
136
+ const url = `${this.tokens?.instanceUrl}/wiki/rest/api/search?cql=${cql}&limit=${limit}&expand=content.space`;
137
+ const res = await fetch(url, { headers: this.buildHeaders(token) });
138
+ if (!res.ok)
139
+ throw res;
140
+ return res.json();
141
+ });
142
+ if ("error" in result)
143
+ throw new Error(result.error.message);
144
+ return result.data;
145
+ }
146
+ async createPage(params) {
147
+ const result = await this.apiCall(async (token) => {
148
+ const payload = {
149
+ spaceId: params.spaceId,
150
+ status: "current",
151
+ title: params.title,
152
+ body: {
153
+ representation: "storage",
154
+ value: params.body,
155
+ },
156
+ };
157
+ if (params.parentId) {
158
+ payload.parentId = params.parentId;
159
+ }
160
+ const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/pages`;
161
+ const res = await fetch(url, {
162
+ method: "POST",
163
+ headers: {
164
+ ...this.buildHeaders(token),
165
+ "Content-Type": "application/json",
166
+ },
167
+ body: JSON.stringify(payload),
168
+ });
169
+ if (!res.ok)
170
+ throw res;
171
+ return res.json();
172
+ });
173
+ if ("error" in result)
174
+ throw new Error(result.error.message);
175
+ return result.data;
176
+ }
177
+ async appendToPage(pageId, content) {
178
+ // Fetch current page to get version number and existing body
179
+ const page = await this.getPage(pageId, true);
180
+ if (!page)
181
+ throw new Error(`Page ${pageId} not found`);
182
+ const existing = page.body?.storage?.value ?? "";
183
+ const newBody = `${existing}\n${content}`;
184
+ const nextVersion = page.version.number + 1;
185
+ const result = await this.apiCall(async (token) => {
186
+ const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/pages/${pageId}`;
187
+ const res = await fetch(url, {
188
+ method: "PUT",
189
+ headers: {
190
+ ...this.buildHeaders(token),
191
+ "Content-Type": "application/json",
192
+ },
193
+ body: JSON.stringify({
194
+ id: pageId,
195
+ status: "current",
196
+ title: page.title,
197
+ version: { number: nextVersion },
198
+ body: { representation: "storage", value: newBody },
199
+ }),
200
+ });
201
+ if (!res.ok)
202
+ throw res;
203
+ return res.json();
204
+ });
205
+ if ("error" in result)
206
+ throw new Error(result.error.message);
207
+ return result.data;
208
+ }
209
+ async listSpaces(limit = 50) {
210
+ const result = await this.apiCall(async (token) => {
211
+ const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/spaces?limit=${limit}&status=current`;
212
+ const res = await fetch(url, { headers: this.buildHeaders(token) });
213
+ if (!res.ok)
214
+ throw res;
215
+ const data = (await res.json());
216
+ return data.results;
217
+ });
218
+ if ("error" in result)
219
+ throw new Error(result.error.message);
220
+ return result.data;
221
+ }
222
+ // ── Helpers ────────────────────────────────────────────────────────────────
223
+ buildHeaders(token) {
224
+ const email = this.tokens?.email ?? "";
225
+ const basic = Buffer.from(`${email}:${token}`).toString("base64");
226
+ return {
227
+ Authorization: `Basic ${basic}`,
228
+ Accept: "application/json",
229
+ };
230
+ }
231
+ }
232
+ // ── Token persistence ────────────────────────────────────────────────────────
233
+ export function loadTokens() {
234
+ const envToken = process.env.CONFLUENCE_API_TOKEN;
235
+ const envUrl = process.env.CONFLUENCE_INSTANCE_URL;
236
+ const envEmail = process.env.CONFLUENCE_EMAIL;
237
+ if (envToken && envUrl && envEmail) {
238
+ return {
239
+ accessToken: envToken,
240
+ email: envEmail,
241
+ instanceUrl: envUrl.replace(/\/$/, ""),
242
+ connected_at: new Date().toISOString(),
243
+ };
244
+ }
245
+ return getSecretJsonSync("confluence");
246
+ }
247
+ export function saveTokens(tokens) {
248
+ storeSecretJsonSync("confluence", tokens);
249
+ }
250
+ export function clearTokens() {
251
+ try {
252
+ deleteSecretJsonSync("confluence");
253
+ }
254
+ catch {
255
+ // ignore
256
+ }
257
+ }
258
+ // ── Singleton instance ───────────────────────────────────────────────────────
259
+ let _instance = null;
260
+ function resetConfluenceConnector() {
261
+ _instance = null;
262
+ }
263
+ export function getConfluenceConnector() {
264
+ if (!_instance) {
265
+ _instance = new ConfluenceConnector();
266
+ }
267
+ return _instance;
268
+ }
269
+ export { getConfluenceConnector as confluence };
270
+ /**
271
+ * POST /connections/confluence/connect { token, email, instanceUrl }
272
+ */
273
+ export async function handleConfluenceConnect(body) {
274
+ let token;
275
+ let email;
276
+ let instanceUrl;
277
+ try {
278
+ const parsed = JSON.parse(body);
279
+ if (typeof parsed.token !== "string" || !parsed.token) {
280
+ return {
281
+ status: 400,
282
+ contentType: "application/json",
283
+ body: JSON.stringify({ ok: false, error: "token is required" }),
284
+ };
285
+ }
286
+ if (typeof parsed.email !== "string" || !parsed.email) {
287
+ return {
288
+ status: 400,
289
+ contentType: "application/json",
290
+ body: JSON.stringify({ ok: false, error: "email is required" }),
291
+ };
292
+ }
293
+ if (typeof parsed.instanceUrl !== "string" || !parsed.instanceUrl) {
294
+ return {
295
+ status: 400,
296
+ contentType: "application/json",
297
+ body: JSON.stringify({
298
+ ok: false,
299
+ error: "instanceUrl is required (e.g. https://myteam.atlassian.net)",
300
+ }),
301
+ };
302
+ }
303
+ token = parsed.token;
304
+ email = parsed.email;
305
+ instanceUrl = parsed.instanceUrl.replace(/\/$/, "");
306
+ }
307
+ catch {
308
+ return {
309
+ status: 400,
310
+ contentType: "application/json",
311
+ body: JSON.stringify({ ok: false, error: "Invalid JSON body" }),
312
+ };
313
+ }
314
+ // Verify credentials by hitting spaces endpoint
315
+ try {
316
+ const basic = Buffer.from(`${email}:${token}`).toString("base64");
317
+ const res = await fetch(`${instanceUrl}${CONFLUENCE_API_V2}/spaces?limit=1`, {
318
+ headers: {
319
+ Authorization: `Basic ${basic}`,
320
+ Accept: "application/json",
321
+ },
322
+ });
323
+ if (!res.ok) {
324
+ return {
325
+ status: 401,
326
+ contentType: "application/json",
327
+ body: JSON.stringify({
328
+ ok: false,
329
+ error: `Credentials rejected by Confluence (HTTP ${res.status}) — check token and email`,
330
+ }),
331
+ };
332
+ }
333
+ const tokens = {
334
+ accessToken: token,
335
+ email,
336
+ instanceUrl,
337
+ connected_at: new Date().toISOString(),
338
+ };
339
+ saveTokens(tokens);
340
+ resetConfluenceConnector();
341
+ return {
342
+ status: 200,
343
+ contentType: "application/json",
344
+ body: JSON.stringify({
345
+ ok: true,
346
+ instanceUrl,
347
+ connectedAt: tokens.connected_at,
348
+ }),
349
+ };
350
+ }
351
+ catch (err) {
352
+ return {
353
+ status: 500,
354
+ contentType: "application/json",
355
+ body: JSON.stringify({
356
+ ok: false,
357
+ error: err instanceof Error ? err.message : String(err),
358
+ }),
359
+ };
360
+ }
361
+ }
362
+ /**
363
+ * POST /connections/confluence/test
364
+ */
365
+ export async function handleConfluenceTest() {
366
+ const tokens = loadTokens();
367
+ if (!tokens) {
368
+ return {
369
+ status: 400,
370
+ contentType: "application/json",
371
+ body: JSON.stringify({ ok: false, error: "Confluence not connected" }),
372
+ };
373
+ }
374
+ try {
375
+ const connector = getConfluenceConnector();
376
+ const check = await connector.healthCheck();
377
+ return {
378
+ status: check.ok ? 200 : 401,
379
+ contentType: "application/json",
380
+ body: JSON.stringify(check.ok ? { ok: true } : { ok: false, error: check.error?.message }),
381
+ };
382
+ }
383
+ catch (err) {
384
+ return {
385
+ status: 500,
386
+ contentType: "application/json",
387
+ body: JSON.stringify({
388
+ ok: false,
389
+ error: err instanceof Error ? err.message : String(err),
390
+ }),
391
+ };
392
+ }
393
+ }
394
+ /**
395
+ * DELETE /connections/confluence
396
+ */
397
+ export function handleConfluenceDisconnect() {
398
+ clearTokens();
399
+ resetConfluenceConnector();
400
+ return {
401
+ status: 200,
402
+ contentType: "application/json",
403
+ body: JSON.stringify({ ok: true }),
404
+ };
405
+ }
406
+ //# sourceMappingURL=confluence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confluence.js","sourceRoot":"","sources":["../../src/connectors/confluence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Datadog connector — query metrics, monitors, alerts, and incidents.
3
+ *
4
+ * Auth: API key + Application key.
5
+ * - Env vars: DATADOG_API_KEY, DATADOG_APP_KEY, DATADOG_SITE (optional)
6
+ * - Stored: getSecretJsonSync("datadog") → DatadogTokens
7
+ * - Headers: DD-API-KEY + DD-APPLICATION-KEY
8
+ *
9
+ * Tools: queryMetrics, listMonitors, getMonitor, listActiveAlerts, muteMonitor, listIncidents
10
+ *
11
+ * Extends BaseConnector for unified auth, retry, rate-limit, error handling.
12
+ */
13
+ import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus } from "./baseConnector.js";
14
+ export interface DatadogTokens {
15
+ apiKey: string;
16
+ appKey: string;
17
+ site?: string;
18
+ orgName?: string;
19
+ connected_at: string;
20
+ }
21
+ export interface DatadogSeries {
22
+ metric: string;
23
+ display_name: string;
24
+ unit: Array<{
25
+ family: string;
26
+ name: string;
27
+ short_name: string;
28
+ }> | null;
29
+ pointlist: Array<[number, number | null]>;
30
+ start: number;
31
+ end: number;
32
+ interval: number;
33
+ length: number;
34
+ aggr: string | null;
35
+ scope: string;
36
+ }
37
+ export interface DatadogMonitor {
38
+ id: number;
39
+ name: string;
40
+ type: string;
41
+ query: string;
42
+ message: string;
43
+ status: string;
44
+ state: string;
45
+ tags: string[];
46
+ created: string;
47
+ modified: string;
48
+ overall_state: string;
49
+ }
50
+ export interface DatadogIncident {
51
+ id: string;
52
+ type: string;
53
+ attributes: {
54
+ title: string;
55
+ status: string;
56
+ severity: string;
57
+ created: string;
58
+ modified: string;
59
+ customer_impact_scope?: string;
60
+ customer_impacted: boolean;
61
+ };
62
+ }
63
+ export declare class DatadogConnector extends BaseConnector {
64
+ readonly providerName = "datadog";
65
+ private tokens;
66
+ protected getOAuthConfig(): null;
67
+ authenticate(): Promise<AuthContext>;
68
+ healthCheck(): Promise<{
69
+ ok: boolean;
70
+ error?: ConnectorError;
71
+ }>;
72
+ normalizeError(error: unknown): ConnectorError;
73
+ getStatus(): ConnectorStatus;
74
+ queryMetrics(query: string, from: number, to: number): Promise<{
75
+ series: DatadogSeries[];
76
+ }>;
77
+ listMonitors(params?: {
78
+ groupStates?: string[];
79
+ tags?: string[];
80
+ perPage?: number;
81
+ }): Promise<DatadogMonitor[]>;
82
+ getMonitor(monitorId: number): Promise<DatadogMonitor>;
83
+ listActiveAlerts(params?: {
84
+ priority?: number;
85
+ }): Promise<DatadogMonitor[]>;
86
+ muteMonitor(monitorId: number, end?: number): Promise<DatadogMonitor>;
87
+ listIncidents(params?: {
88
+ perPage?: number;
89
+ }): Promise<{
90
+ data: DatadogIncident[];
91
+ }>;
92
+ private baseUrl;
93
+ private buildHeaders;
94
+ }
95
+ export declare function loadTokens(): DatadogTokens | null;
96
+ export declare function saveTokens(tokens: DatadogTokens): void;
97
+ export declare function clearTokens(): void;
98
+ export declare function getDatadogConnector(): DatadogConnector;
99
+ export { getDatadogConnector as datadog };
100
+ export interface ConnectorHandlerResult {
101
+ status: number;
102
+ body: string;
103
+ contentType?: string;
104
+ }
105
+ /**
106
+ * POST /connections/datadog/connect { apiKey, appKey, site? }
107
+ */
108
+ export declare function handleDatadogConnect(body: string): Promise<ConnectorHandlerResult>;
109
+ /**
110
+ * POST /connections/datadog/test
111
+ */
112
+ export declare function handleDatadogTest(): Promise<ConnectorHandlerResult>;
113
+ /**
114
+ * DELETE /connections/datadog
115
+ */
116
+ export declare function handleDatadogDisconnect(): ConnectorHandlerResult;