diff --git a/app/[userId]/[ruleId]/page.tsx b/app/[userId]/[ruleId]/page.tsx index 4b5f220..4fae8fc 100644 --- a/app/[userId]/[ruleId]/page.tsx +++ b/app/[userId]/[ruleId]/page.tsx @@ -15,6 +15,7 @@ interface CursorRule { id: string title: string content: string + type: string ruleType: string views: number createdAt: string diff --git a/app/api/cursor-rules/route.ts b/app/api/cursor-rules/route.ts index b16d652..17f1d6b 100644 --- a/app/api/cursor-rules/route.ts +++ b/app/api/cursor-rules/route.ts @@ -71,6 +71,7 @@ export async function GET(request: NextRequest) { id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, isPublic: cursorRule.isPublic, views: cursorRule.views, @@ -121,7 +122,7 @@ export async function POST(request: NextRequest) { } const body = await request.json() - const { title, content, ruleType = "always", isPublic = false } = body + const { title, content, type = "rule", ruleType = "always", isPublic = false } = body if (!title || !content) { return NextResponse.json({ error: "Title and content are required" }, { status: 400 }) @@ -135,6 +136,7 @@ export async function POST(request: NextRequest) { userId: session.user.id, title, content, + type, ruleType, isPublic, views: 0, @@ -142,7 +144,7 @@ export async function POST(request: NextRequest) { updatedAt: now, }).returning() - await track('Rule Created', { ruleId: id, isPublic, ruleType }) + await track('Rule Created', { ruleId: id, isPublic, type, ruleType }) return NextResponse.json(newRule) } catch (error) { console.error("Error creating cursor rule:", error) @@ -182,7 +184,7 @@ export async function PUT(request: NextRequest) { } const body = await request.json() - const { id, title, content, ruleType, isPublic } = body + const { id, title, content, type, ruleType, isPublic } = body if (!id || !title || !content) { return NextResponse.json({ error: "ID, title and content are required" }, { status: 400 }) @@ -193,6 +195,7 @@ export async function PUT(request: NextRequest) { .set({ title, content, + type, ruleType, isPublic, updatedAt: new Date(), @@ -207,7 +210,7 @@ export async function PUT(request: NextRequest) { return NextResponse.json({ error: "Rule not found or unauthorized" }, { status: 404 }) } - await track('Rule Updated', { ruleId: id, isPublic: Boolean(isPublic), ruleType }) + await track('Rule Updated', { ruleId: id, isPublic: Boolean(isPublic), type, ruleType }) return NextResponse.json(updatedRule) } catch (error) { console.error("Error updating cursor rule:", error) diff --git a/app/api/feed/hot/route.ts b/app/api/feed/hot/route.ts index c4f488c..e6f59bc 100644 --- a/app/api/feed/hot/route.ts +++ b/app/api/feed/hot/route.ts @@ -11,6 +11,7 @@ export async function GET(request: NextRequest) { id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, views: cursorRule.views, createdAt: cursorRule.createdAt, diff --git a/app/api/feed/new/route.ts b/app/api/feed/new/route.ts index adbdf33..80c9bea 100644 --- a/app/api/feed/new/route.ts +++ b/app/api/feed/new/route.ts @@ -11,6 +11,7 @@ export async function GET(request: NextRequest) { id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, views: cursorRule.views, createdAt: cursorRule.createdAt, diff --git a/app/api/my-rules/route.ts b/app/api/my-rules/route.ts index 0d77be4..890a34a 100644 --- a/app/api/my-rules/route.ts +++ b/app/api/my-rules/route.ts @@ -42,6 +42,7 @@ export async function GET(request: NextRequest) { id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, isPublic: cursorRule.isPublic, views: cursorRule.views, diff --git a/app/api/public-rule/[userId]/[ruleId]/route.ts b/app/api/public-rule/[userId]/[ruleId]/route.ts index f11b69c..bcfb281 100644 --- a/app/api/public-rule/[userId]/[ruleId]/route.ts +++ b/app/api/public-rule/[userId]/[ruleId]/route.ts @@ -15,6 +15,7 @@ export async function GET( id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, views: cursorRule.views, createdAt: cursorRule.createdAt, diff --git a/app/api/registry/[ruleId]/route.ts b/app/api/registry/[ruleId]/route.ts index 0053c37..1094aac 100644 --- a/app/api/registry/[ruleId]/route.ts +++ b/app/api/registry/[ruleId]/route.ts @@ -16,6 +16,7 @@ export async function GET( id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, userId: cursorRule.userId, user: { @@ -36,15 +37,19 @@ export async function GET( } // Generate universal registry item with content + const isCommand = rule.type === 'command'; + const directory = isCommand ? 'commands' : 'rules'; + const extension = isCommand ? 'md' : 'mdc'; + const registryItem = { "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": rule.title, "type": "registry:item", // Changed to registry:item for universal items "files": [ { - "path": `cursor.link/rules/${rule.title}.mdc`, // Source path (not used but required) + "path": `cursor.link/${directory}/${rule.title}.${extension}`, // Source path (not used but required) "type": "registry:file", - "target": `~/.cursor/rules/${rule.title}.mdc`, // Explicit target makes it universal + "target": `~/.cursor/${directory}/${rule.title}.${extension}`, // Explicit target makes it universal "content": rule.content // Include the actual content } ] diff --git a/app/api/registry/rules/[ruleId]/route.ts b/app/api/registry/rules/[ruleId]/route.ts index b24142f..a58fac4 100644 --- a/app/api/registry/rules/[ruleId]/route.ts +++ b/app/api/registry/rules/[ruleId]/route.ts @@ -16,6 +16,7 @@ export async function GET( id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, }) .from(cursorRule) @@ -30,8 +31,8 @@ export async function GET( return NextResponse.json({ error: "Rule file not found" }, { status: 404 }) } - // Generate .mdc file content dynamically - const mdcContent = `--- + // Generate file content dynamically based on type + const fileContent = `--- description: ${rule.title} globs: alwaysApply: ${rule.ruleType === 'always' ? 'true' : 'false'} @@ -39,11 +40,12 @@ alwaysApply: ${rule.ruleType === 'always' ? 'true' : 'false'} ${rule.content}` - return new NextResponse(mdcContent, { + return new NextResponse(fileContent, { status: 200, headers: { "Content-Type": "text/markdown", "Cache-Control": "public, max-age=300, s-maxage=300", // 5 minute cache + "Content-Disposition": `attachment; filename="${rule.title}.${rule.type === 'command' ? 'md' : 'mdc'}"`, }, }) } catch (error) { diff --git a/app/api/rule/[slug]/route.ts b/app/api/rule/[slug]/route.ts index 8d58692..7f0b04f 100644 --- a/app/api/rule/[slug]/route.ts +++ b/app/api/rule/[slug]/route.ts @@ -81,6 +81,7 @@ export async function GET( id: cursorRule.id, title: cursorRule.title, content: cursorRule.content, + type: cursorRule.type, ruleType: cursorRule.ruleType, isPublic: cursorRule.isPublic, views: cursorRule.views, diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index 9aa5edd..5e4c4e4 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -23,6 +23,7 @@ interface CursorRule { id: string title: string content: string + type: string ruleType: string isPublic: boolean views: number @@ -442,6 +443,13 @@ export default function DashboardPage() {

{rule.title}

+ + {rule.type === 'command' ? 'Command' : 'Rule'} +