ShellPilot.psd1
|
# # Module manifest for module 'ShellPilot' # # Generated by: raandree # # Generated on: 6/6/2026 # @{ # Script module or binary module file associated with this manifest. RootModule = 'ShellPilot.psm1' # Version number of this module. ModuleVersion = '0.4.0' # Supported PSEditions # CompatiblePSEditions = @() # ID used to uniquely identify this module GUID = 'd2a14b3e-8f6e-4a07-9c2d-1e5a6e3b9c01' # Author of this module Author = 'raandree' # Company or vendor of this module CompanyName = 'raandree' # Copyright statement for this module Copyright = '(c) raandree. All rights reserved.' # Description of the functionality provided by this module Description = 'GitHub Copilot in your PowerShell terminal: device-flow auth, model listing, chat and agentic tool-calling with usage and cost.' # Minimum version of the PowerShell engine required by this module PowerShellVersion = '7.4' # Name of the PowerShell host required by this module # PowerShellHostName = '' # Minimum version of the PowerShell host required by this module # PowerShellHostVersion = '' # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. # DotNetFrameworkVersion = '' # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. # ClrVersion = '' # Processor architecture (None, X86, Amd64) required by this module # ProcessorArchitecture = '' # Modules that must be imported into the global environment prior to importing this module RequiredModules = @() # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @() # Script files (.ps1) that are run in the caller's environment prior to importing this module. # ScriptsToProcess = @() # Type files (.ps1xml) to be loaded when importing this module # TypesToProcess = @() # Format files (.ps1xml) to be loaded when importing this module FormatsToProcess = @('ShellPilot.Format.ps1xml') # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. FunctionsToExport = @('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') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() # Variables to export from this module VariablesToExport = @() # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. AliasesToExport = @() # DSC resources to export from this module DscResourcesToExport = @() # List of all modules packaged with this module # ModuleList = @() # List of all files packaged with this module # FileList = @() # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. Tags = @('GitHubCopilot', 'Copilot', 'AI', 'LLM', 'Chat', 'Agent', 'PSEdition_Core') # A URL to the license for this module. LicenseUri = 'https://github.com/raandree/ShellPilot/blob/main/LICENSE' # A URL to the main website for this project. ProjectUri = 'https://github.com/raandree/ShellPilot' # A URL to an icon representing this module. IconUri = 'https://raw.githubusercontent.com/raandree/ShellPilot/main/assets/shellpilot-icon.png' # ReleaseNotes of this module ReleaseNotes = '## [0.4.0-preview0016] - 2026-09-30 ### 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' # Prerelease string of this module Prerelease = 'preview0016' # Flag to indicate whether the module requires explicit user acceptance for install/update/save # RequireLicenseAcceptance = $false # External dependent modules of this module # ExternalModuleDependencies = @() } # End of PSData hashtable } # End of PrivateData hashtable # HelpInfo URI of this module # HelpInfoURI = '' # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' } |