AGENT SKILL

my-issues

Query and act on the local index of every GitHub issue assigned to you (default org:microsoft), enriched with Sweeper (vscodesweeper) triage proposals, and drive the My Work canvas. Use when the user asks about "my issues", their backlog, feature-area counts, what Sweeper proposes for an issue, propose-close/needs-info/route-to-area/autoFixable/stale/no-repro lists, what changed since the last refresh, wants to record a triage decision, or sends a "Panel request"/"Panel message" from the My Work canvas.

License 许可
MIT
最近更新
2026-11-11
Stars
★ 66
Forks
12

01 前言 Front Matter

name
my-issues
description
Query and act on the local index of every GitHub issue assigned to you (default org:microsoft), enriched with Sweeper (vscodesweeper) triage proposals, and drive the My Work canvas. Use when the user asks about "my issues", their backlog, feature-area counts, what Sweeper proposes for an issue, propose-close/needs-info/route-to-area/autoFixable/stale/no-repro lists, what changed since the last refresh, wants to record a triage decision, or sends a "Panel request"/"Panel message" from the My Work canvas.

02 资源文件 6

03 SKILL.md 正文

My Issues index and the My Work canvas

A daily automation ("My Issues Indexer", set up with the my-work-setup skill) maintains a local index of all issues assigned to the user in their GitHub org. Use it to answer questions about the user's issues before calling GitHub. It is fast and offline.

Paths below use <board> for <COPILOT_HOME>/project-boards (default ~/.copilot/project-boards) and <scripts> for this skill's scripts/ folder. Per-user settings (org, plan repository, local clones, Sweeper source, rules file, data folder) live in <board>/my-work.config.json; see the my-work-setup skill.

Files (<board>/)

File Role
my-issues.json Source of truth (can be tens of MB). Never read it whole; use the helper script.
my-issue-outcomes.json User-owned triage decisions. The refresh re-applies these to the index each run.
my-issues-refresh-manifest.json Last refresh: added/updated counts, Sweeper commit, Sweeper triageActionChanges.
my-issue-features.json Feature areas (label → area, priority): the user's own, plus "auto": true areas the refresh adds for every GitHub feature label (microsoft/vscode labels coloured #c5def5, except perf) found on an open issue, at priority 10. Auto areas are kept; edit them (rename, priority) or list labels in ignoredAutoLabels only when the user asks.
my-issues.md Generated human view. Don't edit.
my-triage-queue.md / .json Generated daily triage queue. Don't edit.
my-triage-chats.json Which refresh already got its daily triage message, and persistentChat: the one triage chat reused every day. Written by mark-chat.
my-work.config.json Per-user settings (optional; defaults suit the VS Code team).
my-issues-refresh-status.json Progress of the running (or last failed) refresh, written by refresh_my_issues.py; the canvas shows it on Today, Cleanup and Implement.

Record keys are owner/repo#number. A bare number means <planRepo>#number (default microsoft/vscode).

Helper scripts

python3 <scripts>/my_issues.py <command>

Command Use
stats [--state open|closed|all] Counts by area, Sweeper action/severity, autoFixable, outcomes
list [filters] [--sort ...] [--limit N] [--json] Filtered issue lists (open by default)
get <key|number|url> Full compact record plus Sweeper's current Summary / Best solution / Proposed action
changes [--limit N] What the last refresh changed, including Sweeper verdict flips
record <issue> --decision <d> [--note ...] [--canonical owner/repo#n] Record an explicit user decision
record <issue> --clear Remove a recorded decision
queue [--write] Build the daily triage queue (my-triage-queue.md/.json) and count unread GitHub notifications. Prints triageChat (the reused triage chat), postToChat (send today's chatMessage to it), createChat (no triage chat yet: create one with title and chatPrompt) for the automation. Both are false when today was already handled or there is nothing new
mark-chat <link> Record that the current refresh was posted to (or created) this triage chat, and make it the chat reused on later days
cleanup [--group fixed|duplicate|reason|needs-info] [--limit N] Sweeper-backed cleanup candidates. With no group it prints counts. Each item has evidence, the exact proposed comment, and the planned gh steps
proposal <issue> The same cleanup view for a single issue
apply <issue> --comment-file F --confirm [--group G] [--label L] [--duplicate-of N] [--note ...] [--force] Execute ONE approved cleanup action on GitHub and record the outcome
checks <issue> [--popular N] Live, read-only fact checks on a cleanup proposal
judge-prompt <issue...> Blind judge prompt and title (issue identity only) for a separate judge chat
opinion <issue> --action keep-open|fixed|duplicate|not-planned|needs-info [--reference R] [--confidence C] --reasoning "..." [--evidence E] / opinion <issue> --clear Record or clear a blind judgement (judge chats only)
implement [--readiness implement|plan] [--limit N] Agent-ready issues (Sweeper agentReadiness), bugs first, then by severity and upvotes
find-clones [--repo owner/repo] Local clones the user's Agents window sessions worked in, by GitHub repository, most used first (read-only; works without an index)

python3 <scripts>/refresh_my_issues.py [--full] is the indexer pipeline. Only the indexer automation (or first-time setup) runs it; it never changes GitHub. The first run indexes open issues first (published quickly), then closed ones. Later runs only fetch issues updated since the last refresh (seconds); every 7 days, or with --full, a full pass also catches issues that were unassigned, transferred or deleted.

list filters: --area <id>, --repo owner/repo, --label L (repeatable, all required), --action keep-open|propose-close|needs-info|route-to-area, --severity S (repeatable), --autofixable, --no-milestone, --no-outcome, --has-outcome, --no-repro, --stale-days N, --text <title substring>, --state. Sort: updated (default), created, upvotes, confidence, severity.

Feature area ids: read my-issue-features.json (fallback others). Sweeper severities: data-loss, crash, freeze, perf, correctness, visual, papercut. Sweeper only covers microsoft/vscode. Its data comes from Sweeper's published index (index-vscode.json, read with gh, cached) and, for the issues that need them, its review records (cached until the issue's review changes; read from the optional local clone when it's current). If GitHub can't be reached, the previous Sweeper data stays. Rows also carry Sweeper's value score (valueRaw, comparable within the bugs or features lane), verifyVerdict (a blinded second review: only confirmed establishes a duplicate), infoAnsweredAt (the reporter answered a request for information), contentStale, linkedPr and dismissed.

Common recipes

  • Daily triage (the reused triage chat, titled "My Work"): read <board>/my-triage-queue.md. Its sections are Newly assigned, Sweeper changed its verdict, Reporter replied (a reporter answered your request for information), New activity, Severe bugs, Easy closes, and Top close proposals. It only lists open issues with no decision, or issues changed on GitHub after the last decision.
  • Morning overview: changes, then list --no-outcome --action propose-close --limit 15.
  • Close candidates: list --action propose-close --no-outcome --sort confidence.
  • Worst bugs: list --label bug --severity data-loss --severity crash --severity freeze --sort upvotes.
  • Hand-off to Copilot: list --autofixable --no-outcome.
  • Backlog cleanup: list --stale-days 365 --no-milestone, or list --label bug --no-repro.
  • One issue: get 12345.

Present lists as Markdown tables or bullets with issue links. Keep them short (≤25 rows) and say how many matched in total.

Cleanup workflow (Sweeper-assisted, one issue at a time)

Triggers: "clean up my issues", "clean up: already fixed", "close the duplicates", "send info requests", or an issue from the triage queue or a notification that has a Sweeper close or needs-info proposal.

Group Sweeper proposal Planned GitHub action
fixed Already fixed on main (fix commit + shipped version) comment, then close as completed
duplicate Duplicate of #N comment (includes /duplicate of #N), add *duplicate, close as duplicate of #N
reason as-designed / out-of-scope / question comment, add *as-designed/*out-of-scope/*question, close as not planned
needs-info Needs more info from reporter comment, add info-needed (stays open)

Steps:

  1. cleanup for counts, then cleanup --group <g> --limit 10. Items with activitySinceReview: true sort last. Treat their proposal as possibly outdated.
  2. For each issue, one at a time: a. Fetch it live: gh issue view <n> -R <repo> --comments, and read the latest comments. If someone added information or disagreed after Sweeper's reviewedAt, say so and suggest skipping. b. For fixed, glance at the fix commit (gh api repos/<repo>/commits/<sha> --jq .commit.message). For duplicate, check that the original issue is open and matches. c. Show the user: issue link and title, Sweeper's summary, the key evidence, confidence, the exact comment text, and the planned steps. d. Ask with the ask_user tool: Approve, Edit comment, Skip, Keep open (record rejected), or Defer (record deferred). Never batch approvals; each issue needs its own explicit approval. e. On Approve or an approved edit: write the final comment to a temp file and run apply <issue> --comment-file <file> --confirm. It re-checks live state, refuses if the issue was closed or got new comments since review (use --force only if the user approves after seeing them), runs the planned gh steps, and records the outcome. Delete the temp file. f. On Skip, record nothing. On Keep open or Defer, use record with a short note.
  3. After the batch, summarise what was done and what's left (cleanup counts).

Rotation with notifications: in the daily triage chat, the user may ask to alternate batches, e.g. "10 notifications, then 10 cleanups". Alternate fixed-size batches: notifications newest first, then cleanup with Easy closes first and then fixed → duplicate → reason → needs-info. Handle an issue only once even if it appears in both. Show a one-line tally after each batch and continue until the user stops.

In microsoft/vscode, *-labels can make the triage bot close the issue and post its own canned comment. apply tolerates the bot having closed it already.

Help: when the user says "help" in a triage chat, show this skill's triage-help.md verbatim.

Principles, rules and memory: every triage decision follows triage-principles.md, refined by the user's inbox rules (rulesFile, default ~/.copilot/github-inbox-rules.md), which win on conflict. The user's inbox memory (memoryFile, default ~/.copilot/github-inbox-memory.md) holds facts: people's GitHub logins, area owners, the user's team and preferences. Both files are shared with the github-inbox plugin; read them before triaging.

The My Work canvas

The my-issues-triage canvas ("My Work", from the my-work plugin) has a left activity bar: Today (the daily queue), My Work, Notifications, Cleanup and Implement (agent-ready and not already taken by a PR, bugs first, then by Sweeper value). Each view shows one batch at a time (size configurable, default 10). Every button click (Approve / Dismiss / Done / Keep open / Defer / Skip / Start session / Route …) is the user's explicit per-item decision. Without an index, My Work and Notifications still work and the other views explain how to build it.

Canvas actions:

  • setNotificationTriage {items:[{id, group: action|route|auto|cleanup|dismiss|fyi, reason, rule?, routeTo?}], keepBatch?}: auto = matches an auto-dismiss rule in the user's inbox rules (give rule, e.g. "A1. Merged own PR" from the triage principles or a numbered rule of the user); the panel offers a bulk Auto-dismiss / Safe to dismiss review. route = the issue/PR belongs to another owner per the user's routing rules: give routeTo (logins; [] = only unassign the user) and rule; the panel's Route list lets the user bulk Route & dismiss. Put uncertain owners in action with replyToIssue choices instead. This also sets the notification batch unless keepBatch: true. Answer "Panel request: classify these N notifications", "triage the next N untriaged notifications" and "re-check the classification" messages with one call and keepBatch: true, using auto/dismiss whenever a rule applies after reading the latest comments.
  • setBatch {tab, ids}: show exactly these items as a tab's current batch.
  • setOpinion {key, action, reference?, confidence?, reasoning, evidence?}: record a blind judgement (judge chats normally use my_issues.py opinion).
  • replyToIssue {key, text, choices?}: answer a "Panel message about <issue>" in that issue's thread (markdown). choices (max 5) are one-click quick replies {label, reply, style?: primary|secondary|danger, edit?}. Always add choices when asking for approval or a decision.
  • judgeFailed {keys, error}: report that a panel-requested judge chat could not be created.
  • getActivity {since?}: what the user did in the panel. Check it before each batch.
  • focus {kind: notification|issue, id}: select an item in the panel.
  • refresh: reload after the chat acted. getSummary: counts, current batches and batch size.
  • setIssueRules {items:[{key, group: route|close|needs-info|keep, reason, rule?, routeTo?, closeAs?}]}: the verdict of the user's inbox rules (the rulesFile in my-work.config.json, default ~/.copilot/github-inbox-rules.md, shared with the github-inbox plugin) for issues in the Cleanup / Implement / Today views. Answer "Panel request: apply my inbox rules to these N issues" with one call after checking each issue live. Rules win over Sweeper. Only clear routing candidates are route; uncertain owners are keep with the doubt in the reason.
  • dismissNotifications {ids | issues, unsubscribe?}: dismiss notifications (by thread ids, or every unread one about the given owner/repo#N issues) and update the panel at once. Always use this instead of gh api on notification threads. Once an action the user approved is done on GitHub and it addresses why a notification came in (the requested comment and info-needed label, a close, a reroute, a review), dismiss that notification without asking and say so.
  • getConfig: built-in plus the user's custom groups ({id, label, criteria, bulk}); call it at the start of every triage chat. defineGroup {id, label, criteria, bulk?, order?} / removeGroup {id} manage custom groups.
  • getMyWork / updateMyWork {op, ...} / setMyWorkChat {link}: the My Work board (below).

My Work

  • Groups: the current and next milestone of planRepo (live GitHub search), then My priorities (the user's own ordered list, stored locally; closed issues drop off), then Active sessions (collapsible; hide irrelevant ones). The user's own custom sections (for example MSRC) sit at the top.
  • Adding work: Browse issues & PRs (right pane: my bugs, feature requests, all my issues or PRs awaiting my review, optionally narrowed to one feature area; a filter applied on Enter narrows the selected list: plain words become a Panel request to turn the filter into GitHub search qualifiers, which the chat answers with the setBrowseQuery canvas action (only the qualifiers to add; names resolved with the memory file; GitHub syntax such as author:x applies directly); click a title to open it in the panel to read, discuss, start a session or add it; drag rows into a group or use the + buttons), Add to My Work in any issue's menu, or the My Work chat box at the bottom (pasted #123, issue URLs, links matching a custom section's link pattern and agent-host-session:// links are added at once; anything else goes to the chat). Local placement never changes GitHub; Plan for… sets a GitHub milestone and Remove from <milestone> (untriaged) clears it (the issue then leaves My Work until found again); both are the user's explicit decision.
  • Sessions: adding a session first resolves the issue it works on (session title #N, branch number, issues its PRs close, its first request, chat titles; only one open issue in a tier counts). If found, the issue is added with the session linked; otherwise the session is added and the My Work chat is asked to describe it (updateMyWork {op: "describeSession", session, summary, issue?}; pass issue only with explicit evidence). Session details are read locally from the Agents window session store and transcript (best effort; internal formats). Keep #N in session titles so they link.
  • Custom sections: the user creates them in the panel (+ Section): a name, optional instructions for sessions, and an optional link pattern. A section holds notes (title, link, description, due date; stored privately in the My Work data folder) plus issues and sessions moved or dragged into it. Start session on a note sends "Panel request: start a session for <note> from my <section> section": follow the section's instructions exactly (for a security section they say to work privately) and keep the note's reference in the session title so the panel links it. The built-in MSRC group of earlier versions became a custom "MSRC" section with the same items and msrc.fixWorkflow as its instructions.
  • Worktrees are the host's job: fix, implement and review sessions are created with the repository clone as workspace and worktree: true (or set_workspace with isolation: true), so the host creates and manages the worktree. Never run git worktree add yourself or pass an existing worktree folder as the workspace.
  • Review sessions: for someone else's pull request, the panel's main action is Start review session, which sends "Panel request: start a review session". Create a session nested under the My Work session (omit relationship) with the repository clone, worktree true, titled Review #N: …, whose prompt checks out the PR, reviews it (with reviewSkill if configured) and drafts review comments. It never submits a review, approves, comments or pushes without the user's approval. Right after create_session, link the session to the PR with updateMyWork {"op": "linkSession", "session": "<link>", "issue": "owner/repo#N"}; fix sessions do the same for their issue. The panel adds the PR to My Work's current group and dismisses its notifications when the review starts.
  • Investigating and fix tracking: asking to reproduce (the Reproduce recommendation) or investigate (the Investigate buttons) puts the issue in the Investigating section, a custom section created on first use. When the reproduce attempt or investigation is done, the chat calls updateMyWork {"op": "investigationResult", "issue": "owner/repo#N", "result": "reproduced" | "not-reproduced" | "partly" | "findings", "summary": "<one line>"}, and the item shows the result and moves to To do. Starting a fix or implementation session from anywhere puts the issue in the current group (local only), moving it out of Investigating; issues already planned or placed in the user's own sections stay where they are.
  • My Work chat: its first message asks the triage chat to create a nested chat titled "My Work chat" and register it with setMyWorkChat {link}; later messages arrive as "Panel request: forward a My Work message" — just send_message them verbatim. The My Work chat uses getMyWork / updateMyWork (addIssue, pinSession, moveSession, unpinSession, describeSession, add/move/removePriority, addNote {section, title, link?, due?, description?} — local only; group may also be a custom section id, no approval needed) and replies with replyToIssue {"key": "my-work", …}. "The session I'm in" = the most recently active session other than the triage and My Work chats. If the nested chat is gone, call setMyWorkChat {"link": null}.
  • Finished issue chats: when a notification is dismissed (by the user in the panel, or by a chat with dismissNotifications), the panel sends the My Work session "Panel request: archive finished issue chats" for that issue's discussion chat. Check each chat with get_session_context; archive it with archive_chat and call setIssueChat {key, link: null} only if its latest turn is complete, it isn't waiting for the user, and it isn't a work session. A later message about the issue starts a new chat. Starting a reproduce, investigation or review also dismisses the notification, but keeps the chat.
  • Requests that create chats from a panel outside the My Work session arrive as "Panel request: run a request in the My Work session": check get_current_session; inside that session handle it, otherwise send_message it there verbatim.
  • Issue chats: the first message about an issue from the panel sends "Panel request: create the chat for <issue>": create a chat nested under the My Work session (omit relationship), without a workspace, titled #N: …, with the prompt verbatim, and register it with the setIssueChat canvas action. Later messages arrive as "Panel request: forward a message to the chat for <issue>": only send_message them to that chat. The issue chat answers in the panel with replyToIssue.
  • Start session on an issue with a discussion chat forwards "The user clicked Start session" to that chat. It renames itself Fix #N: … / Implement #N: …, registers itself with setIssueChat stage session, records fixing, then calls set_workspace with the repository clone and a worktree, and starts the work in the same conversation. Without an issue chat (or with Start another session), the request is "Panel request: start a work session for <issue>": create a session nested under the My Work session (omit relationship) with a worktree of the repository's configured local clone, titled Fix #N: … / Implement #N: …, record fixing, and reply with replyToIssue.

Panel requests

  • "Panel request: start a nested judge chat": call create_session exactly as instructed (omit relationship so it is nested, no workspace), passing the enclosed prompt verbatim. Do not judge it yourself and do not add Sweeper context.
  • "Panel message about <issue>": handle it like any request from the user about that issue (GitHub changes still need explicit approval), then answer with replyToIssue.
  • "Start a fix session…" / "Panel request: start a fix or implementation session…": the click is explicit confirmation. Fetch the live issue and latest comments, decide bug vs feature, create an independent isolated-worktree session in the configured local clone, record fixing only after creation (and only for indexed issues), post the session link with replyToIssue, and do not dismiss the notification.
  • "Panel request: start a nested investigation chat": call create_session exactly as instructed (nested, no workspace), post its link with replyToIssue, and continue without waiting. Neither chat changes GitHub during the investigation.

Standing instructions ("from now on…")

The daily triage chat is reused every day, but older history gets compacted, so persist lasting requests instead of remembering them. Show the user exactly what will be saved and where, and wait for OK. Then:

  • (a) Classification or handling rule: append it as the next numbered rule in the user's rules file.
  • (a2) A lasting fact (someone's GitHub login, who owns an area, the user's team): add it to the user's memory file in the matching section.
  • (b) New panel section or bulk list (e.g. "group CODENOTIFY"): defineGroup with criteria a future chat can apply without asking, add the matching rule from (a), then reclassify today's notifications with setNotificationTriage and keepBatch: true.
  • (c) Panel UI or behaviour changes: these are changes to the shared my-work plugin (microsoft/vscode-team-kit). Describe the change and offer to open an issue or pull request there; don't edit the installed plugin.

Independent (blind) judgements

Judge chats get only the issue identity. They must not read Sweeper data or my_issues.py get/proposal/checks/cleanup/list. They record each verdict with my_issues.py opinion …, which writes one file per issue to <board>/my-issue-opinions/, so parallel judges never collide. The panel compares each verdict with Sweeper's proposal.

When the user asks for an independent judgement in chat, run my_issues.py judge-prompt <issue...> and call create_session with its title and prompt verbatim, omitting relationship and with no workspace (the judge reads the local clone read only). For a second round with Sweeper's evidence, use judge-prompt --informed <issue>; the judge records with opinion <issue> --informed ....

Rules

  1. The index can be up to a day old. Before acting on GitHub (closing, commenting, labelling, assigning), fetch the live issue and its latest comments. The user's inbox rules still apply, including showing comment text for approval before posting.
  2. Sweeper is advisory. Present its verdict as a proposal with its confidence. Never treat it as a decision.
  3. Record outcomes only on explicit user decisions. Use record only after the user explicitly decides, or after the user-approved GitHub action has succeeded. apply records automatically after its approved action. Never record outcomes in bulk from Sweeper proposals, and never run apply --confirm without that issue's explicit approval. Decisions: accepted, rejected, deferred, closed, needs-info-sent, routed, fixing, fixed, duplicate (with --canonical), wont-fix. Put the reason in --note.
  4. Never edit my-issues.json directly. The indexer owns it, and record is the only supported write.
  5. Issues not assigned to the user are not in the index. Fall back to GitHub for those.

04 同仓库更多 Skills

microsoft
microsoft/vscode-team-kit

generate-test-video

Make a short narrated "how to test" or "how to verify" video for a VS Code test plan item (TPI), a fixed bug, or a few fixed bugs of one area: recorded in real VS Code Insiders in a throwaway profile, every step checked in the app, with captions, a zoom, flags that pause where something is wrong, a verdict slide and a recap. macOS. USE FOR: "make a how-to-test video for TPI 342400", "a video to verify issue 341013", "how-to-verify video for bugs 339711 339712 339714". DO NOT USE FOR: explaining a PR to someone who won't test it (use pr-studio:generate-video), plain screen recordings, editing an existing video.

测试与质量图像与多媒体
★ 66
microsoft
microsoft/vscode-team-kit

session-timeline

Open a live timeline canvas for the current Copilot session. Use when asked to inspect session events, system prompts, reasoning, tool executions, or subagent activity in a session timeline.

★ 66
microsoft
microsoft/vscode-team-kit

review-plan

Review an implementation plan produced by the Plan agent. It is CRITICAL to review plans before handing off to implementation — plans often have gaps, incorrect assumptions, or suboptimal sequencing that are cheaper to catch now than after coding. Use when the user asks to 'review the plan', 'check my plan', 'is this plan ready', or after the Plan agent produces a plan.md.

Skill与智能体开发
★ 66
microsoft
microsoft/vscode-team-kit

review-areas

In-depth code review that fans out parallel subagents across review areas — CRITICAL after non-trivial development. USE FOR: "in-depth review of a pull request", "code quality check or bug hunt", "review correctness, tests, security, performance and product areas", "review after any non-trivial development phase". DO NOT USE FOR: "plan a new implementation", "explain how existing code works".

代码审查Skill与智能体开发
★ 66
microsoft
microsoft/vscode-team-kit

generate-video

Make the shortest narrated video that fully explains a GitHub pull request (at most 90 seconds, captions, diagrams chosen for the PR, and real footage of the app, before and after side by side, when the change is visible) in one white Microsoft look. USE FOR: "/generate-video 12345", "make a video of this PR", "explain PR <url> in a video", "a video for my manager about this PR". DO NOT USE FOR: a screen recording on its own (no PR to explain), editing existing videos, slide decks (use generate-presentation).

图像与多媒体
★ 66
microsoft
microsoft/vscode-team-kit

generate-presentation

Make the shortest slide deck (a 16:9 PDF with speaker notes, at most 12 slides) that fully explains a GitHub pull request, in one white Microsoft look: one idea per slide, drawn as diagrams, with screenshots of the real app when the change is visible, every fact from the PR. USE FOR: "/generate-presentation 12345", "make slides about this PR", "a deck for my manager on PR <url>", "present this pull request". DO NOT USE FOR: editing PowerPoint files, videos (use generate-video), decks with no pull request behind them.

文档处理演示文稿
★ 66