@noodleseed/one 0.97.0 → 0.98.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 (71) hide show
  1. package/node_modules/@noodle-borg/service/dist/feedback-operations/bootstrap.d.ts +7 -0
  2. package/node_modules/@noodle-borg/service/dist/feedback-operations/bootstrap.d.ts.map +1 -0
  3. package/node_modules/@noodle-borg/service/dist/feedback-operations/bootstrap.js +23 -0
  4. package/node_modules/@noodle-borg/service/dist/feedback-operations/bootstrap.js.map +1 -0
  5. package/node_modules/@noodle-borg/service/dist/feedback-operations/config.d.ts +12 -0
  6. package/node_modules/@noodle-borg/service/dist/feedback-operations/config.d.ts.map +1 -0
  7. package/node_modules/@noodle-borg/service/dist/feedback-operations/config.js +47 -0
  8. package/node_modules/@noodle-borg/service/dist/feedback-operations/config.js.map +1 -0
  9. package/node_modules/@noodle-borg/service/dist/feedback-operations/contracts.d.ts +24 -0
  10. package/node_modules/@noodle-borg/service/dist/feedback-operations/contracts.d.ts.map +1 -0
  11. package/node_modules/@noodle-borg/service/dist/feedback-operations/contracts.js +2 -0
  12. package/node_modules/@noodle-borg/service/dist/feedback-operations/contracts.js.map +1 -0
  13. package/node_modules/@noodle-borg/service/dist/feedback-operations/delivery-worker.d.ts +29 -0
  14. package/node_modules/@noodle-borg/service/dist/feedback-operations/delivery-worker.d.ts.map +1 -0
  15. package/node_modules/@noodle-borg/service/dist/feedback-operations/delivery-worker.js +256 -0
  16. package/node_modules/@noodle-borg/service/dist/feedback-operations/delivery-worker.js.map +1 -0
  17. package/node_modules/@noodle-borg/service/dist/feedback-operations/linear-client.d.ts +39 -0
  18. package/node_modules/@noodle-borg/service/dist/feedback-operations/linear-client.d.ts.map +1 -0
  19. package/node_modules/@noodle-borg/service/dist/feedback-operations/linear-client.js +142 -0
  20. package/node_modules/@noodle-borg/service/dist/feedback-operations/linear-client.js.map +1 -0
  21. package/node_modules/@noodle-borg/service/dist/feedback-operations/reporter-email.d.ts +33 -0
  22. package/node_modules/@noodle-borg/service/dist/feedback-operations/reporter-email.d.ts.map +1 -0
  23. package/node_modules/@noodle-borg/service/dist/feedback-operations/reporter-email.js +142 -0
  24. package/node_modules/@noodle-borg/service/dist/feedback-operations/reporter-email.js.map +1 -0
  25. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-card.d.ts +138 -0
  26. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-card.d.ts.map +1 -0
  27. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-card.js +199 -0
  28. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-card.js.map +1 -0
  29. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-client.d.ts +44 -0
  30. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-client.d.ts.map +1 -0
  31. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-client.js +95 -0
  32. package/node_modules/@noodle-borg/service/dist/feedback-operations/slack-client.js.map +1 -0
  33. package/node_modules/@noodle-borg/service/dist/main.js +38 -3
  34. package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
  35. package/node_modules/@noodle-borg/service/dist/options.d.ts +14 -0
  36. package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
  37. package/node_modules/@noodle-borg/service/dist/routes/feedback-operations-dispatch.d.ts +9 -0
  38. package/node_modules/@noodle-borg/service/dist/routes/feedback-operations-dispatch.d.ts.map +1 -0
  39. package/node_modules/@noodle-borg/service/dist/routes/feedback-operations-dispatch.js +53 -0
  40. package/node_modules/@noodle-borg/service/dist/routes/feedback-operations-dispatch.js.map +1 -0
  41. package/node_modules/@noodle-borg/service/dist/routes/feedback.d.ts +2 -0
  42. package/node_modules/@noodle-borg/service/dist/routes/feedback.d.ts.map +1 -1
  43. package/node_modules/@noodle-borg/service/dist/routes/feedback.js +22 -0
  44. package/node_modules/@noodle-borg/service/dist/routes/feedback.js.map +1 -1
  45. package/node_modules/@noodle-borg/service/dist/routes/linear-feedback-webhook.d.ts +17 -0
  46. package/node_modules/@noodle-borg/service/dist/routes/linear-feedback-webhook.d.ts.map +1 -0
  47. package/node_modules/@noodle-borg/service/dist/routes/linear-feedback-webhook.js +141 -0
  48. package/node_modules/@noodle-borg/service/dist/routes/linear-feedback-webhook.js.map +1 -0
  49. package/node_modules/@noodle-borg/service/dist/routes/slack-feedback-actions.d.ts +13 -0
  50. package/node_modules/@noodle-borg/service/dist/routes/slack-feedback-actions.d.ts.map +1 -0
  51. package/node_modules/@noodle-borg/service/dist/routes/slack-feedback-actions.js +99 -0
  52. package/node_modules/@noodle-borg/service/dist/routes/slack-feedback-actions.js.map +1 -0
  53. package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
  54. package/node_modules/@noodle-borg/service/dist/serve.js +23 -0
  55. package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
  56. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts +1 -0
  57. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts.map +1 -1
  58. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js +2 -0
  59. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js.map +1 -1
  60. package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
  61. package/node_modules/@noodle-borg/service/dist/service.js +6 -0
  62. package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
  63. package/node_modules/@noodle-borg/service/dist/store/feedback-operations.d.ts +186 -0
  64. package/node_modules/@noodle-borg/service/dist/store/feedback-operations.d.ts.map +1 -0
  65. package/node_modules/@noodle-borg/service/dist/store/feedback-operations.js +483 -0
  66. package/node_modules/@noodle-borg/service/dist/store/feedback-operations.js.map +1 -0
  67. package/node_modules/@noodle-borg/service/dist/store/postgres-feedback-operations.d.ts +35 -0
  68. package/node_modules/@noodle-borg/service/dist/store/postgres-feedback-operations.d.ts.map +1 -0
  69. package/node_modules/@noodle-borg/service/dist/store/postgres-feedback-operations.js +172 -0
  70. package/node_modules/@noodle-borg/service/dist/store/postgres-feedback-operations.js.map +1 -0
  71. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-client.js","sourceRoot":"","sources":["../../src/feedback-operations/linear-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { RenderedFeedbackEmail } from './contracts.js';
2
+ export interface FeedbackReporterEmailInput {
3
+ readonly githubIssueNumber: number;
4
+ readonly recipient: string;
5
+ readonly title: string;
6
+ readonly message: string;
7
+ }
8
+ export interface FeedbackReporterEmailSender {
9
+ send(input: FeedbackReporterEmailInput, options?: {
10
+ readonly signal?: AbortSignal;
11
+ }): Promise<{
12
+ readonly providerMessageId: string;
13
+ }>;
14
+ }
15
+ export declare class ResendFeedbackReporterEmailSender implements FeedbackReporterEmailSender {
16
+ #private;
17
+ constructor(options: {
18
+ apiKey: string;
19
+ from: string;
20
+ replyTo: string;
21
+ fetch?: typeof fetch;
22
+ });
23
+ send(input: FeedbackReporterEmailInput, options?: {
24
+ readonly signal?: AbortSignal;
25
+ }): Promise<{
26
+ readonly providerMessageId: string;
27
+ }>;
28
+ }
29
+ export declare function renderFeedbackAcceptedEmail(input: {
30
+ readonly title: string;
31
+ readonly message: string;
32
+ }): RenderedFeedbackEmail;
33
+ //# sourceMappingURL=reporter-email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter-email.d.ts","sourceRoot":"","sources":["../../src/feedback-operations/reporter-email.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAS5D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CACF,KAAK,EAAE,0BAA0B,EACjC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC;QAAE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,qBAAa,iCAAkC,YAAW,2BAA2B;;gBAMvE,OAAO,EAAE;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;KACtB;IAOK,IAAI,CACR,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAC9C,OAAO,CAAC;QAAE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAC;CA+BnD;AAOD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GAAG,qBAAqB,CAkCxB"}
@@ -0,0 +1,142 @@
1
+ import { z } from 'zod';
2
+ import { sanitizedFeedbackText } from './slack-card.js';
3
+ const SUBJECT = "We're looking into your Noodle Seed feedback";
4
+ const RESEND_ENDPOINT = 'https://api.resend.com/emails';
5
+ const DELIVERY_TIMEOUT_MS = 10_000;
6
+ const MAX_PROVIDER_RESPONSE_BYTES = 64_000;
7
+ const ProviderResponseSchema = z.object({ id: z.string().trim().min(1) });
8
+ export class ResendFeedbackReporterEmailSender {
9
+ #apiKey;
10
+ #from;
11
+ #replyTo;
12
+ #fetch;
13
+ constructor(options) {
14
+ this.#apiKey = options.apiKey;
15
+ this.#from = options.from;
16
+ this.#replyTo = options.replyTo;
17
+ this.#fetch = options.fetch ?? globalThis.fetch;
18
+ }
19
+ async send(input, options = {}) {
20
+ const response = await this.#fetch(RESEND_ENDPOINT, {
21
+ method: 'POST',
22
+ redirect: 'error',
23
+ signal: boundedSignal(options.signal),
24
+ headers: {
25
+ authorization: `Bearer ${this.#apiKey}`,
26
+ 'content-type': 'application/json',
27
+ 'idempotency-key': `feedback-accepted/${input.githubIssueNumber}`,
28
+ },
29
+ body: JSON.stringify({
30
+ from: this.#from,
31
+ to: [input.recipient],
32
+ reply_to: this.#replyTo,
33
+ ...renderFeedbackAcceptedEmail(input),
34
+ }),
35
+ });
36
+ if (!response.ok) {
37
+ throw new Error(`feedback email provider rejected request with status ${response.status}`);
38
+ }
39
+ let providerResponse;
40
+ try {
41
+ providerResponse = JSON.parse(await readBoundedText(response, MAX_PROVIDER_RESPONSE_BYTES));
42
+ }
43
+ catch {
44
+ throw new Error('feedback email provider returned an invalid response');
45
+ }
46
+ const parsed = zProviderResponse(providerResponse);
47
+ return { providerMessageId: parsed };
48
+ }
49
+ }
50
+ function boundedSignal(signal) {
51
+ const timeout = AbortSignal.timeout(DELIVERY_TIMEOUT_MS);
52
+ return signal === undefined ? timeout : AbortSignal.any([signal, timeout]);
53
+ }
54
+ export function renderFeedbackAcceptedEmail(input) {
55
+ const title = clean(sanitizedFeedbackText(input.title, 200), 200);
56
+ const message = sanitizedFeedbackText(input.message, 4_000);
57
+ const text = `Hi,
58
+
59
+ Thanks for sharing this feedback with Noodle Seed. I wanted to let you know that our engineering team is now looking into:
60
+
61
+ ${title}
62
+
63
+ ${message}
64
+
65
+ If you'd like to discuss it directly, just reply to this email.
66
+
67
+ — Asad`;
68
+ const html = `<!doctype html>
69
+ <html lang="en">
70
+ <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(SUBJECT)}</title></head>
71
+ <body style="margin:0;background:#f4f2ed;color:#171714;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;">
72
+ <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background:#f4f2ed;padding:32px 16px;"><tr><td align="center">
73
+ <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="max-width:600px;background:#fff;border:1px solid #dedbd3;border-radius:16px;">
74
+ <tr><td style="padding:40px;">
75
+ <h1 style="margin:0 0 24px;font-size:28px;line-height:1.2;">We're looking into your feedback</h1>
76
+ <p style="margin:0 0 18px;font-size:16px;line-height:1.65;">Hi,</p>
77
+ <p style="margin:0 0 18px;font-size:16px;line-height:1.65;">Thanks for sharing this feedback with Noodle Seed. I wanted to let you know that our engineering team is now looking into:</p>
78
+ <p style="margin:0 0 10px;font-size:18px;line-height:1.5;"><strong>${escapeHtml(title)}</strong></p>
79
+ <p style="margin:0 0 24px;font-size:16px;line-height:1.65;white-space:pre-wrap;">${escapeHtml(message)}</p>
80
+ <p style="margin:0 0 18px;font-size:16px;line-height:1.65;">If you'd like to discuss it directly, just reply to this email.</p>
81
+ <p style="margin:0;font-size:16px;line-height:1.65;">— Asad</p>
82
+ </td></tr>
83
+ </table>
84
+ </td></tr></table>
85
+ </body>
86
+ </html>`;
87
+ return { subject: SUBJECT, text, html };
88
+ }
89
+ function clean(value, length) {
90
+ return value
91
+ .replace(/[\r\n]+/g, ' ')
92
+ .trim()
93
+ .slice(0, length);
94
+ }
95
+ function escapeHtml(value) {
96
+ return value
97
+ .replaceAll('&', '&amp;')
98
+ .replaceAll('<', '&lt;')
99
+ .replaceAll('>', '&gt;')
100
+ .replaceAll('"', '&quot;')
101
+ .replaceAll("'", '&#039;');
102
+ }
103
+ function zProviderResponse(value) {
104
+ const parsed = ProviderResponseSchema.safeParse(value);
105
+ if (!parsed.success) {
106
+ throw new Error('feedback email provider returned an invalid response');
107
+ }
108
+ return parsed.data.id;
109
+ }
110
+ async function readBoundedText(response, maxBytes) {
111
+ const declaredLength = Number(response.headers.get('content-length'));
112
+ if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
113
+ throw new Error('response exceeds byte limit');
114
+ }
115
+ if (response.body === null)
116
+ return '';
117
+ const reader = response.body.getReader();
118
+ const chunks = [];
119
+ let total = 0;
120
+ try {
121
+ while (true) {
122
+ const { done, value } = await reader.read();
123
+ if (done)
124
+ break;
125
+ total += value.byteLength;
126
+ if (total > maxBytes)
127
+ throw new Error('response exceeds byte limit');
128
+ chunks.push(value);
129
+ }
130
+ }
131
+ finally {
132
+ await reader.cancel().catch(() => undefined);
133
+ }
134
+ const bytes = new Uint8Array(total);
135
+ let offset = 0;
136
+ for (const chunk of chunks) {
137
+ bytes.set(chunk, offset);
138
+ offset += chunk.byteLength;
139
+ }
140
+ return new TextDecoder().decode(bytes);
141
+ }
142
+ //# sourceMappingURL=reporter-email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter-email.js","sourceRoot":"","sources":["../../src/feedback-operations/reporter-email.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ import { z } from 'zod';
2
+ import type { SlackFeedbackCardInput } from './contracts.js';
3
+ export declare const SlackFeedbackCardSchema: z.ZodObject<{
4
+ text: z.ZodString;
5
+ blocks: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
6
+ type: z.ZodLiteral<"header">;
7
+ text: z.ZodObject<{
8
+ type: z.ZodLiteral<"plain_text">;
9
+ text: z.ZodString;
10
+ emoji: z.ZodOptional<z.ZodBoolean>;
11
+ }, z.core.$strict>;
12
+ }, z.core.$strict>, z.ZodObject<{
13
+ type: z.ZodLiteral<"section">;
14
+ text: z.ZodObject<{
15
+ type: z.ZodLiteral<"mrkdwn">;
16
+ text: z.ZodString;
17
+ }, z.core.$strict>;
18
+ }, z.core.$strict>, z.ZodObject<{
19
+ type: z.ZodLiteral<"context">;
20
+ elements: z.ZodArray<z.ZodObject<{
21
+ type: z.ZodLiteral<"mrkdwn">;
22
+ text: z.ZodString;
23
+ }, z.core.$strict>>;
24
+ }, z.core.$strict>, z.ZodObject<{
25
+ type: z.ZodLiteral<"actions">;
26
+ elements: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
27
+ type: z.ZodLiteral<"button">;
28
+ text: z.ZodObject<{
29
+ type: z.ZodLiteral<"plain_text">;
30
+ text: z.ZodString;
31
+ emoji: z.ZodOptional<z.ZodBoolean>;
32
+ }, z.core.$strict>;
33
+ url: z.ZodURL;
34
+ action_id: z.ZodLiteral<"feedback_open_linear">;
35
+ }, z.core.$strict>, z.ZodObject<{
36
+ type: z.ZodLiteral<"button">;
37
+ text: z.ZodObject<{
38
+ type: z.ZodLiteral<"plain_text">;
39
+ text: z.ZodString;
40
+ emoji: z.ZodOptional<z.ZodBoolean>;
41
+ }, z.core.$strict>;
42
+ style: z.ZodLiteral<"primary">;
43
+ action_id: z.ZodLiteral<"feedback_start_work">;
44
+ value: z.ZodString;
45
+ confirm: z.ZodObject<{
46
+ title: z.ZodObject<{
47
+ type: z.ZodLiteral<"plain_text">;
48
+ text: z.ZodString;
49
+ emoji: z.ZodOptional<z.ZodBoolean>;
50
+ }, z.core.$strict>;
51
+ text: z.ZodObject<{
52
+ type: z.ZodLiteral<"mrkdwn">;
53
+ text: z.ZodString;
54
+ }, z.core.$strict>;
55
+ confirm: z.ZodObject<{
56
+ type: z.ZodLiteral<"plain_text">;
57
+ text: z.ZodString;
58
+ emoji: z.ZodOptional<z.ZodBoolean>;
59
+ }, z.core.$strict>;
60
+ deny: z.ZodObject<{
61
+ type: z.ZodLiteral<"plain_text">;
62
+ text: z.ZodString;
63
+ emoji: z.ZodOptional<z.ZodBoolean>;
64
+ }, z.core.$strict>;
65
+ }, z.core.$strict>;
66
+ }, z.core.$strict>]>>;
67
+ }, z.core.$strict>]>>;
68
+ }, z.core.$strict>;
69
+ export type SlackFeedbackCard = z.infer<typeof SlackFeedbackCardSchema>;
70
+ export declare const SlackFeedbackCardJsonSchema: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
71
+ text: z.ZodString;
72
+ blocks: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
73
+ type: z.ZodLiteral<"header">;
74
+ text: z.ZodObject<{
75
+ type: z.ZodLiteral<"plain_text">;
76
+ text: z.ZodString;
77
+ emoji: z.ZodOptional<z.ZodBoolean>;
78
+ }, z.core.$strict>;
79
+ }, z.core.$strict>, z.ZodObject<{
80
+ type: z.ZodLiteral<"section">;
81
+ text: z.ZodObject<{
82
+ type: z.ZodLiteral<"mrkdwn">;
83
+ text: z.ZodString;
84
+ }, z.core.$strict>;
85
+ }, z.core.$strict>, z.ZodObject<{
86
+ type: z.ZodLiteral<"context">;
87
+ elements: z.ZodArray<z.ZodObject<{
88
+ type: z.ZodLiteral<"mrkdwn">;
89
+ text: z.ZodString;
90
+ }, z.core.$strict>>;
91
+ }, z.core.$strict>, z.ZodObject<{
92
+ type: z.ZodLiteral<"actions">;
93
+ elements: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
94
+ type: z.ZodLiteral<"button">;
95
+ text: z.ZodObject<{
96
+ type: z.ZodLiteral<"plain_text">;
97
+ text: z.ZodString;
98
+ emoji: z.ZodOptional<z.ZodBoolean>;
99
+ }, z.core.$strict>;
100
+ url: z.ZodURL;
101
+ action_id: z.ZodLiteral<"feedback_open_linear">;
102
+ }, z.core.$strict>, z.ZodObject<{
103
+ type: z.ZodLiteral<"button">;
104
+ text: z.ZodObject<{
105
+ type: z.ZodLiteral<"plain_text">;
106
+ text: z.ZodString;
107
+ emoji: z.ZodOptional<z.ZodBoolean>;
108
+ }, z.core.$strict>;
109
+ style: z.ZodLiteral<"primary">;
110
+ action_id: z.ZodLiteral<"feedback_start_work">;
111
+ value: z.ZodString;
112
+ confirm: z.ZodObject<{
113
+ title: z.ZodObject<{
114
+ type: z.ZodLiteral<"plain_text">;
115
+ text: z.ZodString;
116
+ emoji: z.ZodOptional<z.ZodBoolean>;
117
+ }, z.core.$strict>;
118
+ text: z.ZodObject<{
119
+ type: z.ZodLiteral<"mrkdwn">;
120
+ text: z.ZodString;
121
+ }, z.core.$strict>;
122
+ confirm: z.ZodObject<{
123
+ type: z.ZodLiteral<"plain_text">;
124
+ text: z.ZodString;
125
+ emoji: z.ZodOptional<z.ZodBoolean>;
126
+ }, z.core.$strict>;
127
+ deny: z.ZodObject<{
128
+ type: z.ZodLiteral<"plain_text">;
129
+ text: z.ZodString;
130
+ emoji: z.ZodOptional<z.ZodBoolean>;
131
+ }, z.core.$strict>;
132
+ }, z.core.$strict>;
133
+ }, z.core.$strict>]>>;
134
+ }, z.core.$strict>]>>;
135
+ }, z.core.$strict>>;
136
+ export declare function renderSlackFeedbackCard(input: SlackFeedbackCardInput): SlackFeedbackCard;
137
+ export declare function sanitizedFeedbackText(value: string, maxLength?: number): string;
138
+ //# sourceMappingURL=slack-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-card.d.ts","sourceRoot":"","sources":["../../src/feedback-operations/slack-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAyD7D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAUzB,CAAC;AAEZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAEtC,CAAC;AAEH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CA8DxF;AAoBD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAqB,GAAG,MAAM,CAE3F"}
@@ -0,0 +1,199 @@
1
+ import { z } from 'zod';
2
+ const START_WORK_ACTION_ID = 'feedback_start_work';
3
+ const MAX_EXCERPT_LENGTH = 900;
4
+ const PlainTextSchema = z
5
+ .object({
6
+ type: z.literal('plain_text'),
7
+ text: z.string().min(1).max(300),
8
+ emoji: z.boolean().optional(),
9
+ })
10
+ .strict();
11
+ const MrkdwnTextSchema = z
12
+ .object({ type: z.literal('mrkdwn'), text: z.string().min(1).max(3_000) })
13
+ .strict();
14
+ const HeaderBlockSchema = z.object({ type: z.literal('header'), text: PlainTextSchema }).strict();
15
+ const SectionBlockSchema = z
16
+ .object({ type: z.literal('section'), text: MrkdwnTextSchema })
17
+ .strict();
18
+ const ContextBlockSchema = z
19
+ .object({ type: z.literal('context'), elements: z.array(MrkdwnTextSchema).min(1).max(10) })
20
+ .strict();
21
+ const LinearButtonSchema = z
22
+ .object({
23
+ type: z.literal('button'),
24
+ text: PlainTextSchema,
25
+ url: z.url(),
26
+ action_id: z.literal('feedback_open_linear'),
27
+ })
28
+ .strict();
29
+ const StartWorkButtonSchema = z
30
+ .object({
31
+ type: z.literal('button'),
32
+ text: PlainTextSchema,
33
+ style: z.literal('primary'),
34
+ action_id: z.literal(START_WORK_ACTION_ID),
35
+ value: z.string().min(1).max(2_000),
36
+ confirm: z
37
+ .object({
38
+ title: PlainTextSchema,
39
+ text: MrkdwnTextSchema,
40
+ confirm: PlainTextSchema,
41
+ deny: PlainTextSchema,
42
+ })
43
+ .strict(),
44
+ })
45
+ .strict();
46
+ const ActionsBlockSchema = z
47
+ .object({
48
+ type: z.literal('actions'),
49
+ elements: z
50
+ .array(z.union([LinearButtonSchema, StartWorkButtonSchema]))
51
+ .min(1)
52
+ .max(2),
53
+ })
54
+ .strict();
55
+ export const SlackFeedbackCardSchema = z
56
+ .object({
57
+ text: z.string().min(1).max(300),
58
+ blocks: z
59
+ .array(z.union([HeaderBlockSchema, SectionBlockSchema, ContextBlockSchema, ActionsBlockSchema]))
60
+ .min(3)
61
+ .max(4),
62
+ })
63
+ .strict();
64
+ export const SlackFeedbackCardJsonSchema = z.toJSONSchema(SlackFeedbackCardSchema, {
65
+ target: 'draft-2020-12',
66
+ });
67
+ export function renderSlackFeedbackCard(input) {
68
+ const title = projectionSafeText(input.title, 180) || 'Feedback';
69
+ const metadata = [
70
+ priority(input.labels),
71
+ area(input.labels),
72
+ kind(input.labels),
73
+ input.status.name,
74
+ input.assigneeName,
75
+ reporterNotificationLabel(input.reporterNotification),
76
+ ]
77
+ .filter((value) => value !== undefined)
78
+ .map((value) => projectionSafeText(value, 150))
79
+ .filter((value) => value.length > 0);
80
+ const blocks = [
81
+ {
82
+ type: 'header',
83
+ text: { type: 'plain_text', text: clamp(title, 150), emoji: true },
84
+ },
85
+ {
86
+ type: 'section',
87
+ text: { type: 'mrkdwn', text: sanitizedExcerpt(input.message) },
88
+ },
89
+ {
90
+ type: 'context',
91
+ elements: [{ type: 'mrkdwn', text: metadata.map(escapeMrkdwn).join(' • ') }],
92
+ },
93
+ ];
94
+ const actions = [];
95
+ const linearUrl = approvedLinearUrl(input.linearUrl);
96
+ if (linearUrl !== undefined) {
97
+ actions.push({
98
+ type: 'button',
99
+ text: { type: 'plain_text', text: 'Open in Linear', emoji: true },
100
+ url: linearUrl,
101
+ action_id: 'feedback_open_linear',
102
+ });
103
+ }
104
+ if (mayStartWork(input)) {
105
+ actions.push({
106
+ type: 'button',
107
+ text: { type: 'plain_text', text: 'Start work & notify reporter', emoji: true },
108
+ style: 'primary',
109
+ action_id: START_WORK_ACTION_ID,
110
+ value: input.linearIssueId,
111
+ confirm: {
112
+ title: { type: 'plain_text', text: 'Start work?' },
113
+ text: {
114
+ type: 'mrkdwn',
115
+ text: 'Move this issue to In Progress and email the reporter?\n\nThis will send an external email.',
116
+ },
117
+ confirm: { type: 'plain_text', text: 'Start work' },
118
+ deny: { type: 'plain_text', text: 'Cancel' },
119
+ },
120
+ });
121
+ }
122
+ if (actions.length > 0)
123
+ blocks.push({ type: 'actions', elements: actions });
124
+ return SlackFeedbackCardSchema.parse({
125
+ text: `${projectionSafeText(input.linearIdentifier, 100) || 'Feedback'}: ${title}`,
126
+ blocks,
127
+ });
128
+ }
129
+ function reporterNotificationLabel(state) {
130
+ if (state === 'sent')
131
+ return 'Reporter notified';
132
+ if (state === 'delayed')
133
+ return 'Reporter notification delayed';
134
+ if (state === 'queued')
135
+ return 'Reporter notification queued';
136
+ if (state === 'unknown')
137
+ return 'Reporter notification outcome unknown';
138
+ return undefined;
139
+ }
140
+ function mayStartWork(input) {
141
+ return (input.trustedReporter &&
142
+ input.reporterNotification === 'pending' &&
143
+ (input.status.type === 'backlog' || input.status.type === 'unstarted'));
144
+ }
145
+ export function sanitizedFeedbackText(value, maxLength = MAX_EXCERPT_LENGTH) {
146
+ return projectionSafeText(value, maxLength);
147
+ }
148
+ function projectionSafeText(value, maxLength) {
149
+ const withoutPrivateSections = value.split(/^#{1,6}\s+(?:Reporter|Diagnostics)\b/im)[0] ?? '';
150
+ const redacted = withoutPrivateSections
151
+ .replace(/https?:\/\/\S+/gi, '[redacted URL]')
152
+ .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, '[redacted]')
153
+ .replace(/\bBearer\s+[A-Za-z0-9._~+/-]+=*/gi, 'Bearer [redacted]')
154
+ .replace(/\b(?:xox[baprs]-|sk-|gh[pousr]_)[A-Za-z0-9_-]+\b/gi, '[redacted]')
155
+ .replace(/\b(?:api[_ -]?key|access[_ -]?token|refresh[_ -]?token|token|password|secret|authorization)\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi, '[redacted]')
156
+ .replace(/(?:\/(?:Users|home|private|var|tmp)\/|[A-Z]:\\Users\\)\S+/gi, '[redacted path]');
157
+ return clamp(redacted.trim(), maxLength);
158
+ }
159
+ function sanitizedExcerpt(value) {
160
+ const sanitized = sanitizedFeedbackText(value);
161
+ return sanitized.length > 0 ? escapeMrkdwn(sanitized) : '_No feedback excerpt available._';
162
+ }
163
+ function priority(labels) {
164
+ return labels.find((label) => /^P[0-3]$/i.test(label))?.toUpperCase();
165
+ }
166
+ function area(labels) {
167
+ return labelValue(labels, 'area:');
168
+ }
169
+ function kind(labels) {
170
+ return labelValue(labels, 'type:');
171
+ }
172
+ function labelValue(labels, prefix) {
173
+ const label = labels.find((candidate) => candidate.toLowerCase().startsWith(prefix));
174
+ const value = label?.slice(prefix.length);
175
+ return value ? value.toUpperCase() : undefined;
176
+ }
177
+ function clamp(value, length) {
178
+ const trimmed = value.trim();
179
+ return trimmed.length <= length ? trimmed : `${trimmed.slice(0, Math.max(0, length - 1))}…`;
180
+ }
181
+ function escapeMrkdwn(value) {
182
+ return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
183
+ }
184
+ function approvedLinearUrl(value) {
185
+ try {
186
+ const url = new URL(value);
187
+ if (url.origin !== 'https://linear.app' ||
188
+ url.username !== '' ||
189
+ url.password !== '' ||
190
+ url.hash !== '') {
191
+ return undefined;
192
+ }
193
+ return url.href;
194
+ }
195
+ catch {
196
+ return undefined;
197
+ }
198
+ }
199
+ //# sourceMappingURL=slack-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-card.js","sourceRoot":"","sources":["../../src/feedback-operations/slack-card.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { SlackFeedbackCard } from './slack-card.js';
2
+ export interface SlackFeedbackClient {
3
+ publishCard(input: {
4
+ channelId: string;
5
+ messageTs: string | undefined;
6
+ clientMessageId: string;
7
+ card: SlackFeedbackCard;
8
+ }, options?: {
9
+ readonly signal?: AbortSignal;
10
+ }): Promise<{
11
+ readonly messageTs: string;
12
+ }>;
13
+ sendPrivateResponse(input: {
14
+ responseUrl: string;
15
+ text: string;
16
+ }, options?: {
17
+ readonly signal?: AbortSignal;
18
+ }): Promise<void>;
19
+ }
20
+ export declare class SlackWebApiFeedbackClient implements SlackFeedbackClient {
21
+ #private;
22
+ constructor(options: {
23
+ botToken: string;
24
+ fetch?: typeof fetch;
25
+ });
26
+ publishCard(input: {
27
+ channelId: string;
28
+ messageTs: string | undefined;
29
+ clientMessageId: string;
30
+ card: SlackFeedbackCard;
31
+ }, options?: {
32
+ readonly signal?: AbortSignal;
33
+ }): Promise<{
34
+ readonly messageTs: string;
35
+ }>;
36
+ sendPrivateResponse(input: {
37
+ responseUrl: string;
38
+ text: string;
39
+ }, options?: {
40
+ readonly signal?: AbortSignal;
41
+ }): Promise<void>;
42
+ }
43
+ export declare function assertSlackResponseUrl(value: string): void;
44
+ //# sourceMappingURL=slack-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-client.d.ts","sourceRoot":"","sources":["../../src/feedback-operations/slack-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMzD,MAAM,WAAW,mBAAmB;IAClC,WAAW,CACT,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,eAAe,EAAE,MAAM,CAAC;QACxB,IAAI,EAAE,iBAAiB,CAAC;KACzB,EACD,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,mBAAmB,CACjB,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAC5C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,qBAAa,yBAA0B,YAAW,mBAAmB;;gBAIvD,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;KAAE;IAMzD,WAAW,CACf,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,eAAe,EAAE,MAAM,CAAC;QACxB,IAAI,EAAE,iBAAiB,CAAC;KACzB,EACD,OAAO,GAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAC9C,OAAO,CAAC;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAyBpC,mBAAmB,CACvB,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAC5C,OAAO,GAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAC9C,OAAO,CAAC,IAAI,CAAC;CAoDjB;AAOD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAS1D"}