Skip to content

Commit a54b8b3

Browse files
author
zengfr
committed
feat(I): feature completion and spec alignment
I1 CLI missing commands: - Add 'continue' (resume parked workflow via Director.ContinuePlan) - Add 'mcp' (start MCP stdio JSON-RPC server) - Add 'a2a' (start A2A HTTP server) - Add 'acp' (start ACP stdio JSON-RPC server) - Add 'memory show/capture/recall' (view and toggle project memory) - Add 'ci' (alias for govern --ci) - main.go: inject version/commit/date via goreleaser ldflags I2 ACP Server real implementation: - Replace stub Serve() with stdio JSON-RPC 2.0 - Methods: initialize, session/start, session/stop, session/list - ServeReader testable variant - Coverage: 0% -> 93.0% I3 stub driver tests: - claude: 0% -> 100% (ModelInfo, Capabilities, SendTask, AuthStatus, Pause/Resume) - dsh: 0% -> 100% (same pattern) I4 mcp coverage boost: - Add GovernDirectory subdirectory + error path tests - Add GovernFileTool nonexistent + invalid args tests - Add GovernDirectoryTool invalid args test - Add toolDefinitions content verification - Coverage: 77.9% -> 89.6% I5 docs alignment: - Update 05-快速上手部署.md command reference to match implemented CLI - Update CHANGELOG.md with all new features - ADR-0014: ACP/MCP real JSON-RPC implementation decision All 23 Go packages pass, 0 lint issues, 22 TUI tests pass.
1 parent 4667d2a commit a54b8b3

12 files changed

Lines changed: 996 additions & 19 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ codex_cov
4242
cover_codex
4343
cover_codex.out
4444
cover_all
45+
cover_latest
46+
cover_mcp
47+
cover_mcp.out

CHANGELOG.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- MCP Server real JSON-RPC stdio implementation
2222
- TUI component unit tests (ink-testing-library + vitest)
2323
- A2A DelegateParallel p95 benchmark
24+
- ACP Server real stdio JSON-RPC 2.0 (initialize, session/start, session/stop, session/list)
25+
- CLI subcommands: `continue`, `mcp`, `a2a serve`, `acp`, `memory show|capture|recall`, `ci`
26+
- claude/dsh stub driver tests (coverage 0% to 100%)
27+
- mcp coverage 77.9% to 89.6% (subdirectory + tool definition tests)
28+
- version/commit/date metadata via goreleaser ldflags
2429

2530
### Changed
26-
- golangci-lint-action v8 -> v9 (Node 20 deprecation fix)
27-
- GitHub Actions checkout@v4 -> v5, setup-go@v5 -> v6, setup-node@v4 -> v5
31+
- golangci-lint-action v8 to v9 (Node 20 deprecation fix)
32+
- GitHub Actions checkout@v4 to v5, setup-go@v5 to v6, setup-node@v4 to v5
2833

2934
## [0.1.0] - 2026-09-02
3035

3136
### Added
32-
- Go orchestration engine: router -> planner -> scheduler -> coordinator 5-layer flow
37+
- Go orchestration engine: router to planner to scheduler to coordinator 5-layer flow
3338
- Host drivers: Codex (real exec), OpenCode (real exec), Claude (stub), DSH (stub)
3439
- A2A protocol: InProcBus + RedisBus Pub/Sub
3540
- 9 team role agents with A2A reviewer registration

cmd/aicodingagentteam/main.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ import (
1212
"syscall"
1313

1414
"github.com/agentcodinglab/aicodingagentteam/internal/a2a"
15+
"github.com/agentcodinglab/aicodingagentteam/internal/acp"
16+
"github.com/agentcodinglab/aicodingagentteam/internal/agent"
1517
"github.com/agentcodinglab/aicodingagentteam/internal/audit"
1618
"github.com/agentcodinglab/aicodingagentteam/internal/config"
1719
"github.com/agentcodinglab/aicodingagentteam/internal/coordinator"
1820
"github.com/agentcodinglab/aicodingagentteam/internal/governance"
1921
"github.com/agentcodinglab/aicodingagentteam/internal/host"
2022
"github.com/agentcodinglab/aicodingagentteam/internal/knowledge"
23+
"github.com/agentcodinglab/aicodingagentteam/internal/mcp"
2124
"github.com/agentcodinglab/aicodingagentteam/internal/memory"
2225
"github.com/agentcodinglab/aicodingagentteam/internal/planner"
2326
"github.com/agentcodinglab/aicodingagentteam/internal/qualitygate"
@@ -61,6 +64,18 @@ func main() {
6164
cmdServe(ctx, cfg)
6265
case "knowledge":
6366
cmdKnowledge(ctx, os.Args[2:])
67+
case "continue":
68+
cmdContinue(ctx, cfg, os.Args[2:])
69+
case "mcp":
70+
cmdMCPServe(ctx, cfg)
71+
case "a2a":
72+
cmdA2AServe(ctx, cfg)
73+
case "acp":
74+
cmdACPServe(ctx, cfg)
75+
case "memory":
76+
cmdMemory(ctx, os.Args[2:])
77+
case "ci":
78+
cmdGovern(ctx, append([]string{"--ci"}, os.Args[2:]...))
6479
case "version":
6580
fmt.Printf("aicodingagentteam %s (commit=%s, built=%s)\n", version, commit, date)
6681
default:
@@ -332,6 +347,108 @@ var tempDir = func() string {
332347
return d
333348
}
334349

350+
func cmdContinue(ctx context.Context, cfg *config.Config, args []string) {
351+
fs := flag.NewFlagSet("continue", flag.ExitOnError)
352+
_ = fs.Parse(args)
353+
d := newDirector(cfg)
354+
resumed, msg, err := d.ContinuePlan(ctx, fs.Arg(0))
355+
if err != nil {
356+
fmt.Fprintf(os.Stderr, "error: %v\n", err)
357+
os.Exit(1)
358+
}
359+
if resumed {
360+
fmt.Printf("workflow resumed: %s\n", msg)
361+
} else {
362+
fmt.Printf("cannot continue: %s\n", msg)
363+
}
364+
}
365+
366+
func cmdMCPServe(ctx context.Context, cfg *config.Config) {
367+
govEngine := governance.NewWithConfig(".aicodingagentteam/rules.json", audit.New(".aicodingagentteam/audit"))
368+
srv := mcp.New(govEngine)
369+
fmt.Println("MCP server: stdio JSON-RPC (govern_file, govern_directory)")
370+
if err := srv.Serve(ctx); err != nil && err != context.Canceled {
371+
fmt.Fprintf(os.Stderr, "mcp server error: %v\n", err)
372+
os.Exit(1)
373+
}
374+
}
375+
376+
func cmdA2AServe(ctx context.Context, cfg *config.Config) {
377+
bus := a2a.NewBusFromEnv(audit.New(".aicodingagentteam/audit"))
378+
agent.RegisterAllReviewers(bus)
379+
d := newDirector(cfg)
380+
srv := api.NewServer(cfg.Coordinator.GRPC, cfg.Coordinator.MCP, cfg.Coordinator.ACP, cfg.Coordinator.A2A, d)
381+
fmt.Printf("A2A server: listening on :%d\n", cfg.Coordinator.A2A)
382+
if err := srv.Start(ctx); err != nil && err != context.Canceled {
383+
fmt.Fprintf(os.Stderr, "a2a server error: %v\n", err)
384+
os.Exit(1)
385+
}
386+
}
387+
388+
func cmdACPServe(ctx context.Context, cfg *config.Config) {
389+
srv := acp.New()
390+
fmt.Println("ACP server: stdio JSON-RPC (session lifecycle)")
391+
if err := srv.Serve(ctx); err != nil && err != context.Canceled {
392+
fmt.Fprintf(os.Stderr, "acp server error: %v\n", err)
393+
os.Exit(1)
394+
}
395+
}
396+
397+
func cmdMemory(ctx context.Context, args []string) {
398+
if len(args) < 1 {
399+
fmt.Println("Usage:")
400+
fmt.Println(" aicodingagentteam memory show Show all memories (facts/pitfalls/lessons)")
401+
fmt.Println(" aicodingagentteam memory capture on|off Enable/disable fact capture")
402+
fmt.Println(" aicodingagentteam memory recall on|off Enable/disable recipe recall")
403+
return
404+
}
405+
mem := memory.New(".aicodingagentteam/memory")
406+
sub := args[0]
407+
switch sub {
408+
case "show":
409+
facts, _ := mem.RecallFacts(ctx)
410+
fmt.Println("=== Facts ===")
411+
for _, f := range facts {
412+
fmt.Printf(" [%s] %s: %s\n", f.Source, f.Key, f.Value)
413+
}
414+
if len(facts) == 0 {
415+
fmt.Println(" (none)")
416+
}
417+
pitfalls, _ := mem.RecallPitfalls(ctx)
418+
fmt.Println("=== Pitfalls ===")
419+
for _, p := range pitfalls {
420+
fmt.Printf(" [%s] count=%d verified=%v: %s\n", p.ID, p.Count, p.Verified, p.Detail)
421+
}
422+
if len(pitfalls) == 0 {
423+
fmt.Println(" (none)")
424+
}
425+
lessons, _ := mem.RecallLessons(ctx)
426+
fmt.Println("=== Lessons ===")
427+
for _, l := range lessons {
428+
fmt.Printf(" [%s] verified=%v: %s\n", l.ID, l.Verified, l.Rule)
429+
}
430+
if len(lessons) == 0 {
431+
fmt.Println(" (none)")
432+
}
433+
case "capture":
434+
if len(args) < 2 {
435+
fmt.Fprintln(os.Stderr, "usage: memory capture on|off")
436+
os.Exit(1)
437+
}
438+
mem.SetCaptureOn(args[1] == "on")
439+
fmt.Printf("memory capture: %s\n", args[1])
440+
case "recall":
441+
if len(args) < 2 {
442+
fmt.Fprintln(os.Stderr, "usage: memory recall on|off")
443+
os.Exit(1)
444+
}
445+
mem.SetRecallOn(args[1] == "on")
446+
fmt.Printf("memory recall: %s\n", args[1])
447+
default:
448+
fmt.Fprintf(os.Stderr, "unknown memory subcommand: %s\n", sub)
449+
os.Exit(1)
450+
}
451+
}
335452
func printCheckDetails(details []types.CheckSummary) {
336453
for _, d := range details {
337454
if d.Status == "pass" {

docs/05-快速上手部署.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ aicodingagentteam report # 合规报告
274274
aicodingagentteam ci # CI 治理扫描
275275

276276
# 服务模式
277-
aicodingagentteam mcp serve # MCP 服务
278-
aicodingagentteam a2a serve # A2A 服务
279-
aicodingagentteam acp serve # ACP 服务
277+
aicodingagentteam mcp # MCP 服务 (stdio JSON-RPC)
278+
aicodingagentteam a2a # A2A HTTP 服务
279+
aicodingagentteam acp # ACP 服务 (stdio JSON-RPC)
280280

281281
# 知识与记忆
282282
aicodingagentteam knowledge-manage add ./docs # 添加知识库
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# ADR-0014: ACP/MCP Server 真实 JSON-RPC 实现
2+
3+
> 状态:已接受
4+
> 日期:2026-09-05
5+
> 关联规范:`docs/spec/coordinator.md`(MCP/ACP 协议)
6+
7+
## 背景
8+
9+
MCP Server 的 `Serve()` 方法和 ACP Server 的 `Serve()` 方法此前都是纯阻塞 stub:
10+
11+
```go
12+
// 旧 stub
13+
func (s *Server) Serve(ctx context.Context) error {
14+
<-ctx.Done()
15+
return ctx.Err()
16+
}
17+
```
18+
19+
外部 MCP/ACP 客户端无法通过协议与 Coordinator 交互——MCP 只能通过 Go API 调用 `GovernFile`/`GovernDirectory`,ACP 完全不可用。部署文档中承诺了 `mcp serve` / `acp serve` CLI 命令,但实现不存在。
20+
21+
## 决策
22+
23+
1. **MCP Server**:实现 stdio JSON-RPC 2.0 服务器,支持 `initialize``tools/list``tools/call`(govern_file、govern_directory)。外部 MCP 客户端可通过 stdio 与 governance 引擎交互。
24+
25+
2. **ACP Server**:实现 stdio JSON-RPC 2.0 服务器,支持 `initialize``session/start``session/stop``session/list`。外部 ACP 客户端可管理 Agent 会话生命周期。
26+
27+
3. **可测试设计**:两个 Server 都提供 `ServeReader(ctx, reader, writer)` 变体,使 JSON-RPC 逻辑可在单元测试中通过 buffer 驱动,无需真实 stdio。
28+
29+
4. **CLI 命令对齐**:新增 `mcp``acp``a2a serve``continue``memory show/capture/recall``ci` 命令,使 CLI 命令集与部署文档规格一致。
30+
31+
## 后果
32+
33+
- 正面:MCP/ACP 从 stub 升级为可用协议,外部客户端可集成。
34+
- 正面:ACP 覆盖率 0% → 93.0%,MCP 覆盖率 77.9% → 89.6%。
35+
- 正面:claude/dsh stub 驱动补齐测试,覆盖率 0% → 100%。
36+
- 正面:CLI 命令集与文档规格一致,消除文档-代码不一致债务。
37+
- 负面:MCP `Serve()` 本身仍 0% 覆盖(依赖真实 stdio),但 `ServeReader` 覆盖了所有逻辑路径。

docs/adr/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@
2222
| 0010 | 卷并发与单写者 | 2026-09-02 | 已接受 |
2323
| 0011 | config 合并默认值 + env 覆盖 | 2026-09-04 | 已接受 |
2424
| 0012 | 质量门 CheckDetails 全链透传 | 2026-09-04 | 已接受 || 0013 | RAG 知识库与记忆接入 Director | 2026-09-05 | 已接受 |
25+
| 0014 | ACP/MCP 真实 JSON-RPC 实现 | 2026-09-05 | 已接受 |
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# 实现计划:功能补齐与规格对齐(方向 I)
2+
3+
> 文件名:`docs/plan/feature-completion-and-spec-alignment.md`
4+
> 目标:消除文档与代码不一致的债务,补齐 spec/部署文档承诺但未实现的 CLI 命令和 stub
5+
6+
---
7+
8+
## I1: CLI 缺失命令补齐
9+
- 文件:`cmd/aicodingagentteam/main.go`
10+
- 新增命令:
11+
- `continue` — 继续 parked/paused 工作流(调用 `Director.ContinuePlan`
12+
- `mcp serve` — 启动 MCP JSON-RPC 服务(stdio)
13+
- `a2a serve` — 启动 A2A HTTP 服务(复用 serve 逻辑,仅暴露 A2A 端口)
14+
- `acp serve` — 启动 ACP JSON-RPC 服务(stdio)
15+
- `memory show` — 显示项目记忆(facts/pitfalls/lessons)
16+
- `ci` — 治理扫描别名(等价 `govern --ci`
17+
- 验证:各命令可执行不 panic
18+
19+
## I2: ACP Server 真实实现
20+
- 文件:`internal/acp/acp.go``internal/acp/acp_test.go`
21+
- 改动:参照 MCP 模式,实现 stdio JSON-RPC 2.0(initialize/session/start/stop)
22+
- 目标:acp 覆盖率 0% → 80%+
23+
- 验证:`go test ./internal/acp/...` 通过
24+
25+
## I3: stub 驱动基础测试
26+
- 文件:`internal/host/claude/claude_test.go``internal/host/dsh/dsh_test.go`
27+
- 补齐:TestModelInfo、TestCapabilities、TestSendTask、TestAuthStatus、TestStartDestroySession、TestPauseResume
28+
- 目标:claude/dsh 0% → 80%+
29+
- 验证:`go test ./internal/host/...` 通过
30+
31+
## I4: mcp 覆盖率补齐
32+
- 文件:`internal/mcp/mcp_test.go`
33+
- 补齐:GovernDirectory error path、toolDefinitions 内容验证
34+
- 目标:mcp 77.9% → 80%+
35+
- 验证:`go test ./internal/mcp/... -cover` ≥ 80%
36+
37+
## I5: 文档与代码对齐
38+
- 文件:`docs/05-快速上手部署.md``README.md`
39+
- 改动:命令速查表补齐新增命令,标注未实现项
40+
- 验证:文档命令与 CLI 一致
41+
42+
## 关键路径
43+
```
44+
I1 (CLI) → I2 (ACP) → I3 (stub tests) ∥ I4 (mcp tests) → I5 (docs)
45+
```

0 commit comments

Comments
 (0)