patchwork-os 0.2.0-alpha.25 → 0.2.0-alpha.27

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 (55) hide show
  1. package/deploy/bootstrap-vps.sh +1 -1
  2. package/deploy/deploy-dashboard.sh +164 -0
  3. package/deploy/deploy-landing.sh +79 -0
  4. package/dist/ccPermissions.js +6 -4
  5. package/dist/ccPermissions.js.map +1 -1
  6. package/dist/commands/recipe.js +1 -1
  7. package/dist/commands/recipe.js.map +1 -1
  8. package/dist/commands/recipeInstall.d.ts +72 -0
  9. package/dist/commands/recipeInstall.js +339 -0
  10. package/dist/commands/recipeInstall.js.map +1 -0
  11. package/dist/connectors/datadog.d.ts +116 -0
  12. package/dist/connectors/datadog.js +385 -0
  13. package/dist/connectors/datadog.js.map +1 -0
  14. package/dist/connectors/hubspot.d.ts +112 -0
  15. package/dist/connectors/hubspot.js +408 -0
  16. package/dist/connectors/hubspot.js.map +1 -0
  17. package/dist/connectors/intercom.d.ts +102 -0
  18. package/dist/connectors/intercom.js +402 -0
  19. package/dist/connectors/intercom.js.map +1 -0
  20. package/dist/connectors/stripe.d.ts +116 -0
  21. package/dist/connectors/stripe.js +379 -0
  22. package/dist/connectors/stripe.js.map +1 -0
  23. package/dist/index.js +33 -26
  24. package/dist/index.js.map +1 -1
  25. package/dist/recipes/manifest.d.ts +47 -0
  26. package/dist/recipes/manifest.js +141 -0
  27. package/dist/recipes/manifest.js.map +1 -0
  28. package/dist/recipes/schemaGenerator.js +3 -3
  29. package/dist/recipes/schemaGenerator.js.map +1 -1
  30. package/dist/recipes/tools/datadog.d.ts +6 -0
  31. package/dist/recipes/tools/datadog.js +239 -0
  32. package/dist/recipes/tools/datadog.js.map +1 -0
  33. package/dist/recipes/tools/hubspot.d.ts +6 -0
  34. package/dist/recipes/tools/hubspot.js +232 -0
  35. package/dist/recipes/tools/hubspot.js.map +1 -0
  36. package/dist/recipes/tools/index.d.ts +4 -0
  37. package/dist/recipes/tools/index.js +4 -0
  38. package/dist/recipes/tools/index.js.map +1 -1
  39. package/dist/recipes/tools/intercom.d.ts +6 -0
  40. package/dist/recipes/tools/intercom.js +226 -0
  41. package/dist/recipes/tools/intercom.js.map +1 -0
  42. package/dist/recipes/tools/stripe.d.ts +6 -0
  43. package/dist/recipes/tools/stripe.js +265 -0
  44. package/dist/recipes/tools/stripe.js.map +1 -0
  45. package/dist/recipes/yamlRunner.js +28 -0
  46. package/dist/recipes/yamlRunner.js.map +1 -1
  47. package/dist/schemas/dry-run-plan.v1.json +1 -1
  48. package/dist/schemas/recipe.v1.json +1 -1
  49. package/dist/server.js +155 -1
  50. package/dist/server.js.map +1 -1
  51. package/dist/tools/searchTools.js +1 -1
  52. package/dist/tools/searchTools.js.map +1 -1
  53. package/dist/tools/testTraceToSource.js +2 -2
  54. package/dist/tools/testTraceToSource.js.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,408 @@
1
+ /**
2
+ * HubSpot connector — read/write HubSpot CRM via the HubSpot REST API v3.
3
+ *
4
+ * Auth: Private App access token (Bearer).
5
+ * - Env var: HUBSPOT_ACCESS_TOKEN
6
+ * - Stored: getSecretJsonSync("hubspot") → HubSpotTokens
7
+ *
8
+ * Tools: listContacts, getContact, listDeals, getDeal, createNote, searchContacts
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
+ const HUBSPOT_BASE = "https://api.hubapi.com";
15
+ export class HubSpotConnector extends BaseConnector {
16
+ providerName = "hubspot";
17
+ getOAuthConfig() {
18
+ return null;
19
+ }
20
+ async authenticate() {
21
+ const tokens = loadTokens();
22
+ if (!tokens) {
23
+ throw new Error("HubSpot not connected. Run: patchwork-os connect hubspot or set HUBSPOT_ACCESS_TOKEN");
24
+ }
25
+ return {
26
+ token: tokens.accessToken,
27
+ scopes: ["read", "write"],
28
+ };
29
+ }
30
+ async healthCheck() {
31
+ try {
32
+ const result = await this.apiCall(async (token) => {
33
+ const res = await fetch(`${HUBSPOT_BASE}/account-info/v3/details`, {
34
+ headers: this.buildHeaders(token),
35
+ });
36
+ if (!res.ok)
37
+ throw new Error(`HTTP ${res.status}`);
38
+ return res.json();
39
+ });
40
+ if ("error" in result)
41
+ return { ok: false, error: result.error };
42
+ return { ok: true };
43
+ }
44
+ catch (err) {
45
+ return { ok: false, error: this.normalizeError(err) };
46
+ }
47
+ }
48
+ normalizeError(error) {
49
+ if (error instanceof Response) {
50
+ const s = error.status;
51
+ if (s === 401)
52
+ return {
53
+ code: "auth_expired",
54
+ message: "HubSpot authentication expired — reconnect",
55
+ retryable: false,
56
+ suggestedAction: "patchwork-os connect hubspot",
57
+ };
58
+ if (s === 403)
59
+ return {
60
+ code: "permission_denied",
61
+ message: "Insufficient HubSpot permissions",
62
+ retryable: false,
63
+ };
64
+ if (s === 404)
65
+ return {
66
+ code: "not_found",
67
+ message: "HubSpot resource not found",
68
+ retryable: false,
69
+ };
70
+ if (s === 429)
71
+ return {
72
+ code: "rate_limited",
73
+ message: "HubSpot API rate limit exceeded",
74
+ retryable: true,
75
+ suggestedAction: "Wait and retry",
76
+ };
77
+ return {
78
+ code: "provider_error",
79
+ message: `HubSpot API error: HTTP ${s}`,
80
+ retryable: s >= 500,
81
+ };
82
+ }
83
+ if (error instanceof Error) {
84
+ if (error.message.includes("ENOTFOUND") ||
85
+ error.message.includes("ECONNREFUSED")) {
86
+ return {
87
+ code: "network_error",
88
+ message: `Cannot connect to HubSpot: ${error.message}`,
89
+ retryable: true,
90
+ };
91
+ }
92
+ }
93
+ return {
94
+ code: "provider_error",
95
+ message: error instanceof Error ? error.message : String(error),
96
+ retryable: false,
97
+ };
98
+ }
99
+ getStatus() {
100
+ const tokens = loadTokens();
101
+ return {
102
+ id: "hubspot",
103
+ status: tokens ? "connected" : "disconnected",
104
+ lastSync: tokens?.connected_at,
105
+ workspace: tokens?.portalName ?? (tokens ? "HubSpot" : undefined),
106
+ };
107
+ }
108
+ // ── API Methods ────────────────────────────────────────────────────────────
109
+ async listContacts(params = {}) {
110
+ const result = await this.apiCall(async (token) => {
111
+ const qs = new URLSearchParams({
112
+ limit: String(params.limit ?? 25),
113
+ properties: "firstname,lastname,email,phone,company",
114
+ });
115
+ if (params.after)
116
+ qs.set("after", params.after);
117
+ const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/contacts?${qs}`, {
118
+ headers: this.buildHeaders(token),
119
+ });
120
+ this.updateRateLimitFromHeaders({
121
+ "x-ratelimit-remaining": res.headers.get("x-ratelimit-remaining") ?? undefined,
122
+ "retry-after": res.headers.get("retry-after") ?? undefined,
123
+ });
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 getContact(contactId) {
133
+ const result = await this.apiCall(async (token) => {
134
+ const qs = new URLSearchParams({
135
+ properties: "firstname,lastname,email,phone,company,lifecyclestage",
136
+ });
137
+ const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/contacts/${contactId}?${qs}`, { headers: this.buildHeaders(token) });
138
+ if (res.status === 404)
139
+ return null;
140
+ if (!res.ok)
141
+ throw res;
142
+ return res.json();
143
+ });
144
+ if ("error" in result)
145
+ throw new Error(result.error.message);
146
+ return result.data;
147
+ }
148
+ async listDeals(params = {}) {
149
+ const result = await this.apiCall(async (token) => {
150
+ const qs = new URLSearchParams({
151
+ limit: String(params.limit ?? 25),
152
+ properties: "dealname,amount,dealstage,closedate,pipeline",
153
+ });
154
+ const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/deals?${qs}`, {
155
+ headers: this.buildHeaders(token),
156
+ });
157
+ this.updateRateLimitFromHeaders({
158
+ "x-ratelimit-remaining": res.headers.get("x-ratelimit-remaining") ?? undefined,
159
+ "retry-after": res.headers.get("retry-after") ?? undefined,
160
+ });
161
+ if (!res.ok)
162
+ throw res;
163
+ const data = (await res.json());
164
+ // Client-side filter by stage if requested
165
+ if (params.stage) {
166
+ data.results = data.results.filter((d) => d.properties.dealstage === params.stage);
167
+ }
168
+ return data;
169
+ });
170
+ if ("error" in result)
171
+ throw new Error(result.error.message);
172
+ return result.data;
173
+ }
174
+ async getDeal(dealId) {
175
+ const result = await this.apiCall(async (token) => {
176
+ const qs = new URLSearchParams({
177
+ properties: "dealname,amount,dealstage,closedate,pipeline,hs_deal_stage_probability",
178
+ });
179
+ const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/deals/${dealId}?${qs}`, { headers: this.buildHeaders(token) });
180
+ if (res.status === 404)
181
+ return null;
182
+ if (!res.ok)
183
+ throw res;
184
+ return res.json();
185
+ });
186
+ if ("error" in result)
187
+ throw new Error(result.error.message);
188
+ return result.data;
189
+ }
190
+ async createNote(body, contactId, dealId) {
191
+ const result = await this.apiCall(async (token) => {
192
+ const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/notes`, {
193
+ method: "POST",
194
+ headers: {
195
+ ...this.buildHeaders(token),
196
+ "Content-Type": "application/json",
197
+ },
198
+ body: JSON.stringify({
199
+ properties: {
200
+ hs_note_body: body,
201
+ hs_timestamp: String(Date.now()),
202
+ },
203
+ }),
204
+ });
205
+ if (!res.ok)
206
+ throw res;
207
+ const note = (await res.json());
208
+ // Associate with contact if provided
209
+ if (contactId) {
210
+ await fetch(`${HUBSPOT_BASE}/crm/v3/objects/notes/${note.id}/associations/contacts/${contactId}/note_to_contact`, {
211
+ method: "PUT",
212
+ headers: this.buildHeaders(token),
213
+ });
214
+ }
215
+ // Associate with deal if provided
216
+ if (dealId) {
217
+ await fetch(`${HUBSPOT_BASE}/crm/v3/objects/notes/${note.id}/associations/deals/${dealId}/note_to_deal`, {
218
+ method: "PUT",
219
+ headers: this.buildHeaders(token),
220
+ });
221
+ }
222
+ return note;
223
+ });
224
+ if ("error" in result)
225
+ throw new Error(result.error.message);
226
+ return result.data;
227
+ }
228
+ async searchContacts(query) {
229
+ const result = await this.apiCall(async (token) => {
230
+ const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/contacts/search`, {
231
+ method: "POST",
232
+ headers: {
233
+ ...this.buildHeaders(token),
234
+ "Content-Type": "application/json",
235
+ },
236
+ body: JSON.stringify({
237
+ query,
238
+ properties: ["firstname", "lastname", "email", "company"],
239
+ limit: 10,
240
+ }),
241
+ });
242
+ if (!res.ok)
243
+ throw res;
244
+ const data = (await res.json());
245
+ return data.results;
246
+ });
247
+ if ("error" in result)
248
+ throw new Error(result.error.message);
249
+ return result.data;
250
+ }
251
+ // ── Helpers ────────────────────────────────────────────────────────────────
252
+ buildHeaders(token) {
253
+ return {
254
+ Authorization: `Bearer ${token}`,
255
+ Accept: "application/json",
256
+ };
257
+ }
258
+ }
259
+ // ── Token persistence ────────────────────────────────────────────────────────
260
+ export function loadTokens() {
261
+ const envToken = process.env.HUBSPOT_ACCESS_TOKEN;
262
+ if (envToken) {
263
+ return {
264
+ accessToken: envToken,
265
+ connected_at: new Date().toISOString(),
266
+ };
267
+ }
268
+ return getSecretJsonSync("hubspot");
269
+ }
270
+ export function saveTokens(tokens) {
271
+ storeSecretJsonSync("hubspot", tokens);
272
+ }
273
+ export function clearTokens() {
274
+ try {
275
+ deleteSecretJsonSync("hubspot");
276
+ }
277
+ catch {
278
+ // ignore
279
+ }
280
+ }
281
+ // ── Singleton instance ───────────────────────────────────────────────────────
282
+ let _instance = null;
283
+ function resetHubSpotConnector() {
284
+ _instance = null;
285
+ }
286
+ export function getHubSpotConnector() {
287
+ if (!_instance) {
288
+ _instance = new HubSpotConnector();
289
+ }
290
+ return _instance;
291
+ }
292
+ export { getHubSpotConnector as hubspot };
293
+ /**
294
+ * POST /connections/hubspot/connect { accessToken }
295
+ */
296
+ export async function handleHubSpotConnect(body) {
297
+ let accessToken;
298
+ try {
299
+ const parsed = JSON.parse(body);
300
+ if (typeof parsed.accessToken !== "string" || !parsed.accessToken) {
301
+ return {
302
+ status: 400,
303
+ contentType: "application/json",
304
+ body: JSON.stringify({ ok: false, error: "accessToken is required" }),
305
+ };
306
+ }
307
+ accessToken = parsed.accessToken;
308
+ }
309
+ catch {
310
+ return {
311
+ status: 400,
312
+ contentType: "application/json",
313
+ body: JSON.stringify({ ok: false, error: "Invalid JSON body" }),
314
+ };
315
+ }
316
+ try {
317
+ const res = await fetch(`${HUBSPOT_BASE}/account-info/v3/details`, {
318
+ headers: {
319
+ Authorization: `Bearer ${accessToken}`,
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 HubSpot (HTTP ${res.status}) — check accessToken`,
330
+ }),
331
+ };
332
+ }
333
+ const details = (await res.json());
334
+ const tokens = {
335
+ accessToken,
336
+ hubId: details.portalId,
337
+ portalName: details.uiDomain,
338
+ connected_at: new Date().toISOString(),
339
+ };
340
+ saveTokens(tokens);
341
+ resetHubSpotConnector();
342
+ return {
343
+ status: 200,
344
+ contentType: "application/json",
345
+ body: JSON.stringify({
346
+ ok: true,
347
+ hubId: tokens.hubId,
348
+ portalName: tokens.portalName,
349
+ connectedAt: tokens.connected_at,
350
+ }),
351
+ };
352
+ }
353
+ catch (err) {
354
+ return {
355
+ status: 500,
356
+ contentType: "application/json",
357
+ body: JSON.stringify({
358
+ ok: false,
359
+ error: err instanceof Error ? err.message : String(err),
360
+ }),
361
+ };
362
+ }
363
+ }
364
+ /**
365
+ * POST /connections/hubspot/test
366
+ */
367
+ export async function handleHubSpotTest() {
368
+ const tokens = loadTokens();
369
+ if (!tokens) {
370
+ return {
371
+ status: 400,
372
+ contentType: "application/json",
373
+ body: JSON.stringify({ ok: false, error: "HubSpot not connected" }),
374
+ };
375
+ }
376
+ try {
377
+ const connector = getHubSpotConnector();
378
+ const check = await connector.healthCheck();
379
+ return {
380
+ status: check.ok ? 200 : 401,
381
+ contentType: "application/json",
382
+ body: JSON.stringify(check.ok ? { ok: true } : { ok: false, error: check.error?.message }),
383
+ };
384
+ }
385
+ catch (err) {
386
+ return {
387
+ status: 500,
388
+ contentType: "application/json",
389
+ body: JSON.stringify({
390
+ ok: false,
391
+ error: err instanceof Error ? err.message : String(err),
392
+ }),
393
+ };
394
+ }
395
+ }
396
+ /**
397
+ * DELETE /connections/hubspot
398
+ */
399
+ export function handleHubSpotDisconnect() {
400
+ clearTokens();
401
+ resetHubSpotConnector();
402
+ return {
403
+ status: 200,
404
+ contentType: "application/json",
405
+ body: JSON.stringify({ ok: true }),
406
+ };
407
+ }
408
+ //# sourceMappingURL=hubspot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hubspot.js","sourceRoot":"","sources":["../../src/connectors/hubspot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Intercom connector — read/write Intercom conversations via the Intercom REST API v2.10.
3
+ *
4
+ * Auth: Bearer access token (single workspace).
5
+ * - Env var: INTERCOM_ACCESS_TOKEN
6
+ * - Stored: getSecretJsonSync("intercom") → IntercomTokens
7
+ * - Header: Authorization: Bearer <token>, Intercom-Version: 2.10
8
+ *
9
+ * Tools: listConversations, getConversation, replyToConversation, closeConversation, listContacts
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 IntercomTokens {
15
+ accessToken: string;
16
+ workspaceName?: string;
17
+ connected_at: string;
18
+ }
19
+ export interface IntercomConversation {
20
+ id: string;
21
+ type: string;
22
+ title: string | null;
23
+ created_at: number;
24
+ updated_at: number;
25
+ state: "open" | "closed" | "snoozed" | "pending";
26
+ assignee: {
27
+ type: string;
28
+ id: string;
29
+ } | null;
30
+ contacts: {
31
+ contacts: Array<{
32
+ type: string;
33
+ id: string;
34
+ }>;
35
+ };
36
+ }
37
+ export interface IntercomContact {
38
+ id: string;
39
+ type: string;
40
+ name: string | null;
41
+ email: string | null;
42
+ created_at: number;
43
+ updated_at: number;
44
+ }
45
+ export interface IntercomListResult<T> {
46
+ conversations?: T[];
47
+ contacts?: T[];
48
+ total_count: number;
49
+ pages: {
50
+ type: string;
51
+ page: number;
52
+ per_page: number;
53
+ total_pages: number;
54
+ };
55
+ }
56
+ export declare class IntercomConnector extends BaseConnector {
57
+ readonly providerName = "intercom";
58
+ protected getOAuthConfig(): null;
59
+ authenticate(): Promise<AuthContext>;
60
+ healthCheck(): Promise<{
61
+ ok: boolean;
62
+ error?: ConnectorError;
63
+ }>;
64
+ normalizeError(error: unknown): ConnectorError;
65
+ getStatus(): ConnectorStatus;
66
+ listConversations(params?: {
67
+ status?: "open" | "closed" | "snoozed" | "pending";
68
+ assigneeId?: string;
69
+ perPage?: number;
70
+ }): Promise<IntercomListResult<IntercomConversation>>;
71
+ getConversation(conversationId: string): Promise<IntercomConversation>;
72
+ replyToConversation(conversationId: string, body: string, type?: "comment" | "note"): Promise<IntercomConversation>;
73
+ closeConversation(conversationId: string): Promise<IntercomConversation>;
74
+ listContacts(params?: {
75
+ query?: string;
76
+ perPage?: number;
77
+ }): Promise<IntercomListResult<IntercomContact>>;
78
+ searchContacts(query: string): Promise<IntercomListResult<IntercomContact>>;
79
+ private buildHeaders;
80
+ }
81
+ export declare function loadTokens(): IntercomTokens | null;
82
+ export declare function saveTokens(tokens: IntercomTokens): void;
83
+ export declare function clearTokens(): void;
84
+ export declare function getIntercomConnector(): IntercomConnector;
85
+ export { getIntercomConnector as intercom };
86
+ export interface ConnectorHandlerResult {
87
+ status: number;
88
+ body: string;
89
+ contentType?: string;
90
+ }
91
+ /**
92
+ * POST /connections/intercom/connect { accessToken }
93
+ */
94
+ export declare function handleIntercomConnect(body: string): Promise<ConnectorHandlerResult>;
95
+ /**
96
+ * POST /connections/intercom/test
97
+ */
98
+ export declare function handleIntercomTest(): Promise<ConnectorHandlerResult>;
99
+ /**
100
+ * DELETE /connections/intercom
101
+ */
102
+ export declare function handleIntercomDisconnect(): ConnectorHandlerResult;