DeskPilot.psd1

@{
    RootModule        = 'DeskPilot.psm1'
    ModuleVersion     = '0.5.0'
    GUID              = 'b8f3a2d1-7c4e-4a9b-9f1d-2e6c5a0b3d77'
    Author            = 'Raimund Andree'
    CompanyName       = 'Raimund Andree'
    Copyright         = '(c) Raimund Andree. MIT licensed.'
    Description       = 'DeskPilot is a local, desktop-style web UI that fronts the ShellPilot engine to give non-technical users the full GitHub Copilot agent toolset (browse, read/write files, run commands, skills, instructions) with visible permissions and honest cost - no terminal or IDE required. The web UI is bundled in the module and served on loopback; ShellPilot and a Copilot-enabled GitHub account are required.'
    PowerShellVersion = '7.0'
    FunctionsToExport = 'Start-DeskPilot'
    CmdletsToExport   = @()
    VariablesToExport = @()
    AliasesToExport   = @()
    PrivateData       = @{
        PSData = @{
            Tags         = @('Copilot', 'GitHubCopilot', 'ShellPilot', 'Agent', 'AI', 'GUI', 'AgenticOperatingModel', 'PSEdition_Core', 'Windows', 'Linux', 'macOS')
            LicenseUri   = 'https://github.com/raandree/DeskPilot/blob/main/LICENSE'
            ProjectUri   = 'https://github.com/raandree/DeskPilot'
            IconUri      = 'https://raw.githubusercontent.com/raandree/DeskPilot/main/source/web/assets/logo-mark.png'
            ReleaseNotes = '## [0.5.0-preview0023] - 2026-09-08

### Added

- Add **Terminal Amber** and **Terminal Green** themes with a bundled 3270 font, independent Light/Dark/System modes, and a Theme selector in General Settings. See [themes and font research](docs/themes.md).

- Add **Require a bot mention in groups** to Intercom Settings so unaddressed group Messages start no work and receive no reply; direct plain-text answers to the pending question in the same group need no mention, and private chats stay unchanged. See [group setup](docs/intercom-getting-started.md#require-a-mention-in-groups).

- **Allow Terminal commands for the current Turn.** Choose **Allow once** or
  **Allow for this Turn** in an ordinary Terminal approval. Reuse is limited to
  the same Conversation, Turn, Project, working directory, and execution policy;
  Stop or scope revocation invalidates it. Activity records the chosen scope.
  Browser and child approvals remain once-only, and no grant is persisted.

- **Add an opt-in complete private child with explicit estimated budgets.**
  Run one credentialless Engine with confined File and Terminal Tools, exact
  per-action approvals, hard local limits, Stop/recovery, and private proposals.
  Provider token/cost budgets are estimates, not invoice caps. Startup requires
  proof of current prepared bytes and fresh per-run consent; ordinary Turns,
  strict V2, and the real Project remain unchanged. No parallel execution or
  automatic proposal application is enabled. See
  [the V3 operator contract](docs/single-child-v3.md).

- **Add experimental child storage components and an explicit readiness gate.**
  Prove private byte/inode quotas, selected-file capture, proposal export,
  lease, Stop, and recovery without changing ordinary Turns. Full child startup
  was initially unavailable pending Engine request admission and integration;
  no parallel Agents or real Project application are enabled. See
  [status and component proof](docs/child-agent-isolation.md).

- **Add optional isolated Terminal execution in disposable Docker containers.**
  Keep Local behavior by default; opt in through Settings after preparing the
  runtime in Diagnostics. Isolated commands run in Linux with the selected
  Project read-only and network off by default. Explicitly grant read-write
  access, exact HTTPS origins, or selected environment variables when needed.
  Approvals and Activity show the boundary; resource limits, Stop, and cleanup
  govern each command. Requires Windows, Docker Desktop/WSL2, PowerShell 7.4+,
  and an Engine enforcing disabled Tools. There is no silent Local fallback.
  Returning to Local or removing the runtime does not undo Project edits.
  Other Tools are not isolated; a total read-write Project disk quota is not
  supported. See [setup, migration, and removal](docs/isolated-terminal.md).

- **DeskPilot can read a web page by working through it, not just fetching it.**
  A new **Browser** permission lets the agent open a page in a real browser,
  follow links, and read what it finds — the way you would click from a country
  list to a city to reach a forecast. It is off until you switch it on, and
  switching it on is separate from the existing Browsing permission, because
  fetching one address and driving a live page are not the same thing.

  The browser it opens is not yours. It is a throwaway with none of your
  sign-ins, saved passwords, history or extensions, it cannot open files on your
  computer, and it is closed when the turn ends.

  It stays on the site your task started from. If a page tries to send it
  somewhere else, DeskPilot stops *before* anything is contacted and asks you,
  showing the whole address — including the part after the question mark, which
  is where a hostile page hides what it is trying to smuggle out. Declining
  means it does not happen. Approving covers that one address, for that one run;
  if you want a site allowed permanently, you add it to the project in settings,
  never from the card.

  Reading a page is all it does unless you say otherwise — see the next entry.
  Addresses that could reach your own machine — local files, your network,
  numeric addresses, DeskPilot''s own controls — are refused outright and are
  never offered to you as a choice.

  Before it can run, DeskPilot needs Node.js and a browser it manages itself.
  It never installs either behind your back: **Diagnostics** reports what is
  missing and downloads the browser only when you ask it to.

- **The browser can fill in and send forms, but only where you allow it.**
  Reading a page is always available. Typing into one, pressing a button,
  attaching a file and saving a download are four separate permissions you grant
  **per project**, and a project starts with none of them.

  Every one of these stops and asks you, every single time. There is no "allow
  the rest of this turn": two button presses ask twice. The card shows you what
  actually happens — every field and the exact value going into it, the name of
  the button being pressed, the full path of the file being sent — because
  "submit a form" is not something anyone can sensibly say yes or no to. If a
  page tries to change the values after you have approved them, the approval no
  longer matches and nothing happens.

  **DeskPilot will not type into a password box, a one-time code, or a security
  question — ever, whatever the field is called.** It checks the real field on
  the page rather than trusting its name, and it hands sign-in back to you.

  A file you attach must be inside your project folder; anything else is refused
  before you are even asked. A file you download is put in a separate holding
  folder rather than into your project, so it never gets mistaken for your own
  work, and DeskPilot never opens or runs it.

- **The browser only goes where you said, not where the agent decides.**
  DeskPilot works out which sites are allowed from **your own message** — name a
  site and it is allowed for that task. It deliberately does not take this from
  the address the agent picks, because a page that had talked the agent into
  something could then send it anywhere without asking you.

  You are also asked when the agent invents a web address on a site you did name
  — a made-up search query rather than a link the page actually offered. Normal
  page-to-page navigation does not interrupt you.

  The browser now closes when a turn ends and when you press **Stop**, rather
  than when you next send a message. Diagnostics reports anything left behind
  after an unexpected shutdown and offers to close it, and can uninstall the
  downloaded browser without touching Node or the files you saved.

  You are asked about a web address the agent made up even when it is on a site
  you named — including one that hides what it is carrying in the path or after
  a `#`, not just after a `?`, and including one that hides it in the **web
  address itself**, such as `something-long.the-site-you-named.com`, or in the
  **capitalisation** of an address that otherwise matches a real link. Only the
  site''s own links, addresses you typed yourself, and the front page of a site
  you or your project named go through without interrupting you.

  A site is taken from your message only when you wrote its full address
  starting with `https://`. Note that DeskPilot cannot tell an address you typed
  from one you pasted, so a web address inside an error message or log you paste
  in counts too — everything reached through it is still subject to the same
  asking and the same refusals.

- **DeskPilot asks before it runs a command.** When per-call approval is on, the
  agent''s own terminal is taken away and replaced by DeskPilot''s, which stops and
  asks you first. The card shows the command exactly as it will run, the folder
  it will run in, and two buttons. Nothing has run when the card appears — the
  agent is waiting inside the tool — so **No** actually prevents it, rather than
  reporting it afterwards.

  You are not asked about everything. Routine read-only commands — `git status`,
  `git log`, `Get-ChildItem`, `ls`, `cat`, `--version` checks — run without
  interrupting you. Everything else asks, including anything DeskPilot does not
  recognise, and anything carrying a `;`, a pipe or a redirect, because those can
  hide a second command behind a harmless-looking first one. You can add your own
  commands to the list in settings; DeskPilot deliberately never offers to add
  one from the card itself.

  Approving is per command. There is no "allow everything for this turn", so two
  risky commands ask twice. Declining is not a failure: the agent is told you
  declined, and you can add a note telling it what to do instead. Your phone can
  answer too, and whichever answers first wins; a group chat can only approve
  when you switch that on separately. A request nobody answers is declined after
  15 minutes so it cannot hold the agent up.

  Off by default while the feature settles in — the reason is now the card''s
  operating experience, not the boundary. A turn parked for the full timeout on
  someone''s first unrecognised command is a bad first impression, so the default
  flips in a later slice.

### Fixed

- Show redacted error details when Terminal runtime preparation fails; report missing Docker Desktop as unavailable with installation guidance instead of generic disk-space and download advice. See [runtime troubleshooting](docs/isolated-terminal.md#if-preparation-fails).

- Fix Support bundle exports on Linux and macOS by including the hidden temporary archive when checking its size; destination protections and byte limits remain unchanged.

- **An approval card can no longer authorise text it never showed you.** A long
  command, web address or form value was shortened for the card with a
  "...[truncated]" marker while the whole string was still handed to the
  terminal or the page — so the part you never saw ran anyway. Form values were
  w'

            Prerelease   = 'preview0023'
        }
    }
}