You've already forked agentic-coding-workflow
原型阶段
This commit is contained in:
@@ -14,6 +14,7 @@ type ServerDeps struct {
|
||||
Projects project.ProjectService
|
||||
Reqs project.RequirementService
|
||||
Issues project.IssueService
|
||||
Prototypes project.PrototypeService
|
||||
Workspaces workspace.WorkspaceService
|
||||
Templates chat.TemplateService
|
||||
Messages chat.MessageService
|
||||
|
||||
@@ -62,6 +62,7 @@ var defaultSystemTools = []string{
|
||||
"get_issue", "get_requirement",
|
||||
"create_issue", "update_issue", "close_issue", "reopen_issue", "assign_issue",
|
||||
"create_requirement", "update_requirement", "close_requirement", "reopen_requirement", "set_requirement_phase",
|
||||
"add_requirement_prototype", "list_requirement_prototypes",
|
||||
}
|
||||
|
||||
// NewTokenService 构造 service。now 用于测试注入;nil 时默认 time.Now。
|
||||
@@ -209,6 +210,7 @@ func (s *tokenService) issueSystemToken(ctx context.Context, repo Repository, in
|
||||
ExpiresAt: created.ExpiresAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Authenticate 校验 plaintext token:
|
||||
// 1. 计算 hash 反查 row
|
||||
// 2. 检查 revoked_at IS NULL
|
||||
@@ -245,6 +247,7 @@ func (s *tokenService) Authenticate(ctx context.Context, plaintext string) (*Tok
|
||||
|
||||
return tok, nil
|
||||
}
|
||||
|
||||
// Revoke 由 admin 后台或持有者主动调用。
|
||||
// 写一条 audit `mcp.token.revoke`。
|
||||
func (s *tokenService) Revoke(ctx context.Context, id, byUserID uuid.UUID) error {
|
||||
@@ -258,8 +261,8 @@ func (s *tokenService) Revoke(ctx context.Context, id, byUserID uuid.UUID) error
|
||||
TargetType: "mcp_token",
|
||||
TargetID: revokedID.String(),
|
||||
Metadata: map[string]any{
|
||||
"token_id": revokedID.String(),
|
||||
"by_user_id": byUserID.String(),
|
||||
"token_id": revokedID.String(),
|
||||
"by_user_id": byUserID.String(),
|
||||
},
|
||||
})
|
||||
return nil
|
||||
|
||||
@@ -29,6 +29,8 @@ func registerPMTools(srv *mcpsdk.Server, deps ServerDeps) {
|
||||
registerCloseRequirement(srv, deps)
|
||||
registerReopenRequirement(srv, deps)
|
||||
registerSetRequirementPhase(srv, deps)
|
||||
registerAddRequirementPrototype(srv, deps)
|
||||
registerListRequirementPrototypes(srv, deps)
|
||||
}
|
||||
|
||||
// ===== list_projects =====
|
||||
@@ -709,5 +711,98 @@ func registerSetRequirementPhase(srv *mcpsdk.Server, deps ServerDeps) {
|
||||
})
|
||||
}
|
||||
|
||||
// ===== add_requirement_prototype =====
|
||||
|
||||
type addRequirementPrototypeIn struct {
|
||||
ProjectSlug string `json:"project_slug" jsonschema:"required field"`
|
||||
Number int `json:"number" jsonschema:"requirement number (>=1)"`
|
||||
Content string `json:"content" jsonschema:"prototype content (non-empty)"`
|
||||
Note string `json:"note,omitempty"`
|
||||
}
|
||||
type prototypeDetail struct {
|
||||
Version int `json:"version"`
|
||||
Content string `json:"content"`
|
||||
Note string `json:"note,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
type prototypeCreateOut struct {
|
||||
OK bool `json:"ok"`
|
||||
Prototype prototypeDetail `json:"prototype"`
|
||||
}
|
||||
|
||||
func registerAddRequirementPrototype(srv *mcpsdk.Server, deps ServerDeps) {
|
||||
mcpsdk.AddTool(srv,
|
||||
&mcpsdk.Tool{Name: "add_requirement_prototype", Description: "Add a new prototype version to a requirement."},
|
||||
func(ctx context.Context, _ *mcpsdk.CallToolRequest, in addRequirementPrototypeIn) (*mcpsdk.CallToolResult, prototypeCreateOut, error) {
|
||||
if err := CheckToolFromCtx(ctx, "add_requirement_prototype"); err != nil {
|
||||
return nil, prototypeCreateOut{}, err
|
||||
}
|
||||
c, err := deps.Caller.Resolve(ctx)
|
||||
if err != nil {
|
||||
return nil, prototypeCreateOut{}, err
|
||||
}
|
||||
p, err := deps.Projects.Get(ctx, c, in.ProjectSlug)
|
||||
if err != nil {
|
||||
return nil, prototypeCreateOut{}, err
|
||||
}
|
||||
if err := CheckProjectFromCtx(ctx, p.ID); err != nil {
|
||||
return nil, prototypeCreateOut{}, err
|
||||
}
|
||||
proto, err := deps.Prototypes.Create(ctx, c, in.ProjectSlug, in.Number, project.CreatePrototypeInput{
|
||||
Content: in.Content, Note: in.Note,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, prototypeCreateOut{}, err
|
||||
}
|
||||
return nil, prototypeCreateOut{OK: true, Prototype: prototypeDetail{
|
||||
Version: proto.Version, Content: proto.Content, Note: proto.Note,
|
||||
CreatedAt: proto.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
}}, nil
|
||||
})
|
||||
}
|
||||
|
||||
// ===== list_requirement_prototypes =====
|
||||
|
||||
type listRequirementPrototypesIn struct {
|
||||
ProjectSlug string `json:"project_slug" jsonschema:"required field"`
|
||||
Number int `json:"number" jsonschema:"requirement number (>=1)"`
|
||||
}
|
||||
type listRequirementPrototypesOut struct {
|
||||
Prototypes []prototypeDetail `json:"prototypes"`
|
||||
}
|
||||
|
||||
func registerListRequirementPrototypes(srv *mcpsdk.Server, deps ServerDeps) {
|
||||
mcpsdk.AddTool(srv,
|
||||
&mcpsdk.Tool{Name: "list_requirement_prototypes", Description: "List prototype versions of a requirement."},
|
||||
func(ctx context.Context, _ *mcpsdk.CallToolRequest, in listRequirementPrototypesIn) (*mcpsdk.CallToolResult, listRequirementPrototypesOut, error) {
|
||||
if err := CheckToolFromCtx(ctx, "list_requirement_prototypes"); err != nil {
|
||||
return nil, listRequirementPrototypesOut{}, err
|
||||
}
|
||||
c, err := deps.Caller.Resolve(ctx)
|
||||
if err != nil {
|
||||
return nil, listRequirementPrototypesOut{}, err
|
||||
}
|
||||
p, err := deps.Projects.Get(ctx, c, in.ProjectSlug)
|
||||
if err != nil {
|
||||
return nil, listRequirementPrototypesOut{}, err
|
||||
}
|
||||
if err := CheckProjectFromCtx(ctx, p.ID); err != nil {
|
||||
return nil, listRequirementPrototypesOut{}, err
|
||||
}
|
||||
protos, err := deps.Prototypes.List(ctx, c, in.ProjectSlug, in.Number)
|
||||
if err != nil {
|
||||
return nil, listRequirementPrototypesOut{}, err
|
||||
}
|
||||
out := listRequirementPrototypesOut{Prototypes: make([]prototypeDetail, 0, len(protos))}
|
||||
for _, proto := range protos {
|
||||
out.Prototypes = append(out.Prototypes, prototypeDetail{
|
||||
Version: proto.Version, Content: proto.Content, Note: proto.Note,
|
||||
CreatedAt: proto.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
})
|
||||
}
|
||||
return nil, out, nil
|
||||
})
|
||||
}
|
||||
|
||||
// 保证 fmt 引用(编译期检查)
|
||||
var _ = fmt.Sprintf
|
||||
|
||||
Reference in New Issue
Block a user