Add create-workstream: MCP tool, CLI commands, dashboard hint

MCP server: add create_workstream(topic_id, title, slug?, owner?,
  description?, due_date?) — auto-generates slug from title if omitted;
  emits workstream_created progress event. Now 12 tools total.

CLI: add two new subcommands —
  custodian create-workstream --domain DOMAIN --title TITLE [--slug] [--owner] [--description]
  custodian create-task --workstream ID_OR_SLUG --title TITLE [--priority] [--assignee]
  create-task accepts workstream UUID or slug (resolves via API).

Dashboard: hint box below "Open Workstreams by Domain" chart listing
  registered domains that have zero workstreams, with the exact
  custodian create-workstream command to run.

TOOLS.md: updated tool count (11 → 12) and added create_workstream row.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-24 23:35:54 +01:00
parent 34b1114a01
commit ebe7369249
4 changed files with 173 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
# State Hub MCP — Tool Reference Card
Quick reference for all 11 tools and 5 resources. Read this instead of `server.py`.
Quick reference for all 12 tools and 5 resources. Read this instead of `server.py`.
## Query Tools (read-only)
@@ -16,6 +16,7 @@ Quick reference for all 11 tools and 5 resources. Read this instead of `server.p
| Tool | Key Args | Notes |
|------|----------|-------|
| `create_workstream(topic_id, title, ...)` | `slug?` (auto-generated); `owner?`; `description?`; `due_date?` | Creates workstream under a topic. Use `get_state_summary()` to find topic IDs. |
| `create_task(workstream_id, title, ...)` | `priority`: low/medium/high/critical; `assignee?`; `due_date?` | Creates task under a workstream. |
| `update_task_status(task_id, status, ...)` | `status`: todo/in_progress/blocked/done/cancelled; `blocking_reason` required when blocked | |
| `record_decision(title, ...)` | `decision_type`: made/pending; `topic_id?`; `workstream_id?`; `deadline?` | Financial/legal + pending → auto-escalated per constitution §4. At least one of topic_id/workstream_id required. |
@@ -40,8 +41,11 @@ Quick reference for all 11 tools and 5 resources. Read this instead of `server.p
## Common Patterns
```python
# New workstream (via API — no MCP tool yet):
# POST /workstreams/ {"topic_id": "...", "slug": "...", "title": "...", "status": "active", "owner": "..."}
# New workstream:
create_workstream(topic_id="<uuid>", title="My Workstream", owner="me")
# New task:
create_task(workstream_id="<uuid>", title="Do the thing", priority="high")
# Session start ritual:
get_state_summary()

View File

@@ -7,6 +7,7 @@ from __future__ import annotations
import json
import os
import re
import sys
from datetime import datetime
from typing import Any
@@ -156,6 +157,47 @@ def get_recent_progress(limit: int = 20, since: str | None = None) -> str:
# Mutate tools
# ---------------------------------------------------------------------------
@mcp.tool()
def create_workstream(
topic_id: str,
title: str,
slug: str | None = None,
description: str | None = None,
owner: str | None = None,
due_date: str | None = None,
) -> str:
"""Create a new workstream under a topic and emit a progress_event.
Args:
topic_id: UUID of the parent topic
title: workstream title
slug: URL-friendly identifier (auto-generated from title if omitted)
description: optional longer description
owner: optional owner name
due_date: optional ISO date string (YYYY-MM-DD)
"""
if not slug:
slug = re.sub(r"[^a-z0-9]+", "-", title.lower()).strip("-")
ws = _post("/workstreams", {
"topic_id": topic_id,
"title": title,
"slug": slug,
"description": description,
"owner": owner,
"due_date": due_date,
"status": "active",
})
_post("/progress", {
"topic_id": topic_id,
"workstream_id": ws["id"],
"event_type": "workstream_created",
"summary": f"Workstream created: {title}",
"author": "custodian",
"detail": {"owner": owner, "slug": slug},
})
return json.dumps(ws, indent=2)
@mcp.tool()
def create_task(
workstream_id: str,