Skip to content

Commit 2913891

Browse files
authored
Merge pull request #375 from Frank802/agentic-sdlc-microhack
Agentic sdlc microhack
2 parents 768e033 + 9fbded9 commit 2913891

279 files changed

Lines changed: 31915 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM mcr.microsoft.com/devcontainers/base:bookworm
2+
3+
RUN apt-get update \
4+
&& apt-get install -y --no-install-recommends \
5+
make \
6+
sqlite3 \
7+
&& rm -rf /var/lib/apt/lists/*
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"dockerComposeFile": [
3+
"docker-compose.yml"
4+
],
5+
"service": "dev",
6+
"workspaceFolder": "/workspaces/octocat-supply-hack",
7+
"features": {
8+
"ghcr.io/devcontainers/features/common-utils:2": {
9+
"installZsh": false,
10+
"upgradePackages": false,
11+
"username": "vscode"
12+
},
13+
"ghcr.io/devcontainers/features/node:1": {
14+
"version": "24",
15+
"nodeGypDependencies": true
16+
},
17+
"ghcr.io/devcontainers/features/python:1": {
18+
"version": "3.13",
19+
"installTools": true
20+
},
21+
"ghcr.io/devcontainers/features/dotnet:2": {
22+
"version": "10.0"
23+
},
24+
"ghcr.io/devcontainers/features/java:1": {
25+
"version": "17",
26+
"installMaven": true,
27+
"installGradle": false
28+
},
29+
"ghcr.io/devcontainers/features/github-cli:1": {},
30+
"ghcr.io/devcontainers/features/azure-cli:1": {}
31+
},
32+
"forwardPorts": [
33+
3000,
34+
5137,
35+
5500
36+
],
37+
"portsAttributes": {
38+
"3000": {
39+
"label": "API",
40+
"onAutoForward": "notify",
41+
"visibility": "public"
42+
},
43+
"5137": {
44+
"label": "Frontend",
45+
"onAutoForward": "notify"
46+
},
47+
"5500": {
48+
"label": "HTML Preview",
49+
"onAutoForward": "openPreview"
50+
}
51+
},
52+
"customizations": {
53+
"vscode": {
54+
"extensions": [
55+
"ms-azuretools.vscode-docker",
56+
"GitHub.copilot",
57+
"ms-vscode.extension-test-runner",
58+
"vitest.explorer",
59+
"ms-vscode.vscode-speech",
60+
"ms-vscode.live-server",
61+
"ritwickdey.liveserver",
62+
"Blodwynn.featurehighlight",
63+
"bierner.markdown-mermaid",
64+
"ms-azuretools.vscode-bicep",
65+
"GitHub.vscode-pull-request-github"
66+
],
67+
"settings": {
68+
"editor.inlineSuggest.experimentalInlineEditsEnabled": true,
69+
"github.copilot.chat.advanced.inlineEdits.enabled": true,
70+
"github.copilot.chat.agent.enabled": true,
71+
"github.copilot.chat.codesearch.enabled": true,
72+
"github.copilot.chat.generateTests.codeLens": true,
73+
"chat.agent.enabled": true,
74+
"chat.promptFiles": true,
75+
"git.enableSmartCommit": true,
76+
"github.copilot.chat.search.semanticTextResults": true,
77+
"github.copilot.chat.edits.temporalContext.enabled": true,
78+
"github.copilot.chat.completionContext.typescript.mode": "on",
79+
"github.copilot.chat.languageContext.typescript.enabled": true,
80+
"github.copilot.nextEditSuggestions.enabled": true,
81+
"github.copilot.chat.editor.temporalContext.enabled": true
82+
}
83+
}
84+
},
85+
"postCreateCommand": "cd src && make install && make build",
86+
// set the API port to public visibility (best effort in Codespaces)
87+
"postAttachCommand": "bash -lc 'if command -v gh >/dev/null 2>&1 && [ -n \"$CODESPACE_NAME\" ]; then gh cs ports visibility 3000:public -c \"$CODESPACE_NAME\" || true; gh cs ports visibility 5500:public -c \"$CODESPACE_NAME\" || true; fi'",
88+
"shutdownAction": "stopCompose",
89+
"hostRequirements": {
90+
"cpus": 4,
91+
"memory": "8gb"
92+
}
93+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Docker Compose File for Application Container with Docker bindings
2+
version: "3.8"
3+
4+
services:
5+
dev:
6+
image: mcr.microsoft.com/devcontainers/typescript-node:24-bookworm
7+
command: sleep infinity
8+
9+
ports:
10+
- "3000:3000"
11+
- "5137:5137"
12+
13+
volumes:
14+
- ..:/workspaces/octocat-supply-hack:cached
15+
16+
environment:
17+
- NODE_ENV=development
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"name": "OctoSupply Frontend + TypeScript API",
3+
"build": {
4+
"dockerfile": "../Dockerfile",
5+
"context": ".."
6+
},
7+
"workspaceFolder": "/workspaces/octocat-supply-hack",
8+
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/octocat-supply-hack,type=bind,consistency=cached",
9+
"features": {
10+
"ghcr.io/devcontainers/features/common-utils:2": {
11+
"installZsh": false,
12+
"upgradePackages": false,
13+
"username": "vscode"
14+
},
15+
"ghcr.io/devcontainers/features/node:1": {
16+
"version": "24",
17+
"nodeGypDependencies": true
18+
},
19+
"ghcr.io/devcontainers/features/github-cli:1": {},
20+
"ghcr.io/devcontainers/features/azure-cli:1": {}
21+
},
22+
"mounts": [
23+
"source=octocat-supply-hack-frontend-node-modules,target=/workspaces/octocat-supply-hack/src/frontend/node_modules,type=volume",
24+
"source=octocat-supply-hack-ts-api-node-modules,target=/workspaces/octocat-supply-hack/src/api-ts/node_modules,type=volume",
25+
"source=octocat-supply-hack-npm-cache,target=/home/vscode/.npm,type=volume"
26+
],
27+
"remoteEnv": {
28+
"NODE_ENV": "development"
29+
},
30+
"forwardPorts": [3000, 5137, 5500],
31+
"portsAttributes": {
32+
"3000": {
33+
"label": "TypeScript API",
34+
"onAutoForward": "notify",
35+
"visibility": "public"
36+
},
37+
"5137": {
38+
"label": "Frontend",
39+
"onAutoForward": "openPreview",
40+
"visibility": "public"
41+
},
42+
"5500": {
43+
"label": "HTML Preview",
44+
"onAutoForward": "openPreview",
45+
"visibility": "public"
46+
}
47+
},
48+
"customizations": {
49+
"vscode": {
50+
"extensions": [
51+
"GitHub.copilot",
52+
"GitHub.copilot-chat",
53+
"dbaeumer.vscode-eslint",
54+
"bradlc.vscode-tailwindcss",
55+
"ms-vscode.live-server",
56+
"ritwickdey.liveserver",
57+
"ms-vscode.vscode-typescript-next",
58+
"ms-azuretools.vscode-docker",
59+
"ms-azuretools.vscode-bicep",
60+
"GitHub.vscode-pull-request-github",
61+
"vitest.explorer"
62+
],
63+
"settings": {
64+
"editor.inlineSuggest.experimentalInlineEditsEnabled": true,
65+
"github.copilot.chat.advanced.inlineEdits.enabled": true,
66+
"github.copilot.chat.agent.enabled": true,
67+
"github.copilot.chat.codesearch.enabled": true,
68+
"github.copilot.chat.generateTests.codeLens": true,
69+
"chat.agent.enabled": true,
70+
"chat.promptFiles": true,
71+
"git.enableSmartCommit": true,
72+
"github.copilot.chat.search.semanticTextResults": true,
73+
"github.copilot.chat.edits.temporalContext.enabled": true,
74+
"github.copilot.chat.completionContext.typescript.mode": "on",
75+
"github.copilot.chat.languageContext.typescript.enabled": true,
76+
"github.copilot.nextEditSuggestions.enabled": true,
77+
"github.copilot.chat.editor.temporalContext.enabled": true
78+
}
79+
}
80+
},
81+
"postCreateCommand": "cd src && make install-frontend && make install-ts",
82+
"postAttachCommand": "if [ \"${CODESPACES:-}\" = \"true\" ] && [ -n \"${CODESPACE_NAME:-}\" ]; then gh cs ports visibility 3000:public -c \"$CODESPACE_NAME\"; gh cs ports visibility 5137:public -c \"$CODESPACE_NAME\"; gh cs ports visibility 5500:public -c \"$CODESPACE_NAME\"; fi",
83+
"shutdownAction": "stopContainer",
84+
"hostRequirements": {
85+
"cpus": 4,
86+
"memory": "8gb"
87+
}
88+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Custom agents — `.github/agents/`
2+
3+
This folder holds **custom agents** for the repo. This README is a short "anatomy of a custom agent" so you can read one, use one, and build your own — the working example here is [`requirement-refiner.agent.md`](requirement-refiner.agent.md), built for the Challenge 3 requirement-refinement stretch.
4+
5+
## What is a custom agent?
6+
7+
A custom agent is a reusable chat persona: a set of **instructions** plus a scoped list of **tools** that the AI adopts when you switch to it. Instead of re-explaining a role and hand-picking tools every time, you save the configuration once and select it whenever you need it.
8+
9+
- **Where they live:** workspace agents are Markdown files with the `.agent.md` extension in `.github/agents/`. VS Code detects them automatically.
10+
- **Where you use them:** the Copilot Chat **agent dropdown** in VS Code, and — because the same file is portable — in the **GitHub Copilot App / CLI** (background agents) and **cloud agents**.
11+
- **Why bother:** a focused agent gives more consistent results, and a scoped tool list keeps it safe (least privilege) and cheaper (less context, fewer stray tool calls).
12+
13+
## Frontmatter fields
14+
15+
A custom agent is YAML frontmatter (the config) followed by a Markdown body (the system prompt). The common frontmatter fields:
16+
17+
| Field | What it does |
18+
| --- | --- |
19+
| `description` | Short summary of the agent; shown as placeholder text in the chat input. |
20+
| `name` | Display name in the agent dropdown. Defaults to the file name if omitted. |
21+
| `argument-hint` | Optional hint telling the user what to type to get started. |
22+
| `tools` | The tools / tool-sets the agent may use. Keep it minimal — least privilege. |
23+
| `model` | Optional model to run with. **Omit** to use whatever model the user has selected. |
24+
| `handoffs` | Optional next-step buttons that transition to another agent with pre-filled context. |
25+
| `target` | Optional surface (`vscode` or `github-copilot`). **Omit** for the default VS Code surface. |
26+
27+
Only `tools` and the body really shape behaviour; everything else is presentation or portability. Fields are optional — when in doubt, leave one out.
28+
29+
## How this example is built
30+
31+
[`requirement-refiner.agent.md`](requirement-refiner.agent.md) maps to those fields like this:
32+
33+
- **`name: Requirement Refiner`** — what you pick from the agent dropdown.
34+
- **`description`** — one line so you know what it's for before selecting it.
35+
- **`argument-hint`** — nudges you to point it at `assets/workiq/` to start.
36+
- **`tools: ['codebase', 'search', 'web', 'github-remote/search_issues', 'github-remote/create_issue']`** — a **read-only analysis core plus one tightly-scoped write capability**. `codebase` and `search` read repo files and the WorkIQ artifacts; `web` pulls external context — none of them can change your workspace. The two `github-remote/...` entries add exactly one write action (create an issue) and one search action (to dedupe before creating), and nothing else. The guardrail here is deliberate on two fronts: **no file-editing or terminal tools** (it can't touch code or run commands), and the write capability is **scoped to two named tools rather than the whole server**. Note what is *not* here: `github-remote/*` would hand the agent the entire GitHub toolset (closing issues, pushing code, editing PRs…). Least privilege is a design choice — grant only the one or two tools the task needs.
37+
- **Write access ≠ autonomy.** Granting `create_issue` doesn't mean the agent files issues on its own. The body pairs that capability with a **mandatory human-confirmation step**: it confirms the need, title, labels, and target repo, and creates **exactly one** issue only after an explicit yes — with a paste-ready-markdown fallback if the MCP server isn't available. A write tool in `tools` and a human-in-the-loop instruction in the body are two halves of the same guardrail.
38+
- **Referencing MCP tools.** In `tools`, an MCP tool is written as `<serverName>/<toolName>` (e.g. `github-remote/create_issue`); `<serverName>/*` would include *all* of that server's tools. Here `github-remote` is the hosted GitHub MCP server preconfigured in [`.vscode/mcp.json`](../../.vscode/mcp.json) with the `issues` toolset, so `create_issue` and `search_issues` are available without any extra setup.
39+
- **`model` is omitted** on purpose, so it runs with whatever model you've selected (no dependency on a model name that might not exist in your environment).
40+
- **The body** is the system prompt: a **Role**, the **Inputs** it may read, a numbered **Process**, a fixed **Output format** (the "Requirement brief"), and explicit **Guardrails**. The clear headings aren't just for humans — a well-structured prompt gives the agent a reliable routine to follow.
41+
42+
## How to use it
43+
44+
1. Open **Copilot Chat** in VS Code.
45+
2. Select **Requirement Refiner** from the agent dropdown.
46+
3. Give it a starting prompt, e.g. _"Refine a requirement from the signal in `assets/workiq/`."_
47+
4. Work through the refinement with it — confirm the need it proposes, then let it draft the **Requirement brief**. If you want, it can either render a paste-ready GitHub issue or, on your explicit confirmation, **file the issue for you** via the `github-remote` MCP server. Building the feature stays your job.
48+
49+
## Build your own
50+
51+
1. Create `.github/agents/<name>.agent.md`.
52+
2. Add frontmatter — at minimum a `name` and `description`, plus a **minimal** `tools` list (only what the task needs).
53+
3. Write the instruction body: define the role, the process, and any output format and guardrails. Use clear headings.
54+
4. Reload/open Copilot Chat and select your agent from the dropdown to try it.
55+
56+
> Tip: match the tools to the job. Prefer read-only by default — an analysis or advisory agent usually needs nothing more. When a task genuinely needs a write action, scope it to the **minimum** named tools (not a whole MCP server) and keep a **human in the loop** in the instructions. This example stays read-only for analysis but adds just `create_issue` (+ issue search to dedupe), gated behind explicit confirmation — write access without autonomy.

0 commit comments

Comments
 (0)