From 5fd9c08b0d8a8411223b37fd33a4133c05bca6f1 Mon Sep 17 00:00:00 2001 From: Alex Gold Date: Thu, 26 Feb 2026 15:09:28 -0500 Subject: [PATCH 1/2] Add plan --- plans/migrate-email-to-mailgun.md | 205 ++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 plans/migrate-email-to-mailgun.md diff --git a/plans/migrate-email-to-mailgun.md b/plans/migrate-email-to-mailgun.md new file mode 100644 index 000000000..f285a1a80 --- /dev/null +++ b/plans/migrate-email-to-mailgun.md @@ -0,0 +1,205 @@ +# Migrate Email Sending from Customer.io to Mailgun + +## Overview + +Replace Customer.io transactional email API with Mailgun's Node.js SDK (`mailgun.js`). Instead of referencing remote Customer.io template IDs, we'll render the local HTML templates in `src/lib/emails/*.html` server-side and send the full HTML body to Mailgun. + +## Current Architecture + +- **Provider**: Customer.io via `customerio-node` SDK +- **Config**: `CUSTOMERIO_EMAIL_API_KEY` in `config.server.ts` +- **Templates**: Remote, stored in Customer.io, referenced by numeric ID (`'10'`, `'11'`, etc.) +- **Variable substitution**: Done by Customer.io using Liquid syntax (`{{ var }}`, `{% if %}`) +- **Send function**: `send()` in `email.ts` creates `APIClient` + `SendEmailRequest` + +## Target Architecture + +- **Provider**: Mailgun via `mailgun.js` SDK + `form-data` +- **Config**: `MAILGUN_API_KEY` and `MAILGUN_DOMAIN` in `config.server.ts` +- **Templates**: Local HTML files in `src/lib/emails/*.html` +- **Variable substitution**: Done server-side in Node.js before sending +- **Send function**: `send()` calls `mg.messages.create()` + +## Changes Required + +### 1. Config (`src/lib/config.server.ts`) + +- Add `MAILGUN_API_KEY` and `MAILGUN_DOMAIN` env vars +- Eventually remove `CUSTOMERIO_EMAIL_API_KEY` (can keep both during transition) + +### 2. Template Rendering (`src/lib/email.ts`) + +> **Note**: This may not be the right place to put the email templates — looking for guidance on where they should live. + +Create a `renderTemplate()` function that: + +1. Reads the HTML file from `src/lib/emails/{name}.html` using `fs.readFileSync` +2. Replaces `{{ variable_name }}` with the provided values using a single regex + +```typescript +function renderTemplate(name: string, vars: Record) { + const templatePath = path.join(__dirname, 'emails', `${name}.html`); + const html = fs.readFileSync(templatePath, 'utf-8'); + return html.replace(/\{\{\s*(\w+)\s*\}\}/g, (_, key) => { + if (!(key in vars)) { + throw new Error(`Missing template variable '${key}' in email template '${name}'`); + } + return vars[key]; + }); +} +``` + +**Pre-requisite template changes** (do before migration): + +- ~~Replace `{{ "now" | date: "%Y" }}` with `{{ year }}` in all 12 templates~~ ✅ Done +- Replace the `{% if has_credits %}...{% endif %}` block with `{{ credits_section }}` in the 3 OSS templates (`ossInviteNewUser.html`, `ossInviteExistingUser.html`, `ossExistingOrgProvisioned.html`) +- This eliminates all Liquid syntax — templates only use `{{ variable }}` interpolation + +**`credits_section` logic**: The 3 OSS templates currently have this conditional block: + +```html +{% if has_credits %}
• +${{ monthly_credits_usd }} USD in Kilo credits, which reset +every 30 days{% endif %} +``` + +This becomes `{{ credits_section }}` in the template, and the JS builds it: + +```typescript +function buildCreditsSection(monthlyCreditsUsd: number): string { + if (monthlyCreditsUsd <= 0) return ''; + return `
$${monthlyCreditsUsd} USD in Kilo credits, which reset every 30 days`; +} +``` + +Then in each OSS send function: + +```typescript +export async function sendOssInviteNewUserEmail(data: OssInviteEmailData) { + const tierConfig = ossTierConfig[data.tier]; + const html = renderTemplate('ossInviteNewUser', { + tier_name: tierConfig.name, + seats: String(tierConfig.seats), + seat_value: tierConfig.seatValue.toLocaleString(), + credits_section: buildCreditsSection(data.monthlyCreditsUsd), + accept_invite_url: data.acceptInviteUrl, + integrations_url: `${NEXTAUTH_URL}/organizations/${data.organizationId}/integrations`, + code_reviews_url: `${NEXTAUTH_URL}/organizations/${data.organizationId}/code-reviews`, + year: String(new Date().getFullYear()), + }); + return send({ to: data.to, subject: 'Kilo: OSS Sponsorship Offer', html }); +} +``` + +### 3. Send Function (`src/lib/email.ts`) + +Replace the `send()` function. Use `mailgun.js` SDK + `form-data`: + +```typescript +import formData from 'form-data'; +import Mailgun from 'mailgun.js'; + +const mailgun = new Mailgun(formData); +const mg = mailgun.client({ username: 'api', key: MAILGUN_API_KEY }); + +async function send(params: { to: string; subject: string; html: string }) { + if (!MAILGUN_API_KEY) { + const message = 'MAILGUN_API_KEY is not set - cannot send email'; + console.warn(message); + captureMessage(message, { level: 'warning', tags: { source: 'email_service' } }); + return; + } + + return mg.messages.create(MAILGUN_DOMAIN, { + from: 'Kilo Code ', + to: [params.to], + subject: params.subject, + html: params.html, + 'h:Reply-To': 'hi@app.kilocode.ai', + }); +} +``` + +Dependencies to install: `pnpm add mailgun.js form-data` + +### 4. Update Each Send Function + +Each `send*Email` function needs to: + +1. Call `renderTemplate('templateName', { ...variables })` to get the final HTML +2. Call `send({ to, subject, html, replyTo: 'hi@kilocode.ai' })` + +**Key difference**: Each function now needs to provide a `subject` line, since Customer.io stored subjects in the template but Mailgun needs it passed explicitly. + +Suggested subjects: +| Function | Subject | +|---|---| +| `sendOrgSubscriptionEmail` | "Welcome to Kilo for Teams!" | +| `sendOrgRenewedEmail` | "Kilo: Your Teams Subscription Renewal" | +| `sendOrgCancelledEmail` | "Kilo: Your Teams Subscription is Cancelled" | +| `sendOrgSSOUserJoinedEmail` | "Kilo: New SSO User Joined Your Organization" | +| `sendOrganizationInviteEmail` | "Kilo: Teams Invitation" | +| `sendMagicLinkEmail` | "Sign in to Kilo Code" | +| `sendBalanceAlertEmail` | "Kilo: Low Balance Alert" | +| `sendAutoTopUpFailedEmail` | "Kilo: Auto Top-Up Failed" | +| `sendOssInviteNewUserEmail` | "Kilo: OSS Sponsorship Offer" | +| `sendOssInviteExistingUserEmail` | "Kilo: OSS Sponsorship Offer" | +| `sendOssExistingOrgProvisionedEmail` | "Kilo: OSS Sponsorship Offer" | +| `sendDeploymentFailedEmail` | "Kilo: Your Deployment Failed" | + +### 5. Remove Customer.io Dependencies + +- Remove `customerio-node` from `package.json` +- Remove `CUSTOMERIO_EMAIL_API_KEY` from `config.server.ts` +- Remove the `templates` map (no longer needed) +- Remove `SendEmailRequestOptions` type imports +- Note: `src/lib/external-services.ts` also references Customer.io for user deletion — that's a separate concern and uses different API keys (`CUSTOMERIO_SITE_ID`, `CUSTOMERIO_API_KEY`) + +### 6. Template Variable Changes + +All templates use `{{ variable }}` interpolation. The `renderTemplate()` function replaces each `{{ name }}` with the corresponding value from the provided variables object. + +| Template file | Variables | +| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `orgSubscription.html` | `seats`, `organization_url`, `invoices_url`, `year` | +| `orgRenewed.html` | `seats`, `invoices_url`, `year` | +| `orgCancelled.html` | `invoices_url`, `year` | +| `orgSSOUserJoined.html` | `new_user_email`, `organization_url`, `year` | +| `orgInvitation.html` | `organization_name`, `inviter_name`, `accept_invite_url`, `year` | +| `magicLink.html` | `magic_link_url`, `email`, `expires_in`, `year` | +| `balanceAlert.html` | `minimum_balance`, `organization_url`, `year` | +| `autoTopUpFailed.html` | `reason`, `credits_url`, `year` | +| `ossInviteNewUser.html` | `tier_name`, `seats`, `seat_value`, `credits_section`, `accept_invite_url`, `integrations_url`, `code_reviews_url`, `year` | +| `ossInviteExistingUser.html` | `tier_name`, `seats`, `seat_value`, `credits_section`, `organization_url`, `integrations_url`, `code_reviews_url`, `year` | +| `ossExistingOrgProvisioned.html` | `tier_name`, `seats`, `seat_value`, `credits_section`, `organization_url`, `integrations_url`, `code_reviews_url`, `year` | +| `deployFailed.html` | `deployment_name`, `deployment_url`, `repository`, `year` | + +Notes: + +- `year` is always `String(new Date().getFullYear())` +- `credits_section` is built in JS: either the credits HTML snippet or empty string, depending on whether the org has monthly credits + +### 7. Environment Variables + +New env vars needed: + +- `MAILGUN_API_KEY` — Mailgun API key (starts with `key-...`) +- `MAILGUN_DOMAIN` — Mailgun sending domain (e.g., `mail.kilocode.ai`) + +## Migration Strategy + +1. Add Mailgun env vars and new `send()` function alongside existing Customer.io code +2. Migrate one email at a time (start with `deployFailed` as it's simplest) +3. Test each email by triggering it in staging + — **TODO: how will this work?** We need a way to trigger each email send path (e.g. trigger a deployment failure, send a magic link, etc.) in a staging environment and verify the email arrives via Mailgun. Need guidance on what staging setup exists and whether there's a way to trigger these flows without side effects. +4. Once all emails are migrated, remove Customer.io code and dependency + +## Files Changed + +| File | Change | +| -------------------------- | ------------------------------------------------------------------------------- | +| `src/lib/email.ts` | Major rewrite: new send(), renderTemplate(), update all send\*Email functions | +| `src/lib/config.server.ts` | Add MAILGUN_API_KEY, MAILGUN_DOMAIN; eventually remove CUSTOMERIO_EMAIL_API_KEY | +| `package.json` | Remove `customerio-node`; add `mailgun.js` + `form-data` | +| `src/lib/emails/AGENTS.md` | Update to reflect Mailgun | +| `.env` files | Add MAILGUN_API_KEY, MAILGUN_DOMAIN | From 155d5a34062e4574588988902c4ec4806f5d6482 Mon Sep 17 00:00:00 2001 From: Alex Gold Date: Thu, 26 Feb 2026 15:11:00 -0500 Subject: [PATCH 2/2] Add email templates --- src/lib/emails/AGENTS.md | 66 ++++++ src/lib/emails/autoTopUpFailed.html | 149 ++++++++++++++ src/lib/emails/balanceAlert.html | 139 +++++++++++++ src/lib/emails/deployFailed.html | 106 ++++++++++ src/lib/emails/magicLink.html | 186 +++++++++++++++++ src/lib/emails/orgCancelled.html | 124 +++++++++++ src/lib/emails/orgInvitation.html | 124 +++++++++++ src/lib/emails/orgRenewed.html | 125 +++++++++++ src/lib/emails/orgSSOUserJoined.html | 115 +++++++++++ src/lib/emails/orgSubscription.html | 130 ++++++++++++ src/lib/emails/ossExistingOrgProvisioned.html | 193 +++++++++++++++++ src/lib/emails/ossInviteExistingUser.html | 194 ++++++++++++++++++ src/lib/emails/ossInviteNewUser.html | 194 ++++++++++++++++++ 13 files changed, 1845 insertions(+) create mode 100644 src/lib/emails/AGENTS.md create mode 100644 src/lib/emails/autoTopUpFailed.html create mode 100644 src/lib/emails/balanceAlert.html create mode 100644 src/lib/emails/deployFailed.html create mode 100644 src/lib/emails/magicLink.html create mode 100644 src/lib/emails/orgCancelled.html create mode 100644 src/lib/emails/orgInvitation.html create mode 100644 src/lib/emails/orgRenewed.html create mode 100644 src/lib/emails/orgSSOUserJoined.html create mode 100644 src/lib/emails/orgSubscription.html create mode 100644 src/lib/emails/ossExistingOrgProvisioned.html create mode 100644 src/lib/emails/ossInviteExistingUser.html create mode 100644 src/lib/emails/ossInviteNewUser.html diff --git a/src/lib/emails/AGENTS.md b/src/lib/emails/AGENTS.md new file mode 100644 index 000000000..f27a0257a --- /dev/null +++ b/src/lib/emails/AGENTS.md @@ -0,0 +1,66 @@ +# Email Templates + +These HTML files are Customer.io transactional email templates. They are uploaded to Customer.io and referenced by ID in [`src/lib/email.ts`](../email.ts). + +## Styling + +All templates use the Kilo brand design system: + +| Property | Value | +| ----------------------- | ----------------------------------------------------- | +| Font | `'JetBrains Mono', 'Courier New', Courier, monospace` | +| Page background | `#1a1a1a` | +| Card background | `#2a2a2a` | +| Card border | `1px solid #3a3a3a` | +| H1 color | `#f4e452` (yellow) | +| Body text | `#9ca3af` (gray) | +| Strong / emphasis text | `#d1d5db` (light gray) | +| Links | `#f4e452` (yellow) | +| CTA button background | `#f4e452` (yellow) | +| CTA button text | `#6b7280` (dark gray) | +| Footer / secondary text | `#6b7280` | +| Section divider | `1px solid #3a3a3a` | + +## Footer + +Every template must include this branding footer below the card: + +```html + + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San Francisco, CA + 94105, USA +

+
+``` + +## Template Variables + +Customer.io transactional emails receive variables from `message_data` as **top-level Liquid variables** — use `{{ variable_name }}` directly, not `{{ trigger.variable_name }}`. + +| Template file | Customer.io ID | Variables | +| -------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `orgSubscription.html` | `10` | `seats`, `organization_url`, `invoices_url` | +| `orgRenewed.html` | `11` | `seats`, `invoices_url` | +| `orgCancelled.html` | `12` | `invoices_url` | +| `orgSSOUserJoined.html` | `13` | `new_user_email`, `organization_url` | +| `orgInvitation.html` | `6` | `organization_name`, `inviter_name`, `accept_invite_url` | +| `magicLink.html` | `14` | `magic_link_url`, `email`, `expires_in`, `expires_at`, `app_url` | +| `balanceAlert.html` | `16` | `organizationId`, `minimum_balance`, `organization_url`, `invoices_url` | +| `autoTopUpFailed.html` | `17` | `reason`, `credits_url` | +| `ossInviteNewUser.html` | `18` | `organization_name`, `accept_invite_url`, `integrations_url`, `code_reviews_url`, `tier_name`, `seats`, `seat_value`, `has_credits`, `monthly_credits_usd` | +| `ossInviteExistingUser.html` | `19` | `organization_name`, `organization_url`, `integrations_url`, `code_reviews_url`, `tier_name`, `seats`, `seat_value`, `has_credits`, `monthly_credits_usd` | +| `ossExistingOrgProvisioned.html` | `20` | `organization_name`, `organization_url`, `integrations_url`, `code_reviews_url`, `tier_name`, `seats`, `seat_value`, `has_credits`, `monthly_credits_usd` | +| `deployFailed.html` | `21` | `deployment_name`, `deployment_url`, `repository` | diff --git a/src/lib/emails/autoTopUpFailed.html b/src/lib/emails/autoTopUpFailed.html new file mode 100644 index 000000000..ef0a66c04 --- /dev/null +++ b/src/lib/emails/autoTopUpFailed.html @@ -0,0 +1,149 @@ + + + + + + Auto Top-Up Failed + + + + + + +
+ + + + + + + + + + + + + +
+

+ Auto Top-Up Failed +

+
+

+ We couldn't process your automatic top-up. + {{ reason }} +

+

+ We've disabled auto-top-up to prevent repeated failures. To continue using Kilo + without interruption, please update your payment method or manually add credits on + your + credits page. +

+ + + + + +
+ + Go to Credits Page + +
+

+ If you have any questions, please don't hesitate to reply to this email. We are + here to help! +

+
+

+ — The Kilo Team +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/balanceAlert.html b/src/lib/emails/balanceAlert.html new file mode 100644 index 000000000..21859aa11 --- /dev/null +++ b/src/lib/emails/balanceAlert.html @@ -0,0 +1,139 @@ + + + + + + Balance Alert + + + + + + +
+ + + + + + + + + + + + + +
+

+ Balance Alert +

+
+

+ Your Kilo available balance has dropped below your configured alert threshold of + ${{ minimum_balance }}. You can add more + credits + on your organization page. +

+ + + + + +
+ + Add Credits + +
+

+ If you have any questions, please don't hesitate to reply to this email. We are + here to help! +

+
+

+ — The Kilo Team +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/deployFailed.html b/src/lib/emails/deployFailed.html new file mode 100644 index 000000000..d407a59a1 --- /dev/null +++ b/src/lib/emails/deployFailed.html @@ -0,0 +1,106 @@ + + + + + + Deployment Failed + + + + + + +
+ + + + + + + + + +
+

+ Deployment Failed +

+
+

+ Your deployment + {{ deployment_name }} from repository + {{ repository }} has failed. +

+ + + + + +
+ + View Deployment + +
+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/magicLink.html b/src/lib/emails/magicLink.html new file mode 100644 index 000000000..7aa8f3a40 --- /dev/null +++ b/src/lib/emails/magicLink.html @@ -0,0 +1,186 @@ + + + + + + Sign in to Kilo Code + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+

+ Sign in to Kilo Code +

+
+

+ Click the button below to sign in to your Kilo Code account: +

+ + + + + + +
+ + Sign in to Kilo Code + +
+ +

+ Or copy and paste this link into your browser: +

+

+ {{ magic_link_url }} +

+
+
+

+ Security Notice: This link will expire + in {{ expires_in }} and can only be used once. +

+
+
+

+ If you didn't request this email, you can safely ignore it. +

+

+ This email was sent to {{ email }} +

+
+ + + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/orgCancelled.html b/src/lib/emails/orgCancelled.html new file mode 100644 index 000000000..75d33a40b --- /dev/null +++ b/src/lib/emails/orgCancelled.html @@ -0,0 +1,124 @@ + + + + + + Your Kilo for Teams Subscription is Cancelled + + + + + + +
+ + + + + + + + + + + + + +
+

+ Your Kilo for Teams Subscription is Cancelled +

+
+

+ Your subscription for Kilo for Teams has been cancelled. We're sad to see you go! +

+

+ You can view your organization's invoices + here + including your final invoice. +

+

+ If you have any questions, please don't hesitate to reply to this email. We are + here to help! +

+
+

+ — The Kilo Team +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/orgInvitation.html b/src/lib/emails/orgInvitation.html new file mode 100644 index 000000000..8d0859c35 --- /dev/null +++ b/src/lib/emails/orgInvitation.html @@ -0,0 +1,124 @@ + + + + + + Kilo Code Teams Invitation + + + + + + +
+ + + + + + + + + + + + + +
+

+ Kilo Code Teams Invitation +

+
+

+ You've been invited to join a team on Kilo Code by + {{ inviter_name }}. Please click the + accept invite button to be added to the team "{{ organization_name }}". +

+ + + + + +
+ + Accept Invite + +
+
+

+ Happy coding!

~ The Kilo Code Team +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/orgRenewed.html b/src/lib/emails/orgRenewed.html new file mode 100644 index 000000000..70c5e1938 --- /dev/null +++ b/src/lib/emails/orgRenewed.html @@ -0,0 +1,125 @@ + + + + + + Kilo for Teams Subscription Renewal + + + + + + +
+ + + + + + + + + + + + + +
+

+ Kilo for Teams Subscription Renewal +

+
+

+ Your subscription for + {{ seats }} has been renewed for another + month. +

+

+ You can view your organization's invoices + here. +

+

+ If you have any questions, please don't hesitate to reply to this email. We are + here to help! +

+
+

+ — The Kilo Team +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/orgSSOUserJoined.html b/src/lib/emails/orgSSOUserJoined.html new file mode 100644 index 000000000..8e9ad5254 --- /dev/null +++ b/src/lib/emails/orgSSOUserJoined.html @@ -0,0 +1,115 @@ + + + + + + New SSO User Joined Your Organization + + + + + + +
+ + + + + + + + + + + + + +
+

+ New SSO User Joined +

+
+

+ Howdy! {{ new_user_email }} has joined + your organization by logging in with Enterprise SSO. You can view your member list + on your organization page. +

+

+ If you have any questions, please don't hesitate to reply to this email. We are + here to help! +

+
+

+ — The Kilo Team +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/orgSubscription.html b/src/lib/emails/orgSubscription.html new file mode 100644 index 000000000..8afda2bc0 --- /dev/null +++ b/src/lib/emails/orgSubscription.html @@ -0,0 +1,130 @@ + + + + + + Welcome to Kilo for Teams! + + + + + + +
+ + + + + + + + + + + + + +
+

+ Welcome to Kilo for Teams! +

+
+

+ Your subscription for {{ seats }} is now + active! Visit your + organization dashboard + to invite members & purchase AI credits to get your team going. +

+

+ You can also view your organization's invoices + here. +

+

+ If you have any questions, please don't hesitate to reply to this email. We are + here to help! +

+
+

+ — The Kilo Team +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/ossExistingOrgProvisioned.html b/src/lib/emails/ossExistingOrgProvisioned.html new file mode 100644 index 000000000..60f5f4d53 --- /dev/null +++ b/src/lib/emails/ossExistingOrgProvisioned.html @@ -0,0 +1,193 @@ + + + + + + Kilo OSS Sponsorship Offer + + + + + + +
+ + + + + + + + + + + + + +
+

+ Kilo OSS Sponsorship Offer +

+
+

+ Congratulations! You've been selected for the + Kilo OSS Sponsorship Program at the + {{ tier_name }} tier. +

+

+ Your sponsorship includes: +

+

+ • {{ seats }} Enterprise Seats (a ${{ + seat_value }} value){% if has_credits %}
• + ${{ monthly_credits_usd }} USD in Kilo credits, which reset every 30 days{% endif %} +

+

+ View your upgraded Organization here: +

+ + + + + +
+ + View Organization + +
+

+ To accept the offer and complete onboarding, please enable these features for your + open-source repo: +

+

+ • + GitHub Integration: + Enable GitHub
Code Reviews: + Enable Code Reviews +

+
+

+ Excited to build together!

~ Brian
DevRel @ Kilo +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/ossInviteExistingUser.html b/src/lib/emails/ossInviteExistingUser.html new file mode 100644 index 000000000..04e109334 --- /dev/null +++ b/src/lib/emails/ossInviteExistingUser.html @@ -0,0 +1,194 @@ + + + + + + Kilo OSS Sponsorship Offer + + + + + + +
+ + + + + + + + + + + + + +
+

+ Kilo OSS Sponsorship Offer +

+
+

+ Congratulations! You've been selected for the + Kilo OSS Sponsorship Program at the + {{ tier_name }} tier. +

+

+ You've been added as the Owner of a new + Kilo Enterprise Organization. Your sponsorship includes: +

+

+ • {{ seats }} Enterprise Seats (a ${{ + seat_value }} value){% if has_credits %}
• + ${{ monthly_credits_usd }} USD in Kilo credits, which reset every 30 days{% endif %} +

+

+ Sign in to access your organization: +

+ + + + + +
+ + View Organization + +
+

+ To accept the offer and complete onboarding, please enable these features for your + open-source repo: +

+

+ • + GitHub Integration: + Enable GitHub
Code Reviews: + Enable Code Reviews +

+
+

+ Excited to build together!

~ Brian
DevRel @ Kilo +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ + diff --git a/src/lib/emails/ossInviteNewUser.html b/src/lib/emails/ossInviteNewUser.html new file mode 100644 index 000000000..37a096055 --- /dev/null +++ b/src/lib/emails/ossInviteNewUser.html @@ -0,0 +1,194 @@ + + + + + + Kilo OSS Sponsorship Offer + + + + + + +
+ + + + + + + + + + + + + +
+

+ Kilo OSS Sponsorship Offer +

+
+

+ Congratulations! You've been selected for the + Kilo OSS Sponsorship Program at the + {{ tier_name }} tier. +

+

+ You've been added as the Owner of a new + Kilo Enterprise Organization. Your sponsorship includes: +

+

+ • {{ seats }} Enterprise Seats (a ${{ + seat_value }} value){% if has_credits %}
• + ${{ monthly_credits_usd }} USD in Kilo credits, which reset every 30 days{% endif %} +

+

+ Sign in to access your organization: +

+ + + + + +
+ + Accept Invite + +
+

+ To accept the offer and complete onboarding, please enable these features for your + open-source repo: +

+

+ • + GitHub Integration: + Enable GitHub
Code Reviews: + Enable Code Reviews +

+
+

+ Excited to build together!

~ Brian
DevRel @ Kilo +

+
+ + + + + +
+

+ © {{ year }} Kilo Code, LLC
455 Market St, Ste 1940 PMB 993504
San + Francisco, CA 94105, USA +

+
+
+ +