Skip to content

homeant/agent-server-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

asvc

统一管理本地开发服务的 守护进程(daemon) + 一套 asvc CLI。人和 agent 共用同一套命令。

解决的问题:开发时 agent 会帮你启动服务,你自己也会启动,导致端口冲突进程难管理。 本工具让人和 agent 都通过同一个 daemon 操作服务:

  • 启动即注册:只有一个 asvc start。带 -c 给命令就自动注册并启动,按名去重不重复拉起。
  • asvc start <name> -c "..."):前台运行,像直接敲 npm run dev 一样实时刷日志,Ctrl-C 停。
  • agentasvc start <name> -c "..." -d):加 -d 后台启动、跑完返回拿退出码。
  • 任何人都能 asvc logs / asvc list / asvc restart / asvc stop 操作同一批服务。
  • daemon 按服务名去重:同名服务只有一个实例,agent 和你都不会把它启动两遍 → 不再撞端口。

同一个 asvc start,靠 -d 区分前台/后台:

命令 谁用 行为
asvc start <name> -c "..." 前台:占住终端实时刷日志,像原始命令;Ctrl-C 停止服务
asvc start <name> -c "..." -d agent 后台:启动后立即返回,带退出码(成功 0 / 启动失败 1)

为什么是 CLI 而不是 MCP:agent(如 Claude Code)本来就有 shell,直接跑 asvc 命令最简单—— 不用配 MCP server、不用单独的协议,人和 agent 认知统一,看到的输出也一样。

核心设计:重启不断开你的终端

服务进程是 daemon 的子进程,不是某个终端 shell 的子进程。 你在终端 asvc start web 前台跑着(或在另一个终端 asvc logs web -f 跟随)时, agent 在另一头 asvc restart web,daemon 只是把底层进程换了一个, 你的终端不会断——只会看到一行 » restarting... 然后新日志继续刷。 (注意:只有你自己按 Ctrl-C 才会停服务并退出;agent 的 restart 不会让你的终端退出。)

   人的终端  ──┐
   (asvc CLI)   │        ┌─────────────┐      ┌── 服务进程 web (pid A)
               ├─ IPC ─▶│   daemon    │─────▶├── 服务进程 api (pid B)
   agent     ──┘ (sock) │  (单实例)    │      └── ...
   (asvc CLI)            └─────────────┘

安装

npm install -g @homeant/asvc

装完 asvc / asvc-daemon 就在 PATH 上,agent 和你都能直接敲 asvc。 daemon 会在首次执行任意 asvc 命令时自动拉起,无需手动启动。

Shell 补全(Tab 提示)

# zsh:加到 ~/.zshrc
eval "$(asvc completion zsh)"
# bash:加到 ~/.bashrc
eval "$(asvc completion bash)"

补全覆盖子命令、各命令的 flag,以及服务名——asvc restart <TAB> 会实时列出 daemon 里已注册的服务(daemon 未运行时安静地不补全,不会触发自动拉起)。

从源码开发时改用本地构建:

npm install && npm run build
npm link        # 把本地构建的 asvc 装到全局 PATH

命令一览(asvc

# 启动即注册(前台,人用):像直接敲原始命令,实时刷日志,Ctrl-C 停止服务
asvc start web -c "npm run dev" --port 3000              # cwd 默认当前目录
asvc start web                                           # 已注册过则可省略 -c

# 启动即注册(后台,agent 用):加 -d,跑完即返回、带退出码
asvc start web -c "npm run dev" --port 3000 -d
asvc start api -c "go run ." --cwd /path/api --env KEY=VAL --autorestart -d

asvc list                 # 列出所有服务及状态
asvc logs web             # 看 web 最近 200 行日志
asvc logs web -f          # 持续跟随(agent 重启服务也不断开)
asvc logs web -n 500      # 看最近 500 行
asvc restart web          # 重启(前台/跟随的终端都不会断)
asvc stop web             # 停止(保留定义,可再启动)
asvc rm web               # 移除(先停后删)

asvc daemon status        # 看 daemon 是否运行
asvc daemon stop          # 停 daemon(会先关闭所有服务)

start 参数:-c/--cmd(命令,经 shell 执行)、-w/--cwd(默认当前目录)、 -p/--port(仅展示/排查)、-e/--env KEY=VAL(可多个)、--autorestart-d/--detach(后台)。

启动失败 / 端口冲突,agent 当场知道

register / start / restart 在拉起进程后会观察约 1 秒确认进程没有立刻崩溃,再返回:

  • 进程稳定运行 → 打印成功,退出码 0
  • 进程在窗口内退出(最常见就是端口被别的进程占了,EADDRINUSE)→ 打印最近日志, 识别到 EADDRINUSE 时给出「请换端口或先停掉占用方」的提示,并以退出码 1 退出。

这样不依赖事先声明 port:无论端口被谁占(你手动起的、孤儿进程、还是另一个服务), 只要进程因此启动失败,走 Bash 的 agent 都能直接从非零退出码 + 输出判定失败和原因, 而不是拿到一个乐观的 “running” 再去翻日志。asvc start(前台)同样:启动即失败会打印提示并以非零码退出。

让 agent 用起来(Claude Code Skill)

npm 包内自带一个 Claude Code skill:skill/asvc/SKILL.md。 它教 agent 在该启动/重启/看日志时改用 asvc,并强调后台启动必须带 -d、按退出码判成败。

安装(软链到全局 skills 目录):

npm install -g @homeant/asvc
ln -sfn "$(npm root -g)/@homeant/asvc/skill/asvc" ~/.claude/skills/asvc

从源码开发时,把软链指向仓库即可(编辑仓库即同步生效):

ln -sfn "$PWD/skill/asvc" ~/.claude/skills/asvc

之后 agent 在「启动服务 / 重启 / 看日志 / 排查起不来」时会自动参考该 skill。 也可以在项目 CLAUDE.md 里加一句兜底约定:

启动/重启/停止开发服务一律用 `asvc`,agent 用 `asvc start <name> -c "<命令>" -d`
(务必带 -d 后台),重启 `asvc restart <name>`,看日志 `asvc logs <name> -n 200`

工作流示例

  1. 你在 web 目录 asvc start web -c "npm run dev" --port 3000 → 前台跑起来,实时刷日志。 (或让 agent asvc start web -c "npm run dev" --port 3000 -d 后台起,你再 asvc logs web -f 看。)
  2. agent 改完代码执行 asvc restart web → 你的终端看到 » restarting...,随后新日志继续,终端不断开
  3. 你不想看了按 Ctrl-C → 服务停止、终端退出(和原始命令一致)。
  4. 你随时 asvc restart web / asvc stop web 手动接管。

数据与配置

  • 全局单实例,家目录默认 ~/.asvc(可用 ASVC_HOME 覆盖)。
  • socket:$ASVC_HOME/daemon.sock(可用 ASVC_SOCKET 覆盖)。
  • 每个服务日志落盘 $ASVC_HOME/logs/<name>.log,内存保留最近 2000 行供快速查询。
  • 服务定义动态注册,无需手写配置文件;注册表持久化在 $ASVC_HOME/registry.json, daemon 重启后自动恢复定义(不自动拉起进程,asvc start <name> 即可再启动,无需重新带 -c)。

实现要点

  • IPC:unix domain socket + newline-delimited JSON(请求/响应 + 事件推送)。
  • 进程组:spawn(..., { shell:true, detached:true }),停止时 kill(-pid) 终止整组, 先 SIGTERM,5s 未退再 SIGKILL
  • 启动后 1s 稳定窗口:进程在窗口内退出即判失败,返回真实状态而非乐观 running。
  • TypeScript + commander,无其他运行时依赖。

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors