Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
09deb98b
提交
09deb98b
authored
4月 23, 2025
作者:
Will Chen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add description (optional) to SQL query
上级
1d0176d1
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
50 行增加
和
19 行删除
+50
-19
ChatInput.tsx
src/components/chat/ChatInput.tsx
+12
-4
DyadExecuteSql.tsx
src/components/chat/DyadExecuteSql.tsx
+4
-1
proposal_handlers.ts
src/ipc/handlers/proposal_handlers.ts
+10
-2
response_processor.ts
src/ipc/processors/response_processor.ts
+12
-7
schemas.ts
src/lib/schemas.ts
+6
-1
supabase_prompt.ts
src/prompts/supabase_prompt.ts
+6
-4
没有找到文件。
src/components/chat/ChatInput.tsx
浏览文件 @
09deb98b
...
...
@@ -38,6 +38,7 @@ import {
SuggestedAction
,
ProposalResult
,
FileChange
,
SqlQuery
,
}
from
"@/lib/schemas"
;
import
type
{
Message
}
from
"@/ipc/ipc_types"
;
import
{
isPreviewOpenAtom
}
from
"@/atoms/viewAtoms"
;
...
...
@@ -547,7 +548,7 @@ function ProposalSummary({
packagesAdded
=
[],
filesChanged
=
[],
}:
{
sqlQueries
?:
string
[]
;
sqlQueries
?:
Array
<
SqlQuery
>
;
serverFunctions
?:
FileChange
[];
packagesAdded
?:
string
[];
filesChanged
?:
FileChange
[];
...
...
@@ -600,9 +601,12 @@ function ProposalSummary({
}
// SQL Query item with expandable functionality
function
SqlQueryItem
({
query
}:
{
query
:
string
})
{
function
SqlQueryItem
({
query
}:
{
query
:
SqlQuery
})
{
const
[
isExpanded
,
setIsExpanded
]
=
useState
(
false
);
const
queryContent
=
query
.
content
;
const
queryDescription
=
query
.
description
;
return
(
<
li
className=
"bg-(--background-lightest) hover:bg-(--background-lighter) rounded-lg px-3 py-2 border border-border cursor-pointer"
...
...
@@ -611,7 +615,9 @@ function SqlQueryItem({ query }: { query: string }) {
<
div
className=
"flex items-center justify-between"
>
<
div
className=
"flex items-center gap-2"
>
<
Database
size=
{
16
}
className=
"text-muted-foreground flex-shrink-0"
/>
<
span
className=
"text-sm font-medium"
>
SQL Query
</
span
>
<
span
className=
"text-sm font-medium"
>
{
queryDescription
||
"SQL Query"
}
</
span
>
</
div
>
<
div
>
{
isExpanded
?
(
...
...
@@ -623,7 +629,9 @@ function SqlQueryItem({ query }: { query: string }) {
</
div
>
{
isExpanded
&&
(
<
div
className=
"mt-2 text-xs max-h-[200px] overflow-auto"
>
<
CodeHighlight
className=
"language-sql "
>
{
query
}
</
CodeHighlight
>
<
CodeHighlight
className=
"language-sql "
>
{
queryContent
}
</
CodeHighlight
>
</
div
>
)
}
</
li
>
...
...
src/components/chat/DyadExecuteSql.tsx
浏览文件 @
09deb98b
...
...
@@ -14,16 +14,19 @@ import { CustomTagState } from "./stateTypes";
interface
DyadExecuteSqlProps
{
children
?:
ReactNode
;
node
?:
any
;
description
?:
string
;
}
export
const
DyadExecuteSql
:
React
.
FC
<
DyadExecuteSqlProps
>
=
({
children
,
node
,
description
,
})
=>
{
const
[
isContentVisible
,
setIsContentVisible
]
=
useState
(
false
);
const
state
=
node
?.
properties
?.
state
as
CustomTagState
;
const
inProgress
=
state
===
"pending"
;
const
aborted
=
state
===
"aborted"
;
const
queryDescription
=
description
||
node
?.
properties
?.
description
;
return
(
<
div
...
...
@@ -40,7 +43,7 @@ export const DyadExecuteSql: React.FC<DyadExecuteSqlProps> = ({
<
div
className=
"flex items-center gap-2"
>
<
Database
size=
{
16
}
/>
<
span
className=
"text-gray-700 dark:text-gray-300 font-medium text-sm"
>
SQL Query
{
queryDescription
||
"SQL Query"
}
</
span
>
{
inProgress
&&
(
<
div
className=
"flex items-center text-amber-600 text-xs"
>
...
...
src/ipc/handlers/proposal_handlers.ts
浏览文件 @
09deb98b
...
...
@@ -3,6 +3,7 @@ import type {
CodeProposal
,
FileChange
,
ProposalResult
,
SqlQuery
,
}
from
"../../lib/schemas"
;
import
{
db
}
from
"../../db"
;
import
{
messages
}
from
"../../db/schema"
;
...
...
@@ -105,7 +106,11 @@ const getProposalHandler = async (
})),
];
// Check if we have enough information to create a proposal
if
(
filesChanged
.
length
>
0
||
packagesAdded
.
length
>
0
)
{
if
(
filesChanged
.
length
>
0
||
packagesAdded
.
length
>
0
||
proposalExecuteSqlQueries
.
length
>
0
)
{
const
proposal
:
CodeProposal
=
{
type
:
"code-proposal"
,
// Use parsed title or a default title if summary tag is missing but write tags exist
...
...
@@ -113,7 +118,10 @@ const getProposalHandler = async (
securityRisks
:
[],
// Keep empty
filesChanged
,
packagesAdded
,
sqlQueries
:
proposalExecuteSqlQueries
,
sqlQueries
:
proposalExecuteSqlQueries
.
map
((
query
)
=>
({
content
:
query
.
content
,
description
:
query
.
description
,
})),
};
logger
.
log
(
"Generated code proposal. title="
,
...
...
src/ipc/processors/response_processor.ts
浏览文件 @
09deb98b
...
...
@@ -15,6 +15,7 @@ import {
executeSupabaseSql
,
}
from
"../../supabase_admin/supabase_management_client"
;
import
{
isServerFunction
}
from
"../../supabase_admin/supabase_utils"
;
import
{
SqlQuery
}
from
"../../lib/schemas"
;
const
readFile
=
fs
.
promises
.
readFile
;
const
logger
=
log
.
scope
(
"response_processor"
);
...
...
@@ -108,14 +109,18 @@ export function getDyadChatSummaryTag(fullResponse: string): string | null {
return
null
;
}
export
function
getDyadExecuteSqlTags
(
fullResponse
:
string
):
string
[]
{
export
function
getDyadExecuteSqlTags
(
fullResponse
:
string
):
SqlQuery
[]
{
const
dyadExecuteSqlRegex
=
/<dyad-execute-sql>
([\s\S]
*
?)
<
\/
dyad-execute-sql>/g
;
/<dyad-execute-sql
([^
>
]
*
)
>
([\s\S]
*
?)
<
\/
dyad-execute-sql>/g
;
const
descriptionRegex
=
/description="
([^
"
]
+
)
"/
;
let
match
;
const
queries
:
string
[]
=
[];
const
queries
:
{
content
:
string
;
description
?:
string
}
[]
=
[];
while
((
match
=
dyadExecuteSqlRegex
.
exec
(
fullResponse
))
!==
null
)
{
let
content
=
match
[
1
].
trim
();
const
attributesString
=
match
[
1
]
||
""
;
let
content
=
match
[
2
].
trim
();
const
descriptionMatch
=
descriptionRegex
.
exec
(
attributesString
);
const
description
=
descriptionMatch
?.[
1
];
// Handle markdown code blocks if present
const
contentLines
=
content
.
split
(
"
\
n"
);
...
...
@@ -127,7 +132,7 @@ export function getDyadExecuteSqlTags(fullResponse: string): string[] {
}
content
=
contentLines
.
join
(
"
\
n"
);
queries
.
push
(
content
);
queries
.
push
(
{
content
,
description
}
);
}
return
queries
;
...
...
@@ -209,11 +214,11 @@ export async function processFullResponseActions(
try
{
const
result
=
await
executeSupabaseSql
({
supabaseProjectId
:
chatWithApp
.
app
.
supabaseProjectId
!
,
query
,
query
:
query
.
content
,
});
}
catch
(
error
)
{
errors
.
push
({
message
:
`Failed to execute SQL query:
${
query
}
`
,
message
:
`Failed to execute SQL query:
${
query
.
content
}
`
,
error
:
error
,
});
}
...
...
src/lib/schemas.ts
浏览文件 @
09deb98b
...
...
@@ -132,13 +132,18 @@ export interface FileChange {
isServerFunction
:
boolean
;
}
export
interface
SqlQuery
{
content
:
string
;
description
?:
string
;
}
export
interface
CodeProposal
{
type
:
"code-proposal"
;
title
:
string
;
securityRisks
:
SecurityRisk
[];
filesChanged
:
FileChange
[];
packagesAdded
:
string
[];
sqlQueries
:
string
[];
sqlQueries
:
SqlQuery
[];
}
export
interface
SuggestedAction
{
...
...
src/prompts/supabase_prompt.ts
浏览文件 @
09deb98b
...
...
@@ -89,12 +89,14 @@ function Login() {
## Database
If the user wants to use the database, use the following
code
:
If the user wants to use the database, use the following
syntax
:
<dyad-execute-sql>
<dyad-execute-sql
description="Get all users"
>
SELECT * FROM users;
</dyad-execute-sql>
The description should be a short description of what the code is doing and be understandable by semi-technical users.
You will need to setup the database schema.
## Creating User Profiles
...
...
@@ -103,7 +105,7 @@ If the user wants to create a user profile, use the following code:
### Create profiles table in public schema
<dyad-execute-sql>
<dyad-execute-sql
description="Create profiles table in public schema"
>
CREATE TABLE public.profiles (
id UUID NOT NULL REFERENCES auth.users ON DELETE CASCADE,
first_name TEXT,
...
...
@@ -130,7 +132,7 @@ create policy "Users can update own profile." on profiles for update using ( aut
### Function to insert profile when user signs up
<dyad-execute-sql>
<dyad-execute-sql
description="Create function to insert profile when user signs up"
>
CREATE FUNCTION public.handle_new_user()
RETURNS TRIGGER
LANGUAGE PLPGSQL
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论