A self-restart extension for GitHub Copilot CLI that enables agents to programmatically restart their own session — critical for workflows where new custom agents need to be discovered without manual intervention.
When you create a new custom agent at .github/agents/*.agent.md, the Copilot CLI's task tool doesn't discover it until a fresh session starts. There's no built-in way to restart the session from within the session itself.
This creates a frustrating workflow:
- Agent creates a new
.agent.mdfile ✅ - Agent tries to delegate to the new agent via
tasktool ❌ — not in the registry - User must manually close and reopen the terminal 😤
This extension solves that. It gives any agent the ability to restart its own session programmatically, with full session resume support.
The extension exposes a restart_session tool that orchestrates a controlled shutdown and respawn:
┌─────────────────────────────────────────────────────────────┐
│ Current Copilot CLI Session (PID 1234) │
│ │
│ Agent calls restart_session(reason="New agent created") │
│ │ │
│ ▼ │
│ Extension writes temp .ps1 script │
│ Extension calls execSync → Start-Process (new window) │
│ │ │
└───────┼─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ New Independent PowerShell Window │
│ │
│ 1. Stop-Process -Id 1234 (kills old runtime) │
│ 2. Start-Sleep -Seconds 3 (cleanup grace period) │
│ 3. Runs restart-copilot.ps1 │
│ → Ensures folder is trusted │
│ → Launches: copilot --add-dir . --resume=<sessionId> │
│ 4. Self-cleans the temp script │
│ │
└─────────────────────────────────────────────────────────────┘
On Windows, Node.js child_process.spawn() with detached: true creates headless processes that cannot spawn visible child windows. This is a well-known limitation — the spawned process inherits the console but can't create new independent window stations.
The working pattern this extension uses:
execSync(
`pwsh -NoProfile -Command "Start-Process -FilePath pwsh -ArgumentList @(...) -WorkingDirectory '...'"`,
{ cwd, timeout: 5000, windowsHide: false }
);This creates a fully independent visible process tree — a new PowerShell window that outlives the calling process and can spawn further visible windows. The new window then kills the old runtime and launches a fresh Copilot CLI session.
Copy the extension files into your project's extensions directory:
# From your project root
mkdir -p .github/extensions/self-restart
cp extension.mjs .github/extensions/self-restart/
cp restart-copilot.ps1 .github/extensions/self-restart/Install globally for all Copilot CLI sessions:
# Copy to user extensions directory
mkdir -p ~/.copilot/extensions/self-restart
cp extension.mjs ~/.copilot/extensions/self-restart/
cp restart-copilot.ps1 ~/.copilot/extensions/self-restart/Once installed, the restart_session tool is automatically available to all agents in the session.
| Parameter | Type | Required | Description |
|---|---|---|---|
reason |
string | No | Why the restart is needed (logged for debugging) |
new_session |
boolean | No | If true, starts a brand new session. If false (default), resumes the current session with --resume |
Resume current session (preserves conversation history):
restart_session(reason="Context window bloated after long session")
Fresh session (clean slate, new agent discovery):
restart_session(reason="New agent created: budget-review", new_session=true)
For production use, pair this extension with a Safe Restart Skill that wraps the restart in safety checks. Here's the full workflow:
- List background agents — call
list_agents()and verify none arerunning - Wait for running agents — if any are active, wait with
read_agent(..., wait=true)until they complete - Close idle agents — send a final message via
write_agent()then wait for completion - Save all work — commit uncommitted changes, update memory files
- Warn the user — notify via Telegram/chat that a restart is coming
- Call
restart_session— with appropriatereasonandnew_sessionflag
- Verify new agent is available — check that the
tasktool now lists the new agent type - Smoke test — launch a minimal delegation to the new agent to confirm it works
- Confirm to user — notify that restart completed successfully
# Safe Restart Skill
## When to Use
After creating a NEW agent file at `.github/agents/{name}.agent.md`
## Steps
1. Call `list_agents()` — ensure no background agents are running
2. If any running: `read_agent(agent_id, wait=true)` until complete
3. If any idle: `write_agent(agent_id, "Wrap up")` then wait
4. Save/commit any pending work
5. Notify user: "Restarting session to discover new agent: {name}"
6. Call `restart_session(reason="New agent: {name}", new_session=true)`
7. After resume: verify agent in task tool, run smoke test- Windows — uses PowerShell
Start-Processfor visible window spawning - PowerShell 7+ (
pwsh) — must be in PATH - GitHub Copilot CLI — the
copilotcommand must be available - Copilot Extension SDK —
@github/copilot-sdk(provided by the Copilot CLI runtime)
The restart-copilot.ps1 script handles the actual session launch:
- Resolves the working directory to an absolute path
- Ensures the folder is trusted — updates
~/.copilot/config.jsonso the CLI doesn't prompt for trust approval - Launches a new Copilot CLI session in an independent PowerShell window with:
--add-dirpointing to the project root (for extension/agent discovery)--yolofor autonomous operation--autopilotfor non-interactive mode--resume=<sessionId>(optional) to continue the conversation
Calling process.exit() from an extension kills the extension process, not the Copilot runtime. The runtime would detect the extension died and either restart it or continue without it — neither results in a session restart.
On Windows, detached Node.js processes inherit the console's window station but cannot create new visible windows. The spawned process runs headless, which means:
- It can't open a new terminal window for the fresh Copilot session
- The user can't see or interact with the new session
Start-Processcalled from a headless process also creates headless children
The execSync → Start-Process pattern breaks out of this by using PowerShell's native window management to create a truly independent process tree.
The extension uses process.ppid (parent PID) which is the Copilot CLI runtime process. Killing this process cleanly terminates:
- The runtime itself
- All child extension processes (including this one)
- The CLI's terminal UI
The 3-second sleep after the kill ensures all file handles are released before the new session starts.
- copilot-cli — GitHub Copilot in the terminal
- Copilot Extension SDK — Build custom tools for Copilot CLI
- htekdev/agent-mesh — Cross-session agent communication for Copilot CLI
MIT — see LICENSE