diff --git a/.husky/.gitignore b/.husky/.gitignore
deleted file mode 100644
index 31354ec138..0000000000
--- a/.husky/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-_
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a933561ea8..7b477aef5f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -92,7 +92,22 @@ To develop locally:
- Use `openssl rand -base64 32` to generate a key and add it under `NEXTAUTH_SECRET` in the `.env` file.
- Use `openssl rand -base64 24` to generate a key and add it under `CALENDSO_ENCRYPTION_KEY` in the `.env` file.
-6. Start developing and watch for code changes:
+6. Setup Node
+ If your Node version does not meet the project's requirements as instructed by the docs, "nvm" (Node Version Manager) allows using Node at the version required by the project:
+
+ ```sh
+ nvm use
+ ```
+
+ You first might need to install the specific version and then use it:
+
+ ```sh
+ nvm install && nvm use
+ ```
+
+ You can install nvm from [here](https://github.com/nvm-sh/nvm).
+
+7. Start developing and watch for code changes:
```sh
yarn dev
@@ -120,6 +135,16 @@ This will run and test all flows in multiple Chromium windows to verify that no
yarn test-e2e
```
+#### Resolving issues
+
+##### E2E test browsers not installed
+
+Run `npx playwright install` to download test browsers and resolve the error below when running `yarn test-e2e`:
+
+```
+Executable doesn't exist at /Users/alice/Library/Caches/ms-playwright/chromium-1048/chrome-mac/Chromium.app/Contents/MacOS/Chromium
+```
+
## Linting
To check the formatting of your code:
@@ -135,4 +160,4 @@ If you get errors, be sure to fix them before committing.
- Be sure to [check the "Allow edits from maintainers" option](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) while creating your PR.
- If your PR refers to or fixes an issue, be sure to add `refs #XXX` or `fixes #XXX` to the PR description. Replacing `XXX` with the respective issue number. See more about [Linking a pull request to an issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).
- Be sure to fill the PR Template accordingly.
-- Review [App Contribution Guidelines](./packages/app-store/CONTRIBUTING.md) when building integrations
\ No newline at end of file
+- Review [App Contribution Guidelines](./packages/app-store/CONTRIBUTING.md) when building integrations
diff --git a/README.md b/README.md
index 944c4c6764..1f64390a7a 100644
--- a/README.md
+++ b/README.md
@@ -131,23 +131,39 @@ Here is what you need to be able to run Cal.com.
> If you are on Windows, run the following command on `gitbash` with admin privileges: > `git clone -c core.symlinks=true https://github.com/calcom/cal.com.git`
> See [docs](https://cal.com/docs/how-to-guides/how-to-troubleshoot-symbolic-link-issues-on-windows#enable-symbolic-links) for more details.
-1. Go to the project folder
+2. Go to the project folder
```sh
cd cal.com
```
-1. Install packages with yarn
+3. Install packages with yarn
```sh
yarn
```
-1. Set up your `.env` file
+4. Set up your `.env` file
+
- Duplicate `.env.example` to `.env`
- Use `openssl rand -base64 32` to generate a key and add it under `NEXTAUTH_SECRET` in the `.env` file.
- Use `openssl rand -base64 24` to generate a key and add it under `CALENDSO_ENCRYPTION_KEY` in the `.env` file.
+5. Setup Node
+ If your Node version does not meet the project's requirements as instructed by the docs, "nvm" (Node Version Manager) allows using Node at the version required by the project:
+
+ ```sh
+ nvm use
+ ```
+
+ You first might need to install the specific version and then use it:
+
+ ```sh
+ nvm install && nvm use
+ ```
+
+ You can install nvm from [here](https://github.com/nvm-sh/nvm).
+
#### Quick start with `yarn dx`
> - **Requires Docker and Docker Compose to be installed**
@@ -221,6 +237,7 @@ echo 'NEXT_PUBLIC_DEBUG=1' >> .env
```
1. Run [mailhog](https://github.com/mailhog/MailHog) to view emails sent during development
+
> **_NOTE:_** Required when `E2E_TEST_MAILHOG_ENABLED` is "1"
```sh
@@ -259,6 +276,16 @@ yarn test-e2e
yarn playwright show-report test-results/reports/playwright-html-report
```
+#### Resolving issues
+
+##### E2E test browsers not installed
+
+Run `npx playwright install` to download test browsers and resolve the error below when running `yarn test-e2e`:
+
+```
+Executable doesn't exist at /Users/alice/Library/Caches/ms-playwright/chromium-1048/chrome-mac/Chromium.app/Contents/MacOS/Chromium
+```
+
### Upgrading from earlier versions
1. Pull the current version:
@@ -470,9 +497,8 @@ following
4. Select Basecamp 4 as the product to integrate with.
5. Set the Redirect URL for OAuth `/api/integrations/basecamp3/callback` replacing Cal.com URL with the URI at which your application runs.
6. Click on done and copy the Client ID and secret into the `BASECAMP3_CLIENT_ID` and `BASECAMP3_CLIENT_SECRET` fields.
-7. Set the `BASECAMP3_CLIENT_SECRET` env variable to `{your_domain} ({support_email})`.
-For example, `Cal.com (support@cal.com)`.
-
+7. Set the `BASECAMP3_CLIENT_SECRET` env variable to `{your_domain} ({support_email})`.
+ For example, `Cal.com (support@cal.com)`.
### Obtaining HubSpot Client ID and Secret
@@ -507,6 +533,7 @@ For example, `Cal.com (support@cal.com)`.
### Obtaining Zoho Calendar Client ID and Secret
[Follow these steps](./packages/app-store/zohocalendar/)
+
### Obtaining Zoho Bigin Client ID and Secret
[Follow these steps](./packages/app-store/zoho-bigin/)
diff --git a/apps/ai/README.md b/apps/ai/README.md
index a504fcc19c..95316cd356 100644
--- a/apps/ai/README.md
+++ b/apps/ai/README.md
@@ -1,12 +1,12 @@
# Cal.com Email Assistant
-Welcome to the first stage of Cal AI!
+Welcome to the first stage of Cal.ai!
This app lets you chat with your calendar via email:
- - Turn informal emails into bookings eg. forward "wanna meet tmrw at 2pm?"
- - List and rearrange your bookings eg. "Cancel my next meeting"
- - Answer basic questions about your busiest times eg. "How does my Tuesday look?"
+- Turn informal emails into bookings eg. forward "wanna meet tmrw at 2pm?"
+- List and rearrange your bookings eg. "Cancel my next meeting"
+- Answer basic questions about your busiest times eg. "How does my Tuesday look?"
The core logic is contained in [agent/route.ts](/apps/ai/src/app/api/agent/route.ts). Here, a [LangChain Agent Executor](https://docs.langchain.com/docs/components/agents/agent-executor) is tasked with following your instructions. Given your last-known timezone, working hours, and busy times, it attempts to CRUD your bookings.
@@ -24,10 +24,10 @@ If you haven't yet, please run the [root setup](/README.md) steps.
Before running the app, please see [env.mjs](./src/env.mjs) for all required environment variables. You'll need:
- - An [OpenAI API key](https://platform.openai.com/account/api-keys) with access to GPT-4
- - A [SendGrid API key](https://app.sendgrid.com/settings/api_keys)
- - A default sender email (for example, `ai@cal.dev`)
- - The Cal AI's app ID and URL (see [add.ts](/packages/app-store/cal-ai/api/index.ts))
+- An [OpenAI API key](https://platform.openai.com/account/api-keys) with access to GPT-4
+- A [SendGrid API key](https://app.sendgrid.com/settings/api_keys)
+- A default sender email (for example, `ai@cal.dev`)
+- The Cal.ai's app ID and URL (see [add.ts](/packages/app-store/cal-ai/api/index.ts))
To stand up the API and AI apps simultaneously, simply run `yarn dev:ai`.
diff --git a/apps/ai/package.json b/apps/ai/package.json
index a0dc4943ec..8eaf474ed1 100644
--- a/apps/ai/package.json
+++ b/apps/ai/package.json
@@ -1,6 +1,6 @@
{
"name": "@calcom/ai",
- "version": "1.1.0",
+ "version": "1.1.1",
"private": true,
"author": "Cal.com Inc.",
"dependencies": {
diff --git a/apps/ai/src/app/api/receive/route.ts b/apps/ai/src/app/api/receive/route.ts
index 262a72e5e5..1697bdd4a5 100644
--- a/apps/ai/src/app/api/receive/route.ts
+++ b/apps/ai/src/app/api/receive/route.ts
@@ -61,9 +61,9 @@ export const POST = async (request: NextRequest) => {
// User is not a cal.com user or is using an unverified email.
if (!signature || !user) {
await sendEmail({
- html: `Thanks for your interest in Cal AI! To get started, Make sure you have a cal.com account with this email address.`,
+ html: `Thanks for your interest in Cal.ai! To get started, Make sure you have a cal.com account with this email address.`,
subject: `Re: ${body.subject}`,
- text: `Thanks for your interest in Cal AI! To get started, Make sure you have a cal.com account with this email address. You can sign up for an account at: https://cal.com/signup`,
+ text: `Thanks for your interest in Cal.ai! To get started, Make sure you have a cal.com account with this email address. You can sign up for an account at: https://cal.com/signup`,
to: envelope.from,
from: aiEmail,
});
@@ -78,9 +78,9 @@ export const POST = async (request: NextRequest) => {
const url = env.APP_URL;
await sendEmail({
- html: `Thanks for using Cal AI! To get started, the app must be installed. Click this link to install it.`,
+ html: `Thanks for using Cal.ai! To get started, the app must be installed. Click this link to install it.`,
subject: `Re: ${body.subject}`,
- text: `Thanks for using Cal AI! To get started, the app must be installed. Click this link to install the Cal AI app: ${url}`,
+ text: `Thanks for using Cal.ai! To get started, the app must be installed. Click this link to install the Cal.ai app: ${url}`,
to: envelope.from,
from: aiEmail,
});
diff --git a/apps/ai/src/utils/agent.ts b/apps/ai/src/utils/agent.ts
index 2164917d6f..1ef3319198 100644
--- a/apps/ai/src/utils/agent.ts
+++ b/apps/ai/src/utils/agent.ts
@@ -16,7 +16,7 @@ import now from "./now";
const gptModel = "gpt-4";
/**
- * Core of the Cal AI booking agent: a LangChain Agent Executor.
+ * Core of the Cal.ai booking agent: a LangChain Agent Executor.
* Uses a toolchain to book meetings, list available slots, etc.
* Uses OpenAI functions to better enforce JSON-parsable output from the LLM.
*/
@@ -49,7 +49,7 @@ const agent = async (
*/
const executor = await initializeAgentExecutorWithOptions(tools, model, {
agentArgs: {
- prefix: `You are Cal AI - a bleeding edge scheduling assistant that interfaces via email.
+ prefix: `You are Cal.ai - a bleeding edge scheduling assistant that interfaces via email.
Make sure your final answers are definitive, complete and well formatted.
Sometimes, tools return errors. In this case, try to handle the error intelligently or ask the user for more information.
Tools will always handle times in UTC, but times sent to users should be formatted per that user's timezone.
@@ -74,18 +74,19 @@ ${
? `The email references the following @usernames and emails: ${users
.map(
(u) =>
- (u.id ? `, id: ${u.id}` : "id: (non user)") +
- (u.username
- ? u.type === "fromUsername"
- ? `, username: @${u.username}`
- : ", username: REDACTED"
- : ", (no username)") +
- (u.email
- ? u.type === "fromEmail"
- ? `, email: ${u.email}`
- : ", email: REDACTED"
- : ", (no email)") +
- ";"
+ `${
+ (u.id ? `, id: ${u.id}` : "id: (non user)") +
+ (u.username
+ ? u.type === "fromUsername"
+ ? `, username: @${u.username}`
+ : ", username: REDACTED"
+ : ", (no username)") +
+ (u.email
+ ? u.type === "fromEmail"
+ ? `, email: ${u.email}`
+ : ", email: REDACTED"
+ : ", (no email)")
+ };`
)
.join("\n")}`
: ""
diff --git a/apps/ai/src/utils/extractUsers.ts b/apps/ai/src/utils/extractUsers.ts
index b7c1345d59..0a5686bef1 100644
--- a/apps/ai/src/utils/extractUsers.ts
+++ b/apps/ai/src/utils/extractUsers.ts
@@ -1,8 +1,10 @@
+import prisma from "@calcom/prisma";
+
+import type { UserList } from "../types/user";
+
/*
* Extracts usernames (@Example) and emails (hi@example.com) from a string
*/
-import type { UserList } from "../types/user";
-
export const extractUsers = async (text: string) => {
const usernames = text.match(/(? username.slice(1));
const emails = text.match(/[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/g);
diff --git a/apps/ai/src/utils/sendEmail.ts b/apps/ai/src/utils/sendEmail.ts
index 799428091e..adbc9693e7 100644
--- a/apps/ai/src/utils/sendEmail.ts
+++ b/apps/ai/src/utils/sendEmail.ts
@@ -27,7 +27,7 @@ const send = async ({
cc,
from: {
email: from,
- name: "Cal AI",
+ name: "Cal.ai",
},
text,
html,
diff --git a/apps/api/test/lib/bookings/_post.test.ts b/apps/api/test/lib/bookings/_post.test.ts
index 5e4b17f23d..a36b3b70fc 100644
--- a/apps/api/test/lib/bookings/_post.test.ts
+++ b/apps/api/test/lib/bookings/_post.test.ts
@@ -1,3 +1,5 @@
+import prismaMock from "../../../../../tests/libs/__mocks__/prisma";
+
import type { Request, Response } from "express";
import type { NextApiRequest, NextApiResponse } from "next";
import { createMocks } from "node-mocks-http";
@@ -8,7 +10,6 @@ import sendPayload from "@calcom/features/webhooks/lib/sendPayload";
import { buildBooking, buildEventType, buildWebhook } from "@calcom/lib/test/builder";
import prisma from "@calcom/prisma";
-import prismaMock from "../../../../../tests/libs/__mocks__/prisma";
import handler from "../../../pages/api/bookings/_post";
type CustomNextApiRequest = NextApiRequest & Request;
diff --git a/apps/web/components/AppListCard.tsx b/apps/web/components/AppListCard.tsx
index b41cddd1be..7252a8ffc6 100644
--- a/apps/web/components/AppListCard.tsx
+++ b/apps/web/components/AppListCard.tsx
@@ -79,8 +79,8 @@ export default function AppListCard(props: AppListCardProps) {
}, []);
return (
-
{/**
* Only display calendar selector if user has connected calendars AND if it's not
* a team event. Since we don't have logic to handle each attendee calendar (for now).
* This will fallback to each user selected destination calendar.
*/}
- {!!connectedCalendarsQuery.data?.connectedCalendars.length && !team && (
-
- You have no apps installed. View popular apps below and explore more in our
+ View popular apps below and explore more in our
App Store
diff --git a/apps/web/components/eventtype/EventAvailabilityTab.tsx b/apps/web/components/eventtype/EventAvailabilityTab.tsx
index 07ed8a9515..caf04147de 100644
--- a/apps/web/components/eventtype/EventAvailabilityTab.tsx
+++ b/apps/web/components/eventtype/EventAvailabilityTab.tsx
@@ -98,42 +98,43 @@ const EventTypeScheduleDetails = memo(
schedule?.schedule.filter((item) => item.days.includes((dayNum + 1) % 7)) || [];
return (
-