microsoft/TypeAgent

Public

mirrored fromhttps://github.com/microsoft/TypeAgentAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/fix-github-actions-job-shell-and-cli

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

.devcontainer/agent/devcontainer.json

180lines · modecode

1{
2 "name": "TypeAgent Development (Agent Worktrees)",
3 "build": { "dockerfile": "../Dockerfile" },
4
5 // Variant of the standard devcontainer where the container sees the
6 // workspace at the SAME absolute path as the host. This lets VS Code's
7 // Copilot CLI agent worktree feature work end-to-end:
8 //
9 // src/vs/platform/agentHost/node/copilot/copilotAgent.ts
10 // getCopilotWorktreesRoot() -> <parent>/<basename>.worktrees
11 //
12 // is hardcoded, so the only way to have host VS Code open an agent-
13 // created worktree at the same path the container created it is to
14 // make the parent directory a single bind mount with matching paths.
15 //
16 // This config is LOCAL-ONLY (Linux/macOS host with Docker). It will not
17 // work in Codespaces - there is no `localWorkspaceFolder` on the cloud
18 // host. Use ../devcontainer.json (the default config) for Codespaces.
19 //
20 // Prerequisites on the host:
21 // - Your host user's UID matches the `codespace` user inside the
22 // container. `updateRemoteUserUID` below handles the common case
23 // by re-chowning `codespace` to your host UID on first start.
24 // - The sibling `<repo>.worktrees` directory must exist on the host
25 // before container start (Docker bind-mount requirement). The
26 // `initializeCommand` below creates it automatically.
27
28 "features": {
29 "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
30 "ghcr.io/devcontainers/features/sshd:1": {
31 "version": "latest"
32 },
33 "ghcr.io/devcontainers/features/git-lfs:1": {
34 "autoPull": false
35 },
36 "ghcr.io/devcontainers/features/node:1": {
37 "version": "22",
38 "nodeGypDependencies": true
39 },
40 "ghcr.io/devcontainers/features/python:1": {
41 "version": "3.12",
42 "installTools": true
43 },
44 "ghcr.io/devcontainers/features/dotnet:2": {
45 "version": "8.0"
46 },
47 "ghcr.io/devcontainers/features/azure-cli:1": {},
48 "ghcr.io/devcontainers/features/github-cli:1": {},
49 "ghcr.io/devcontainers/features/common-utils:2": {
50 "installZsh": true,
51 "configureZshAsDefaultShell": true,
52 "installOhMyZsh": true,
53 "username": "codespace",
54 "userUid": "1001",
55 "userGid": "1001"
56 }
57 },
58
59 // Re-chown the `codespace` user to the host user's UID/GID on container
60 // start so the bind-mounted source tree (owned by the host user) is
61 // writable from inside the container.
62 "updateRemoteUserUID": true,
63
64 // Hardening for agent use:
65 // - userEnvProbe "none" stops the Dev Containers CLI from sourcing your
66 // host login shell and copying its environment (including any tokens
67 // or agent-friendly env vars) into the container.
68 // - runArgs apply Docker-level constraints: drop all capabilities then
69 // add back only those the post-create script needs (chown/dac_override
70 // /fowner for volume ownership fixes; setuid/setgid because sudo and
71 // the common-utils feature need them), and cap the process table to
72 // limit fork-bomb blast radius.
73 //
74 // Note: `--security-opt=no-new-privileges` is intentionally NOT set,
75 // because it blocks setuid binaries (including sudo), which
76 // post-create.sh needs to chown the named-volume mountpoints Docker
77 // creates as root:root on first start.
78 "userEnvProbe": "none",
79 "runArgs": [
80 "--cap-drop=ALL",
81 // Needed by post-create.sh (chown volume mountpoints, sudo, common-utils)
82 "--cap-add=CHOWN",
83 "--cap-add=DAC_OVERRIDE",
84 "--cap-add=FOWNER",
85 "--cap-add=SETUID",
86 "--cap-add=SETGID",
87 // Needed by sudo to manipulate the capability bounding set, and by
88 // sshd's privilege separation (chroot, dropping caps on the child).
89 "--cap-add=SETPCAP",
90 "--cap-add=SYS_CHROOT",
91 "--cap-add=KILL",
92 // Needed if sshd binds a privileged port; harmless if it doesn't.
93 "--cap-add=NET_BIND_SERVICE",
94 // Silences `sudo: unable to send audit message` warnings; also used
95 // by sshd when logging auth events to the kernel audit subsystem.
96 "--cap-add=AUDIT_WRITE",
97 "--pids-limit=4096"
98 ],
99
100 "appPort": ["127.0.0.1:2222:2222"],
101
102 "forwardPorts": [8999, 8081, 8082, 3000, 3443],
103 "portsAttributes": {
104 "8999": { "label": "Agent Server (WebSocket)", "onAutoForward": "notify" },
105 "8081": { "label": "Browser Agent (WebSocket)", "onAutoForward": "notify" },
106 "8082": { "label": "Code Agent (WebSocket)", "onAutoForward": "notify" },
107 "3000": { "label": "API Server (HTTP)", "onAutoForward": "notify" },
108 "3443": { "label": "API Server (HTTPS)", "onAutoForward": "notify" }
109 },
110
111 // Ensure the sibling worktrees directory exists on the host before the
112 // container starts; Docker bind mounts fail if the source path is
113 // missing. Runs on the host, so we can use POSIX `mkdir -p` safely.
114 "initializeCommand": "mkdir -p '${localWorkspaceFolder}.worktrees'",
115
116 // Mirror the host path INSIDE the container by bind-mounting the repo
117 // at its host absolute path. A second bind mount exposes the sibling
118 // `<repo>.worktrees` directory at the matching host path so that
119 // VS Code's Copilot CLI agent (which writes worktrees to a hardcoded
120 // `<dirname(repo)>/<basename(repo)>.worktrees`) resolves to the same
121 // location on host and container.
122 "workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind,consistency=cached",
123 "workspaceFolder": "${localWorkspaceFolder}",
124
125 "mounts": [
126 // Sibling worktrees directory bound at the same host path so the
127 // Copilot CLI agent worktree feature resolves identically on both
128 // sides.
129 "source=${localWorkspaceFolder}.worktrees,target=${localWorkspaceFolder}.worktrees,type=bind,consistency=cached",
130 // Global pnpm store - shared across containers for fast installs.
131 "source=pnpm-global-store,target=/home/codespace/.local/share/pnpm/store,type=volume",
132 // Per-container node_modules stays on a named volume. We deliberately
133 // do NOT bind-mount this to the host: native modules (better-sqlite3,
134 // etc.) are compiled for the container's libc/arch and would clash
135 // with anything the host has built.
136 "source=typeagent-node_modules-${devcontainerId},target=${containerWorkspaceFolder}/ts/node_modules,type=volume",
137 "source=claude-code-config-${devcontainerId},target=/home/codespace/.claude,type=volume",
138 "source=copilot-cli-config-${devcontainerId},target=/home/codespace/.copilot,type=volume",
139 // VS Code server data (extensions, settings cache, workspace storage, history)
140 // so editor state survives container recreate.
141 "source=vscode-server-${devcontainerId},target=/home/codespace/.vscode-server,type=volume"
142 ],
143
144 "containerEnv": {
145 "LOCAL_GIT_USER_NAME": "${localEnv:LOCAL_GIT_USER_NAME}",
146 "LOCAL_GIT_USER_EMAIL": "${localEnv:LOCAL_GIT_USER_EMAIL}"
147 },
148
149 "postCreateCommand": "bash .devcontainer/scripts/post-create.sh",
150 "postStartCommand": "bash .devcontainer/scripts/post-start.sh",
151
152 "customizations": {
153 "vscode": {
154 "extensions": [
155 "dbaeumer.vscode-eslint",
156 "esbenp.prettier-vscode",
157 "ms-python.python",
158 "ms-python.vscode-pylance",
159 "ms-dotnettools.csharp",
160 "ms-azuretools.vscode-azurefunctions",
161 "github.copilot",
162 "humao.rest-client"
163 ],
164 "settings": {
165 "editor.formatOnSave": true,
166 "editor.defaultFormatter": "esbenp.prettier-vscode",
167 "typescript.tsdk": "node_modules/typescript/lib",
168 "terminal.integrated.defaultProfile.linux": "zsh"
169 }
170 }
171 },
172
173 "remoteUser": "codespace",
174
175 "hostRequirements": {
176 "cpus": 4,
177 "memory": "8gb",
178 "storage": "32gb"
179 }
180}
181