Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
c5632be
T3: Agents tab as a background-tasks list with search and an inline log
PieMH Oct 28, 2026
6673202
T2: model, effort and mode choosers as usage-style popups, model vers…
PieMH Oct 28, 2026
6530f23
T4: Files tab right-click menu (Open with, Show in File Explorer) and…
PieMH Oct 28, 2026
3c9b922
T1: Compose box shows known slash commands in blue anywhere in the te…
PieMH Oct 28, 2026
d6d95d6
T5: Installed list scrolls with the wheel, Discover pages the catalog…
PieMH Oct 28, 2026
18ad1db
T6: Account page in Settings: identity, Claude Code facts, read-only …
PieMH Oct 28, 2026
299b98e
T8: About window's Report a bug button opens a prefilled GitHub bug f…
PieMH Oct 28, 2026
315a58a
T7: Worktree switch in the top bar: new sessions launch with --worktr…
PieMH Oct 28, 2026
cd34496
T7b: Exited worktree tab resumes in the worktree root; Adopt re-roots…
PieMH Oct 28, 2026
911870a
T9: README, PRIVACY and CLAUDE.md in step with 1.2.0: new popups, tab…
PieMH Oct 28, 2026
5d6500d
F2: Explorer gets one raw quoted argument, overlay Resume checks the …
PieMH Oct 28, 2026
35749a3
F1: one model name helper (BarFormat.ModelName) for the Agents tab an…
PieMH Oct 28, 2026
a3b1246
F3: Console links on platform.claude.com (sourced, home as fallback),…
PieMH Oct 28, 2026
58501e9
F4: README test count 585 -> 595 (badge and xUnit line)
PieMH Oct 28, 2026
bf6b4ed
F5: resume's folder-gone dialog runs deferred, out of the WebView2 ha…
PieMH Oct 28, 2026
9e47fae
Model chooser reads Claude Code's cached model catalog instead of a h…
PieMH Oct 28, 2026
383e60c
A /rename in the TUI renames the tab
PieMH Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Bug report
description: Something in CCWrapper does not work as it should
labels: [bug]
body:
- type: input
id: app-version
attributes:
label: CCWrapper version
description: Shown under the name in the About window.
placeholder: "0.1.0"
validations:
required: true
- type: input
id: windows
attributes:
label: Windows version
- type: input
id: claude-version
attributes:
label: Claude Code version
description: The output of `claude --version`.
- type: textarea
id: what-happened
attributes:
label: What happened?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
placeholder: |
1.
2.
3.
- type: textarea
id: expected
attributes:
label: What did you expect to happen?
- type: textarea
id: logs
attributes:
label: Logs, error text or screenshots
description: "Optional. Remove anything private first: file paths, e-mail addresses, prompts, code and session content."
render: text
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: true
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ dotnet test
|---|---|
| `src/CCWrapper` (root) | `Program.cs`: the Velopack hook runs before WPF starts |
| `src/CCWrapper/Core` | Accounts and paths, `AppState`, the `LiveSession` contract the views bind to; `Housekeeping` (start-up deletes by age: pasted images, orphaned status line files); `DraftStore` (compose-box drafts, `drafts-<letter>.json`, saved on exit, before an update restart and when the app is deactivated with an update it knows of; another window's update restart can still lose the drafts of a window that has not seen the update); `AppUpdate` (auto-update), `AppPrefs` (`updateCheck`, `browserTool`) and `CompactPrefs` (`app.json`: each rewrites only its own key) |
| `src/CCWrapper/Data` | Read-only parsers for Claude Code's files (registry, transcripts, file history, `.claude.json`) and for what `claude plugin`/`mcp` print; `SlashCommands` (the `/` list, with enabled plugins' commands and skills), `UsageStats` (the usage popup's token counts); `SettingsData`, the Settings window's load-edit-save of `settings.json` and `CLAUDE.md`; `ClaudeJson`, locked updates of `.claude.json` |
| `src/CCWrapper/Data` | Read-only parsers for Claude Code's files (registry, transcripts, file history, `.claude.json`) and for what `claude plugin`/`mcp` print; `SlashCommands` (the `/` list, with enabled plugins' commands and skills and their `argument-hint`s, which the compose box greys after the command), `UsageStats` (the usage popup's token counts), `ModelCatalog` (the model chooser's list: the main models of the newest `cache\model-catalog\*-cc.json`, the catalog Claude Code fetches per account); `SettingsData`, the Settings window's load-edit-save of `settings.json` and `CLAUDE.md`; `AccountReader` (the Account page's facts: `.claude.json` identity and the read-only "other configuration", with a deny-list for secret-like keys); `PluginData` (also a plugin's manifest from `known_marketplaces.json` and `marketplace.json`, and `SourceUrl`, which yields only http/https); `ClaudeJson`, locked updates of `.claude.json` |
| `src/CCWrapper/Terminal` | ConPTY (`PtySession`), WebView2 + xterm.js (`TerminalHost`, `wwwroot/`), launch, paste, `UsageProbe`, `ProcessTree`, `ClaudeCli` (hidden `claude plugin`/`mcp` runs), `BrowserMcp`/`BrowserPipe` (the Browser tool: MCP handler and the window's named pipe) |
| `src/CCWrapper/Views` | WPF windows and controls; pure logic lives in static helpers (`ShellModel`, `BarFormat`, `TuiInput`) |
| `src/CCWrapper/Theme.xaml` | Every color and custom style; `App.xaml` recolors Fluent's own brushes |
| `src/CCWrapper.StatusRelay` | The silent relay, two jobs: the statusLine command, and with `--browser <pipe>` the stdio MCP server of the Browser tool (native AOT in releases; only the statusLine command is launched by 8.3 short path, as it is a shell command string, so install paths with spaces work; the `--browser` MCP command is the full path, spawned without a shell) |
| `scripts/`, `.github/workflows` | `pack.ps1` builds the Velopack release; `ci.yml` tests, `release.yml` publishes |
| `scripts/`, `.github/` | `pack.ps1` builds the Velopack release; `ci.yml` tests, `release.yml` publishes; `ISSUE_TEMPLATE/bug_report.yml` is the form About's Report a bug prefills (its field ids are the URL parameters) |
| Root `*.md`, `THIRD-PARTY-NOTICES.txt` | PRIVACY, TERMS, CODE_SIGNING_POLICY, SECURITY: the policies the About window and SignPath point to |
| `tests/CCWrapper.Tests` | xUnit, synthetic fixtures only (never real transcripts) |

Expand All @@ -57,8 +57,8 @@ dotnet test
`<id>.jsonl` and its `<id>\` folder (`SessionCatalog.Delete`), only after a confirm and never while a claude process
or tab has the session; it refuses any path outside the account's `projects\<dir>\<id>.jsonl`.
- **The browser tool drives only the Browser panel's WebView2** (its own user-data folder) through in-process CDP, one WebView2 per tab on the panel's one profile. Never the
terminal's WebView2, never a remote debugging port. The pipe is `CurrentUserOnly`, and the only launch flags it adds are
`--mcp-config` and `--append-system-prompt`. `browserTool` off: new tabs get no flags and `BrowserMcp` refuses calls from open ones.
terminal's WebView2, never a remote debugging port. The pipe is `CurrentUserOnly`, and the only launch flags it adds for the
tool are `--mcp-config` and `--append-system-prompt` (`--worktree` comes from the top bar's Worktree switch, not from the tool). `browserTool` off: new tabs get no flags and `BrowserMcp` refuses calls from open ones.
Hardened: each tools/call has a 60 s limit, `navigate`, `new_tab` and `window.open` (which opens a tab only when user-initiated, i.e. within Chromium's few seconds of activation after a click, a CDP click from `click` included, max 20, else dropped; `window.close()` closes only such pop-up tabs, and `DropControlsCloseHandler` stops WPF's WebView2 closing the whole window on it) pass only http, https, blob,
about:blank and data (`BrowserPanel.SchemeAllowed`), every page tool but `navigate` refuses while the front tab shows any other page (`OnUi` captures the front tab once per call and runs both checks, before and after the body, on that tab, whatever got it
there: history, the address bar; `tabs` lists such a tab as "(not a web page)", without title or URL), and `devtools` is an allow-list by domain (`BrowserMcp.DevToolsRefusal`) that denies cookies,
Expand Down
7 changes: 5 additions & 2 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@ If you write to the publisher (see Contact), the publisher handles your message
- Every session in the app is the unmodified `claude.exe` that you installed. It runs under your own login and under your own agreement with Anthropic. What it sends to Anthropic is covered by Anthropic's terms and privacy policy, not by this one.
- The app never reads `.credentials.json`. The app never calls Anthropic's APIs itself.
- To show plan usage, the app runs a hidden `claude "/usage"` through Claude Code. Claude Code contacts Anthropic as it does for any `/usage`, and saves the result in `.claude.json`.
- The Plugins & connectors window runs Claude Code's own `claude plugin` and `claude mcp` commands, only after you click. Those commands may contact plugin marketplaces and servers.
- The Plugins & connectors window runs Claude Code's own `claude plugin` and `claude mcp` commands, only after you click. Those commands may contact plugin marketplaces and servers. Opening a plugin's page there runs `claude plugin details` for it.
- The Account page in Settings and **Report a bug** in About run `claude --version`, which only prints the version.

### 3. Websites you open

- The Browser panel is a WebView2 browser. It loads only what you open in it, or what Claude opens in it (next point). Those sites see what any website sees, and may set cookies.
- Claude can use the Browser panel: each session gets it as a local MCP server (`ccwrapper-browser`), unless you turn it off in Settings → CCWrapper (`browserTool` in `app.json`). CCWrapper itself sends nothing new. The pages load only when Claude or you open them, in the panel's profile for the account, which is stored on your computer in `%LOCALAPPDATA%\CCWrapper\WebView2\browser-<letter>`, so those sites see your logins there, and what Claude runs in a page (the `evaluate` and `devtools` tools) acts with them. `devtools` refuses cookie access, downloads, local files, all simulated input (keyboard, mouse, touch and drag, so it cannot paste your clipboard), the page history and scripts that persist across pages. The panel has tabs, all in that one profile; a pop-up opened by a click opens a new tab (at most 20), one a page opens on its own is dropped (except in the few seconds after a click, Claude's clicks included, as in any browser), and a page's `window.close()` closes only a pop-up tab. Claude opens only `http`, `https`, `blob`, `about:blank` and `data` addresses, not local files, and a pop-up to any other address is dropped. Its tools act on the tab in front, can list, open, switch and close tabs (a tab that is not a web page is listed without title or address), and refuse to work on a page that is not a web address (for example a `file:` page you opened in the address bar yourself). All of this holds in every tab. The tool talks to its CCWrapper window through a named pipe on your own computer that only your Windows user can open. What Claude Code does with a page's text, screenshots or script results is covered in section 2, and Claude Code asks your permission per tool.
- A link in the terminal opens in the Browser panel if it points to your own computer (`localhost`), and in your default browser otherwise. Only `http` and `https` links open.
- Each account has its own browser profile, stored on your computer (see below).
- A few buttons open an address in your default browser, only when you click them, and only `http` and `https`: **View source** on a plugin's page (the plugin's source, as its marketplace gives it), and the account, usage and billing pages of Settings → Account.
- **Report a bug** in About opens GitHub's bug form (`.github/ISSUE_TEMPLATE/bug_report.yml`) in your default browser. The address carries the CCWrapper, Windows and Claude Code versions to prefill the form, so GitHub sees them when the page loads. Nothing else is added, and nothing is submitted until you do it on GitHub, where what you write is public (see above).

### 4. Microsoft Edge WebView2 Runtime

Expand Down Expand Up @@ -85,7 +88,7 @@ These files stay on your computer. The publisher cannot see them.

### Claude Code's files

- The app **reads** files that Claude Code already writes: each account's `.claude.json` (email, plan, cached usage), `settings.json`, transcripts, session status files, file-history backups, and plugin and skill lists. The usage popup (click the usage meters) adds up token counts from the transcripts, and the `/` list in the compose box reads the installed plugins' commands and skills. Both stay on your computer. It also asks `git` (and `gh`) about the folder you work in: branch, upstream, remote, your git user name and email, and your GitHub account name. It shows them in the top bar and sends them nowhere.
- The app **reads** files that Claude Code already writes: each account's `.claude.json` (email, plan, cached usage), `settings.json`, transcripts, session status files, file-history backups, and plugin and skill lists. The plugin page reads the marketplaces' `known_marketplaces.json` and the `marketplace.json` of the marketplace folder Claude Code cloned. The Account page shows the identity fields of `.claude.json` and its other preferences, read-only, with keys, tokens and similar secrets left out; it never reads `.credentials.json`. The usage popup (click the usage meters) adds up token counts from the transcripts, and the `/` list in the compose box reads the installed plugins' commands and skills. Both stay on your computer. It also asks `git` (and `gh`) about the folder you work in: branch, upstream, remote, your git user name and email, and your GitHub account name. It shows them in the top bar and sends them nowhere.
- The app **writes** to Claude Code's files only when you act:
- **Save** in the Settings window writes the `settings.json` and `CLAUDE.md` files you changed.
- A server's folder switch in Plugins & connectors changes the list of turned-off servers for that folder in `.claude.json`.
Expand Down
Loading