ShellPilot

0.4.0-preview0015

GitHub Copilot in your PowerShell terminal: device-flow auth, model listing, chat and agentic tool-calling with usage and cost.

Minimum PowerShell version

7.4

This is a prerelease version of ShellPilot.
There is a newer prerelease version of this module available.
See the version list below for details.

Installation Options

Copy and Paste the following command to install this package using PowerShellGet More Info

Install-Module -Name ShellPilot -RequiredVersion 0.4.0-preview0015 -AllowPrerelease

Copy and Paste the following command to install this package using Microsoft.PowerShell.PSResourceGet More Info

Install-PSResource -Name ShellPilot -Version 0.4.0-preview0015 -Prerelease

You can deploy this package directly to Azure Automation. Note that deploying packages with dependencies will deploy all the dependencies to Azure Automation. Learn More

Manually download the .nupkg file to your system's default download location. Note that the file won't be unpacked, and won't include any dependencies. Learn More

Owners

Copyright

(c) raandree. All rights reserved.

Package Details

Author(s)

  • raandree

Tags

GitHubCopilot Copilot AI LLM Chat Agent

Functions

Clear-ShpChat Clear-ShpContext Clear-ShpRedactionPolicy Clear-ShpToolPolicy Clear-ShpUsage Compress-ShpChat ConvertTo-ShpAnnotation ConvertTo-ShpOtelTrace ConvertTo-ShpTokenCount Get-ShpChat Get-ShpChatCheckpoint Get-ShpContext Get-ShpContextReport Get-ShpCosineSimilarity Get-ShpCostEstimate Get-ShpDefault Get-ShpMcpServer Get-ShpModel Get-ShpModelName Get-ShpRedactionPolicy Get-ShpTool Get-ShpToolPolicy Get-ShpUsage Initialize-Shp Invoke-Shp Invoke-ShpBatch Invoke-ShpEval Invoke-ShpSubagent Register-ShpMcpServer Register-ShpTool Request-ShpEmbedding Resolve-ShpError Restore-ShpChat Save-ShpChat Select-ShpModel Set-ShpContext Set-ShpRedactionPolicy Set-ShpToolPolicy Start-ShpChat Test-ShpCiReadiness Unregister-ShpMcpServer Unregister-ShpTool

PSEditions

Core

Dependencies

This module has no dependencies.

Release Notes

## [0.4.0-preview0015] - 2026-09-25

### Security

- Gate every tool class from one policy. `Set-ShpToolPolicy` gains `Url`, `Mcp`
 and `Tool` rule kinds beside `Read`, `Write` and `Shell`, each matched
 against a resolved form rather than the string the model supplied: a
 normalised address, the `alias/tool` a call will dispatch under, and an exact
 tool name. A deny beats every matching allow. Name the
 `RestrictedUnattended` trust profile to enforce all six kinds at once, so an
 unattended run may do only what is listed. An `Mcp` rule gates tool identity,
 not the arguments inside the call.

- Keep a Copilot credential out of a backend that is not Copilot. An
 alternative backend - `-ApiBase`, the session context,
 `$env:SHELLPILOT_API_BASE`, or a caller-owned request transport - now
 resolves no GitHub host, reads no OAuth token from any source, and exchanges
 no Copilot session token, in `Invoke-Shp` and `Request-ShpEmbedding` alike. A
 pipeline pointed at its own endpoint therefore needs no GitHub sign-in at
 all, and `Test-ShpCiReadiness` reports `TokenSource` as `NotRequired`
 instead of raising a standing issue. The Copilot backend is unchanged.

- Refuse a Skill or Instruction body whose bytes changed after the caller
 approved it. Every file that shapes the model's behaviour is fingerprinted
 when it is catalogued and re-checked when it is loaded, so a body swapped
 between the description the caller read and the content the model receives is
 denied with a reason instead of injected. The result carries
 `ResourceProvenance` - source root, relative path, hash, size, trust and
 validation state - for every load attempt, so it is possible to establish
 after a surprising answer exactly which bytes the model was given. Nothing is
 discovered: every root is still one the caller named.

- Bound a Subagent to what dispatched it. `Invoke-ShpSubagent` can only narrow
 the tool policy, redaction policy, tool visibility and budget it inherited,
 never widen them, and depth, fan-out, concurrency and duration are capped
 before any credential work. A child returns its answer and evidence rather
 than its transcript, so its exploration never enters the parent's context
 window, and a handed-back capability cannot arrive without the controls it
 was given.

- Decide a Tool call, or contain it, from outside the model. `-ToolCallControl`
 is consulted before dispatch and after a result exists and may allow, deny
 with a reason, or modify the arguments or the result; `-ExecutionContract`
 wraps covered dispatch for a caller who supplies containment of their own.
 Each stage can only narrow: a control is asked only about a call the Tool
 policy already allowed, and arguments a control rewrote are re-checked
 against the policy before dispatch. Both take a scriptblock or a command
 name, are validated before the first request, and are never discovered from
 disk. Neither is a sandbox.

- Reach a remote MCP server only where it was approved to be reached. A
 Streamable HTTP attachment validates its endpoint at registration and again
 before every request and every redirect, requires HTTPS unless a loopback
 opt-in is given, refuses embedded credentials, refuses an address that is not
 publicly routable, and pins the approved address set so a later answer -
 redirect target or re-resolution - cannot move the connection. The body,
 stream events and redirect chain are capped. Authorization is only what the
 caller supplies through a header or a per-request credential callback: a 401
 is reported by name rather than answered with whatever token is in reach, and
 nothing is cached or written to disk.

- Correct embedding backend precedence and prevent a Copilot Session token
 from reaching a keyless alternative backend. Environment-selected backends
 now use the shared resolver. See [embeddings](README.md#embeddings-and-similarity).
- Apply protected environment-assignment checks to colon-bound PowerShell
 parameter arguments as well as separate arguments.

- Limit `run_command` to a minimal environment and refuse execution-sensitive
 literal environment assignments before child startup, even without a Tool
 policy. See [command environment](README.md#command-environment).

- **Protect Unix `edit_file` staging from creation.** Apply the source file
 mode when creating the empty temporary file, before any content is copied,
 so a private source is not temporarily exposed through default permissions.

- **Keep `edit_file` on the target approved by the tool policy.** Repointing
 the original directory alias after authorization no longer redirects the
 edit to a different file. Confirmation names the authorized target. Refuse
 special files again after staging so a named-pipe swap cannot block the
 final content check. External filesystem races remain outside the tool's
 guarantees.

- **Tool policy refuses paths when link resolution fails.** A missing runtime
 API or filesystem error no longer leaves an unresolved path eligible for
 Read or Write access. This prevents a junction inside an allowed directory
 from bypassing rules for its destination on an unsupported runtime.

- **A disabled tool can no longer be executed.** `-DisableTerminal`,
 `-DisableFileAccess`, `-DisableBrowsing`, `-DisableUserPrompts` and
 `-DisableTodoList` removed a tool from the set offered to the model, but the
 dispatch switch matched built-in tool names unconditionally — so a model that
 named a disabled tool anyway, from its own priors or from a replayed history,
 had it run. `-DisableTerminal` bounded what was advertised and nothing about
 what executed.

 Dispatch now refuses any built-in that this call did not offer, before the
 tool runs. The refusal reuses the existing tool-policy path: the `tool.call`
 event carries `policy = denied`, the reason names the disabled tool, the call
 appears on `ToolCallsDenied`, and the model receives `{"denied": "..."}` so it
 can choose another route instead of failing the turn. The offered set is
 derived from the assembled tool list rather than re-tested against each
 switch, so a tool added later cannot be offered under one condition and
 dispatched under another.

- **`Register-ShpTool` refuses a built-in tool name.** Dispatch matches built-in
 names before it consults the user tool table, so registering `run_command`,
 `read_file` or any other built-in produced a tool that was advertised to the
 model and then silently ignored while the built-in ran instead — with the
 caller believing it had replaced it. An attached MCP server has always been
 refused a colliding name; a local registration now fails the same way, loudly
 and at registration time. Choose a distinct `-ToolName`.

### Added

- Grade agent behaviour without spending anything. `Invoke-ShpEval` runs a case
 suite through the real Tool-calling loop with the model replaced by a
 scripted transport, so it sends no request, reads no credential and exchanges
 no token, and a behaviour regression is caught by the ordinary test gate
 rather than by a credentialed job. Outcome, trajectory and cost are graded
 separately, because an agent that reached the right answer by running a
 forbidden command has still failed. A grader this module does not implement
 is an error rather than a pass, reliability is reported over repeated trials
 instead of a single green run, and credentialed live canaries are skipped
 unless they are explicitly asked for.

- Add `Invoke-ShpSubagent` for dispatching part of a task to a child turn with
 its own model, reasoning effort, tool set and system prompt, read from an
 agent definition file the caller names. The child's answer and evidence come
 back, never its transcript, so a broad exploration costs the parent an answer
 instead of a conversation. The whole tree shares one budget ledger.

- Add `-ToolCallControl` and `-ExecutionContract` to `Invoke-Shp` and
 `Invoke-ShpBatch`. A control receives one typed, versioned, independent
 request per Tool call - identifiers that correlate with the Event stream, the
 tool and its provenance, the original and effective arguments, and the result
 in the post phase - and answers with a decision. Every decision is recorded
 on the result's `ToolCallDecisions` as a receipt and as a `tool.decision`
 Event, so an unattended run can show afterwards what was approved, what was
 rewritten and what was refused.

- Add `Get-ShpContextReport` to price a call before sending it, and
 `Invoke-Shp -ContextReport` / `Invoke-ShpBatch -ContextReport` to attribute a
 call after it. The report breaks the context window down by source - system
 prompt, instructions, skills, tool schemas, attachments, history, this turn -
 so hitting a context limit says what filled it, and the saving from deferred
 tool loading is measurable rather than asserted. The pre-call report sends no
 request and needs no credential.

- Add `Compress-ShpChat -Focus` to steer compaction: one short instruction
 naming what the compression must try to keep, applied as a drop-order
 preference over whole exchanges. Anchors, the estimator and the default are
 unchanged, and omitting `-Focus` compacts exactly as before.

- Add `-ToolResultSpillRoot` to `Invoke-Shp` and `Invoke-ShpBatch` so an
 oversized Tool result is written in full to a caller-named directory and the
 model receives a window plus the path, instead of a truncated result it
 cannot ask for the rest of. One seam covers every producer, and the spilled
 content composes with `read_file`'s existing offset and limit.

- Add `Save-ShpChat`, `Restore-ShpChat` and `Get-ShpChatCheckpoint` to save a
 conversation, inspect its checkpoints, resume it, and roll it back to an
 earlier turn, plus `Invoke-Shp -SaveChatPath` to checkpoint a turn as it
 completes. Content is written only to a path the caller names - never
 discovered, never defaulted - redaction is appl

FileList

Version History

Version Downloads Last updated
0.4.0-previe... 11 9/30/2026
0.4.0-previe... (current version) 10 9/25/2026
0.4.0-previe... 13 9/7/2026
0.4.0-previe... 4 9/7/2026
0.4.0-previe... 5 9/6/2026
0.4.0-previe... 9 9/6/2026
0.4.0-previe... 8 8/26/2026
0.4.0-previe... 5 8/24/2026
0.4.0-previe... 10 8/19/2026
0.4.0-previe... 6 8/12/2026
0.4.0-previe... 8 8/12/2026
0.4.0-previe... 7 8/11/2026
0.4.0-previe... 4 8/11/2026
0.4.0-previe... 11 8/6/2026
0.4.0-previe... 12 7/28/2026
0.4.0-previe... 4 7/28/2026
0.3.1 119 7/23/2026
0.3.1-previe... 4 7/23/2026
0.3.0-previe... 9 7/12/2026
0.3.0-previe... 8 7/9/2026
0.3.0-previe... 5 7/9/2026
0.3.0-previe... 8 7/9/2026
0.2.1-previe... 9 7/8/2026
0.2.0 39 7/8/2026
0.2.0-previe... 7 7/8/2026
0.2.0-previe... 5 7/8/2026
0.2.0-previe... 32 6/12/2026
Show more