Merge remote-tracking branch 'origin/main' into feature/chat-process-split-r1
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# feature/cross-session-reading 任务卡
|
||||
|
||||
任务主记录:PR #67 https://git-panel.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/67(merge 816b40e8f7);状态:已完成(回填);owner:weichen
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= ffda6d33eabb23c9be5bac221529367d771c5f7b
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-cross-session-reading(worktree);分支:feature/cross-session-reading
|
||||
- 授权与交付终点:实施授权(用户已批准计划并选择"提案+全量实现")。终点:documents 提案、core/backend/frontend 实现 PR 全部合入,Dev 仓 gitlink 钉入并 `make test` 组合验证通过,任务卡闭合。未授权:改写历史、分支保护变更、删除归档引用、发布版本(双钥匙)。
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
目标:同项目会话间按需读取对话记录——分层权限(项目开关 `crossSession.read` 默认关 + 会话出站 `allowCrossRead` 默认 true / 入站 `crossPrivate` 默认 false)+ 两个内置工具(`list_conversations`/`read_conversation`,落地设计 4.8 规划的"会话历史检索")+ fail-closed 门禁(runmgr toolCtx 内逐条校验)+ UI(项目设置面板首个项目级设置 UI、会话两开关)。受影响:modules/documents(提案)、modules/core(Conversation 契约+TS 镜像+golden)、modules/backend(settings schema/迁移 v11/store/PATCH/工具+门禁)、modules/frontend(api/contracts/项目设置/会话开关)。
|
||||
非目标:项目关时的 per-session opt-in;跨项目读取;自动注入其他会话摘要(远期可选档);squad 中间工作区暴露;artifacts/知识可见性变更(本就项目共享)。
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||
|---|---|---|---|
|
||||
| 启动 | ffda6d33eabb23c9be5bac221529367d771c5f7b | ffda6d33eabb23c9be5bac221529367d771c5f7b | 2026-09-30T14:55:34Z |
|
||||
| 合入前(task-sync 并入上游 ca848883;最终 make test 于合并后头全绿) | ca8488834529f154b30dda5a96d9ea8896f1782c | 见下行 task-sync 检查点 | 2026-09-30T15:35:00Z |
|
||||
|
||||
## 结果与验证
|
||||
|
||||
- 结果:跨会话读取全链路交付。子仓 PR 全部合入:Documents #21(提案 bf0988b)、Core #6(Conversation 契约字段 fd44179)、Backend #18(settings crossSession.read + 迁移 v11 + PATCH + list/read 工具 + runmgr fail-closed 门禁 cb7f79d)、Frontend #16(项目设置面板 + 会话开关 9c87953)、UI #15(contracts 镜像同步 c756479,make contracts 机制联动)。Dev 仓仅 gitlink 钉入。
|
||||
- 验证:① backend `go test ./...` 全绿,含 runmgr/crossread_test.go 门禁矩阵(项目开关×出站×私有×跨项目×跨租户×自读×归档×limit 钳制)与 store 迁移/标记持久化测试;② core `go test ./...` golden 一致;③ frontend `npm run build` + `npm test` 15/15;④ Dev `make test` 组合验证在钉入树(五子仓新 gitlink)两轮全绿(core/backend/frontend/ui/agentcmd 五套件);⑤ `make task-sync` 合入前节点通过。
|
||||
- 影响与剩余项:默认关闭,升级无行为变化。剩余(提案非目标):项目关时的 per-session opt-in、自动注入摘要档(远期)、squad 中间工作区暴露(非目标)。
|
||||
| 同步前验收 | ca8488834529f154b30dda5a96d9ea8896f1782c | e6c5cd99df36b8bfd549cacfa7bcb4a9b0f2aa2e | 2026-09-30T15:26:30Z |
|
||||
|
||||
## 闭合记录(card-autoclose 回填)
|
||||
|
||||
- 依据:merge 816b40e8f74d27218c2ed321dc88007fd298bed3(PR #67)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
|
||||
- 合并主题:Merge pull request 'Deliver layered cross-session reading and pin the five module PRs' (#67) from feature/cross-session-reading into main
|
||||
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
|
||||
@@ -0,0 +1,64 @@
|
||||
# feature/svc-auto-update 任务卡
|
||||
|
||||
任务主记录:PR #65 https://git-panel.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/65(merge 4ae98489fa);状态:已完成(回填);owner:weichen
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= ffda6d33eabb23c9be5bac221529367d771c5f7b
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-svc-auto-update(worktree);分支:feature/svc-auto-update
|
||||
- 授权与交付终点:用户确认方案(按需 update 命令、可点名、local 源允许自动 pull)后授权实施;
|
||||
终点 = 实现合入 main 并回收工作区。仅改 Dev 仓 scripts/svc.sh / Makefile / docs/svc.md。
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
目标:新增 `svc.sh update [name...] [--check] [--all] [--no-fetch]`——
|
||||
fetch 远端 → 逐服务比较登记 source 与最新(Dev 仓 origin/main / Releases 最新版本)→
|
||||
--check 只报告;否则更新过时且运行中的服务(点名/--all 含已停止)。local 源自动 pull
|
||||
三重防护(分支==main + 树干净 + --ff-only);dev@ 源部署远端 main 最新(隔离 worktree);
|
||||
release@ 源部署 Releases 最新(sha256 校验);postgres/static --dir 不适用。复用 deploy
|
||||
全链路与持久化配置;update 事件入 history。Makefile 加 svc-update;帮助与文档同步。
|
||||
|
||||
非目标:不做常驻轮询/守护(--watch 不在本轮);不自动 pull Releases 仓以外的主检出分支;
|
||||
不处理 local 源工作树的未提交变更内容(脏树=跳过)。
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||
|---|---|---|---|
|
||||
| 启动 | ffda6d33eabb23c9be5bac221529367d771c5f7b | ffda6d33eabb23c9be5bac221529367d771c5f7b | 2026-09-30T15:02:15Z |
|
||||
|
||||
## 关键实现与修复记录
|
||||
|
||||
- 修复 main 潜伏 bug(v2 重构引入):materialize_dev_commit 改为 $() 捕获 worktree 路径后,
|
||||
git submodule update 与 make 的 stdout 混入捕获值 → 产物路径损坏(cp: File name too
|
||||
long)。dev@sha 源的真实部署自 v2 起实际不可用(此前仅 dry-run 覆盖)。修复:构建期
|
||||
stdout 全部改走 stderr,stdout 只留 worktree 路径。已实测修复后 dev@73b2802 部署成功。
|
||||
- 修复本轮新代码:cmd_update 执行循环中 `local name=... rest=... from="${rest%%|*}..."`
|
||||
同语句后项引用前项,set -u 下 unbound variable。拆分两条 local 语句。
|
||||
|
||||
## 结果与验证
|
||||
|
||||
- 结果:update 命令落地(检测表 + 分源更新 + 三重 pull 防护 + 汇总退出码);Makefile
|
||||
svc-update;--help(命令表/短帮助/lifecycle 主题)与 docs/svc.md(6.3 节/上手/配方/
|
||||
事件表/排查表)同步;RESERVED_ENVS 加 update。
|
||||
- 验证(任务工作区 runtime 内,5 个测试服务全链路,已全部清理):
|
||||
- dev@ 源完整更新链路:deploy --from dev@73b2802(真实隔离构建)→ update --check 报告
|
||||
可更新 → update devold → 隔离构建 ffda6d3 组合 → source=dev@ffda6d3、HTTP 200、
|
||||
标签 updtest 与端口 8794 保留(复用持久化 exec=)→ 构建 worktree 回收。
|
||||
- local 源防护:source 置为旧祖先提交(测试 fixture)→ 状态"可更新"→ 执行时"当前分支
|
||||
非 main——跳过自动 pull",汇总 跳过=1、exit 0、登记未动。"领先远端 main(不动作)"
|
||||
路径由 local@<feature-head> 天然覆盖(feature 分支领先 origin/main)。
|
||||
- 已停止 + 可更新:不加 --all 仅警告;--all 后更新并启动(release@0.0.9 → 0.1.0,
|
||||
sha256 校验通过)。
|
||||
- postgres / static --dir:报告"不适用"。release@0.1.0:报告"✓ 最新"。
|
||||
- --check 只读性:前后 svc.env md5 一致。点名未登记服务 exit 2。--no-fetch 跳过网络
|
||||
并在报告注明。history 记录 update begin/ok 事件。
|
||||
- 影响与剩余项:main 分支上"落后→自动 pull→重建"路径受三重防护保护、逻辑简单,留待
|
||||
真实使用首次触发验证;--watch 常驻轮询未做(用户选择按需命令);dirty-tree 跳过路径
|
||||
代码就位(同防护块),工作区(feature 分支)无法真实触发,与 pull 路径一并留待验证。
|
||||
|
||||
## 闭合记录(card-autoclose 回填)
|
||||
|
||||
- 依据:merge 4ae98489fa567cc228f38f1a8c8bc4ad41e09de4(PR #65)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
|
||||
- 合并主题:Merge pull request 'Add svc.sh update command: auto-detect repo advances and refresh services' (#65) from feature/svc-auto-update into main
|
||||
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
|
||||
@@ -0,0 +1,33 @@
|
||||
# feature/task-start-rootfix 任务卡
|
||||
|
||||
任务主记录:PR #69 https://git-panel.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/69(merge 84b6ab084e);状态:已完成(回填);owner:weichen
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= ffda6d33eabb23c9be5bac221529367d771c5f7b
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-rootfix(worktree);分支:feature/task-start-rootfix
|
||||
- 授权与交付终点:修复 cmd_start 的 worktree 落点推算并验证;终点为 PR 合入 main 后回收 worktree。
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
- 目标:`task.sh start` 的 worktree 落点从 `$PWD` 推算改为经 `git rev-parse --git-common-dir` 定位主检出,使从仓库子目录(或任务 worktree 内)运行时也落在主检出平级 `../Agent-System-Dev-wt-<slug>`;受影响入口仅 `cmd_start`。
|
||||
- 非目标:不改 worktree 布局本身(维持平级散放,布局决策已定);不改 sync/close/finish;不引入对 `.gitignore` 的变更。
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||
|---|---|---|---|
|
||||
| 启动 | ffda6d33eabb23c9be5bac221529367d771c5f7b | ffda6d33eabb23c9be5bac221529367d771c5f7b | 2026-09-30T15:22:51Z |
|
||||
| 同步前验收 | 7fab8feaf7 | aecaa52e6b | 2026-09-30T15:28:27Z |
|
||||
|
||||
## 结果与验证
|
||||
|
||||
- 结果:`cmd_start` 增设 `mainroot=$(dirname "$(cd "$(git rev-parse --git-common-dir)" && pwd)")`(与 `cmd_finish` 定位主检出同款惯用法),落点改为 `$(dirname "$mainroot")/$(basename "$mainroot")-wt-${slug}`;主检出根运行时路径与旧实现一致。
|
||||
- 验证:`bash -n` 通过(shellcheck 未安装,跳过);冒烟 A——主检出 `scripts/` 子目录运行修复版 start,worktree 落在 `/home/weichen/projects/Agent-System-Dev-wt-feature-rootfix-smoke`(修复前形态 `scripts-wt-…` 已断言不存在);冒烟 B——主检出根目录运行,落点与现有惯例一致;smoke worktree/分支已全部清理,`git worktree list` 无残留。
|
||||
- 影响与剩余项:无剩余项;pre-commit 的 Mimosa 钩子报 advisory(scanner_no_output,兼容策略放行),属环境侧扫描器无输出,非本次改动引入。
|
||||
|
||||
## 闭合记录(card-autoclose 回填)
|
||||
|
||||
- 依据:merge 84b6ab084e2f70b4501c607b1395d647e4ed3af2(PR #69)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
|
||||
- 合并主题:Merge pull request 'Fix task worktree path derivation to anchor on the main checkout' (#69) from feature/task-start-rootfix into main
|
||||
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
|
||||
@@ -0,0 +1,54 @@
|
||||
# feature/chat-order-artifact-files 任务卡
|
||||
|
||||
任务主记录:Dev PR(本卡随分支合入,PR 见 Git 远端 feature/chat-order-artifact-files → main);状态:已完成;owner:weichen
|
||||
|
||||
## 基线与授权
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= ffda6d33eabb23c9be5bac221529367d771c5f7b
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-chat-order-artifact-files(worktree);分支:feature/chat-order-artifact-files
|
||||
- 授权与交付终点:用户四项反馈的修复(消息顺序保真 / 下载通道 / 工件文件管理 / 设置界面布局),实现+验证+PR 合入 main + gitlink 推进 + 卡闭合。
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
用户反馈(2026-09-30,附用户设置界面截图):
|
||||
1. 会议纪要 docx 任务中"工具调用的位置和实际的位置不符,助手输出显示的顺序没有保持"——根因:Conversation.tsx 按 `p.process` 布尔把一条消息的 parts 二分重排(过程全前置);live 流式同病(固定模板序)且 live 期间无工件 chip。
|
||||
2. "整理好的内容,没有下载通道"——后端无 Content-Disposition/MIME 回退;chip 无下载;DocViewer 弹层套弹层。
|
||||
3. "工作区中的文件应该能浏览、显示、下载、回看"——ArtifactsPanel 仅 图标+名+kind 裸列表;收件箱结果卡 doc-ref 点不开(无 docBridge)。
|
||||
4. "用户设置界面设计有问题"——根因:SettingsShell 根挂 `.modal.ui-settings-shell`,宿主 styles.css 后加载以同特异性覆盖(column/860px)压坏左右布局;设置行未用 @ui SettingRow;保存按钮随内容滚动。
|
||||
|
||||
非目标:docx 在线预览(无新依赖原则,下载为主);新增 fs 类工具/工作区目录("工作区文件"即 artifacts);live 事件协议改动。
|
||||
|
||||
## 修复要点(四仓)
|
||||
|
||||
- modules/ui:`.modal.ui-settings-shell` 复合选择器(0,2,0)免疫加载顺序;SettingsShell 增 `actions` 固定底栏 + `.ui-settings-scroll` 滚动区;ActivityCardView/InboxList 透传 `docBridge`;Icon 增 file/image/download/trash/eye;SettingRow label/desc 放宽 ReactNode。
|
||||
- modules/backend:`artifactContent` 始终回 Content-Disposition(默认 inline,`?download=1` → attachment;RFC 5987 filename* + ASCII 兜底);`contentTypeOf` 增 Office/PDF/CSV/MD 扩展名显式表 + mime.TypeByExtension 回退。
|
||||
- modules/frontend:`messageparts.ts` 新增 `groupParts`(连续过程部件就地聚块,渲染顺序=落库顺序)+ humanSize/artifactIcon;AssistantMessage 按块序渲染;LiveState.parts 按事件到达序维护(含 artifact.created 即时上 chip);工件 chip = 图标+打开+下载;ArtifactsPanel = 搜索+kind 过滤+上传+行内 预览/下载/删除(确认);DocViewer 单层 OverlayHost(pdf iframe / csv·json 等宽 / 二进制信息卡+下载 CTA);SettingsModal 迁移 SettingRow+actions 底栏;InboxList 接 docBridge。
|
||||
- modules/documents:本卡 + 提案补记(渲染顺序=落库顺序 约定)。
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||
|---|---|---|---|
|
||||
| 启动 | ffda6d33eabb23c9be5bac221529367d771c5f7b | ffda6d33eabb23c9be5bac221529367d771c5f7b | 2026-09-30T14:54:07Z |
|
||||
| 同步前验收 | ffda6d33eabb23c9be5bac221529367d771c5f7b | 76e255342b24e34f1b344784c87f5b076c6b8557 | 2026-09-30T15:18:27Z |
|
||||
| 合入前(子仓变基至 cross-session-reading 合入后的 main 并全套重验) | ca84888… | e6fdc5b… | 2026-09-30T15:35:00Z |
|
||||
|
||||
## 结果与验证
|
||||
|
||||
- 结果(四子仓 PR 均已合入 main;Dev gitlink 推进):
|
||||
- UI https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-UI/pulls/14(merged)
|
||||
- Backend https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/19(merged)
|
||||
- Frontend https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/15(merged)
|
||||
- Documents https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/22(merged)
|
||||
- 验证:
|
||||
- `make precheck`(READY,R0=ffda6d33ea);`make task-sync`(synced,15:18:27Z)。
|
||||
- `make test`(Dev 组合,gitlink 推进后):core ok、backend 全包 ok(含 disposition/MIME 新测)、frontend vitest 20 passed、ui tsc + 37 passed、agent-command ok。
|
||||
- 头链(Playwright + 缓存 Chromium,mock 后端 + SQLite 直插交错 parts 探针消息)12/12:
|
||||
消息 DOM 序 = text → process-collapse(含 knowledge_search) → text → artifact-chip;
|
||||
设置外壳 computed flex-direction=row、侧栏/主区并排、actions 底栏含"保存设置";
|
||||
`?download=1` → attachment + RFC5987 中文名、默认 inline;工件面板 工具栏/过滤/上传/行内下载齐全。
|
||||
- 影响与剩余项:
|
||||
- docx 在线预览未做(下载为主;pdf 已内嵌预览)——如需 docx 预览需引入新依赖,另行裁定。
|
||||
- live 流式顺序为到达序投影,与顺序执行的工具调用一致;并行工具执行的顺序语义需后端先定义。
|
||||
- Mimosa 钩子在个别 commit 报 scanner_no_output(按兼容策略继续);未宣称安全结论。
|
||||
| 同步前验收 | 816b40e8f74d27218c2ed321dc88007fd298bed3 | 26230bcea061c71f71ff7c124b3a91d7a0656140 | 2026-09-30T15:27:57Z |
|
||||
@@ -42,3 +42,5 @@
|
||||
| 同步前验收 | d54bfdd8e99d5d3d9a7f5b1db65ab90c841dd7e0 | 69871136e591b2b8416660651679554824efc823 | 2026-09-30T14:11:30Z |
|
||||
| 同步前验收 | 22d14db80c31e4bcfa24411f847018f527b16a01 | 6cd8cf1d0d8c7b82cabe4ecbdf82b5cfd83e39fe | 2026-09-30T14:19:33Z |
|
||||
| 同步前验收 | 7db242792a1561b2aad7877278d42f249369c2b9 | 314de91df3755cae006f5ced777eb71d0baa92b1 | 2026-09-30T14:29:40Z |
|
||||
| 同步前验收 | ffda6d33eabb23c9be5bac221529367d771c5f7b | ac8db54ecb8ddc1e077bfec772a1665d3c2d753a | 2026-09-30T15:22:40Z |
|
||||
| 同步前验收 | 7fab8feaf7b454fda4b85fd01fb6ad179496dfcd | aecaa52e6bca27c072cd89b295a75c8a4ea744aa | 2026-09-30T15:28:27Z |
|
||||
|
||||
@@ -13,7 +13,7 @@ PLUGINS := plugins
|
||||
COMBO := core=$(shell git -C $(CORE) rev-parse --short HEAD 2>/dev/null)+backend=$(shell git -C $(BACKEND) rev-parse --short HEAD 2>/dev/null)+frontend=$(shell git -C $(FRONTEND) rev-parse --short HEAD 2>/dev/null)+ui=$(shell git -C $(UI) rev-parse --short HEAD 2>/dev/null)+agentcmd=$(shell git -C deps/agent-command rev-parse --short HEAD 2>/dev/null)+documents=$(shell git -C modules/documents rev-parse --short HEAD 2>/dev/null)
|
||||
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null)+$(COMBO)
|
||||
|
||||
.PHONY: help sync status build frontend svc svc-list svc-commits svc-history test-backend test-frontend test-ui test-core test-agentcmd dev pin clean setup precheck task-start task-sync task-close task-finish version
|
||||
.PHONY: help sync status build frontend svc svc-list svc-commits svc-history svc-update test-backend test-frontend test-ui test-core test-agentcmd dev pin clean setup precheck task-start task-sync task-close task-finish version
|
||||
|
||||
version:
|
||||
@echo "agent-system $(VERSION)"
|
||||
@@ -49,6 +49,7 @@ help:
|
||||
@echo "make svc-list 服务总览:make svc-list [ARGS='--tag core'];数据库运维:scripts/svc.sh db create|dsn|backup|backups|restore|clone|copy|ls|set"
|
||||
@echo "make svc-commits 列出可部署提交:make svc-commits SRC=dev|release [N=20]"
|
||||
@echo "make svc-history 事件历史:make svc-history [ENV] [N=20](完整文档:docs/svc.md)"
|
||||
@echo "make svc-update 自动更新过时服务:make svc-update [NAMES='dev pg1'] [ARGS='--check --all']"
|
||||
@echo "make dev 开发模式说明(前后端分离热更新)"
|
||||
@echo "make pin 推进 submodule 指针到各仓远端 main(提交前须 make test 通过)"
|
||||
@echo "make status submodule 状态"
|
||||
@@ -110,6 +111,9 @@ svc-commits:
|
||||
svc-history:
|
||||
scripts/svc.sh history $(ENV) $(N)
|
||||
|
||||
svc-update:
|
||||
scripts/svc.sh update $(NAMES) $(ARGS)
|
||||
|
||||
demo: build
|
||||
$(BIN) serve --addr 127.0.0.1:8787 --data ./data --plugins $(PLUGINS) --mock
|
||||
|
||||
|
||||
+50
-4
@@ -73,6 +73,10 @@ scripts/svc.sh history # 事件追溯
|
||||
scripts/svc.sh db backup pg1 # pg_dump -Fc,自动自检
|
||||
scripts/svc.sh db restore pg1 --file <dump> --force # 覆盖恢复需 --force
|
||||
scripts/svc.sh db clone pg1 pg1test --port 8896 # 克隆一套到新端口
|
||||
|
||||
# 仓库更新后,一条命令把服务刷到最新
|
||||
scripts/svc.sh update --check # 先看哪些服务落后
|
||||
scripts/svc.sh update # 自动更新过时且运行中的服务
|
||||
```
|
||||
|
||||
## 3. 概念与目录布局
|
||||
@@ -80,8 +84,8 @@ scripts/svc.sh db clone pg1 pg1test --port 8896 # 克隆一套到新端口
|
||||
### 3.1 服务名
|
||||
|
||||
`^[a-z][a-z0-9-]{0,15}$`(小写字母开头,可含数字与连字符,≤16 位)。保留字不可用作
|
||||
服务名:`status list add set db rm create dsn commits history deploy stop start restart
|
||||
logs help version`。
|
||||
服务名:`status list add set db rm create dsn commits history update deploy stop start
|
||||
restart logs help version`。
|
||||
|
||||
三个名字有默认端口:`dev` = `127.0.0.1:8788`,`prod` = `127.0.0.1:8787`;其余名字按
|
||||
名称哈希在 **8800–9099** 确定性派生端口,与已登记端口或正在监听的端口冲突时自动向后
|
||||
@@ -293,7 +297,42 @@ scripts/svc.sh history [name] [N] # 默认全部服务、最近 20 条;首
|
||||
合并各服务 `history.jsonl`(按时间排序),字段:时间 / 服务 / kind / 事件 / 结果 /
|
||||
来源 / pid / 详情。事件类型见 §10.2。
|
||||
|
||||
### 6.3 help
|
||||
### 6.3 update(自动检索并更新)
|
||||
|
||||
```bash
|
||||
scripts/svc.sh update [name...] [--check] [--all] [--no-fetch]
|
||||
```
|
||||
|
||||
仓库更新后把服务刷到最新:fetch 远端 → 逐服务比较登记来源与最新 → 报告并(可选)更新。
|
||||
|
||||
| 用法 | 行为 |
|
||||
|---|---|
|
||||
| `update --check` | 只输出检测表,不改任何状态 |
|
||||
| `update` | 自动更新所有"过时且**运行中**"的服务 |
|
||||
| `update dev pg1` | 点名更新(已停止的过时服务也会更新并启动) |
|
||||
| `update --all` | 范围扩大到已停止服务 |
|
||||
| `update --no-fetch` | 跳过网络 fetch,用本地已有引用比较(报告注明) |
|
||||
|
||||
检测表输出:服务 / 当前来源 / 最新 / 状态。状态含义:
|
||||
|
||||
- `✓ 最新`——登记来源与最新一致,不动作;
|
||||
- `可更新`——本地来源是远端最新的祖先,将被更新;
|
||||
- `领先远端 main(不动作)` / `与远端 main 分叉(不自动更新)`——不盲目降级或强更;
|
||||
- `不适用`——postgres(无代码版本)与 static `--dir`(外部目录)不参与。
|
||||
|
||||
各来源的更新动作(复用 deploy 全链路:停旧 → 构建/校验 → 启动 → 健康检查;持久化配置
|
||||
与标签保留;写 `update` 事件入 history):
|
||||
|
||||
| 来源 | 更新方式 |
|
||||
|---|---|
|
||||
| `local@<sha>` | 当前分支为 main 且工作树干净时:自动 `git pull --ff-only origin main` + `make sync` + 重建;**树脏或非 main 分支则跳过并警告**(绝不碰未提交现场) |
|
||||
| `dev@<sha>` | `deploy --from dev@<远端 main 最新>`(隔离 worktree 构建,不碰主检出) |
|
||||
| `release@<版本>` | `deploy --from release@<Releases 最新版本>`(sha256 校验) |
|
||||
|
||||
任一服务失败不中断其余服务;最终汇总 `成功/失败/跳过`。退出码:0 全部成功或最新;
|
||||
1 有失败;2 用法错误。
|
||||
|
||||
### 6.4 help
|
||||
|
||||
```bash
|
||||
scripts/svc.sh # 一屏速览(短帮助)
|
||||
@@ -487,6 +526,7 @@ scripts/svc.sh prod deploy --env .env.prod # 等价
|
||||
| `restore` | ok / fail | 恢复(库、文件、表数) |
|
||||
| `clone` | ok / fail | 克隆(物理/在线) |
|
||||
| `copy` | ok / fail | 搬库 |
|
||||
| `update` | begin / ok / fail | 自动更新(from → to) |
|
||||
| `rm` | ok | 注销(是否 purge) |
|
||||
|
||||
## 11. 安全与边界
|
||||
@@ -526,6 +566,7 @@ scripts/svc.sh prod deploy --env .env.prod # 等价
|
||||
| `worktree 回收失败` | 按提示手动 `git worktree remove --force runtime/.worktrees/<sha>` |
|
||||
| `子模块物化失败` | 子模块对象缺失:先 fetch;或网络问题重试 |
|
||||
| `目标库已有 N 张表——拒绝覆盖` | 确认后加 `--force`(会 drop 重建) |
|
||||
| `update 报"当前分支非 main"或"工作树不干净" | local 源服务的自动 pull 被防护跳过:先自行收尾/pull,再重跑 update;或改用 `deploy --from dev@<sha>` |
|
||||
| `list 里服务显示未运行但进程在` | 手工起的进程不满足 pidcheck 标记:脚本不会动它;纳入管理请走 svc 部署 |
|
||||
|
||||
## 14. 配方索引
|
||||
@@ -567,7 +608,12 @@ scripts/svc.sh db copy pgdev pgprod --db app --force
|
||||
# ⑨ 换端口
|
||||
scripts/svc.sh set pg1 --port 8895 --apply
|
||||
|
||||
# ⑩ 总览与追溯
|
||||
# ⑩ 仓库更新后刷新服务
|
||||
scripts/svc.sh update --check # 看哪些落后
|
||||
scripts/svc.sh update # 更新过时且运行中的(数据与配置保留)
|
||||
scripts/svc.sh update dev # 只刷新指定服务
|
||||
|
||||
# ⑪ 总览与追溯
|
||||
scripts/svc.sh list --tag test
|
||||
scripts/svc.sh history pg1 50
|
||||
```
|
||||
|
||||
+1
-1
Submodule modules/core updated: e5c9c540cd...fd441794b1
+1
-1
Submodule modules/documents updated: 2c238af241...5882448237
+1
-1
Submodule modules/ui updated: 7371f854cc...efa6c69248
+215
-3
@@ -19,6 +19,7 @@
|
||||
# scripts/svc.sh db set <name> [...] 等价于 set
|
||||
# scripts/svc.sh commits [dev|release] [N] 可部署提交列表(默认 dev,N=20)
|
||||
# scripts/svc.sh history [name] [N] 事件历史(默认全部,最近 20 条)
|
||||
# scripts/svc.sh update [name] [--check] [--all] 检测远端最新并更新过时服务
|
||||
# scripts/svc.sh help [主题] 分主题详细帮助
|
||||
#
|
||||
# ════════════════════ 部署来源(agent/static 的 deploy)════════════════════
|
||||
@@ -118,6 +119,7 @@ svc.sh —— 本机服务管理:后端(agent) / 前端(static) / 数据库(po
|
||||
scripts/svc.sh rm pg1 [--purge] 注销(--purge 连数据删除)
|
||||
scripts/svc.sh commits [dev|release] [N] 可部署提交
|
||||
scripts/svc.sh history [name] [N] 事件历史
|
||||
scripts/svc.sh update [name] [--check] 检测远端最新并更新过时服务
|
||||
|
||||
帮助:--help 完整帮助 | help [主题] 分主题(model deploy lifecycle db dbops config examples safety)
|
||||
文档:docs/svc.md
|
||||
@@ -252,6 +254,17 @@ EOF
|
||||
注销:
|
||||
scripts/svc.sh rm <name> 停止并移除登记(目录/数据/历史保留)
|
||||
scripts/svc.sh rm <name> --purge 连 runtime/<name>/ 整个目录一起删除
|
||||
|
||||
自动更新(仓库更新后一条命令刷新服务):
|
||||
scripts/svc.sh update --check 只报告:每服务 当前来源 vs 最新(fetch 后比较)
|
||||
scripts/svc.sh update 更新所有"过时且运行中"的服务
|
||||
scripts/svc.sh update dev prod 点名更新(已停止的过时服务也会更新并启动)
|
||||
scripts/svc.sh update --all 含已停止服务;--no-fetch 跳过网络
|
||||
- local 源:自动 git pull --ff-only origin main + make sync 后重建
|
||||
(仅当前分支==main 且工作树干净;否则跳过并警告,不碰未提交现场)
|
||||
- dev@sha 源:直接部署远端 main 最新提交(隔离 worktree 构建,不碰主检出)
|
||||
- release@源:部署 Releases 仓最新版本(sha256 校验)
|
||||
- postgres / static --dir 不参与更新;每次更新写 history(update 事件)
|
||||
EOF
|
||||
return 0 ;;
|
||||
db)
|
||||
@@ -444,6 +457,7 @@ CLI_LBASE=""; CLI_LKEY=""; CLI_LNAME=""; CLI_TAVILY=""
|
||||
CLI_FROM=""; CLI_PICK=""; CLI_DRYRUN=0
|
||||
CLI_KIND=""; CLI_DIR=""; CLI_PURGE=0; CLI_REVEAL=0
|
||||
CLI_APPLY=0; CLI_FORCE=0; CLI_ONLINE=0; CLI_FILE=""; CLI_OUT=""
|
||||
CLI_CHECK=0; CLI_ALL=0; CLI_NOFETCH=0
|
||||
CLI_DB_USER=""; CLI_DB_PASSWORD=""; CLI_DB_NAME=""; CLI_DB_AUTH=""
|
||||
CLI_TAGS=()
|
||||
|
||||
@@ -503,7 +517,7 @@ addr_compose() {
|
||||
}
|
||||
|
||||
# ---- 名称与端口 ----
|
||||
RESERVED_ENVS=" status list add set db rm create dsn commits history deploy stop start restart logs help version "
|
||||
RESERVED_ENVS=" status list add set db rm create dsn commits history update deploy stop start restart logs help version "
|
||||
|
||||
# valid_env NAME:服务名合法性(小写字母开头、a-z0-9-、≤16 位;保留字不可用)。
|
||||
valid_env() {
|
||||
@@ -932,12 +946,13 @@ materialize_dev_commit() {
|
||||
git -C "$ROOT" worktree add --detach "$wt" "$full" >/dev/null || return 1
|
||||
fi
|
||||
c_info "[$ENV_NAME] 物化子模块组合(git submodule update --init --recursive;缺对象时需网络)"
|
||||
git -C "$wt" submodule update --init --recursive || {
|
||||
# stdout 只留给最后的 worktree 路径(调用方 $() 捕获)——子模块/构建输出全部走 stderr。
|
||||
git -C "$wt" submodule update --init --recursive >&2 || {
|
||||
c_err "[$ENV_NAME] 子模块物化失败(对象缺失时先 git -C $ROOT fetch origin)"
|
||||
return 1
|
||||
}
|
||||
c_info "[$ENV_NAME] 构建(make $target:npm ci + 构建,需网络)"
|
||||
make -C "$wt" "$target" || return 1
|
||||
make -C "$wt" "$target" >&2 || return 1
|
||||
echo "$wt"
|
||||
}
|
||||
|
||||
@@ -2029,6 +2044,202 @@ cmd_history() {
|
||||
done
|
||||
}
|
||||
|
||||
# ---- 自动检索与更新 ----
|
||||
|
||||
# cmd_update [NAME...] [--check] [--all] [--no-fetch]:
|
||||
# fetch 远端 → 逐服务比较登记 source 与最新(Dev 仓 origin/main / Releases 最新版本)→
|
||||
# --check 只报告;否则更新"过时且运行中"的服务(点名或 --all 时含已停止)。
|
||||
# local 源的自动 pull 受三重保护:当前分支==main + 工作树干净 + --ff-only。
|
||||
cmd_update() {
|
||||
local names=() a
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--check) CLI_CHECK=1; shift ;;
|
||||
--all) CLI_ALL=1; shift ;;
|
||||
--no-fetch) CLI_NOFETCH=1; shift ;;
|
||||
--) shift; break ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
-*) c_err "update 未知参数:$1(可用:--check --all --no-fetch)"; return 2 ;;
|
||||
*) names+=("$1"); shift ;;
|
||||
esac
|
||||
done
|
||||
local targets=() d e
|
||||
if [ "${#names[@]}" -gt 0 ]; then
|
||||
for a in ${names[@]+"${names[@]}"}; do
|
||||
valid_env "$a" || { c_err "非法服务名:$a"; return 2; }
|
||||
[ -f "$RUNTIME/$a/svc.env" ] || { c_err "[$a] 未登记(scripts/svc.sh list 查看)"; return 2; }
|
||||
targets+=("$a")
|
||||
done
|
||||
else
|
||||
for d in "$RUNTIME"/*/; do
|
||||
[ -f "${d}svc.env" ] || continue
|
||||
e="$(basename "$d")"
|
||||
[ "$e" = ".worktrees" ] && continue
|
||||
valid_env "$e" || continue
|
||||
targets+=("$e")
|
||||
done
|
||||
fi
|
||||
[ "${#targets[@]}" -gt 0 ] || { c_info "暂无已登记服务(db create / deploy 会登记)"; return 0; }
|
||||
|
||||
# fetch 远端(一次性;失败不致命,退化为本地缓存引用比较)。
|
||||
local fetch_note=""
|
||||
if [ "$CLI_NOFETCH" = 1 ]; then
|
||||
fetch_note="基于本地缓存引用"
|
||||
else
|
||||
c_info "git fetch origin(检索远端更新)"
|
||||
if git -C "$ROOT" fetch origin --quiet 2>/dev/null; then
|
||||
:
|
||||
else
|
||||
fetch_note="fetch 失败,基于本地缓存引用"
|
||||
c_warn "git fetch 失败——$fetch_note"
|
||||
fi
|
||||
fi
|
||||
local latest_sha
|
||||
latest_sha="$(git -C "$ROOT" rev-parse --verify --quiet origin/main || true)"
|
||||
|
||||
# Releases 最新版本(仅当存在 release 源服务时才访问 Releases 仓)。
|
||||
local latest_rel="" need_rel=0 e_src
|
||||
for e in ${targets[@]+"${targets[@]}"}; do
|
||||
e_src="$(sed -n 's/^source=//p' "$RUNTIME/$e/svc.env" | head -1)"
|
||||
case "$e_src" in release@*) need_rel=1 ;; esac
|
||||
done
|
||||
if [ "$need_rel" = 1 ]; then
|
||||
releases_root
|
||||
if [ "$CLI_NOFETCH" != 1 ]; then
|
||||
git -C "$REL_ROOT" fetch --quiet 2>/dev/null || c_warn "Releases 仓 fetch 失败——基于本地缓存"
|
||||
fi
|
||||
local rel_head
|
||||
rel_head="$(git -C "$REL_ROOT" rev-parse --verify --quiet HEAD || true)"
|
||||
if [ -n "$rel_head" ]; then
|
||||
latest_rel="$(git -C "$REL_ROOT" ls-tree --name-only "$rel_head:versions" 2>/dev/null | sort -V | tail -1 || true)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 逐服务分析:状态判定 + 收集可更新动作。
|
||||
c_info "更新检测($fetch_note;root: $ROOT)"
|
||||
printf ' %-12s %-20s %-12s %s\n' 服务 当前来源 最新 状态
|
||||
local acts=() state to latest_disp="" updated=0 failed=0 skipped=0
|
||||
for e in ${targets[@]+"${targets[@]}"}; do
|
||||
local kind src cur st_running
|
||||
kind="$(svc_kind "$e")"
|
||||
src="$(sed -n 's/^source=//p' "$RUNTIME/$e/svc.env" | head -1)"
|
||||
to=""
|
||||
latest_disp=""
|
||||
case "$kind" in
|
||||
postgres)
|
||||
state="不适用(数据库)" ;;
|
||||
*)
|
||||
case "$src" in
|
||||
dir@*)
|
||||
state="不适用(外部目录)" ;;
|
||||
"")
|
||||
state="来源未知(重新 deploy 后可参与更新)" ;;
|
||||
local@*|dev@*)
|
||||
cur="${src##*@}"
|
||||
if [ -z "$latest_sha" ]; then
|
||||
state="远端 main 未知"; latest_disp="-"
|
||||
elif [ "${latest_sha:0:${#cur}}" = "$cur" ]; then
|
||||
state="✓ 最新"; latest_disp="$(git -C "$ROOT" rev-parse --short "$latest_sha" 2>/dev/null || echo "-")"
|
||||
elif git -C "$ROOT" merge-base --is-ancestor "$cur" "$latest_sha" 2>/dev/null; then
|
||||
to="$(git -C "$ROOT" rev-parse --short "$latest_sha" 2>/dev/null || true)"
|
||||
latest_disp="$to"
|
||||
state="可更新"
|
||||
elif git -C "$ROOT" merge-base --is-ancestor "$latest_sha" "$cur" 2>/dev/null; then
|
||||
state="领先远端 main(不动作)"; latest_disp="$(git -C "$ROOT" rev-parse --short "$latest_sha" 2>/dev/null || echo "-")"
|
||||
else
|
||||
state="与远端 main 分叉(不自动更新)"; latest_disp="-"
|
||||
fi
|
||||
;;
|
||||
release@*)
|
||||
cur="${src#release@}"
|
||||
latest_disp="${latest_rel:--}"
|
||||
if [ -z "$latest_rel" ]; then
|
||||
state="Releases 仓不可用"
|
||||
elif [ "$cur" = "$latest_rel" ]; then
|
||||
state="✓ 最新"
|
||||
else
|
||||
local ordered
|
||||
ordered="$(printf '%s\n%s\n' "$cur" "$latest_rel" | sort -V | tail -1)"
|
||||
if [ "$ordered" = "$latest_rel" ]; then
|
||||
state="可更新"; to="$latest_rel"
|
||||
else
|
||||
state="领先 Releases(不动作)"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
state="来源未知(重新 deploy 后可参与更新)" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
printf ' %-12s %-20s %-12s %s\n' "$e" "${src:--}" "$latest_disp" "$state"
|
||||
if [ "$state" = "可更新" ]; then
|
||||
st_running="$(svc_pid_state "$e")"
|
||||
if [ "${st_running%% *}" = alive ] || [ "$CLI_ALL" = 1 ] || [ "${#names[@]}" -gt 0 ]; then
|
||||
acts+=("$e|$src|$to")
|
||||
else
|
||||
c_warn "[$e] 已停止且可更新——加 --all 或点名以更新(更新会启动服务)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$CLI_CHECK" = 1 ]; then
|
||||
c_info "--check:仅报告,未做任何变更"
|
||||
return 0
|
||||
fi
|
||||
[ ${#acts[@]} -gt 0 ] || { c_ok "无需更新(全部最新或不适用)"; return 0; }
|
||||
|
||||
# 执行更新:逐服务走 deploy 全链路(复用持久化配置与标签)。
|
||||
for a in ${acts[@]+"${acts[@]}"}; do
|
||||
local name="${a%%|*}" rest="${a#*|}"
|
||||
local from="${rest%%|*}" tov="${rest#*|}"
|
||||
local deploy_from=""
|
||||
env_config "$name"
|
||||
case "$from" in
|
||||
local@*)
|
||||
local branch dirty
|
||||
branch="$(git -C "$ROOT" rev-parse --abbrev-ref HEAD)"
|
||||
if [ "$branch" != "main" ]; then
|
||||
c_warn "[$name] 当前分支 $branch 非 main——跳过自动 pull(手动更新后重跑 update)"
|
||||
skipped=$((skipped + 1)); continue
|
||||
fi
|
||||
dirty="$(git -C "$ROOT" status --porcelain | grep -v '^.. \.zcode/' || true)"
|
||||
if [ -n "$dirty" ]; then
|
||||
c_warn "[$name] 主检出工作树不干净——跳过(不碰未提交现场)"
|
||||
skipped=$((skipped + 1)); continue
|
||||
fi
|
||||
c_info "[$name] git pull --ff-only origin main + make sync"
|
||||
if ! git -C "$ROOT" pull --ff-only origin main >/dev/null 2>&1; then
|
||||
c_err "[$name] 自动 pull 失败(可能本地 main 与远端分叉)——跳过,请手动处理"
|
||||
hist_event update fail "$(read_pid)" "pull 失败(from=$from)"
|
||||
failed=$((failed + 1)); continue
|
||||
fi
|
||||
if ! make -C "$ROOT" sync >/dev/null 2>&1; then
|
||||
c_warn "[$name] make sync 失败——继续构建(若子模块缺失构建会失败)"
|
||||
fi
|
||||
deploy_from="local"
|
||||
;;
|
||||
dev@*) deploy_from="dev@$tov" ;;
|
||||
release@*) deploy_from="release@$tov" ;;
|
||||
esac
|
||||
c_info "[$name] 更新:$from → $tov($deploy_from)"
|
||||
hist_event update begin "$(read_pid)" "from=$from to=$tov"
|
||||
CLI_FROM="$deploy_from"
|
||||
if agent_do_deploy; then
|
||||
hist_event update ok "$(read_pid)" "from=$from to=$tov"
|
||||
c_ok "[$name] 已更新:$from → $tov"
|
||||
updated=$((updated + 1))
|
||||
else
|
||||
hist_event update fail "$(read_pid)" "from=$from to=$tov(部署失败)"
|
||||
c_err "[$name] 更新失败($from → $tov),其余服务继续"
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
CLI_FROM=""
|
||||
done
|
||||
c_info "更新汇总:成功 $updated / 失败 $failed / 跳过 $skipped / 其余最新或不适用"
|
||||
[ "$failed" -eq 0 ] && return 0 || return 1
|
||||
}
|
||||
|
||||
# ---- main ----
|
||||
|
||||
main() {
|
||||
@@ -2069,6 +2280,7 @@ main() {
|
||||
rm) shift; cmd_rm "$@"; exit 0 ;;
|
||||
commits) shift; cmd_commits "$@"; exit 0 ;;
|
||||
history) shift; cmd_history "$@"; exit 0 ;;
|
||||
update) shift; cmd_update "$@" || exit $?; exit 0 ;;
|
||||
esac
|
||||
ENV_NAME="$1"; shift
|
||||
# 动作词可省略(省略 = deploy);flags 可直接跟随服务名。
|
||||
|
||||
+5
-2
@@ -63,10 +63,13 @@ cmd_start() {
|
||||
[ "$(git status --porcelain | { grep -v '^.. \.zcode/' || true; } | wc -l)" -eq 0 ] || die "dirty tree — resolve first (precheck verdict BUSY)"
|
||||
[ "$(git submodule status --recursive 2>/dev/null | { grep -cE '^\+|^U' || true; })" -eq 0 ] || die "submodule drift/conflict — resolve first (precheck verdict BUSY)"
|
||||
git merge-base --is-ancestor "origin/${TARGET_BRANCH}" HEAD || die "local ${TARGET_BRANCH} behind origin — pull --ff-only first"
|
||||
local rmain slug wt
|
||||
local rmain slug wt mainroot
|
||||
rmain=$(git rev-parse "origin/${TARGET_BRANCH}")
|
||||
slug=$(echo "$name" | tr '/' '-')
|
||||
wt="$(dirname "$(pwd)")/$(basename "$(pwd)")-wt-${slug}"
|
||||
# 落点须为主检出的平级目录:$PWD 推算在子目录(或任务 worktree 内)运行时会算错,
|
||||
# 改用 git-common-dir 的父目录定位主检出(与 cmd_finish 同款惯用法)。
|
||||
mainroot=$(dirname "$(cd "$(git rev-parse --git-common-dir)" && pwd)")
|
||||
wt="$(dirname "$mainroot")/$(basename "$mainroot")-wt-${slug}"
|
||||
[ -e "$wt" ] && die "worktree path exists: $wt"
|
||||
git worktree add -q "$wt" -b "$name" "$rmain"
|
||||
(cd "$wt" && git submodule update --init --recursive >/dev/null 2>&1 || echo "[warn] submodule init incomplete in worktree")
|
||||
|
||||
Reference in New Issue
Block a user