{
  "schemaVersion": "1.0",
  "id": "request-flow-from-handler",
  "title": "Request flow diagram from handler code",
  "slug": "request-flow-from-handler",
  "diagramFamily": "sequence",
  "goal": "Maintain a current sequence diagram of an HTTP endpoint's request flow by walking the handler's async/await chain and external integrations, then patching the persisted Zindex scene each time a relevant code path changes.",
  "inputs": [
    "Handler file path (e.g. apps/api/src/routes/checkout.ts) plus its directly-imported service modules",
    "Optional: monorepo paths to client SDK definitions for external integrations (Stripe, Twilio, etc.) so the agent emits accurate provider-side lifelines",
    "Existing Zindex scene id (stored as a repo secret)",
    "Zindex API key with scene-write scope"
  ],
  "outputs": [
    "Updated persisted scene with one lifeline per participant, one message per service interaction, and combined-fragment frames for branching paths",
    "Rendered SVG showing the canonical request flow at the current revision",
    "Revision diff highlighting added/removed lifelines, new fragments, message-type changes (sync→async, etc.)",
    "PR comment summarising the structural change and linking to the rendered SVG"
  ],
  "mcpTools": [
    "dsp_create_scene",
    "dsp_apply_ops",
    "dsp_validate_scene",
    "dsp_render_scene",
    "dsp_diff_scene"
  ],
  "httpEndpoints": [
    "POST /v1/scenes",
    "POST /v1/scenes/:id/applyOps",
    "POST /v1/scenes/:id/render",
    "GET /v1/scenes/:id/diff"
  ],
  "steps": [
    {
      "id": "create_or_fetch_scene",
      "label": "Create or fetch the persisted scene",
      "description": "On first run, create a scene with diagramFamily: \"sequence\". On subsequent runs, fetch the existing scene by id to read the current revision and elements.",
      "mcp": "dsp_create_scene",
      "http": {
        "method": "POST",
        "path": "/v1/scenes",
        "exampleResponse": "{ \"sceneId\": \"sc_checkout_flow\", \"revision\": 1 }"
      }
    },
    {
      "id": "parse_handler",
      "label": "Walk the handler's call graph",
      "description": "Parse the handler source file (TypeScript via the TS compiler API, Python via ast, Go via go/parser). Identify every awaited service call, queue publish, cache read/write, DB query, and external API request - each becomes a (caller, callee, operationName, kind) tuple. Distinguish synchronous calls (await response) from asynchronous publishes (fire-and-forget queue/topic). Branching constructs (try/catch with retry, if/else with parallel paths) become fragment metadata. Self-message candidates: handler-internal helpers that are visually meaningful (validation, response shaping).",
      "mcp": null,
      "http": null
    },
    {
      "id": "diff_against_scene",
      "label": "Diff parsed flow against the persisted scene",
      "description": "Compare parsed lifelines + messages + fragments against the current scene. New participants → createNode (sequence.lifeline / sequence.actor). New interactions → createEdge with appropriate edgeType. New branching paths → createFrame with containerType: \"fragment\" and the right operator (alt | opt | loop | par). Use stable element ids derived from service names so a renamed lifeline stays the same element.",
      "mcp": "dsp_get_scene",
      "http": {
        "method": "GET",
        "path": "/v1/scenes/${SCENE_ID}",
        "exampleResponse": "{ \"sceneId\": \"sc_checkout_flow\", \"revision\": 47, \"elements\": [\"...\"] }"
      }
    },
    {
      "id": "apply_ops",
      "label": "Apply the operation batch",
      "description": "Send the diff as one applyOps batch with errorPolicy=allOrNothing. The agent uses stable lifeline ids (service.kebab-case) so a renamed service updates the existing lifeline rather than creating a duplicate. Set a meaningful revisionMessage (e.g. \"add Redis cache lifeline; move notifications to async publish\").",
      "mcp": "dsp_apply_ops",
      "http": {
        "method": "POST",
        "path": "/v1/scenes/${SCENE_ID}/applyOps",
        "exampleResponse": "{ \"sceneId\": \"sc_checkout_flow\", \"revision\": 48, \"applied\": 6 }"
      }
    },
    {
      "id": "validate",
      "label": "Validate the updated scene",
      "description": "Resolve any LABEL_DUPLICATION_DETECTED diagnostics - sequence diagrams allow same-label messages (different timestamps), but suspicious duplicates (e.g. two replies labelled the same on the same source) are usually mis-typed. CANVAS_AUTO_EXTENDED is informational; the engine sizes the canvas as the flow grows.",
      "mcp": "dsp_validate_scene",
      "http": {
        "method": "POST",
        "path": "/v1/scenes/validate",
        "exampleResponse": "{ \"ok\": true, \"diagnostics\": [{ \"code\": \"CANVAS_AUTO_EXTENDED\", \"severity\": \"info\" }] }"
      }
    },
    {
      "id": "render",
      "label": "Render to SVG",
      "description": "Render the updated scene at the new revision. The watermark stamps scene-id + revision + date so the rendered artifact is traceable back to the persisted scene. Theme defaults to clean; pass theme: \"dark\" if your docs site uses a dark canvas.",
      "mcp": "dsp_render_scene",
      "http": {
        "method": "POST",
        "path": "/v1/scenes/${SCENE_ID}/render",
        "exampleResponse": "{ \"output\": { \"mimeType\": \"image/svg+xml\", \"content\": \"<svg ...\" } }"
      }
    },
    {
      "id": "diff",
      "label": "Diff against the previous revision",
      "description": "Get a structural summary of what changed between PREV_REVISION and the new revision: added/removed/modified lifelines and messages. Drives the PR comment.",
      "mcp": "dsp_diff_scene",
      "http": {
        "method": "GET",
        "path": "/v1/scenes/${SCENE_ID}/diff?from=${PREV_REVISION}&to=${NEW_REVISION}",
        "exampleResponse": "{ \"added\": [\"cache\", \"m_cache_get\", \"m_cache_hit\"], \"removed\": [], \"modified\": [\"m_notify\"] }"
      }
    },
    {
      "id": "comment",
      "label": "Post PR comment",
      "description": "Post a structural-diff summary as a PR comment with the rendered SVG attached as a workflow artifact. The reviewer sees what the new code does differently without reading the full code diff.",
      "mcp": null,
      "http": null
    }
  ]
}