This commit is contained in:
2026-06-18 22:56:41 +08:00
parent 3d831650b7
commit db3d030169
15 changed files with 1123 additions and 0 deletions
+27
View File
@@ -47,6 +47,7 @@ import (
mcp "github.com/yan1h/agent-coding-workflow/internal/mcp"
"github.com/yan1h/agent-coding-workflow/internal/project"
runmod "github.com/yan1h/agent-coding-workflow/internal/run"
"github.com/yan1h/agent-coding-workflow/internal/terminal"
httpx "github.com/yan1h/agent-coding-workflow/internal/transport/http"
"github.com/yan1h/agent-coding-workflow/internal/user"
"github.com/yan1h/agent-coding-workflow/internal/workspace"
@@ -63,6 +64,7 @@ type App struct {
jobsCancel context.CancelFunc
acpSup *acp.Supervisor // ACP supervisor — ShutdownAll on Run shutdown
runSup *runmod.RunSupervisor // run profiles supervisor — ShutdownAll on Run shutdown
termSup *terminal.Supervisor // admin terminal supervisor — CloseAll on shutdown
}
// New 把所有模块按启动顺序拼装好。任何阶段失败都会返回错误,不留半成品资源。
@@ -406,6 +408,23 @@ func New(ctx context.Context, cfg *config.Config, dist embed.FS) (*App, error) {
}).Mount(r)
}
// ===== admin terminal module wiring =====
// 仅限管理员的网页端交互式终端:在宿主进程(部署时即 runtime 容器)内开 shell,
// 主要用于运维(容器内 npm i -g 安装 ACP 客户端 CLI)。会话纯内存、不落库。
// WS 心跳沿用 acp 全局默认值(同类参数,避免新增配置面)。
termSup := terminal.NewSupervisor(terminal.SupervisorConfig{
Shell: cfg.Terminal.Shell,
MaxSessions: cfg.Terminal.MaxSessions,
KillGrace: cfg.Terminal.KillGrace,
EnvWhitelist: cfg.Terminal.EnvWhitelist,
}, log)
if cfg.Terminal.Enabled {
terminal.NewHandler(termSup, userSvc, userAdminAdapter{svc: userSvc}, auditRec, cfg.Terminal.Shell, terminal.WSConfig{
PingInterval: cfg.Acp.WSPingInterval,
PongTimeout: cfg.Acp.WSPongTimeout,
}).Mount(r)
}
// ===== MCP 模块装配(第二段:Server 本体 + transports + admin CRUD)=====
mcpDeps := mcp.ServerDeps{
Caller: mcp.NewCallerResolver(userSvc),
@@ -612,6 +631,7 @@ func New(ctx context.Context, cfg *config.Config, dist embed.FS) (*App, error) {
jobsCancel: jobsCancel,
acpSup: acpSup,
runSup: runSup,
termSup: termSup,
}, nil
}
@@ -645,6 +665,10 @@ func (a *App) Run(ctx context.Context) error {
if a.runSup != nil {
a.runSup.ShutdownAll(shutCtx)
}
// Close admin terminal sessions (整树 kill shell + 子孙) on shutdown.
if a.termSup != nil {
a.termSup.CloseAll(shutCtx)
}
// Stop jobs module first so no in-flight worker can dispatch new
// notifications after we begin to drain the dispatcher.
if a.jobs != nil && a.cfg.Jobs.Enabled {
@@ -673,6 +697,9 @@ func (a *App) Run(ctx context.Context) error {
if a.runSup != nil {
a.runSup.ShutdownAll(drainCtx)
}
if a.termSup != nil {
a.termSup.CloseAll(drainCtx)
}
if a.jobs != nil && a.cfg.Jobs.Enabled {
a.jobsCancel()
stopCtx, stopCancel := context.WithTimeout(context.Background(), a.cfg.Jobs.ShutdownGrace+5*time.Second)