Public/Start-Copilot.ps1
|
function Start-Copilot { <# .SYNOPSIS Starts GitHub Copilot CLI with all permissions, optionally in autopilot mode, resuming the most recent session for the current folder if one exists. .DESCRIPTION Wraps the GitHub Copilot CLI executable with automatic session resume and sensible defaults (--allow-all --experimental), each of which can be turned off with -NoAllowAll / -NoExperimental. Destructive git operations (force push, hard reset, rebase, amend, and similar) are denied by default; pass -NoDefaultDenyTools to opt out of those deny rules. When a Prompt is provided, runs in non-interactive autopilot mode (-p --autopilot). When no Prompt is provided, starts interactively. If exactly one previous session exists for the current directory it is resumed automatically. If multiple sessions exist, an interactive picker is shown -- except when only one of them is a *named* session (the rest being unnamed '(no summary)' stubs), in which case that lone named session is resumed automatically. When the picker is shown, unnamed '(no summary)' sessions are hidden if any named session exists; pass -IncludeUnnamed to list them too. Use -NoResume to skip session resume entirely, or -ResumeLatest to automatically resume the most recent session without prompting. Auto-generated maintenance sessions are ignored when choosing a session to resume. The prompt values "update" and "help" are treated as passthrough commands, forwarding all arguments directly to the copilot executable (e.g., copilot update, copilot help). .PARAMETER Prompt Prompt to execute. When provided, copilot runs non-interactively in autopilot mode and exits on completion. .PARAMETER Interactive Start interactive mode and automatically execute this prompt. Unlike -Prompt, the session remains interactive after the initial prompt completes. .PARAMETER NoResume Skip session resume even if a matching session exists. .PARAMETER NoAllowAll Do not pass --allow-all. By default Start-Copilot enables all permissions; use this switch to start with normal permission prompting. .PARAMETER NoDefaultDenyTools Do not add the built-in deny rules for destructive git operations (force push, hard reset, rebase, amend, git pull, and similar). Use this if your workflow relies on those commands; you can still add your own via -DenyTool. .PARAMETER ResumeLatest When multiple sessions exist for the current folder, automatically resume the most recently updated session instead of showing the interactive picker. .PARAMETER ResumeSession Resume a specific session directly, by session id, id-prefix, or name (passed to the CLI's --resume). Bypasses the auto-resume heuristics and the picker. Tab-completes the current folder's sessions. Mutually exclusive with -NoResume, -ResumeLatest, and -NoAutoResume. .PARAMETER NoAutoResume Disable auto-resume and always show the interactive session picker for the current folder, even when a session would otherwise be auto-resumed (including when only one session exists). Mutually exclusive with -NoResume, -ResumeLatest, and -ResumeSession. The former name -ShowPicker is retained as an alias for back-compat. .PARAMETER IncludeUnnamed Include unnamed '(no summary)' sessions in the interactive picker. By default the picker hides these stubs whenever at least one named session exists for the folder (if there are no named sessions, unnamed ones are always shown so the picker is never empty). Combine with -NoAutoResume to force the picker and list every session. Has no effect when no picker is shown (e.g. with -NoResume, -ResumeLatest, or -ResumeSession). .PARAMETER Model The AI model to use for the session. .PARAMETER Version Run a specific Copilot CLI engine version for this session, e.g. '1.0.55'. Maps to the engine's --prefer-version flag. When set, --no-auto-update is also added so an auto-update can't replace the pinned version mid-session. .PARAMETER Agent Specify a custom agent to use. .PARAMETER ReasoningEffort Set the reasoning effort level. .PARAMETER AddDir One or more directories to grant file access to. .PARAMETER MaxAutopilotContinues Maximum number of continuation messages in autopilot mode. .PARAMETER Silent Output only the agent response (no stats), useful for scripting with -Prompt. .PARAMETER Share Export session to a markdown file after completion in non-interactive mode. Optionally specify a file path; defaults to ./copilot-session-<id>.md. .PARAMETER ShareGist Export session to a secret GitHub gist after completion in non-interactive mode. .PARAMETER NoCustomInstructions Disable loading of custom instructions from AGENTS.md and related files. .PARAMETER AdditionalMcpConfig Additional MCP servers configuration as JSON string or file path (prefix with @). .PARAMETER AllowTool One or more tools to allow without confirmation. .PARAMETER DenyTool One or more tools to deny permission to use. .PARAMETER AllowUrl One or more URLs or domains to allow access to. .PARAMETER DenyUrl One or more URLs or domains to deny access to. .PARAMETER OutputFormat Output format for non-interactive mode. .PARAMETER LogLevel Set the log level. .PARAMETER NoAskUser Disable the ask_user tool so the agent works fully autonomously. .PARAMETER PluginDir One or more local plugin directories to load. .PARAMETER SecretEnvVars Environment variable names whose values are stripped and redacted. .PARAMETER ScreenReader Enable screen reader accessibility optimizations. .PARAMETER DisableMcpServer One or more MCP server names to disable at startup, in addition to any servers disabled by path-based autoConnect policy in the config. .PARAMETER EnableMcpServer One or more MCP server names to force-enable at startup, overriding path-based autoConnect policy in the config. .PARAMETER Name Set a name for the new session. Cannot be combined with session resume. .PARAMETER Mode Set the initial agent mode: interactive, plan, or autopilot. Supersedes the -Plan switch (which maps to -Mode plan for backward compat). .PARAMETER Plan Start in plan mode instead of interactive mode. Backward-compatibility alias for -Mode plan. .PARAMETER Connect Connect to a remote session. Optionally specify a session ID or task ID. .PARAMETER Attachment One or more file paths (images or documents) to attach to the initial prompt. Only valid with -Prompt (non-interactive mode). .PARAMETER Remote Enable remote control of the session from GitHub web and mobile. .PARAMETER NoRemote Disable remote control of the session from GitHub web and mobile. .PARAMETER Mouse Enable or disable mouse support in alt screen mode ('on' or 'off'). .PARAMETER PlainDiff Disable rich diff rendering (syntax highlighting via git's diff tool). .PARAMETER Stream Enable or disable streaming mode ('on' or 'off'). .PARAMETER AvailableTool Restrict the tools available to the model to only these tools. .PARAMETER ExcludedTool Exclude specific tools from being available to the model. .PARAMETER LogDir Override the log file directory (default: ~/.copilot/logs/). .PARAMETER AddGitHubMcpTool Add individual tools to enable for the GitHub MCP server (can be used multiple times). Use "*" for all tools. .PARAMETER AddGitHubMcpToolset Add toolsets to enable for the GitHub MCP server (can be used multiple times). Use "all" for all toolsets. .PARAMETER EnableAllGitHubMcpTools Enable all GitHub MCP server tools instead of the default CLI subset. .PARAMETER DisableBuiltinMcps Disable all built-in MCP servers (currently: github-mcp-server). .PARAMETER EnableReasoningSummaries Request reasoning summaries for OpenAI models. .PARAMETER SessionId Resume an existing session or task by UUID, or set the UUID for a new session. .PARAMETER NoColor Disable all color output (useful for piping or scripting). .PARAMETER Banner Show the startup banner. .PARAMETER NoAutoUpdate Disable automatic CLI update during the session. .PARAMETER DisallowTempDir Prevent automatic access to the system temporary directory. .PARAMETER Context Set the context window tier: 'default' or 'long_context'. Use 'long_context' for large codebases that need more context. .PARAMETER AllowAllPaths Disable file path verification and allow access to any path. .PARAMETER AllowAllUrls Allow access to all URLs without confirmation. .PARAMETER EnableMemory Enable the memory tools in prompt (-Prompt) mode. Memory is disabled by default in non-interactive mode. .PARAMETER MaxAiCredits Set the maximum AI credits to spend in this session. .PARAMETER AllowAllMcpServerInstructions Include initialization instructions from all MCP servers in the system prompt, instead of only allowlisted servers. .PARAMETER BashEnv Enable or disable BASH_ENV support for bash shells ('on' or 'off'). .PARAMETER NoBashEnv Disable BASH_ENV support for bash shells. .PARAMETER RemoteExport Export the session to GitHub web and mobile (read-only; does not enable remote control). .PARAMETER NoRemoteExport Disable exporting the session to GitHub web and mobile (also disables remote control). .PARAMETER ExtensionSdkPath Override the bundled @github/copilot-sdk injected into extension subprocesses with a local copilot-sdk/ folder (advanced; invalid paths fall back to the bundled SDK). .PARAMETER Acp Start as an Agent Client Protocol (ACP) server. .PARAMETER NoExperimental Do not pass --experimental. By default Start-Copilot opts into experimental features; use this switch to run with them off. .PARAMETER ChangeDir Change the working directory before doing anything else (maps to -C). Aliased as -C. .PARAMETER PassThru Do not launch. Compute the full launch plan — including the resolved executable and the complete argument vector (with the session-resume decision already applied) — and return it as a CopilotLaunchPlan object with Exe, Args, and Passthrough properties. Interactive session selection still runs so the returned plan reflects the real decision (pair with -DeferResume to skip it). Use this to build on top of Start-Copilot (for example, to wrap the launch with a different engine) without duplicating the argument or resume logic. .PARAMETER DeferResume Skip the automatic session-resume decision entirely: no interactive picker runs and no --resume argument is added, leaving session selection to the caller. Intended for -PassThru overlays that own their own multi-session orchestration. An explicit -ResumeSession still takes effect; -NoResume and the resume-mode switches are unaffected. .PARAMETER RemainingArgs Any additional arguments are passed through to the copilot executable. .EXAMPLE Start-Copilot # Starts an interactive Copilot session, auto-resuming if a session exists. .EXAMPLE Start-Copilot "Add unit tests for the auth module" # Runs the prompt in autopilot mode and exits on completion. .EXAMPLE Start-Copilot -Model claude-opus-4.7 -ReasoningEffort high # Starts with a specific model and high reasoning effort. .EXAMPLE Start-Copilot -ResumeLatest # Resumes the most recent session for this folder, even if multiple exist. .EXAMPLE Start-Copilot -NoResume -WhatIf # Renders the full copilot command line without launching a session. .EXAMPLE $plan = Start-Copilot -PassThru -Model claude-opus-4.7 # Returns @{ Exe; Args; Passthrough } without launching, so a caller can # reuse the built arguments (e.g. to launch a different engine). .EXAMPLE $plan = Start-Copilot -PassThru -DeferResume # Returns the plan with no --resume and no picker, so an overlay can make # the session-resume decision itself. #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Copilot')] [OutputType('CopilotLaunchPlan')] param( [Parameter(Position = 0)] [string]$Prompt, [string]$Interactive, [Parameter(ParameterSetName = 'CopilotNoResume', Mandatory)] [switch]$NoResume, [switch]$NoAllowAll, [switch]$NoDefaultDenyTools, [Parameter(ParameterSetName = 'CopilotResumeLatest', Mandatory)] [switch]$ResumeLatest, [Parameter(ParameterSetName = 'CopilotResumeSession', Mandatory)] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete) $sessionStateDir = Join-Path $env:USERPROFILE '.copilot' 'session-state' if (-not (Test-Path $sessionStateDir)) { return } $cwd = (Get-Location).Path Get-ChildItem $sessionStateDir -Directory | ForEach-Object { if ($_.Name -notlike "$wordToComplete*") { return } $wsFile = Join-Path $_.FullName 'workspace.yaml' if (-not (Test-Path $wsFile)) { return } $content = Get-Content $wsFile -Raw $sessionCwd = if ($content -match '(?m)^cwd:\s*(.+)$') { $Matches[1].Trim() } if ($sessionCwd -ne $cwd) { return } $summary = if ($content -match '(?m)^summary:\s*(.+)$') { $Matches[1].Trim() } $name = if ($content -match '(?m)^name:\s+(.+)$') { $Matches[1].Trim() } $display = $name ?? $summary ?? '(no summary)' [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $display) } })] [string]$ResumeSession, [Parameter(ParameterSetName = 'CopilotShowPicker', Mandatory)] [Alias('ShowPicker')] [switch]$NoAutoResume, [Alias('ShowUnnamed')] [switch]$IncludeUnnamed, [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete) @( 'claude-sonnet-4.6', 'claude-sonnet-4.5', 'claude-haiku-4.5', 'claude-opus-4.7', 'claude-opus-4.7-1m', 'claude-opus-4.6', 'claude-opus-4.5', 'claude-sonnet-4', 'gpt-5.5', 'gpt-5.4', 'gpt-5.3-codex', 'gpt-5.2-codex', 'gpt-5.2', 'gpt-5.4-mini', 'gpt-5-mini', 'gpt-4.1' ) | Where-Object { $_ -like "$wordToComplete*" } })] [string]$Model, [string]$Version, [string]$Agent, [ValidateSet('none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max')] [string]$ReasoningEffort, [string[]]$AddDir, [ValidateRange(1, [int]::MaxValue)] [int]$MaxAutopilotContinues, [switch]$Silent, [string]$Share, [switch]$ShareGist, [switch]$NoCustomInstructions, [string[]]$AdditionalMcpConfig, [string[]]$AllowTool, [string[]]$DenyTool, [string[]]$AllowUrl, [string[]]$DenyUrl, [ValidateSet('text', 'json')] [string]$OutputFormat, [ValidateSet('none', 'error', 'warning', 'info', 'debug', 'all', 'default')] [string]$LogLevel, [switch]$NoAskUser, [string[]]$PluginDir, [string[]]$SecretEnvVars, [switch]$ScreenReader, [string[]]$DisableMcpServer, [string[]]$EnableMcpServer, [string]$Name, [ValidateSet('interactive', 'plan', 'autopilot')] [string]$Mode, [switch]$Plan, [string]$Connect, [string[]]$Attachment, [switch]$Remote, [switch]$NoRemote, [ValidateSet('on', 'off')] [string]$Mouse, [switch]$PlainDiff, [ValidateSet('on', 'off')] [string]$Stream, [string[]]$AvailableTool, [string[]]$ExcludedTool, [string]$LogDir, [string[]]$AddGitHubMcpTool, [string[]]$AddGitHubMcpToolset, [switch]$EnableAllGitHubMcpTools, [switch]$DisableBuiltinMcps, [switch]$EnableReasoningSummaries, [string]$SessionId, [switch]$NoColor, [switch]$Banner, [switch]$NoAutoUpdate, [switch]$DisallowTempDir, [ValidateSet('default', 'long_context')] [string]$Context, [switch]$AllowAllPaths, [switch]$AllowAllUrls, [switch]$EnableMemory, [int]$MaxAiCredits, [switch]$AllowAllMcpServerInstructions, [ValidateSet('on', 'off')] [string]$BashEnv, [switch]$NoBashEnv, [switch]$RemoteExport, [switch]$NoRemoteExport, [string]$ExtensionSdkPath, [switch]$Acp, [switch]$NoExperimental, [Alias('C')] [string]$ChangeDir, [switch]$PassThru, [switch]$DeferResume, [Parameter(ValueFromRemainingArguments)] [string[]]$RemainingArgs ) # Delegate all argument building and the session-resume decision to the shared # Get-CopilotLaunchPlan core, so this launcher and any overlay that builds on # top compute identical command lines from one place. Forward every bound # parameter the core accepts (all base parameters plus common ones); -PassThru # and -WhatIf/-Confirm stay here because this function owns launching. $coreParams = (Get-Command Get-CopilotLaunchPlan).Parameters.Keys $planParams = @{} foreach ($kv in $PSBoundParameters.GetEnumerator()) { if ($kv.Key -ne 'PassThru' -and $coreParams -contains $kv.Key) { $planParams[$kv.Key] = $kv.Value } } $launchPlan = Get-CopilotLaunchPlan @planParams # -PassThru: return the resolved launch plan without executing. if ($PassThru) { return $launchPlan } $exitCode = $null if ($PSCmdlet.ShouldProcess("$($launchPlan.Exe) $($launchPlan.Args -join ' ')", 'Execute')) { & $launchPlan.Exe @($launchPlan.Args) $exitCode = $LASTEXITCODE } # If the engine exited non-zero it may have crashed out of its TUI and left the # terminal in a bad state. Reset it via the shared helper (guarded so the built # Shmuelie.Copilot doesn't require Shmuelie.Utilities). if ($null -ne $exitCode -and $exitCode -ne 0 -and (Get-Command Reset-TerminalModes -ErrorAction SilentlyContinue)) { Reset-TerminalModes } } |