Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
37579d01
提交
37579d01
authored
4月 11, 2025
作者:
Will Chen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor app handler
上级
d3c1f8e3
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
83 行增加
和
132 行删除
+83
-132
app_handlers.ts
src/ipc/handlers/app_handlers.ts
+79
-129
ipc_client.ts
src/ipc/ipc_client.ts
+4
-3
没有找到文件。
src/ipc/handlers/app_handlers.ts
浏览文件 @
37579d01
...
...
@@ -26,6 +26,83 @@ import {
import
{
ALLOWED_ENV_VARS
}
from
"../../constants/models"
;
import
{
getEnvVar
}
from
"../utils/read_env"
;
async
function
executeApp
({
appPath
,
appId
,
event
,
}:
{
appPath
:
string
;
appId
:
number
;
event
:
Electron
.
IpcMainInvokeEvent
;
}):
Promise
<
{
processId
:
number
}
>
{
const
process
=
spawn
(
"npm install && npm run dev"
,
[],
{
cwd
:
appPath
,
shell
:
true
,
stdio
:
"pipe"
,
// Ensure stdio is piped so we can capture output/errors and detect close
detached
:
false
,
// Ensure child process is attached to the main process lifecycle unless explicitly backgrounded
});
// Check if process spawned correctly
if
(
!
process
.
pid
)
{
// Attempt to capture any immediate errors if possible
let
errorOutput
=
""
;
process
.
stderr
?.
on
(
"data"
,
(
data
)
=>
(
errorOutput
+=
data
));
await
new
Promise
((
resolve
)
=>
process
.
on
(
"error"
,
resolve
));
// Wait for error event
throw
new
Error
(
`Failed to spawn process for app
${
appId
}
. Error:
${
errorOutput
||
"Unknown spawn error"
}
`
);
}
// Increment the counter and store the process reference with its ID
const
currentProcessId
=
processCounter
.
increment
();
runningApps
.
set
(
appId
,
{
process
,
processId
:
currentProcessId
});
// Log output
process
.
stdout
?.
on
(
"data"
,
(
data
)
=>
{
console
.
log
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) stdout:
${
data
.
toString
().
trim
()}
`
);
event
.
sender
.
send
(
"app:output"
,
{
type
:
"stdout"
,
message
:
data
.
toString
().
trim
(),
appId
:
appId
,
});
});
process
.
stderr
?.
on
(
"data"
,
(
data
)
=>
{
console
.
error
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) stderr:
${
data
.
toString
().
trim
()}
`
);
event
.
sender
.
send
(
"app:output"
,
{
type
:
"stderr"
,
message
:
data
.
toString
().
trim
(),
appId
:
appId
,
});
});
// Handle process exit/close
process
.
on
(
"close"
,
(
code
,
signal
)
=>
{
console
.
log
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) process closed with code
${
code
}
, signal
${
signal
}
.`
);
removeAppIfCurrentProcess
(
appId
,
process
);
});
// Handle errors during process lifecycle (e.g., command not found)
process
.
on
(
"error"
,
(
err
)
=>
{
console
.
error
(
`Error in app
${
appId
}
(PID:
${
process
.
pid
}
) process:
${
err
.
message
}
`
);
removeAppIfCurrentProcess
(
appId
,
process
);
// Note: We don't throw here as the error is asynchronous. The caller got a success response already.
// Consider adding ipcRenderer event emission to notify UI of the error.
});
return
{
processId
:
currentProcessId
};
}
export
function
registerAppHandlers
()
{
ipcMain
.
handle
(
"create-app"
,
async
(
_
,
params
:
CreateAppParams
)
=>
{
const
appPath
=
params
.
name
;
...
...
@@ -197,74 +274,7 @@ export function registerAppHandlers() {
const
appPath
=
getDyadAppPath
(
app
.
path
);
console
.
log
(
"appPath-CWD"
,
appPath
);
try
{
const
process
=
spawn
(
"npm install && npm run dev"
,
[],
{
cwd
:
appPath
,
shell
:
true
,
stdio
:
"pipe"
,
// Ensure stdio is piped so we can capture output/errors and detect close
detached
:
false
,
// Ensure child process is attached to the main process lifecycle unless explicitly backgrounded
});
// Check if process spawned correctly
if
(
!
process
.
pid
)
{
// Attempt to capture any immediate errors if possible
let
errorOutput
=
""
;
process
.
stderr
?.
on
(
"data"
,
(
data
)
=>
(
errorOutput
+=
data
));
await
new
Promise
((
resolve
)
=>
process
.
on
(
"error"
,
resolve
));
// Wait for error event
throw
new
Error
(
`Failed to spawn process for app
${
appId
}
. Error:
${
errorOutput
||
"Unknown spawn error"
}
`
);
}
// Increment the counter and store the process reference with its ID
const
currentProcessId
=
processCounter
.
increment
();
runningApps
.
set
(
appId
,
{
process
,
processId
:
currentProcessId
});
// Log output
process
.
stdout
?.
on
(
"data"
,
(
data
)
=>
{
console
.
log
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) stdout:
${
data
.
toString
()
.
trim
()}
`
);
event
.
sender
.
send
(
"app:output"
,
{
type
:
"stdout"
,
message
:
data
.
toString
().
trim
(),
appId
:
appId
,
});
});
process
.
stderr
?.
on
(
"data"
,
(
data
)
=>
{
console
.
error
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) stderr:
${
data
.
toString
()
.
trim
()}
`
);
event
.
sender
.
send
(
"app:output"
,
{
type
:
"stderr"
,
message
:
data
.
toString
().
trim
(),
appId
:
appId
,
});
});
// Handle process exit/close
process
.
on
(
"close"
,
(
code
,
signal
)
=>
{
console
.
log
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) process closed with code
${
code
}
, signal
${
signal
}
.`
);
removeAppIfCurrentProcess
(
appId
,
process
);
});
// Handle errors during process lifecycle (e.g., command not found)
process
.
on
(
"error"
,
(
err
)
=>
{
console
.
error
(
`Error in app
${
appId
}
(PID:
${
process
.
pid
}
) process:
${
err
.
message
}
`
);
removeAppIfCurrentProcess
(
appId
,
process
);
// Note: We don't throw here as the error is asynchronous. The caller got a success response already.
// Consider adding ipcRenderer event emission to notify UI of the error.
});
const
currentProcessId
=
await
executeApp
({
appPath
,
appId
,
event
});
return
{
success
:
true
,
processId
:
currentProcessId
};
}
catch
(
error
:
any
)
{
...
...
@@ -369,67 +379,7 @@ export function registerAppHandlers() {
const
appPath
=
getDyadAppPath
(
app
.
path
);
console
.
debug
(
`Starting app
${
appId
}
in path
${
app
.
path
}
`
);
const
process
=
spawn
(
"npm install && npm run dev"
,
[],
{
cwd
:
appPath
,
shell
:
true
,
stdio
:
"pipe"
,
detached
:
false
,
});
if
(
!
process
.
pid
)
{
let
errorOutput
=
""
;
process
.
stderr
?.
on
(
"data"
,
(
data
)
=>
(
errorOutput
+=
data
));
await
new
Promise
((
resolve
)
=>
process
.
on
(
"error"
,
resolve
));
throw
new
Error
(
`Failed to spawn process for app
${
appId
}
. Error:
${
errorOutput
||
"Unknown spawn error"
}
`
);
}
const
currentProcessId
=
processCounter
.
increment
();
runningApps
.
set
(
appId
,
{
process
,
processId
:
currentProcessId
});
// Set up output handlers
process
.
stdout
?.
on
(
"data"
,
(
data
)
=>
{
console
.
log
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) stdout:
${
data
.
toString
()
.
trim
()}
`
);
event
.
sender
.
send
(
"app:output"
,
{
type
:
"stdout"
,
message
:
data
.
toString
().
trim
(),
appId
:
appId
,
});
});
process
.
stderr
?.
on
(
"data"
,
(
data
)
=>
{
console
.
error
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) stderr:
${
data
.
toString
()
.
trim
()}
`
);
event
.
sender
.
send
(
"app:output"
,
{
type
:
"stderr"
,
message
:
data
.
toString
().
trim
(),
appId
:
appId
,
});
});
process
.
on
(
"close"
,
(
code
,
signal
)
=>
{
console
.
log
(
`App
${
appId
}
(PID:
${
process
.
pid
}
) process closed with code
${
code
}
, signal
${
signal
}
.`
);
removeAppIfCurrentProcess
(
appId
,
process
);
});
process
.
on
(
"error"
,
(
err
)
=>
{
console
.
error
(
`Error in app
${
appId
}
(PID:
${
process
.
pid
}
) process:
${
err
.
message
}
`
);
removeAppIfCurrentProcess
(
appId
,
process
);
});
const
currentProcessId
=
await
executeApp
({
appPath
,
appId
,
event
});
return
{
success
:
true
,
processId
:
currentProcessId
};
}
catch
(
error
)
{
...
...
src/ipc/ipc_client.ts
浏览文件 @
37579d01
...
...
@@ -90,7 +90,7 @@ export class IpcClient {
console
.
debug
(
"chat:response:end"
);
this
.
chatStreams
.
delete
(
chatId
);
}
else
{
showE
rror
(
console
.
e
rror
(
new
Error
(
`[IPC] No callbacks found for chat
${
chatId
}
on stream end`
)
);
}
...
...
@@ -178,7 +178,8 @@ export class IpcClient {
});
return
content
as
string
;
}
catch
(
error
)
{
showError
(
error
);
// No toast because sometimes the file will disappear.
console
.
error
(
error
);
throw
error
;
}
}
...
...
@@ -237,7 +238,7 @@ export class IpcClient {
if
(
callbacks
)
{
this
.
chatStreams
.
delete
(
chatId
);
}
else
{
showError
(
new
Error
(
"Tried canceling chat that doesn't exist"
)
);
console
.
error
(
"Tried canceling chat that doesn't exist"
);
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论