Merge branch 'mcp-workflow-guidance' into develop
Combines RFC 0011 (MCP Workflow Guidance) with RFC 0013 (Git Forge Integration). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
commit
d3b0ee59c2
2 changed files with 30 additions and 149 deletions
|
|
@ -187,13 +187,13 @@ impl ProjectState {
|
|||
|
||||
if !stalled.is_empty() {
|
||||
return format!(
|
||||
"'{}' might be stalled - it's in-progress but has no worktree",
|
||||
"'{}' might be stalled - it's in-progress but has no worktree. Use blue_worktree_create to fix.",
|
||||
stalled[0].title
|
||||
);
|
||||
}
|
||||
|
||||
if !ready.is_empty() {
|
||||
return format!("'{}' is ready to implement. Want to start?", ready[0].title);
|
||||
return format!("'{}' is ready to implement. Use blue_worktree_create to begin.", ready[0].title);
|
||||
}
|
||||
|
||||
if !active.is_empty() {
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ impl BlueServer {
|
|||
},
|
||||
{
|
||||
"name": "blue_rfc_update_status",
|
||||
"description": "Update an RFC's status. WORKFLOW: Set to 'accepted' when RFC is approved, then use blue_worktree_create to start implementation. Status flow: draft -> accepted -> in-progress -> implemented.",
|
||||
"description": "Update an RFC's status (draft -> accepted -> in-progress -> implemented).",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -481,7 +481,7 @@ impl BlueServer {
|
|||
},
|
||||
{
|
||||
"name": "blue_worktree_create",
|
||||
"description": "Create an isolated git worktree for RFC implementation. WORKFLOW: Use this after an RFC is accepted (status='accepted'), before starting implementation. Creates a feature branch and isolated working directory. After implementation, use blue_rfc_complete then blue_pr_create.",
|
||||
"description": "Create an isolated git worktree for RFC implementation. Use after an RFC is accepted, before starting work. Creates a feature branch and isolated directory.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -534,7 +534,7 @@ impl BlueServer {
|
|||
},
|
||||
{
|
||||
"name": "blue_pr_create",
|
||||
"description": "Create a PR with enforced base branch (develop, not main). WORKFLOW: Use after blue_rfc_complete to submit implementation for review. After PR is merged, use blue_worktree_cleanup to finalize. If rfc is provided, title is formatted as 'RFC NNNN: Title Case Name'.",
|
||||
"description": "Create a PR with enforced base branch (develop, not main). Use after implementation is complete and blue_rfc_complete succeeds. If rfc is provided, title is formatted as 'RFC NNNN: Title Case Name'.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -1010,7 +1010,7 @@ impl BlueServer {
|
|||
},
|
||||
{
|
||||
"name": "blue_rfc_complete",
|
||||
"description": "Mark RFC as implemented based on plan progress. WORKFLOW: Use after completing core implementation work in the worktree. Requires at least 70% task completion. After this, use blue_pr_create to submit for review.",
|
||||
"description": "Mark RFC as implemented based on plan progress. Use after completing tasks in the worktree. Requires at least 70% completion. Follow with blue_pr_create.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -1417,53 +1417,6 @@ impl BlueServer {
|
|||
"required": ["title"]
|
||||
}
|
||||
},
|
||||
// RFC 0012: Alignment Dialogue Orchestration
|
||||
{
|
||||
"name": "blue_alignment_play",
|
||||
"description": "Run a multi-expert alignment dialogue to deliberate on a topic until convergence",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"topic": {
|
||||
"type": "string",
|
||||
"description": "The topic to deliberate on"
|
||||
},
|
||||
"constraint": {
|
||||
"type": "string",
|
||||
"description": "Key constraint or boundary for the discussion"
|
||||
},
|
||||
"expert_count": {
|
||||
"type": "integer",
|
||||
"default": 12,
|
||||
"description": "Number of experts in the panel"
|
||||
},
|
||||
"convergence": {
|
||||
"type": "number",
|
||||
"default": 0.95,
|
||||
"description": "Target convergence threshold (0.0-1.0)"
|
||||
},
|
||||
"max_rounds": {
|
||||
"type": "integer",
|
||||
"default": 12,
|
||||
"description": "Maximum rounds before stopping"
|
||||
},
|
||||
"rfc_title": {
|
||||
"type": "string",
|
||||
"description": "RFC to link the dialogue to"
|
||||
},
|
||||
"template": {
|
||||
"type": "string",
|
||||
"enum": ["infrastructure", "product", "ml", "governance", "general"],
|
||||
"description": "Expert panel template"
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
"description": "Ollama model to use (default: qwen2.5:7b)"
|
||||
}
|
||||
},
|
||||
"required": ["topic"]
|
||||
}
|
||||
},
|
||||
// Phase 8: Playwright verification
|
||||
{
|
||||
"name": "blue_playwright_verify",
|
||||
|
|
@ -2187,8 +2140,6 @@ impl BlueServer {
|
|||
"blue_dialogue_get" => self.handle_dialogue_get(&call.arguments),
|
||||
"blue_dialogue_list" => self.handle_dialogue_list(&call.arguments),
|
||||
"blue_dialogue_save" => self.handle_dialogue_save(&call.arguments),
|
||||
// RFC 0012: Alignment Dialogue Orchestration
|
||||
"blue_alignment_play" => self.handle_alignment_play(&call.arguments),
|
||||
// Phase 8: Playwright handler
|
||||
"blue_playwright_verify" => self.handle_playwright_verify(&call.arguments),
|
||||
// Phase 9: Post-mortem handlers
|
||||
|
|
@ -2273,92 +2224,41 @@ impl BlueServer {
|
|||
Ok(state) => {
|
||||
let summary = state.status_summary();
|
||||
|
||||
// Build recommendations with MCP tool syntax (RFC 0011)
|
||||
let (recommendations, next_action) = if !summary.stalled.is_empty() {
|
||||
let title = &summary.stalled[0].title;
|
||||
(
|
||||
vec![format!(
|
||||
"'{}' is in-progress but has no worktree. Use blue_worktree_create with title='{}' to work in isolation.",
|
||||
title, title
|
||||
)],
|
||||
Some(json!({
|
||||
"tool": "blue_worktree_create",
|
||||
"args": { "title": title },
|
||||
"hint": "Create worktree to continue work in isolation"
|
||||
}))
|
||||
)
|
||||
let recommendations = if !summary.stalled.is_empty() {
|
||||
vec![format!(
|
||||
"'{}' might be stalled. Check if work is still in progress.",
|
||||
summary.stalled[0].title
|
||||
)]
|
||||
} else if !summary.ready.is_empty() {
|
||||
let title = &summary.ready[0].title;
|
||||
(
|
||||
vec![format!(
|
||||
"'{}' is accepted and ready. Use blue_worktree_create with title='{}' to start implementation.",
|
||||
title, title
|
||||
)],
|
||||
Some(json!({
|
||||
"tool": "blue_worktree_create",
|
||||
"args": { "title": title },
|
||||
"hint": "Create worktree to start implementation"
|
||||
}))
|
||||
)
|
||||
vec![format!(
|
||||
"'{}' is ready to implement. Use blue_worktree_create with title='{}' to start.",
|
||||
summary.ready[0].title, summary.ready[0].title
|
||||
)]
|
||||
} else if !summary.drafts.is_empty() {
|
||||
let title = &summary.drafts[0].title;
|
||||
(
|
||||
vec![format!(
|
||||
"'{}' is in draft. Use blue_rfc_update_status with title='{}' and status='accepted' when ready.",
|
||||
title, title
|
||||
)],
|
||||
Some(json!({
|
||||
"tool": "blue_rfc_update_status",
|
||||
"args": { "title": title, "status": "accepted" },
|
||||
"hint": "Accept the RFC to proceed with implementation"
|
||||
}))
|
||||
)
|
||||
vec![format!(
|
||||
"'{}' is in draft. Review and accept it when ready.",
|
||||
summary.drafts[0].title
|
||||
)]
|
||||
} else if !summary.active.is_empty() {
|
||||
let title = &summary.active[0].title;
|
||||
(
|
||||
vec![format!(
|
||||
"{} item(s) in progress. Continue work on '{}', then use blue_rfc_complete when done.",
|
||||
summary.active.len(), title
|
||||
)],
|
||||
Some(json!({
|
||||
"tool": "blue_rfc_complete",
|
||||
"args": { "title": title },
|
||||
"hint": "Mark as implemented when core work is done"
|
||||
}))
|
||||
)
|
||||
vec![format!(
|
||||
"{} item(s) in progress. Keep at it.",
|
||||
summary.active.len()
|
||||
)]
|
||||
} else {
|
||||
(
|
||||
vec!["Nothing in flight. Use blue_rfc_create to start something new.".to_string()],
|
||||
Some(json!({
|
||||
"tool": "blue_rfc_create",
|
||||
"args": {},
|
||||
"hint": "Create a new RFC to plan your next feature"
|
||||
}))
|
||||
)
|
||||
vec!["Nothing pressing. Good time to plan something new.".to_string()]
|
||||
};
|
||||
|
||||
let mut response = json!({
|
||||
Ok(json!({
|
||||
"recommendations": recommendations,
|
||||
"hint": summary.hint
|
||||
});
|
||||
|
||||
if let Some(action) = next_action {
|
||||
response["next_action"] = action;
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
}))
|
||||
}
|
||||
Err(_) => {
|
||||
Ok(json!({
|
||||
"recommendations": [
|
||||
"Blue not initialized here. Use blue_guide to get started."
|
||||
"Run 'blue init' to set up this project first."
|
||||
],
|
||||
"hint": "Can't find Blue here.",
|
||||
"next_action": {
|
||||
"tool": "blue_guide",
|
||||
"args": { "action": "start" },
|
||||
"hint": "Start the interactive guide"
|
||||
}
|
||||
"hint": "Can't find Blue here."
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
@ -2509,10 +2409,10 @@ impl BlueServer {
|
|||
let doc = state.store.find_document(DocType::Rfc, title)
|
||||
.map_err(|e| ServerError::StateLoadFailed(e.to_string()))?;
|
||||
|
||||
// Check for worktree when going to in-progress
|
||||
// Check for worktree if going to in-progress (RFC 0011)
|
||||
let has_worktree = state.has_worktree(title);
|
||||
let worktree_warning = if status == "in-progress" && !has_worktree {
|
||||
Some("No worktree exists for this RFC. Use blue_worktree_create to work in isolation.")
|
||||
Some("No worktree exists for this RFC. Consider using blue_worktree_create for isolated development.")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
@ -2536,18 +2436,6 @@ impl BlueServer {
|
|||
"args": { "title": title },
|
||||
"hint": "Create a worktree to start implementation"
|
||||
}))
|
||||
} else if status == "in-progress" && has_worktree {
|
||||
Some(json!({
|
||||
"tool": "blue_rfc_complete",
|
||||
"args": { "title": title },
|
||||
"hint": "Mark as implemented when core work is done"
|
||||
}))
|
||||
} else if status == "implemented" {
|
||||
Some(json!({
|
||||
"tool": "blue_pr_create",
|
||||
"args": {},
|
||||
"hint": "Create a pull request for review"
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
@ -3152,13 +3040,6 @@ impl BlueServer {
|
|||
crate::handlers::dialogue::handle_save(state, args)
|
||||
}
|
||||
|
||||
// RFC 0012: Alignment Dialogue Orchestration
|
||||
fn handle_alignment_play(&mut self, args: &Option<Value>) -> Result<Value, ServerError> {
|
||||
let args = args.as_ref().ok_or(ServerError::InvalidParams)?;
|
||||
let state = self.ensure_state_mut()?;
|
||||
crate::handlers::alignment::handle_play(state, args)
|
||||
}
|
||||
|
||||
fn handle_playwright_verify(&mut self, args: &Option<Value>) -> Result<Value, ServerError> {
|
||||
let args = args.as_ref().ok_or(ServerError::InvalidParams)?;
|
||||
crate::handlers::playwright::handle_verify(args)
|
||||
|
|
|
|||
Loading…
Reference in a new issue