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
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# AGENTS.md

## Cursor Cloud specific instructions

### Services Overview

| Service | How to run | Port |
|---------|-----------|------|
| Backend (NestJS) | `cd backend && npm run start:dev` | 4000 |
| Bot SDK | `cd bot-sdk && npm run build` | N/A (library) |

### Backend Dev Server

- **Start**: `cd backend && npm run start:dev` (uses nodemon + ts-node)
- **Health check**: `GET http://localhost:4000/api/v1/health`
- **API prefix**: `/api/v1`
- **WebSocket**: `ws://localhost:4000` (Socket.IO)

### Prerequisites (must be running before backend starts)

- **PostgreSQL** on `localhost:5432` — database `flowspace`, user `flowspace`/`flowspace`
- **Redis** on `localhost:6379` — used for Socket.IO horizontal scaling; backend gracefully falls back to in-memory adapter if unavailable

Start services:

```bash
sudo pg_ctlcluster 16 main start
sudo redis-server --daemonize yes
```

Comment thread
coderabbitai[bot] marked this conversation as resolved.
### Key Gotchas

1. **Prisma schema requires manual relation fixes**: The `Bot` and `BotMessage` models reference `Workspace`, `Channel`, and `ChatMessage` but the reverse relation fields (`bots Bot[]`, `botMessages BotMessage[]`) must be present on those models. Run `npx prisma generate` after any schema changes.

2. **`projectTemplates.json` required at startup**: The backend TemplateService throws at boot if `backend/config/projectTemplates.json` doesn't exist. A minimal seed file is committed.

3. **Module DI for `JwtAuthGuard`**: Any NestJS module using `@UseGuards(JwtAuthGuard)` must import `AuthModule` (which exports `AuthService`).

4. **`.env` location**: The backend reads environment from `backend/.env` (via `@nestjs/config`). The committed `env.development` uses Docker service hostnames; for local dev, create `.env` with `localhost` addresses (DATABASE_URL, REDIS_URL, etc.).

5. **TypeScript checking**: `npm run build` runs `prisma generate && nest build`. For type-only checking use `npx tsc --noEmit` from the backend directory.

6. **No ESLint configured**: The project does not have an ESLint config. TypeScript compilation (`tsc --noEmit`) is the primary static analysis.

7. **MinIO/S3 and LiveKit are optional**: File vault and video meeting features require these services but the backend starts fine without them.

### Test Account (local dev)

```text
Email: dev@flowspace.app
Password: TestPass123!
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded credentials committed to source control

Medium Severity

Plaintext credentials (database password flowspace/flowspace and test account TestPass123!) are committed directly into AGENTS.md. Even though these are labeled as local dev credentials, committing passwords to version control makes them permanently discoverable in git history. If these credentials are reused in any shared or deployed environment, they become an exploitable vulnerability. Credentials belong in .env files excluded by .gitignore, not in tracked documentation.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8b5229e. Configure here.


Or register via `POST /api/v1/auth/register` with `{ email, password, name }`.

### Flutter Client

The Flutter client (`client_flutter/`) targets desktop (Windows primary) and mobile. It requires the Flutter SDK and cannot be run in headless Cloud Agent environments. Focus backend development on the NestJS API server.
39 changes: 39 additions & 0 deletions backend/config/projectTemplates.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"version": "1.0.0",
"templates": [
{
"id": "kanban",
"name": "Kanban Board",
"description": "Simple task management with columns: To Do, In Progress, Done",
"backgroundModule": "kanban",
"tools": ["tasks", "labels", "assignments"],
"defaultBoards": ["kanban"],
"defaultSettings": {
"columns": ["To Do", "In Progress", "Done"]
}
},
{
"id": "storyboard",
"name": "Storyboard",
"description": "Visual storyboard for creative projects",
"backgroundModule": "storyboard",
"tools": ["scenes", "characters", "notes"],
"defaultBoards": ["storyboard"],
"defaultSettings": {
"layout": "grid"
}
},
{
"id": "sprint",
"name": "Sprint Planning",
"description": "Agile sprint planning with backlog and sprint boards",
"backgroundModule": "agile",
"tools": ["tasks", "sprints", "velocity"],
"defaultBoards": ["backlog", "kanban"],
"defaultSettings": {
"sprintLength": 14,
"columns": ["Backlog", "To Do", "In Progress", "Review", "Done"]
}
}
]
}
2 changes: 2 additions & 0 deletions backend/src/bots/bots.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BotsService } from './bots.service';
import { BotsController } from './bots.controller';
import { BotsGateway } from './bots.gateway';
import { BotAuthGuard } from './bots-auth.guard';
import { AuthModule } from '../auth/auth.module';
import { SharedModule } from '../shared/shared.module';
import { PrismaModule } from '../database/prisma.module';

Expand All @@ -13,6 +14,7 @@ import { PrismaModule } from '../database/prisma.module';
imports: [
PrismaModule,
SharedModule,
AuthModule,
JwtModule.registerAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
Expand Down
8 changes: 4 additions & 4 deletions backend/src/bots/bots.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import { randomBytes, randomUUID } from 'crypto';
import { hash, compare } from 'bcrypt';
import { PrismaService } from '../database/prisma.service';
import { WorkspaceRole } from '@prisma/client';
import { WorkspaceRole, BotHandlerType } from '@prisma/client';

@Injectable()
export class BotsService {
Expand Down Expand Up @@ -204,7 +204,7 @@ export class BotsService {
workspaceId: string,
botId: string,
userId: string,
data: { command: string; description: string; handlerType?: string; handlerUrl?: string },
data: { command: string; description: string; handlerType?: BotHandlerType; handlerUrl?: string },
) {
await this.requireAdmin(workspaceId, userId);
await this.requireBotOwnership(workspaceId, botId);
Expand All @@ -221,7 +221,7 @@ export class BotsService {
botId,
command: data.command,
description: data.description,
handlerType: (data.handlerType as any) || 'WEBSOCKET',
handlerType: data.handlerType || BotHandlerType.WEBSOCKET,
handlerUrl: data.handlerUrl,
},
});
Expand All @@ -242,7 +242,7 @@ export class BotsService {
botId: string,
commandId: string,
userId: string,
data: { description?: string; enabled?: boolean; handlerType?: string; handlerUrl?: string },
data: { description?: string; enabled?: boolean; handlerType?: BotHandlerType; handlerUrl?: string },
) {
await this.requireAdmin(workspaceId, userId);
await this.requireBotOwnership(workspaceId, botId);
Expand Down
9 changes: 5 additions & 4 deletions backend/src/bots/dto/bot.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IsString, IsOptional, IsBoolean, IsEnum, MaxLength, MinLength } from 'class-validator';
import { BotHandlerType } from '@prisma/client';

export class CreateBotDto {
@IsString()
Expand Down Expand Up @@ -53,8 +54,8 @@ export class CreateCommandDto {
description!: string;

@IsOptional()
@IsString()
handlerType?: string;
@IsEnum(BotHandlerType)
handlerType?: BotHandlerType;

@IsOptional()
@IsString()
Expand All @@ -72,8 +73,8 @@ export class UpdateCommandDto {
enabled?: boolean;

@IsOptional()
@IsString()
handlerType?: string;
@IsEnum(BotHandlerType)
handlerType?: BotHandlerType;

@IsOptional()
@IsString()
Expand Down
3 changes: 2 additions & 1 deletion backend/src/search/search.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Module } from '@nestjs/common';

import { AuthModule } from '../auth/auth.module';
import { PrismaModule } from '../database/prisma.module';
import { SharedModule } from '../shared/shared.module';
import { SearchController } from './search.controller';
import { SearchService } from './search.service';

@Module({
imports: [PrismaModule, SharedModule],
imports: [PrismaModule, SharedModule, AuthModule],
controllers: [SearchController],
providers: [SearchService],
})
Expand Down
141 changes: 141 additions & 0 deletions bot-sdk/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.