huskies: merge 1038

This commit is contained in:
dave
2026-05-14 17:00:33 +00:00
parent 4553df5b21
commit 1f9f34ab58
13 changed files with 940 additions and 2 deletions
+4 -1
View File
@@ -108,10 +108,13 @@ mod tests {
assert!(names.contains(&"unfreeze_story"));
assert!(names.contains(&"find_orphaned_items"));
assert!(names.contains(&"recover_half_written_items"));
assert!(names.contains(&"schedule_event_trigger"));
assert!(names.contains(&"list_event_triggers"));
assert!(names.contains(&"cancel_event_trigger"));
assert!(names.contains(&"schedule_timer"));
assert!(names.contains(&"list_timers"));
assert!(names.contains(&"cancel_timer"));
assert_eq!(tools.len(), 79);
assert_eq!(tools.len(), 82);
}
#[test]
@@ -349,6 +349,64 @@ pub(super) fn system_tools() -> Vec<Value> {
"properties": {}
}
}),
json!({
"name": "schedule_event_trigger",
"description": "Register an event-based pipeline trigger that fires when a TransitionFired event matches the given predicate. Persists across server restarts. Returns the trigger id.",
"inputSchema": {
"type": "object",
"properties": {
"predicate": {
"type": "object",
"description": "Conditions that must all match for the trigger to fire. Omit a field to match any value (wildcard).",
"properties": {
"story_id": { "type": "string", "description": "Match only transitions for this story id (e.g. '42_my_feature')." },
"from_stage": { "type": "string", "description": "Match only when the stage before the transition equals this label (e.g. 'Merge', 'Coding')." },
"to_stage": { "type": "string", "description": "Match only when the stage after the transition equals this label (e.g. 'Done', 'MergeFailure')." },
"event_kind": { "type": "string", "description": "Match only when the PipelineEvent kind equals this label (e.g. 'MergeFailed', 'Block', 'MergeSucceeded')." }
}
},
"action": {
"type": "object",
"description": "What to do when the trigger fires.",
"properties": {
"type": { "type": "string", "enum": ["mcp", "prompt"], "description": "\"mcp\": call an MCP tool (no LLM). \"prompt\": spawn a focused agent with the text as its task." },
"method": { "type": "string", "description": "For type=mcp: the MCP tool name to call (e.g. 'get_pipeline_status')." },
"args": { "type": "object", "description": "For type=mcp: arguments to pass to the tool." },
"text": { "type": "string", "description": "For type=prompt: the task text for the spawned agent." }
},
"required": ["type"]
},
"mode": {
"type": "string",
"enum": ["once", "persistent"],
"description": "\"once\" (default): remove the trigger after it fires once. \"persistent\": keep it active until cancel_event_trigger is called."
}
},
"required": ["predicate", "action"]
}
}),
json!({
"name": "list_event_triggers",
"description": "Return all currently registered event triggers with their ids, predicates, actions, and fire modes.",
"inputSchema": {
"type": "object",
"properties": {}
}
}),
json!({
"name": "cancel_event_trigger",
"description": "Cancel and remove a registered event trigger by its id.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The trigger id returned by schedule_event_trigger."
}
},
"required": ["id"]
}
}),
json!({
"name": "find_orphaned_items",
"description": "Find half-written (orphaned) pipeline items: story IDs that exist in the content store but have no live CRDT entry. These are invisible to all normal read paths (list_refactors, get_pipeline_status, etc.) and result from the bug 1001 split-brain race. Returns a list of orphaned IDs with their names and tombstone status. Use recover_half_written_items to fix them.",