Skip to content

Commit cbbd264

Browse files
committed
2 parents af0eabe + cfa2e0b commit cbbd264

23 files changed

+792
-4893
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
# Optional: Only run on specific file changes
7+
# paths:
8+
# - "src/**/*.ts"
9+
# - "src/**/*.tsx"
10+
# - "src/**/*.js"
11+
# - "src/**/*.jsx"
12+
13+
jobs:
14+
claude-review:
15+
# Optional: Filter by PR author
16+
# if: |
17+
# github.event.pull_request.user.login == 'external-contributor' ||
18+
# github.event.pull_request.user.login == 'new-developer' ||
19+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20+
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
pull-requests: read
25+
issues: read
26+
id-token: write
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 1
33+
34+
- name: Run Claude Code Review
35+
id: claude-review
36+
uses: anthropics/claude-code-action@v1
37+
with:
38+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
39+
prompt: |
40+
REPO: ${{ github.repository }}
41+
PR NUMBER: ${{ github.event.pull_request.number }}
42+
43+
Please review this pull request and provide feedback on:
44+
- Code quality and best practices
45+
- Potential bugs or issues
46+
- Performance considerations
47+
- Security concerns
48+
- Test coverage
49+
50+
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
51+
52+
Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
53+
54+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
55+
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
56+
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
57+

.github/workflows/claude.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
pull-requests: read
24+
issues: read
25+
id-token: write
26+
actions: read # Required for Claude to read CI results on PRs
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 1
32+
33+
- name: Run Claude Code
34+
id: claude
35+
uses: anthropics/claude-code-action@v1
36+
with:
37+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
38+
39+
# This is an optional setting that allows Claude to read CI results on PRs
40+
additional_permissions: |
41+
actions: read
42+
43+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
44+
# prompt: 'Update the pull request description to include a summary of changes.'
45+
46+
# Optional: Add claude_args to customize behavior and configuration
47+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48+
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
49+
# claude_args: '--allowed-tools Bash(gh pr:*)'
50+

app/(chat)/api/chat/route.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { streamText, convertToModelMessages, stepCountIs } from 'ai';
1+
import {
2+
streamText,
3+
convertToModelMessages,
4+
stepCountIs,
5+
type ToolSet,
6+
} from 'ai';
27
import { withSupermemory } from '@supermemory/tools/ai-sdk';
38
import { auth, type UserType } from '@/app/(auth)/auth';
49
import { type RequestHints, systemPrompt } from '@/lib/ai/prompts';
@@ -212,7 +217,7 @@ export async function POST(request: Request) {
212217
const toolsConfig = {
213218
searchMemories: memoryTools.searchMemories,
214219
webSearch: webSearchTool,
215-
};
220+
} as ToolSet;
216221

217222
// Log what messages we're sending to AI SDK
218223
const convertedMessages = convertToModelMessages(messages as any);

bun.lock

Lines changed: 524 additions & 715 deletions
Large diffs are not rendered by default.

components/memory-graph-dialog.tsx

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
'use client';
1+
"use client";
22

3-
import { useState, useCallback } from 'react';
4-
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
5-
import { MemoryGraph } from '@/lib/ui/memory-graph';
6-
import { Button } from '@/components/ui/button';
7-
import { Network } from 'lucide-react';
8-
import type { DocumentWithMemories } from '@/lib/types/supermemory';
3+
import { useState, useCallback } from "react";
4+
import {
5+
Dialog,
6+
DialogContent,
7+
DialogHeader,
8+
DialogTitle,
9+
} from "@/components/ui/dialog";
10+
import { MemoryGraph } from "@supermemory/memory-graph";
11+
import { Button } from "@/components/ui/button";
12+
import { Network } from "lucide-react";
13+
import type { DocumentWithMemories } from "@/lib/types/supermemory";
914

1015
interface MemoryGraphDialogProps {
1116
open?: boolean;
@@ -16,7 +21,7 @@ interface MemoryGraphDialogProps {
1621
export function MemoryGraphDialog({
1722
open: controlledOpen,
1823
onOpenChange: controlledOnOpenChange,
19-
triggerButton = false
24+
triggerButton = false,
2025
}: MemoryGraphDialogProps) {
2126
const [internalOpen, setInternalOpen] = useState(false);
2227
const [documents, setDocuments] = useState<DocumentWithMemories[]>([]);
@@ -32,32 +37,35 @@ export function MemoryGraphDialog({
3237
const onOpenChange = controlledOnOpenChange || setInternalOpen;
3338

3439
// Fetch documents when dialog opens
35-
const fetchDocuments = useCallback(async (page: number, limit: number = 500) => {
36-
try {
37-
const response = await fetch('/api/documents', {
38-
method: 'POST',
39-
headers: {
40-
'Content-Type': 'application/json',
41-
},
42-
body: JSON.stringify({
43-
page,
44-
limit,
45-
sort: 'createdAt',
46-
order: 'desc',
47-
}),
48-
});
40+
const fetchDocuments = useCallback(
41+
async (page: number, limit: number = 500) => {
42+
try {
43+
const response = await fetch("/api/documents", {
44+
method: "POST",
45+
headers: {
46+
"Content-Type": "application/json",
47+
},
48+
body: JSON.stringify({
49+
page,
50+
limit,
51+
sort: "createdAt",
52+
order: "desc",
53+
}),
54+
});
4955

50-
if (!response.ok) {
51-
throw new Error('Failed to fetch documents');
52-
}
56+
if (!response.ok) {
57+
throw new Error("Failed to fetch documents");
58+
}
5359

54-
const data = await response.json();
55-
return data;
56-
} catch (err) {
57-
console.error('Error fetching documents:', err);
58-
throw err;
59-
}
60-
}, []);
60+
const data = await response.json();
61+
return data;
62+
} catch (err) {
63+
console.error("Error fetching documents:", err);
64+
throw err;
65+
}
66+
},
67+
[],
68+
);
6169

6270
// Load initial documents
6371
const loadInitialDocuments = useCallback(async () => {
@@ -86,28 +94,31 @@ export function MemoryGraphDialog({
8694
const data = await fetchDocuments(nextPage, 100);
8795

8896
if (data.documents && data.documents.length > 0) {
89-
setDocuments(prev => [...prev, ...data.documents]);
90-
setTotalLoaded(prev => prev + data.documents.length);
97+
setDocuments((prev) => [...prev, ...data.documents]);
98+
setTotalLoaded((prev) => prev + data.documents.length);
9199
setCurrentPage(nextPage);
92100
setHasMore(data.pagination.currentPage < data.pagination.totalPages);
93101
} else {
94102
setHasMore(false);
95103
}
96104
} catch (err) {
97-
console.error('Error loading more documents:', err);
105+
console.error("Error loading more documents:", err);
98106
// Don't set error state for pagination failures
99107
} finally {
100108
setIsLoadingMore(false);
101109
}
102110
}, [currentPage, hasMore, isLoadingMore, fetchDocuments]);
103111

104112
// Handle dialog open state change
105-
const handleOpenChange = useCallback((newOpen: boolean) => {
106-
onOpenChange(newOpen);
107-
if (newOpen && documents.length === 0) {
108-
loadInitialDocuments();
109-
}
110-
}, [onOpenChange, documents.length, loadInitialDocuments]);
113+
const handleOpenChange = useCallback(
114+
(newOpen: boolean) => {
115+
onOpenChange(newOpen);
116+
if (newOpen && documents.length === 0) {
117+
loadInitialDocuments();
118+
}
119+
},
120+
[onOpenChange, documents.length, loadInitialDocuments],
121+
);
111122

112123
// Render trigger button if requested
113124
if (triggerButton && !controlledOpen) {
@@ -165,4 +176,4 @@ export function MemoryGraphDialog({
165176
</DialogContent>
166177
</Dialog>
167178
);
168-
}
179+
}

0 commit comments

Comments
 (0)