microsoft/TypeAgent

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
dev/georgeng/autogen-cicd

Branches

Tags

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

Clone

HTTPS

Download ZIP

.devcontainer/scripts/start-devcontainer.sh

206lines · modecode

1#!/usr/bin/env bash
2# Copyright (c) Microsoft Corporation.
3# Licensed under the MIT License.
4
5set -euo pipefail
6
7SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
8REPO_ROOT=$(cd -- "$SCRIPT_DIR/../.." && pwd)
9DEFAULT_WORKSPACE_FOLDER="$REPO_ROOT"
10
11usage() {
12 cat <<EOF
13Usage: $(basename "$0") [options]
14
15Start the TypeAgent devcontainer. Optionally configure host SSH access.
16
17Options:
18 --workspace-folder PATH Workspace folder to open (default: repo root)
19 --config PATH|NAME Devcontainer config file. Accepts a path or
20 a short name resolved against .devcontainer/:
21 vnc -> .devcontainer/vnc/devcontainer.json
22 agent -> .devcontainer/agent/devcontainer.json
23 --recreate Recreate container before startup
24 --rebuild Rebuild image and recreate container before startup
25 --clean Remove container and associated Docker volumes
26 --reset Rebuild image and clean volumes (--rebuild + --clean)
27 --ssh After startup, run setup-ssh-access.sh
28 --insecure-local Pass through to setup-ssh-access.sh (implies --ssh)
29 -h, --help Show this help text
30
31Examples:
32 $(basename "$0")
33 $(basename "$0") --ssh
34 $(basename "$0") --recreate --ssh
35 $(basename "$0") --rebuild
36 $(basename "$0") --config vnc
37 $(basename "$0") --config agent
38EOF
39}
40
41log() {
42 printf '[start-devcontainer] %s\n' "$*"
43}
44
45fail() {
46 printf '[start-devcontainer] Error: %s\n' "$*" >&2
47 exit 1
48}
49
50read_git_identity() {
51 local key=$1
52 git config --global --get "$key" 2>/dev/null || true
53}
54
55WORKSPACE_FOLDER="$DEFAULT_WORKSPACE_FOLDER"
56CONFIG_PATH=""
57REMOVE_EXISTING=0
58REBUILD=0
59CLEAN_VOLUMES=0
60SETUP_SSH=0
61INSECURE_LOCAL=0
62
63while [[ $# -gt 0 ]]; do
64 case "$1" in
65 --workspace-folder)
66 [[ $# -ge 2 ]] || fail "Missing value for $1"
67 WORKSPACE_FOLDER=$(cd -- "$2" && pwd)
68 shift 2
69 ;;
70 --config)
71 [[ $# -ge 2 ]] || fail "Missing value for $1"
72 # Allow short names (e.g. `vnc`, `agent`) that resolve to
73 # .devcontainer/<name>/devcontainer.json. Anything containing a
74 # slash or ending in .json is treated as a literal path.
75 _cfg_arg=$2
76 if [[ "$_cfg_arg" != */* && "$_cfg_arg" != *.json ]]; then
77 _short="$REPO_ROOT/.devcontainer/$_cfg_arg/devcontainer.json"
78 if [[ -f "$_short" ]]; then
79 _cfg_arg="$_short"
80 else
81 fail "Unknown config short name '$_cfg_arg' (expected $_short)"
82 fi
83 fi
84 CONFIG_PATH=$(cd -- "$(dirname -- "$_cfg_arg")" && pwd)/$(basename -- "$_cfg_arg")
85 shift 2
86 ;;
87 --recreate|--remove-existing-container)
88 REMOVE_EXISTING=1
89 shift
90 ;;
91 --rebuild)
92 REMOVE_EXISTING=1
93 REBUILD=1
94 shift
95 ;;
96 --clean)
97 REMOVE_EXISTING=1
98 CLEAN_VOLUMES=1
99 shift
100 ;;
101 --reset)
102 REMOVE_EXISTING=1
103 REBUILD=1
104 CLEAN_VOLUMES=1
105 shift
106 ;;
107 --ssh)
108 SETUP_SSH=1
109 shift
110 ;;
111 --insecure-local)
112 SETUP_SSH=1
113 INSECURE_LOCAL=1
114 shift
115 ;;
116 -h|--help)
117 usage
118 exit 0
119 ;;
120 *)
121 fail "Unknown argument: $1"
122 ;;
123 esac
124done
125
126if ! command -v docker >/dev/null 2>&1; then
127 fail "docker is required"
128fi
129
130if command -v devcontainer >/dev/null 2>&1; then
131 DEVCONTAINER_CMD=(devcontainer)
132else
133 DEVCONTAINER_CMD=(npx -y @devcontainers/cli)
134fi
135
136HOST_GIT_USER_NAME=$(read_git_identity user.name)
137HOST_GIT_USER_EMAIL=$(read_git_identity user.email)
138
139if [[ -n "$HOST_GIT_USER_NAME" ]]; then
140 export LOCAL_GIT_USER_NAME="$HOST_GIT_USER_NAME"
141 log "Using host git user.name from ~/.gitconfig"
142fi
143if [[ -n "$HOST_GIT_USER_EMAIL" ]]; then
144 export LOCAL_GIT_USER_EMAIL="$HOST_GIT_USER_EMAIL"
145 log "Using host git user.email from ~/.gitconfig"
146fi
147
148UP_CMD=("${DEVCONTAINER_CMD[@]}" up --workspace-folder "$WORKSPACE_FOLDER")
149if [[ -n "$CONFIG_PATH" ]]; then
150 UP_CMD+=(--config "$CONFIG_PATH")
151fi
152if [[ $REMOVE_EXISTING -eq 1 ]]; then
153 UP_CMD+=(--remove-existing-container)
154fi
155if [[ $REBUILD -eq 1 ]]; then
156 UP_CMD+=(--build-no-cache)
157fi
158
159if [[ $CLEAN_VOLUMES -eq 1 ]]; then
160 # Stop and remove the container first so volumes are no longer in use
161 CONTAINER_ID=$(docker ps -aq --filter "label=devcontainer.local_folder=$WORKSPACE_FOLDER" | head -1)
162 if [[ -n "$CONTAINER_ID" ]]; then
163 log "Stopping container $CONTAINER_ID..."
164 docker rm -f "$CONTAINER_ID" >/dev/null 2>&1 || true
165 fi
166
167 log "Removing Docker volumes..."
168 VOLUME_PREFIXES=(
169 "pnpm-global-store"
170 "typeagent-node_modules-"
171 "claude-code-config-"
172 "copilot-cli-config-"
173 )
174 for prefix in "${VOLUME_PREFIXES[@]}"; do
175 for vol in $(docker volume ls -q --filter "name=^$prefix" 2>/dev/null); do
176 if err=$(docker volume rm "$vol" 2>&1); then
177 log " removed $vol"
178 else
179 log " warn: could not remove $vol: $err"
180 fi
181 done
182 done
183fi
184
185log "Starting devcontainer..."
186"${UP_CMD[@]}"
187
188if [[ $SETUP_SSH -eq 1 ]]; then
189 SSH_SETUP_CMD=("$SCRIPT_DIR/setup-ssh-access.sh" --workspace-folder "$WORKSPACE_FOLDER")
190 if [[ -n "$CONFIG_PATH" ]]; then
191 SSH_SETUP_CMD+=(--config "$CONFIG_PATH")
192 fi
193 if [[ $INSECURE_LOCAL -eq 1 ]]; then
194 SSH_SETUP_CMD+=(--insecure-local)
195 fi
196
197 log "Configuring SSH access..."
198 "${SSH_SETUP_CMD[@]}"
199
200 printf '\nDone. Connect with:\n'
201 printf ' ssh typeagent-devcontainer\n'
202else
203 printf '\nDone. Devcontainer is running.\n'
204 printf 'To set up host SSH access, re-run with --ssh, or invoke:\n'
205 printf ' %s/setup-ssh-access.sh\n' "$SCRIPT_DIR"
206fi
207