Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
20362d7b
Unverified
提交
20362d7b
authored
5月 06, 2025
作者:
Will Chen
提交者:
GitHub
5月 06, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix undo and redo by using initial commit hash for chat (#94)
上级
390496f8
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
314 行增加
和
9 行删除
+314
-9
0004_flawless_jigsaw.sql
drizzle/0004_flawless_jigsaw.sql
+2
-0
0004_snapshot.json
drizzle/meta/0004_snapshot.json
+221
-0
_journal.json
drizzle/meta/_journal.json
+8
-0
MessagesList.tsx
src/components/chat/MessagesList.tsx
+0
-0
schema.ts
src/db/schema.ts
+1
-0
app_handlers.ts
src/ipc/handlers/app_handlers.ts
+9
-1
chat_handlers.ts
src/ipc/handlers/chat_handlers.ts
+53
-3
ipc_client.ts
src/ipc/ipc_client.ts
+17
-5
ipc_types.ts
src/ipc/ipc_types.ts
+1
-0
preload.ts
src/preload.ts
+2
-0
没有找到文件。
drizzle/0004_flawless_jigsaw.sql
0 → 100644
浏览文件 @
20362d7b
ALTER
TABLE
`chats`
ADD
`initial_commit_hash`
text
;
\ No newline at end of file
drizzle/meta/0004_snapshot.json
0 → 100644
浏览文件 @
20362d7b
{
"version"
:
"6"
,
"dialect"
:
"sqlite"
,
"id"
:
"ceedb797-6aa3-4a50-b42f-bc85ee08b3df"
,
"prevId"
:
"859942b1-88b8-4a16-b2d0-77c9ece76693"
,
"tables"
:
{
"apps"
:
{
"name"
:
"apps"
,
"columns"
:
{
"id"
:
{
"name"
:
"id"
,
"type"
:
"integer"
,
"primaryKey"
:
true
,
"notNull"
:
true
,
"autoincrement"
:
true
},
"name"
:
{
"name"
:
"name"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
},
"path"
:
{
"name"
:
"path"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
},
"created_at"
:
{
"name"
:
"created_at"
,
"type"
:
"integer"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
,
"default"
:
"(unixepoch())"
},
"updated_at"
:
{
"name"
:
"updated_at"
,
"type"
:
"integer"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
,
"default"
:
"(unixepoch())"
},
"github_org"
:
{
"name"
:
"github_org"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
false
,
"autoincrement"
:
false
},
"github_repo"
:
{
"name"
:
"github_repo"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
false
,
"autoincrement"
:
false
},
"supabase_project_id"
:
{
"name"
:
"supabase_project_id"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
false
,
"autoincrement"
:
false
}
},
"indexes"
:
{},
"foreignKeys"
:
{},
"compositePrimaryKeys"
:
{},
"uniqueConstraints"
:
{},
"checkConstraints"
:
{}
},
"chats"
:
{
"name"
:
"chats"
,
"columns"
:
{
"id"
:
{
"name"
:
"id"
,
"type"
:
"integer"
,
"primaryKey"
:
true
,
"notNull"
:
true
,
"autoincrement"
:
true
},
"app_id"
:
{
"name"
:
"app_id"
,
"type"
:
"integer"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
},
"title"
:
{
"name"
:
"title"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
false
,
"autoincrement"
:
false
},
"initial_commit_hash"
:
{
"name"
:
"initial_commit_hash"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
false
,
"autoincrement"
:
false
},
"created_at"
:
{
"name"
:
"created_at"
,
"type"
:
"integer"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
,
"default"
:
"(unixepoch())"
}
},
"indexes"
:
{},
"foreignKeys"
:
{
"chats_app_id_apps_id_fk"
:
{
"name"
:
"chats_app_id_apps_id_fk"
,
"tableFrom"
:
"chats"
,
"tableTo"
:
"apps"
,
"columnsFrom"
:
[
"app_id"
],
"columnsTo"
:
[
"id"
],
"onDelete"
:
"cascade"
,
"onUpdate"
:
"no action"
}
},
"compositePrimaryKeys"
:
{},
"uniqueConstraints"
:
{},
"checkConstraints"
:
{}
},
"messages"
:
{
"name"
:
"messages"
,
"columns"
:
{
"id"
:
{
"name"
:
"id"
,
"type"
:
"integer"
,
"primaryKey"
:
true
,
"notNull"
:
true
,
"autoincrement"
:
true
},
"chat_id"
:
{
"name"
:
"chat_id"
,
"type"
:
"integer"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
},
"role"
:
{
"name"
:
"role"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
},
"content"
:
{
"name"
:
"content"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
},
"approval_state"
:
{
"name"
:
"approval_state"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
false
,
"autoincrement"
:
false
},
"commit_hash"
:
{
"name"
:
"commit_hash"
,
"type"
:
"text"
,
"primaryKey"
:
false
,
"notNull"
:
false
,
"autoincrement"
:
false
},
"created_at"
:
{
"name"
:
"created_at"
,
"type"
:
"integer"
,
"primaryKey"
:
false
,
"notNull"
:
true
,
"autoincrement"
:
false
,
"default"
:
"(unixepoch())"
}
},
"indexes"
:
{},
"foreignKeys"
:
{
"messages_chat_id_chats_id_fk"
:
{
"name"
:
"messages_chat_id_chats_id_fk"
,
"tableFrom"
:
"messages"
,
"tableTo"
:
"chats"
,
"columnsFrom"
:
[
"chat_id"
],
"columnsTo"
:
[
"id"
],
"onDelete"
:
"cascade"
,
"onUpdate"
:
"no action"
}
},
"compositePrimaryKeys"
:
{},
"uniqueConstraints"
:
{},
"checkConstraints"
:
{}
}
},
"views"
:
{},
"enums"
:
{},
"_meta"
:
{
"schemas"
:
{},
"tables"
:
{},
"columns"
:
{}
},
"internal"
:
{
"indexes"
:
{}
}
}
\ No newline at end of file
drizzle/meta/_journal.json
浏览文件 @
20362d7b
...
@@ -29,6 +29,13 @@
...
@@ -29,6 +29,13 @@
"when"
:
1746209201530
,
"when"
:
1746209201530
,
"tag"
:
"0003_open_bucky"
,
"tag"
:
"0003_open_bucky"
,
"breakpoints"
:
true
"breakpoints"
:
true
},
{
"idx"
:
4
,
"version"
:
"6"
,
"when"
:
1746556241557
,
"tag"
:
"0004_flawless_jigsaw"
,
"breakpoints"
:
true
}
}
]
]
}
}
\ No newline at end of file
src/components/chat/MessagesList.tsx
浏览文件 @
20362d7b
差异被折叠。
点击展开。
src/db/schema.ts
浏览文件 @
20362d7b
...
@@ -23,6 +23,7 @@ export const chats = sqliteTable("chats", {
...
@@ -23,6 +23,7 @@ export const chats = sqliteTable("chats", {
.
notNull
()
.
notNull
()
.
references
(()
=>
apps
.
id
,
{
onDelete
:
"cascade"
}),
.
references
(()
=>
apps
.
id
,
{
onDelete
:
"cascade"
}),
title
:
text
(
"title"
),
title
:
text
(
"title"
),
initialCommitHash
:
text
(
"initial_commit_hash"
),
createdAt
:
integer
(
"created_at"
,
{
mode
:
"timestamp"
})
createdAt
:
integer
(
"created_at"
,
{
mode
:
"timestamp"
})
.
notNull
()
.
notNull
()
.
default
(
sql
`(unixepoch())`
),
.
default
(
sql
`(unixepoch())`
),
...
...
src/ipc/handlers/app_handlers.ts
浏览文件 @
20362d7b
...
@@ -189,12 +189,20 @@ export function registerAppHandlers() {
...
@@ -189,12 +189,20 @@ export function registerAppHandlers() {
});
});
// Create initial commit
// Create initial commit
await
git
.
commit
({
const
commitHash
=
await
git
.
commit
({
fs
:
fs
,
fs
:
fs
,
dir
:
fullAppPath
,
dir
:
fullAppPath
,
message
:
"Init from react vite template"
,
message
:
"Init from react vite template"
,
author
:
await
getGitAuthor
(),
author
:
await
getGitAuthor
(),
});
});
// Update chat with initial commit hash
await
db
.
update
(
chats
)
.
set
({
initialCommitHash
:
commitHash
,
})
.
where
(
eq
(
chats
.
id
,
chat
.
id
));
}
catch
(
error
)
{
}
catch
(
error
)
{
logger
.
error
(
"Error in background app initialization:"
,
error
);
logger
.
error
(
"Error in background app initialization:"
,
error
);
}
}
...
...
src/ipc/handlers/chat_handlers.ts
浏览文件 @
20362d7b
import
{
ipcMain
}
from
"electron"
;
import
{
ipcMain
}
from
"electron"
;
import
{
db
}
from
"../../db"
;
import
{
db
}
from
"../../db"
;
import
{
chat
s
}
from
"../../db/schema"
;
import
{
apps
,
chats
,
message
s
}
from
"../../db/schema"
;
import
{
desc
,
eq
}
from
"drizzle-orm"
;
import
{
desc
,
eq
}
from
"drizzle-orm"
;
import
type
{
ChatSummary
}
from
"../../lib/schemas"
;
import
type
{
ChatSummary
}
from
"../../lib/schemas"
;
import
*
as
git
from
"isomorphic-git"
;
import
*
as
fs
from
"fs"
;
import
*
as
path
from
"path"
;
import
log
from
"electron-log"
;
import
{
getDyadAppPath
}
from
"../../paths/paths"
;
const
logger
=
log
.
scope
(
"chat_handlers"
);
export
function
registerChatHandlers
()
{
export
function
registerChatHandlers
()
{
ipcMain
.
handle
(
"create-chat"
,
async
(
_
,
appId
:
number
)
=>
{
ipcMain
.
handle
(
"create-chat"
,
async
(
_
,
appId
:
number
)
=>
{
// Get the app's path first
const
app
=
await
db
.
query
.
apps
.
findFirst
({
where
:
eq
(
apps
.
id
,
appId
),
columns
:
{
path
:
true
,
},
});
if
(
!
app
)
{
throw
new
Error
(
"App not found"
);
}
let
initialCommitHash
=
null
;
try
{
// Get the current git revision of main branch
initialCommitHash
=
await
git
.
resolveRef
({
fs
,
dir
:
getDyadAppPath
(
app
.
path
),
ref
:
"main"
,
});
}
catch
(
error
)
{
logger
.
error
(
"Error getting git revision:"
,
error
);
// Continue without the git revision
}
// Create a new chat
// Create a new chat
const
[
chat
]
=
await
db
const
[
chat
]
=
await
db
.
insert
(
chats
)
.
insert
(
chats
)
.
values
({
.
values
({
appId
,
appId
,
initialCommitHash
,
})
})
.
returning
();
.
returning
();
logger
.
info
(
"Created chat:"
,
chat
.
id
,
"for app:"
,
appId
,
"with initial commit hash:"
,
initialCommitHash
);
return
chat
.
id
;
return
chat
.
id
;
});
});
...
@@ -70,7 +110,17 @@ export function registerChatHandlers() {
...
@@ -70,7 +110,17 @@ export function registerChatHandlers() {
await
db
.
delete
(
chats
).
where
(
eq
(
chats
.
id
,
chatId
));
await
db
.
delete
(
chats
).
where
(
eq
(
chats
.
id
,
chatId
));
return
{
success
:
true
};
return
{
success
:
true
};
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"Error deleting chat:"
,
error
);
logger
.
error
(
"Error deleting chat:"
,
error
);
return
{
success
:
false
,
error
:
(
error
as
Error
).
message
};
}
});
ipcMain
.
handle
(
"delete-messages"
,
async
(
_
,
chatId
:
number
)
=>
{
try
{
await
db
.
delete
(
messages
).
where
(
eq
(
messages
.
chatId
,
chatId
));
return
{
success
:
true
};
}
catch
(
error
)
{
logger
.
error
(
"Error deleting messages:"
,
error
);
return
{
success
:
false
,
error
:
(
error
as
Error
).
message
};
return
{
success
:
false
,
error
:
(
error
as
Error
).
message
};
}
}
});
});
...
...
src/ipc/ipc_client.ts
浏览文件 @
20362d7b
...
@@ -330,12 +330,24 @@ export class IpcClient {
...
@@ -330,12 +330,24 @@ export class IpcClient {
}
}
}
}
public
async
deleteChat
(
chatId
:
number
):
Promise
<
{
success
:
boolean
}
>
{
public
async
deleteChat
(
chatId
:
number
):
Promise
<
{
success
:
boolean
;
error
?:
string
}
>
{
try
{
try
{
const
result
=
(
await
this
.
ipcRenderer
.
invoke
(
"delete-chat"
,
chatId
))
as
{
const
result
=
await
this
.
ipcRenderer
.
invoke
(
"delete-chat"
,
chatId
);
success
:
boolean
;
return
result
as
{
success
:
boolean
;
error
?:
string
};
};
}
catch
(
error
)
{
return
result
;
showError
(
error
);
throw
error
;
}
}
public
async
deleteMessages
(
chatId
:
number
):
Promise
<
{
success
:
boolean
;
error
?:
string
}
>
{
try
{
const
result
=
await
this
.
ipcRenderer
.
invoke
(
"delete-messages"
,
chatId
);
return
result
as
{
success
:
boolean
;
error
?:
string
};
}
catch
(
error
)
{
}
catch
(
error
)
{
showError
(
error
);
showError
(
error
);
throw
error
;
throw
error
;
...
...
src/ipc/ipc_types.ts
浏览文件 @
20362d7b
...
@@ -54,6 +54,7 @@ export interface Chat {
...
@@ -54,6 +54,7 @@ export interface Chat {
id
:
number
;
id
:
number
;
title
:
string
;
title
:
string
;
messages
:
Message
[];
messages
:
Message
[];
initialCommitHash
?:
string
|
null
;
}
}
export
interface
App
{
export
interface
App
{
...
...
src/preload.ts
浏览文件 @
20362d7b
...
@@ -58,6 +58,8 @@ const validInvokeChannels = [
...
@@ -58,6 +58,8 @@ const validInvokeChannels = [
"window:get-platform"
,
"window:get-platform"
,
"upload-to-signed-url"
,
"upload-to-signed-url"
,
"delete-chat"
,
"delete-chat"
,
"delete-messages"
,
"start-chat-stream"
,
]
as
const
;
]
as
const
;
// Add valid receive channels
// Add valid receive channels
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论