Skip to content

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-clawpilot on ssutheesh_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 MB app.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's ssutheesh_microsoft EMU; requires different MS-internal access.
  • Engine: built on @github/copilot-sdk v0.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 decompiled dist-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 by miniModeEnabled + startInMiniModeEnabled settings (persisted to disk).
  • Single-instance lock: enforced. Spawning a second Clawpilot.exe focuses 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 MemoryManager and m_remember store, 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 SetWindowPos to 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/focus events 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:focus IPC → bridge does SetForegroundWindow with AttachThreadInput trick
  • Renderer reflects connection state via body.clawpilot-connected / body.clawpilot-unavailable classes

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)

  1. Don't skip Phase 0 — read github.com/microsoft/clawpilot source 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).

  2. Run a 30-min spike on SetParent reparenting 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.

  3. 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.

  4. 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.

  5. 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."

  6. If forking is on the tablegithub.com/microsoft/clawpilot is 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.

  7. 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/clawpilot source if possible (need different MS-internal access than Sush's regular EMU)
  • 30-min SetParent spike 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 fc72665 is reusable