Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Matt DocketNew to Visual Studio Code? Get it now.
Matt Docket

Matt Docket

hurfy

|
2 installs
| (0) | Free
Tickets from .scratch in the mattpocock-skills issue-tracker format
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Matt Docket

A Tickets section in the Claude Code sidebar: the open project's .scratch/, in the issue-tracker format from mattpocock-skills, with every agent-ready ticket one press away from a fresh Claude Code conversation.

The extension is not tied to any particular repository. It wakes up when the open folder has a .scratch/, and shows the section only while one is there.

  ▣ Open              ▤ Resolved
▾ Checkout flow                                 3/5
▤  Spec
●  01  Guest checkout               Ready for agent
●  02  Validate the ship…           Ready for agent
●      Unnumbered ticket                  No status
▾ Receipts                                      0/0
▤  Spec                                           ✳
   No tickets yet

A feature is a section under the same group header the session list above it uses: its name, a badge counting the tickets under it against the ones it has in all, and then its rows, on the header's own line rather than indented under it. The first of those rows is the feature's brief — Spec or Map — standing a little taller than the tickets it was sliced into, so the phase reads before the work does; a press opens it. A ticket is a status dot, its number, its title — which stops at the middle of the row however long it runs — and its triage label at the right edge. Hover a ticket and the label gives way to Claude's mark in its place; press that and the ticket goes off to a fresh conversation.

Above the list, Open and Resolved split the docket rather than merely selecting a side of it. A ticket whose status says the work is over — resolved, or wontfix — leaves the open half and stands under Resolved instead, beneath the same feature headers, so the two halves differ in what they list and not in how it reads. A feature with nothing on the side you are on drops out of it, and the strip remembers which side that was.

Neither half hides the other. The badge on a feature header counts the rows you can see against every ticket the feature has — three of five open reads 3/5 here and 2/5 under Resolved — so what the cut took away is on the header that took it, and the tooltip goes on tallying the whole feature by status either way.

The brief row also says which phase the feature is in. A Spec means the deciding is done and the tickets are work to build. A Map means the effort is still being charted by /wayfinder, and its tickets are questions to settle rather than work — so they carry no send button until /to-spec lays a spec beside the map.

What it reads

.scratch/
  <feature-slug>/
    spec.md                      # or map.md, for a wayfinder effort
    issues/
      <NN>-<slug>.md             # one ticket per file

A ticket's title is its first heading, wherever in the file's opening lines that heading sits; its number comes from the file name, or from the title when the file name carries none. Status:, Type: and Blocked by: are read on both sides of that heading — bold or plain, bulleted or quoted, in front matter, or as ## Status sections of their own — so the order the fields were written in does not matter, only that they are there. A ticket with no heading anywhere is named after its file: 03-empty-states.md reads as Empty states. The tally of - [ ] acceptance criteria comes from the whole file. Only the status reaches the row; the rest wait in its tooltip.

The five triage labels — needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix — and the wayfinder's claimed and resolved each get their own colour. Any other label is shown as written.

Nothing is ever written back into .scratch/. A file watcher picks up edits made in the editor.

The send buttons

Pressing the one on a ticket opens a fresh Claude Code conversation carrying mattDocket.promptTemplate, which defaults to:

/mattpocock-skills:implement ${ticket}

${ticket} is the ticket's path from the workspace folder, ${title} its title, ${number} its number, ${feature} its feature slug, and ${brief} the path of that feature's spec.md or map.md. The button's tooltip shows the prompt it will send, filled in.

It waits for a hover, the way a session's own actions do, and stays grey until the pointer is on it. Nothing in the Resolved half carries one — there is nothing left to hand over — and neither do the questions of an effort still on a map.

The brief row carries a button of its own, for the step that phase is waiting for rather than for the work under it:

mattDocket.specPromptTemplate   /mattpocock-skills:to-tickets ${brief}
mattDocket.mapPromptTemplate    /mattpocock-skills:to-spec ${brief}

Those templates name ${brief}, ${title} and ${feature} — a brief is not a ticket, so ${ticket} and ${number} are left standing rather than blanked if you write them in. A map's button is on offer always; a spec's only while the feature has no tickets, because tickets are what /to-tickets produces and their being there says it has already run.

Either one appears the way a ticket's does — on a hover, grey until the pointer is on the button and then Claude's orange — but on a hover anywhere in the feature rather than on its own row alone, because the step it offers belongs to the feature and not to that one row.

If Claude Code cannot be reached, the prompt falls back to its URI handler and then to the clipboard. It is never lost.

The title bar

Three actions sit above the list: Refresh, Expand All, Collapse All, in that order, so the fold lands where a tree gives it for free. Refreshing is rarely needed — a file watcher brings editor changes back on its own — but the watcher follows what is inside .scratch/, so a directory that has just been created, and is still empty, is the one state it has nothing to report. Refresh is what notices it, which is why it stays in the command palette even when there is no view to press it in. Expand All and Collapse All only appear there once there is.

Looking like the rest of the sidebar

The view is a webview drawing from the same --vscode-* theme variables Claude Code's own webview builds on, at the same sizes, with icons from the same set. Themes and high-contrast modes are followed without the view being told about them, and nothing here animates. See .claude/docs/ARCHITECTURE.md.

Installing

From the Marketplace — Extensions, search for Matt Docket — or from a .vsix when you would rather have a build than a release:

code --install-extension matt-docket-0.1.0.vsix

That file is attached to every release, and is a build artifact on every green CI run; VS Code's Extensions: Install from VSIX… command takes it as well.

It is installed once and follows you between projects. It wakes on any folder that has a .scratch/ and stays out of the way of the ones that do not, so nothing is per-repository except the docket it finds. Claude Code is not a requirement either: without anthropic.claude-code the section lands in the Explorer instead, and the send buttons fall back to the clipboard.

Development

npm install
npm run watch          # both bundles, in watch mode
npm run check-types    # esbuild only transpiles; types are checked separately
npm test               # the domain and the view model, on plain Node

F5 (Run Extension) starts an Extension Development Host on sample-workspace/, whose .scratch/ carries fixtures for every triage label plus the awkward shapes: a feature with no spec, a feature with no tickets, a wayfinder effort mapped rather than specified, a ticket with no status, and a file with no leading number.

It opens that folder rather than the repository root because VS Code refuses to open a folder in the development host while another window already has it — the host comes up empty instead, and the extension never activates.

The "Tickets" section appears in the Claude Code sidebar below the session list. Run Extension (no Claude) starts the same host with anthropic.claude-code disabled, where the view should land in the Explorer instead, quietly, and the send button should fall back to the clipboard.

Releasing

npm run package    # minified dist/
npm run vsix       # the .vsix, through vscode:prepublish

A release is a tag. Bump version in package.json, put the CHANGELOG.md entries under it, then push v0.1.0: .github/workflows/release.yml refuses a tag the manifest disagrees with, runs the checks, attaches the .vsix to a GitHub release, and hands that same file to the Marketplace — signed in as a managed identity GitHub vouches for, so there is no token in the repository to leak or to expire. That last step waits on an AZURE_CLIENT_ID variable and is skipped until one is there, so the release stands on its own and the .vsix can be uploaded by hand. .claude/docs/PUBLISHING.md is the one-time setup, and why it is not the personal access token every other guide reaches for.

Third-party notices, including the one for the Claude mark on the send button, are in THIRD-PARTY.md.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft