Skip to main content

Posts

Monitoring GitHub Copilot usage with the Aspire Dashboard

When talking to developers I get wildly different opinions about how "good" GitHub Copilot actually was for them. Some love it, some find it slow, some weren't sure it was doing anything useful at all(just kidding). The problem: nobody had any data. We were talking about token usage, latency and tool calls purely from gut feeling. GitHub Copilot can export all of that as OpenTelemetry traces, metrics and events. And the easiest way to look at it locally, without spinning up a cloud backend, is the Aspire Dashboard. Let's set that up. Why do we need this? Copilot isn't just autocomplete anymore. Every agent turn is a small orchestration: it calls a model, the model asks for tools, the tools run, the model answers. If you want to know where the time and the tokens go, you need to see that orchestration, not just the end result. That's exactly what the Open Telemetry integration gives you. Every agent interaction produces a span tree: invoke_agent copil...
Recent posts

Setting up GitHub Copilot budget policies without GitHub Enterprise Cloud

If you search for "GitHub Copilot budget policy", most posts point you to cost centers: assign a budget to a cost center, map the cost center to a team or business unit, done. Clean story, except for one detail nobody mentions upfront — cost centers require a GitHub Enterprise Cloud account. That's not the same thing as being on the Copilot Enterprise plan; user-level budgets already work fine on Copilot Business. It's about the account type; a standalone Organization account doesn't have cost centers, and neither does GitHub Enterprise Server if you're self-hosted. If you're not on Enterprise Cloud, cost centers are off the table. We ran into exactly this. No Enterprise Cloud account, no cost centers, but still a real need to keep Copilot spend under control across a growing user base. Remark: if you do have GitHub Enterprise Cloud, cost centers are probably still the better fit. This post is for the rest of us. The starting point We have two...

Renovate hostRules silently ignored? Check your config level

Recently I got lost setting up Renovate against an internal NuGet feed. Dependency updates kept coming back with a 401, even though I had hostRules configured with credentials right there in renovate.json . No error, no obvious warning in the log that jumped out at me. Just an anonymous request going out where an authenticated one should have. Turns out the config was fine. The location wasn't. The problem The error itself didn't point anywhere near the config file: { "message": "Request failed with status code 401 (Unauthorized): GET https://tfs.vlm.be/tfs/DefaultCollection/_packaging/VLMFeed/nuget/v3/index.json", "response": { "statusCode": 401, "statusMessage": "Unauthorized", "body": "{\"$id\":\"1\",\"innerException\":null,\"message\":\"TF400813: Resource not available for anonymous access. Client authentication required.\",\...

Turning a single work session into a reusable Skill with Microsoft's Skill Recorder

In my effort to adopt an 'AI first' philosophy, I spend a lot of time automating my day-to-day activities and transforming them to skills. It's not the most exciting activity: I know exactly how to do a task, I've done it a dozen times by hand, but writing it down as a clean SKILL.md for an agent takes almost as long as just doing the task again. Microsoft created an open-source a tool that skips that step entirely: Skill Recorder . The idea is simple: you record yourself doing the task once, and it generates the skill for you. Sounds good? Let’s give it a try… What it actually does Skill Recorder is a desktop app (Electron, macOS-first with Windows 11 support) that captures a real work session on your screen: clicks, app and window switches, the pages you visit, clipboard snippets, and optionally your spoken narration. Nothing leaves your machine while you're recording. Capture, storage, frame extraction, and narration transcription all happen locally. T...

Packaging skills in a plugin, this time for GitHub Copilot CLI

Note: this post is part of a series. Part one covered packaging a skill in a plugin for Claude Code . Same idea, different tool, this time focussing on GitHub Copilot. After writing that first post I got the obvious follow-up question: does this also work for GitHub Copilot? Short version: yes, SKILL.md itself is portable, but the plugin wrapper isn't. Copilot CLI has its own plugin format, laid out slightly differently from Claude Code's. What's the same? A skill is still just a folder with a SKILL.md inside: YAML frontmatter ( name , description , optionally license ), then a Markdown body with instructions. Copy that file as-is between tools — nothing about the skill content needs to change. What's different? Where Claude Code wants the manifest tucked inside .claude-plugin/plugin.json , Copilot CLI puts plugin.json straight at the plugin root: api-testing-plugin/ ├── plugin.json # Required manifest, at the root ├── agents/ #...

Packaging skills into a plugin

It didn't take long until skills became a key element in our agentic development workflow. At that moment a skill stopped being "that SKILL.md I keep in one project" and became something we want on every machine, for every teammate, without copy-pasting a folder around. That's the point where you package it into a plugin. A plugin is a container: it bundles one or more skills plus optionally commands, agents, hooks, and MCP servers into a single installable unit with a manifest. Skills are the "what to do", plugins are the "how you get it onto someone else's machine". Our first approach: using git submodules Our first approach was through centralizing all our skills in a separate Git repo and share it between projects by using git submodules. That approach worked but felt more like a hack than a final solution. The better approach: wrap it in a plugin A plugin is just a directory with a manifest and a conventional layout: my-plugin/...

Azure DevOps Server – Git submodule support

Yesterday I was talking about git submodule support in Visual Studio and that reminded me of something else: Azure DevOps Server got submodule support too. It's a small feature, but a genuinely useful one. Why do we need this? If you've worked with submodules before, you know the annoying part isn't adding them, it's navigating them afterwards. In the Files hub, a submodule used to just show up as a folder reference. To actually browse its content, you had to know the submodule's repo, open it separately, and find the right commit yourself. What changed Azure DevOps Server now has UI support for Git submodules in the Files hub. You can click straight into a submodule from your project and land exactly on the commit that's referenced there. No more manually tracking down the right repo and commit by hand. It works across multiple Git services that a submodule can point to: Azure Repos GitHub GitLab Bitbucket Multiple .gitmodules URL...