Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .cursor/rules/file-structure.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
description: When creating files
alwaysApply: false
---

We want thin files that aim to have a single responsibility and a single export.
We should have a single export per file.

Specific directories:
- hooks: for hooks
- components: for components
- pages: for pages
84 changes: 84 additions & 0 deletions .cursor/rules/react-tsx.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
description: React and TSX component development guidelines
globs: *.tsx
alwaysApply: false
---

# Components

- One component per file.
- Create smaller, focused components.
- Compose larger components from smaller ones.
- Logical groupings of components should form a new custom component and moved to a separate file.
- When prototyping, keep small components in the same file, but mark to be removed:

```tsx
/**
* ExampleComponent
* Responsibilities:
* To be an example component
*
* TODO: Move to a separate file
*/
function ExampleComponent() {
return <div>ExampleComponent</div>;
}
```

# Hooks

- Complex hooks should be broken down into smaller, composable hooks.
- If a hook can be self-contained, it should be self-contained and should be in a separate file.
- Break complex logic into smaller hooks.
- Compose hooks when it makes sense.
- Keep hooks in the same file as their components.

# Code Separation

- Separate business logic from UI rendering.
- Keep related code together.
- Maintain clear boundaries between concerns.

# Composable Component Pattern

When creating shared templates or reusable components:

1. **Use compound component pattern** - Attach subcomponents as static properties (e.g., `Template.Header`, `Template.Content`) instead of prop drilling.

2. **Templates are pure UI** - Templates should only handle layout/structure. Pages control conditional logic, data fetching, and business logic.

3. **Subcomponents take their own props** - Each subcomponent (Header, Content, Footer, etc.) should accept its own typed props rather than the parent managing them.

4. **Compose via children** - Use `children` for flexible composition. Pages decide what to render in each slot.

**Example:**
```tsx
// Template
const EditDraftTemplate = ({ children, isLoading }) => {
if (isLoading) return <Spinner />;
return <Layout>{children}</Layout>;
};

EditDraftTemplate.Header = ({ title, children }) => (
<header>{title || children}</header>
);

EditDraftTemplate.Content = ({ content, isStreaming }) => (
<div className={isStreaming ? "opacity-50" : ""}>{content}</div>
);

// Usage
<EditDraftTemplate isLoading={isLoading}>
<EditDraftTemplate.Header title="Title" />
<EditDraftTemplate.Content content={story} isStreaming={streaming} />
</EditDraftTemplate>
```

**Avoid:** Prop drilling, templates with business logic, tightly coupled props.

# Class Organization

- Place public methods first.
- Place private methods at the bottom of the class.
- Group related methods together.
- Use clear method names that describe their purpose.
22 changes: 22 additions & 0 deletions .cursor/rules/typescript.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
description:
globs: *.tsx
alwaysApply: false
---

## Typescript Development Guidelines:

### Documentation
- Add TSDoc style documentation when writing functions, methods and components.

### Single Responsibility
- SRP is a core principle of our codebase and should be followed in all functions, methods and components.
=> if the function, method or component is more than one responsibility, suggest how to break it down into smaller functions, methods or components. Encourage the user to use the "Single Responsibility" principle
and explain the benefits of doing so in this case.

### Imports
- Always use named imports for React components and hooks.
- Never use non-destructured imports, such as `React.useMemo` or `React.useCallback`.

### Type Safety
- Never use the `any` type.
3 changes: 3 additions & 0 deletions javascript/examples/vitest/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.scenario

# Audio files
test-audio-output/
10 changes: 8 additions & 2 deletions javascript/examples/vitest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,27 @@
"scripts": {
"test": "pnpm exec vitest",
"typecheck": "tsc --noEmit",
"lint": "eslint ."
"lint": "eslint .",
"realtime-client": "pnpm -F realtime-client"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"concurrently": "^9.1.2",
"dotenv": "^16.5.0",
"dotenv-cli": "^8.0.0",
"nanoid-cli": "^1.0.1",
"vitest-mock-extended": "3.1.0"
},
"dependencies": {
"@langwatch/scenario": "workspace:*",
"@openai/agents": "^0.3.0",
"ai": ">=5.0.0",
"express": "^4.21.2",
"openai": "^5.16.0",
"vitest": "^3.2.4"
"vite": "^6.0.11",
"vitest": "^3.2.4",
"zod": "^3.24.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
/**
* OpenAI supported audio formats for input_audio
*/
type OpenAIAudioFormat = "wav" | "mp3";
type OpenAIAudioFormat = "wav" | "mp3" | "pcm16";

/**
* Comprehensive mapping from MIME types to OpenAI audio formats
Expand All @@ -26,6 +26,7 @@ const MIME_TYPE_TO_OPENAI_FORMAT: Record<string, OpenAIAudioFormat> = {
"audio/mp3": "mp3",
"audio/mpeg3": "mp3",
"audio/x-mpeg-3": "mp3",
"audio/pcm16": "pcm16",
} as const;

/**
Expand Down
Loading
Loading