Clawpilot embed in Atlas HELM — research findings + post-mortem¶
Status: parked 2026-05-27. v2.2.0-clawpilot-tab attempted, reverted. Future attempt should read this file end-to-end before starting. Tag of the last good baseline:
v2.1.11-revert-clawpilotonssutheesh_microsoft/atlas-portfolio. Goal: embed Microsoft-internal Clawpilot inside Atlas HELM so Sush has one workflow (cockpit + AI chat) not two portals.
What Clawpilot is (Phase 0 source-read, 2026-05-27)¶
- Install path:
%LOCALAPPDATA%\Programs\Clawpilot\Clawpilot.exe(~222 MB exe + ~505 MBapp.asar) - Architecture: Electron (Chromium + Node 22+). Main process + renderer + bundled MCP servers (filesystem, Playwright-against-Edge) + bundled-skills folder (
docx,excalidraw,expense-report,loop,pptx,web-artifacts-builder,xlsx) - Source repo:
github.com/microsoft/clawpilot(Microsoft Enterprise GitHub —gim-home/m). NOT accessible via Sush'sssutheesh_microsoftEMU; requires different MS-internal access. - Engine: built on
@github/copilot-sdkv0.1.32 — same engine as GitHub Copilot CLI. Same Atlas, just GUI-wrapped. - Auth: GitHub device-flow OR MSAL for M365 access.
ms-clawpilot://URL protocol exists ONLY for MSAL OAuth callbacks — NOT for external context-passing (confirmed by reading the decompileddist-electron/main.js). - Teams Relay: Clawpilot also ships as a Teams app via
clawpilot-relay.azurewebsites.net. This IS the supported "talk to Clawpilot from outside" channel, but it's designed for remote (mobile Teams → desktop Clawpilot), not for sibling-app embedding. - Mini-mode: real product feature — separate small docked window with its own IPC channels (
mini-mode:setInteractive,mini-mode:showMainWindow, etc.). Controlled byminiModeEnabled+startInMiniModeEnabledsettings (persisted to disk). - Single-instance lock: enforced. Spawning a second
Clawpilot.exefocuses the existing one. No way to run two instances. - Main window class/title:
Chrome_WidgetWin_1+ literal title"Clawpilot"(chat session title is rendered INSIDE the window UI, not in the window-title bar). - Identity: has its own
MemoryManagerandm_rememberstore, separate from CLI Atlas's soul files (~/.copilot/copilot-instructions.md). The "one Atlas, many surfaces" rule survives manually — Sush writes important context to both. Same engine, different memory pool.
What's POSSIBLE for external integration (and what isn't)¶
| Vector | Works? | Notes |
|---|---|---|
| HTTP listener on a port | ❌ | Clawpilot opens zero listening TCP ports |
| Named pipe / Unix socket | ❌ | Not exposed |
ms-clawpilot:// deeplink for prompts |
❌ | Auth-only. Logging in source confirms: "Handled deep-link auth callback". No ?prompt= route. |
| Teams Relay | ✅ supported | But requires Teams bot identity + Azure relay. Overkill for sibling-app embedding. |
| Mini-mode window | ✅ exists | Controlled via in-app IPC, NOT externally. Settings file pre-write CAN trigger startup in mini-mode but feels intrusive. |
Win32 SetWindowPos (positioning Clawpilot's window) |
⚠️ technically works | But Z-order + DPI fragile, see Path A failure below |
Win32 SetParent (true reparenting inside HELM's BrowserWindow) |
⚠️ untested | Rubber-duck flagged as risky for Electron Chromium windows. Not attempted in this session. |
Embed mini-mode-page/index.html in <webview> |
❌ ships dead | The page depends on Clawpilot's main-process IPC bridge for everything — without it, it's a static shell. |
Fork Clawpilot's chat surface from github.com/microsoft/clawpilot |
✅ but expensive | 1+ week of engineering. Locks us to a frozen version, lose auto-updates. |
Win32 SetForegroundWindow (focus Clawpilot on demand) |
✅ works | Standard pattern. Use AttachThreadInput trick to lift Windows' focus-steal restrictions. |
What was attempted in v2.2.0 (Sushion 591b6a54, 2026-05-27 morning)¶
rc1: full window-positioning embed (abandoned)¶
- HELM main process launched Clawpilot at startup
- Used a PowerShell Win32 bridge to find Clawpilot's HWND
- Called
SetWindowPosto position Clawpilot at HELM's right-pane slot (x = helm.x + helm.width - 480,y = helm.y + 32,w = 480,h = helm.height - 32) - Tracked HELM
move/resize/focusevents to keep Clawpilot following - Added Z-order management via
SetWindowPos(clawpilotHwnd, helmHwnd, ...)to keep Clawpilot above HELM
Failure modes hit on real hardware (Sush's box):
1. Multi-monitor mismatch. Sush has monitor 1 (1664x1109 primary) + monitor 2 (1920x1080 at virtual x=2496). Clawpilot ended up at (2775, 108) on monitor 2 when our math computed (1072, 112) for monitor 1. Suspect: Electron's BrowserWindow.getBounds() returned different bounds than expected, OR Clawpilot's own logic moved it. Never fully diagnosed because diag logging didn't propagate inside packaged Electron.
2. Z-order race. Clawpilot at z-order BELOW HELM showed as "empty pane" — body's margin-right: 480px reserved space but Clawpilot wasn't visible there. Even after SetWindowPos(clawpilot, helmHwnd) to insert above HELM, focus changes shuffled it back.
3. Diagnostic blind spot. Packaged Electron's main-process console.log/stderr is invisible — had to write a file-based diag log. The log file never appeared, meaning manager init() may not have run, may have failed pre-log, OR appendFileSync was blocked. Never resolved.
rc2 / Path B: side-by-side launcher (also abandoned)¶
- Same bridge + manager, but stripped to bare minimum: spawn Clawpilot if needed, find HWND,
focus()on demand (no positioning) - Added "Clawpilot" tab in HELM nav — clicking calls
clawpilot:focusIPC → bridge doesSetForegroundWindowwithAttachThreadInputtrick - Renderer reflects connection state via
body.clawpilot-connected/body.clawpilot-unavailableclasses
Self-validated as working (Playwright self-test + view-tool screenshots):
- Tab in nav ✓
- Clawpilot auto-launched ✓
- Status {state: connected, hwnd: 67466} ✓
- Body class applied ✓
- Fallback warning correctly hidden when connected ✓ (after CSS fix)
But Sush rejected it (2026-05-27 09:13 NZST): "the clawpilot integration is not working and seamless like i thought".
The thing he wanted was "single workflow, single window — Clawpilot lives inside HELM." Path B delivered "two windows that launch together" — that's NOT the same UX. Visible seam, separate OS-window borders, focus-stealing weirdness. Functionally OK, emotionally wrong.
What to try NEXT TIME (recommendations from this session)¶
-
Don't skip Phase 0 — read
github.com/microsoft/clawpilotsource FIRST. If access via different MS-internal EMU is now possible, do that before any Win32 work. The asar-extracted version is at~/.copilot/session-state/591b6a54-1de9-4542-a77a-079ba239d967/files/clawpilot-asar/(505 MB, may want to delete if storage matters). -
Run a 30-min spike on
SetParentreparenting on Sush's actual hardware before deciding it's too risky. Rubber-duck called it fragile — but rubber-duck doesn't know your specific box. The duck's blanket "Chromium windows misbehave when reparented" claim should be tested empirically. If it works clean: that's the right architecture. If it doesn't: fall back to Path B with eyes open about why. -
Investigate the Microsoft Loop / Office App embedding pattern — Microsoft internal apps DO embed each other (Outlook embedding Teams in the sidebar, etc). There's probably a documented MS-internal pattern. Ask MS internal forums / WorkIQ / Frontier SE folks how they'd embed Clawpilot.
-
Consider the inverse architecture — instead of "HELM embeds Clawpilot", investigate "Clawpilot embeds HELM as a tab". Clawpilot already has the "Session/Gists" tab system. If Sush wanted HELM as a panel inside Clawpilot, that might be a cleaner ask since Clawpilot's UI is built to host multiple surfaces.
-
Investigate the Clawpilot Teams app + tab embed — the Teams JS SDK supports app-embedded panels. If HELM could be wrapped as a Teams tab, AND Clawpilot is also a Teams tab, they could coexist in a Teams workspace tab strip. Different UX but might satisfy "one workflow."
-
If forking is on the table —
github.com/microsoft/clawpilotis open-source-ish (MS-internal). Forking the chat surface code into HELM's renderer means we get true "Clawpilot inside HELM" with no Win32 hacks. Cost: ~1 week + the maintenance burden of staying in sync with Microsoft's updates. Likely the RIGHT answer eventually. -
Don't ship a half-embed thinking it'll feel like full embed. The 2026-05-27 session lesson: Path B's "two windows pretending to be one" failed Sush's emotional test even though it passed technical tests. If the next attempt can't deliver visual single-window UX, don't ship — write up findings and wait until we have a real path.
Artifacts preserved (don't delete without checking with Sush)¶
~/.copilot/session-state/591b6a54-1de9-4542-a77a-079ba239d967/files/
clawpilot-asar/ # full extracted Clawpilot source (~505 MB)
probe-clawpilot-hwnd.ps1 # working HWND discovery + Win32 probe
quick-bridge-test.mjs # working bridge sanity-test
self-test-v220-pathB.mjs # Playwright self-test for Path B
post-revert-validation.mjs # confirms v2.1.10 baseline after revert
diag-*.png # desktop screenshots from the rc1 + rc2 debug sessions
probe-bug-a-overflow-report.json # (also kept) v2.1.9 recap probe evidence
probe-bug-b-*.json # (also kept) v2.1.9 chat probe evidence
The PowerShell bridge code from v2.2.0 was useful and worked end-to-end (find-clawpilot, set-pos, focus, is-valid, save-placement / restore-placement). When the next attempt starts, pull the relevant bits from electron/clawpilot-bridge.ps1 in commit fc72665 — it's well-tested.
TL;DR for the next session¶
- Read
github.com/microsoft/clawpilotsource if possible (need different MS-internal access than Sush's regular EMU) - 30-min
SetParentspike on Sush's hardware FIRST - If SetParent fragile → consider fork-and-embed (1+ week, real cost)
- DON'T ship side-by-side and call it embedded
- Bridge code from
fc72665is reusable