{
  "$schema": "../../oss/scenecast/schemas/scene-blueprint-v1.json",
  "version": 1,
  "id": "scn_pr_triage",
  "slug": "pr-triage",
  "name": "PR Triage",
  "icon": "checklist",
  "tint": "#10B981",
  "settings": {
    "description": "Daily triage of open PRs on a single repo. Fork it, point it at your repo, connect GitHub. Optionally pipe summaries to a Slack channel."
  },
  "inputs": {
    "repo": {
      "type": "string",
      "required": true,
      "description": "GitHub owner/repo (e.g. 'daslabhq/daslab'). The repo the agent triages each morning."
    }
  },
  "assets": [
    {
      "id": "intro",
      "type": "daslab/note",
      "name": "About PR Triage",
      "fields": {
        "content": "# PR Triage\n\nEvery weekday at **09:00 UTC**, the agent looks at open PRs on `${inputs.repo}`, writes a triage report into the **Today's Triage** note, and (if a Slack channel is connected) posts a one-message summary there.\n\nWhat the report includes for each open PR:\n\n- title, author, age in business days\n- a one-line summary of what it changes\n- a recommended action: *ship it*, *needs review*, *waiting on author*, *stale (close?)*\n- any blocking labels or failing checks\n\n## What to connect\n\n- **GitHub account** — the agent reads PRs through your token. Tap the placeholder tile to connect.\n- **Slack channel** *(optional)* — pick a channel and the triage will post there each morning. Without it, the report lives only in the **Today's Triage** note.\n\n## Try one of these prompts\n\n- *\"Re-run the triage now.\"*\n- *\"What's the oldest open PR?\"*\n- *\"Anything waiting on me specifically?\"*\n- *\"Close all stale PRs without merge conflicts.\"* (with approval)"
      },
      "layout": {
        "sortOrder": 0,
        "size": "medium"
      }
    },
    {
      "id": "today",
      "type": "daslab/note",
      "name": "Today's Triage",
      "fields": {
        "content": "_Not yet run. The first scheduled run fires next 09:00 UTC weekday, or use the **triage-now** task to run it on demand._"
      },
      "layout": {
        "sortOrder": 1,
        "size": "xlarge"
      }
    }
  ],
  "linkedAssets": [
    {
      "type": "github/repository",
      "externalId": "${inputs.repo}",
      "layout": {
        "sortOrder": 2,
        "size": "medium"
      }
    },
    {
      "slot": "github_acct",
      "accepts": "github/account",
      "layout": {
        "sortOrder": 98,
        "size": "icon"
      }
    },
    {
      "slot": "notify_channel",
      "accepts": "slack/channel",
      "layout": {
        "sortOrder": 99,
        "size": "icon"
      }
    }
  ],
  "schedules": [
    {
      "id": "weekday-triage",
      "title": "Weekday PR triage · 09:00 UTC",
      "cron": "0 9 * * 1-5",
      "prompt": "Triage open PRs on ${inputs.repo}.\n\n1. List open PRs via the GitHub tools. Skip drafts unless they've been open >5 business days.\n2. For each one, decide an action: ship-it / needs-review / waiting-on-author / stale-close. Use signals: age, last activity, failing checks, requested-reviewer state, blocking labels.\n3. Use daslab_note_write to replace the **Today's Triage** note. Start with `# <today's date YYYY-MM-DD>` then a per-PR list (title, author, age, action, one-line why). End with a summary line ('N open, M shippable, K stale').\n4. If a Slack channel is connected in this scene, post a 5-line summary of the most-urgent items there. One message, no thread spam.\n\nDo not merge, close, or approve PRs unless explicitly asked.",
      "assetIds": [
        "intro",
        "today"
      ],
      "enabled": true,
      "checks": [
        {
          "op": "lte",
          "path": "$run.cost_usd",
          "value": 0.25,
          "expose": true,
          "severity": "fail",
          "why": "Daily triage budget cap."
        }
      ]
    }
  ],
  "tasks": [
    {
      "id": "triage-now",
      "name": "Triage open PRs now",
      "prompt": "Run the weekday triage now against ${inputs.repo}. Same instructions as the scheduled run — produce the report in the Today's Triage note. If the date already matches today's, this is a re-run; overwrite with fresh state.",
      "initialState": {},
      "tools": {
        "expected": [
          "github_list_pull_requests",
          "github_get_pull_request",
          "daslab_note_write"
        ]
      },
      "checks": [
        {
          "op": "contains",
          "path": "today.content",
          "substring": "20",
          "ci": false,
          "why": "Findings note must mention a year (e.g. 2026) — proves the agent wrote a real report, not a placeholder."
        },
        {
          "op": "lte",
          "path": "$run.cost_usd",
          "value": 0.25,
          "expose": true,
          "severity": "fail",
          "why": "Task budget cap."
        }
      ]
    },
    {
      "id": "oldest-pr",
      "name": "Identify the oldest open PR",
      "prompt": "List the single oldest open PR on ${inputs.repo} by creation date. Skip drafts. Return its title, author, age in days, and one-line of why it's still open. Don't write to any notes — just answer in the chat.",
      "initialState": {},
      "tools": {
        "expected": [
          "github_list_pull_requests"
        ]
      },
      "checks": [
        {
          "op": "lte",
          "path": "$run.cost_usd",
          "value": 0.05,
          "expose": true,
          "severity": "fail",
          "why": "Cheap query, tight cap."
        }
      ]
    }
  ],
  "members": [
    {
      "email": "labhausxyz@gmail.com",
      "role": "owner"
    }
  ],
  "meta": {
    "author": "Daslab",
    "license": "MIT",
    "source": "blueprint demo — fork to your workspace, bind --input repo=your/repo, connect GitHub via the placeholder tile."
  }
}
