feat(mcp): enter_project becomes a small primer: goal, recent work, open work, vocabulary (#4045)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 46s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m44s
CI & Build / Build & push image (push) Successful in 23s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 46s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m44s
CI & Build / Build & push image (push) Successful in 23s
The handshake carried the whole project record, every milestone's plan, full rule text, the notes most recently edited and ~9k of design guidance. For project 2 that was ~222k characters, past what an MCP client accepts as a tool result. Each category was walked through with the operator and sized to what a session needs on arrival; each names the call that has the rest. - project: id, title, status and the full goal (session start's "full goal" pointer still lands here). get_project keeps the whole record. - milestone_summary: the 5 most recently touched milestones, any status, most recent first, without plans. Summaries gain last_touched_at: the later of the milestone's own edit and its newest step update, from the query that already counts steps. milestone_summary_omitted counts the rest and points to list_milestones. get_project and list_milestones list every milestone, also without plans. - open_tasks: the 10 most recently touched open tasks, with or without a milestone, each naming its milestone. list_notes gains sort="touched" (the later of updated_at and the newest work-log), because a log doesn't bump updated_at. - recent_notes: dropped. Retrieval surfaces notes by relevance, and get_recent covers recency. - systems: id and name. - design_system: summary plus guidance_call. get_design_system gains resolved_guidance, the chain-merged prose; its own guidance field is only the departures, so session start's old pointer to it led to a fragment. The session start pointer and using-scribe's "Building UI" section now name resolved_guidance. - rules: rules_payload(brief=True) gives project_rules as id and title plus subscribed_rulebooks, and records only what it shows. Retrieval delivers rules in full and ignores subscriptions (#4052). Other callers unchanged. - pattern_coverage, inception and systems_bootstrap: unchanged. Clients: the plugin's using-scribe skill, the compaction notice and session start are updated here; the REST project summary only gains last_touched_at. Plugin version minted. Tests: a size ceiling on the handshake for a large project; milestone and task selection and naming; brief rules; resolved_guidance; the session start pointer; and a real-Postgres test that a work-log touches its task and a step update touches its milestone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
This commit is contained in:
@@ -197,3 +197,25 @@ async def test_update_token_leaves_supersedes_alone_when_omitted():
|
||||
from scribe.mcp.tools.design_systems import update_design_token
|
||||
await update_design_token(token_id=9, purpose="text on action surfaces")
|
||||
assert "supersedes" not in svc.update_token.await_args.kwargs
|
||||
|
||||
|
||||
# --- get: the guidance a UI session builds from -----------------------------
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_design_system_carries_the_chain_merged_guidance():
|
||||
"""enter_project carries only a summary and points here (#4045). The
|
||||
system's own `guidance` field is only its departures; a session building
|
||||
UI needs the house style too, so the merged form rides alongside."""
|
||||
from scribe.mcp.tools.design_systems import get_design_system
|
||||
|
||||
merged = [{"design_system_id": 1, "title": "House", "guidance": "house style"},
|
||||
{"design_system_id": 2, "title": "App", "guidance": "departures"}]
|
||||
with patch("scribe.mcp.tools.design_systems.ds_svc.get_design_system",
|
||||
AsyncMock(return_value=_fake_design_system())), \
|
||||
patch("scribe.mcp.tools.design_systems.ds_svc.list_tokens",
|
||||
AsyncMock(return_value=[])), \
|
||||
patch("scribe.mcp.tools.design_systems.ds_svc.design_context",
|
||||
AsyncMock(return_value={"guidance": merged})):
|
||||
out = await get_design_system(2)
|
||||
|
||||
assert out["resolved_guidance"] == merged
|
||||
|
||||
Reference in New Issue
Block a user