Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Mellow PeekNew to Visual Studio Code? Get it now.
Mellow Peek

Mellow Peek

Preview

Mellow

|
3 installs
| (0) | Free
Team awareness for the agent era: what colleagues and their coding agents are doing, in your editor.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Mellow Peek for VS Code

Viewer for the Mellow Peek feed, plus human presence. Runs in VS Code and Cursor.

The extension is a client of the local mellow-peek daemon. It shows what your teammates and their coding agents are doing, marks files another session has claimed, and reports this editor window as a vscode-human session if you let it. Install the mellow-peek binary first; the extension does not ship it.

Install

Install mellow.mellow-peek from the VS Code Marketplace or Open VSX (pre-release for now: "Switch to Pre-Release Version"). It needs the mellow-peek daemon. When none is running, the extension offers to install it: it downloads the newest mellow-peek of its channel (insiders for a pre-release build) from releases.mellow.build, verifies it against the TUF root shipped in the extension (resources/tuf/root.json), puts it in ~/.local/bin (%LOCALAPPDATA%\Programs\mellow-peek on Windows) with the harness plugins in the config directory, starts the daemon as a user service, and offers mellow-peek init. It never installs over a mellow-peek that is already there (on PATH, in ~/.local/bin, or from Homebrew). Turn the offer off with mellowPeek.daemon.offerInstall; "Mellow Peek: Install and Start Daemon" runs it any time. The install script in the repository README does the same from a terminal. Publication steps are in docs/RELEASING.md.

What you get

Surface What it shows
Feed view Topics, newest first. Each topic is two lines: the title, then who, how long ago, the repository (a remote as owner/name, a remote-less checkout by the folder name its sender gave; a parent topic shows its sub-topics' repositories), who did the work (agent, 2 agents + editor, from the sessions' harnesses; a *-human harness is the person's editor), and the team. Click a topic to read its summary sentence, with sub-topics nested under it and earlier or merged versions and the facts and agent replies it covers folded under it; a fact belongs to the topic that names its session, so nothing about work sits at the top level. Besides topics the top level holds team joins and leaves and notes addressed to you, each on one line. A brand-new session shows up when its first topic lands (seconds after it goes quiet); the Sessions view has it at once. Each summary reads as written ("lukasfri is wiring the network node into the daemon in peek…") and the facts it covers fold under it; session facts read as "ada started a claude-code session in …", "ada is now working on ", "ada finished <title> (exit)", plus agent messages, directives and team changes. Running/idle flips are hidden unless <code>mellowPeek.feed.showStatusChanges</code>. Filter by team, repository, or person from the view title; defaults to the repository of the first workspace folder. Updates live. The trash icon clears the feed on the daemon (<code>feed.clear</code>); live sessions stay. On top, one card per team whose <strong>team digest</strong> you turned on: what your teammates are doing, with a line per teammate when opened (<code>digest.get</code>; hidden under a person or repository filter).</td> </tr> <tr> <td><strong>Sessions</strong> view</td> <td><strong>+</strong> creates a team for the open repository (a peer-to-peer team about it, linked for you and published as <code>.mellow/peek/team.toml</code> for teammates to discover); each team lists its <strong>Repositories</strong> next to Members (whether you share each one; admins add repositories from a multi-select of the workspace's folders or any folder, remove them, and make the team strict or open), and its <strong>My links</strong> setting says which of your checkouts it hears about; the link icon on a team you are an admin of copies an invite. Each team's description says when you are its owner or an admin, and its tooltip names the owner and admins. Right-click a team, or hover it for the Leave and Delete buttons, to copy its id, to <strong>Publish Team File…</strong>, to <strong>Leave Team…</strong> (not offered to the owner), or, as its owner, to <strong>Delete Team…</strong>: a relay team is deleted on its relay for everyone; a peer-to-peer team's key is destroyed, so nobody can be made admin again (admins can still admit and remove people). Both confirm first, and Delete asks you to type the team name. Under each team, <strong>Settings</strong> shows what you share with it, each row with its current value: your <strong>Scope</strong> (personal teams: all repositories or an allowlist picked from your open folders and live sessions' repositories; a repository team is fixed to its repository), your <strong>Sharing</strong> (a preset, Full, Detailed or Minimal, or Custom; changed through the presets or <strong>Advanced…</strong>, fact by fact, offering only what the team allows, and noting when the team ceiling lowers it; the tooltip lists every fact), and the <strong>Team digest</strong>; the team's policy (<strong>Team ceiling</strong>, <strong>Summary cadence</strong>, <strong>Retention</strong>, <strong>Ask members for the digest</strong>, and on a relay team its <strong>Access</strong>), which its admins change (peer-to-peer: signed into the team's roster log through <code>TeamService.SetPolicy</code>; relay: owners and admins, through the relay); and for a repository team the <strong>Team file</strong>, written with <code>TeamService.PublishTeam</code>. Click a row to change it; rows you may not change show why. <strong>Members</strong> lists everyone (★ owner, shield admin, invitations not yet taken up marked <code>invited</code>); owners and admins can remove a member they outrank (and on a relay team revoke an invitation), and the owner (on a peer-to-peer team, the device holding the team key) can make a member admin or an admin member; admins of a peer-to-peer team invite people too, so it admits newcomers while its creator is offline. People with sessions show their role too. Teams → people → their sessions. A session sits under every team it was sent on (the daemon's binding: a repository team admits its repository, a personal team your scope for it), and under <strong>Unshared</strong> when no team admits it, so it never left this machine (<code>mellowPeek.sessions.showUnshared</code>). Each session is labelled by its title (or "Untitled session") with status and age; a running agent spins. A person's own editor window (a <code>*-human</code> harness) is marked as such: a window icon, <code>editor</code> instead of a status, and, until the daemon narrates it from that person's own edits, the label <code><App> editor</code> (<code>Cursor editor</code>); expanded, the session's description, then a file tree of what it claimed or touched. Files that exist in the workspace open on click. Tooltip has the description, harness, model, repository, commits, unpushed count, teams. Right-click a person or a live session to <strong>Leave a Note…</strong> for them. The gear in the view title opens <strong>Settings…</strong>. Right-click a person to mute them, or a session to mute that device: the daemon deletes what they sent and drops the rest until <code>Mellow Peek: Manage Mutes…</code> unmutes.</td> </tr> <tr> <td><strong>Directives</strong> view</td> <td>Pending first. Acknowledge one inline or all from the title bar; acknowledgements go to the daemon.</td> </tr> <tr> <td>File decorations</td> <td><code>C</code> on a file another session has claimed, <code>T</code> on one it touched, in the explorer and tabs, with who and which session in the tooltip.</td> </tr> <tr> <td>Status bar</td> <td>Connected or not, paused flag, team count, pending directive count; with presence on, the title the daemon narrated for this window's own session. Click it to refresh, or to open setup when the daemon is not reachable.</td> </tr> <tr> <td>Human presence</td> <td>Off by default. Turned on (<code>Mellow Peek: Toggle Human Presence</code>), your window is a <code>vscode-human</code> session: the workspace, the file you have open (<code>touched</code>), a file you start editing (<code>claimed</code>). Never contents, and no title: the daemon titles the session from your own edits. The daemon applies your excludes, scope, and each team's policy. A reload ends the previous window's session; a window that closed without a chance to say so is ended by the next window that activates (heartbeats in <code>globalState</code> tell live windows from gone ones).</td> </tr> </tbody> </table> <h2 id=setup>Setup</h2> <p><code>Mellow Peek: Set Up…</code> (also the status bar item while disconnected) offers each step; they run the <code>mellow-peek</code> binary or call the daemon:</p> <table> <thead> <tr> <th>Command</th> <th>Runs</th> </tr> </thead> <tbody> <tr> <td><code>Mellow Peek: Install and Start Daemon</code></td> <td><code>mellow-peek daemon install</code>, then <code>mellow-peek daemon start</code></td> </tr> <tr> <td><code>Mellow Peek: Start Daemon</code></td> <td><code>mellow-peek daemon start</code></td> </tr> <tr> <td><code>Mellow Peek: Install Harness Plugin (mellow-peek init)</code></td> <td><code>mellow-peek init</code></td> </tr> <tr> <td><code>Mellow Peek: Join Team with Invite</code></td> <td>opens the <strong>join form</strong> for a pasted token: the team (name, kind, home, who invited you, its ceiling, whether it asks for the digest), then what you share, which repositories, your summaries and the digest, privacy-first by default. Nothing joins before you press Join; the answers apply before the team goes live (<code>TeamService.PreviewTeam</code>, then <code>JoinTeam</code> with <code>choices</code>). Show Invitations, teams a relay offers you, a repository's announced team and invite links open the same form</td> </tr> <tr> <td><code>Mellow Peek: Create Team for This Repository…</code></td> <td>creates a team about this repository on this device (<code>TeamService.CreateTeam</code>) or on the configured relay (<code>CreateRelayTeam</code>), publishes <code>.mellow/peek/team.toml</code>, then offers an invite</td> </tr> <tr> <td><code>Mellow Peek: Add Repositories to Team…</code></td> <td>a team you may change the policy of: a multi-select of the workspace's checkouts (checked when the team is already about them; unchecking one removes it) and <strong>Choose a folder…</strong> for any other checkout; then offers to share your checkouts of the ones added. The prompt for a repository no team is about offers it too (<strong>Add to team…</strong>)</td> </tr> <tr> <td>Opening a checkout of a team's repository</td> <td>when the folder is a checkout of one of a joined team's repositories that you have not linked (<code>ResolveWorkspace</code> says <code>pending</code>), asks once: <strong>Share</strong> links the repository, <strong>Not here</strong> excludes it for that team and stops the question</td> </tr> <tr> <td><code>Mellow Peek: Invite to Team…</code></td> <td>asks the daemon for a one-time invite (<code>InviteToTeam</code>), then copies an <strong>invite link</strong> (<code>vscode://mellow.mellow-peek/join?token=…</code>, in Cursor its own scheme) or the raw token. Opening the link opens the join form; it works once, within 7 days, while your daemon is up. On a relay team, after inviting handles, it offers a link that names the relay and the team</td> </tr> <tr> <td><code>Mellow Peek: Leave Team…</code></td> <td>after a confirmation, <code>LeaveTeam</code> (a relay team on its relay first); not offered for a team you own</td> </tr> <tr> <td><code>Mellow Peek: Delete Team…</code></td> <td>owners only, after a confirmation and typing the team name: deleted on its relay (<code>ManageRelayTeam</code>) for a relay team; for a peer-to-peer one, leaving destroys the signing key (<code>LeaveTeam</code>)</td> </tr> <tr> <td><code>Mellow Peek: Log In to Relay</code></td> <td>Signs in to a relay with no terminal: through the browser (the daemon waits for it; cancel from the notification) or with an operator token. Then it lists the teams you can activate on this device; each one you pick opens the join form, and the rest wait under Available teams</td> </tr> <tr> <td><code>Mellow Peek: Be Discoverable Nearby (10 min)</code> / <code>Stop Being Discoverable Nearby</code></td> <td>Invite Nearby (<code>NearbyService.SetDiscoverable</code>): people on this network see your handle and name for ten minutes and can offer you a team. A status bar countdown shows the window (click to stop); each offer shows a notification (<strong>Review…</strong> opens the join form, <strong>Decline</strong>) and waits under Available teams</td> </tr> <tr> <td><code>Mellow Peek: Invite Nearby…</code></td> <td>from a peer-to-peer team you administer, or <strong>Invite to Team…</strong>: a live list of people discoverable nearby, with fingerprints to compare and members marked; picking one offers them the team (<code>OfferTeam</code>) with an invite that works on their device only</td> </tr> <tr> <td><code>Mellow Peek: Pause Sharing</code> / <code>Resume Sharing</code></td> <td>the daemon's <code>pause</code> / <code>resume</code></td> </tr> <tr> <td><code>Mellow Peek: Team Digest…</code></td> <td>from a team's context menu or the palette: turn the team digest on or off for you, or follow the team (<code>SetDigest</code>). When a team asks members to turn it on and you have not answered, a notification asks once per window: "Turn on for me" or "Not for me"</td> </tr> <tr> <td><code>Mellow Peek: Clear Feed</code></td> <td>the daemon's <code>feed.clear</code> ("Clear items") or <code>feed.reset</code> ("Reset everything": also forgets remembered sessions and summary topics; live sessions return), after a confirmation</td> </tr> <tr> <td><code>Mellow Peek: Mute Person</code> / <code>Mute This Device</code> / <code>Manage Mutes…</code></td> <td>the daemon's <code>mute.add</code> / <code>mute.remove</code>; your own handle and device are refused</td> </tr> <tr> <td><code>Mellow Peek: Toggle Human Presence</code></td> <td>flips <code>mellowPeek.presence</code></td> </tr> <tr> <td><code>Mellow Peek: Settings…</code></td> <td>the gear on the Sessions view: one menu over every global control (sharing, excludes, mutes, presence, the summarizer, relays, daemon, plugins, feed)</td> </tr> <tr> <td><code>Mellow Peek: Choose Summarizer…</code> / <code>Set Summarizer Model…</code> / <code>Your Feed Written From (agent threads, facts, off)…</code> / <code>Choose Narrators…</code></td> <td>the daemon's <code>summarizer.set</code>: written to <code>daemon.toml</code> (comments kept) and in force at once. The feed source is this device's own feed only (<code>local_source</code>); what each team gets is its <strong>Sharing</strong></td> </tr> <tr> <td><code>Mellow Peek: Edit daemon.toml…</code></td> <td>opens the daemon's <code>daemon.toml</code> for everything else (cadences, the network); those apply on a daemon restart</td> </tr> <tr> <td><code>Mellow Peek: Stop or Resume Sharing This Repository…</code></td> <td>the daemon's <code>exclude.add</code> for this checkout or the repository wherever it is checked out; when it is already excluded, <code>exclude.remove</code> after a confirmation</td> </tr> <tr> <td><code>Mellow Peek: Manage Excludes…</code></td> <td>lists <code>exclude.list</code>; picking one shares it again (<code>exclude.remove</code>)</td> </tr> <tr> <td><code>Mellow Peek: Leave a Note…</code></td> <td>from a person or a live session in the Sessions view, or the palette: the daemon's <code>directive.post</code> to that session or every session of the person, with a severity (<code>info</code>, <code>warn</code> hands it to their agent as context, <code>interrupt</code> also asks their harness to stop); kept for an hour</td> </tr> <tr> <td><code>Mellow Peek: Log Out of Relay…</code></td> <td>the daemon's <code>TeamService.LogoutRelay</code> for one of your relay teams' relays or <code>mellowPeek.teams.relay</code></td> </tr> <tr> <td><code>Mellow Peek: Show Status</code></td> <td>the daemon's status and <code>mellow-peek doctor</code>, in the output channel</td> </tr> <tr> <td><code>Mellow Peek: Stop Daemon</code> / <code>Restart Daemon</code></td> <td><code>mellow-peek daemon stop</code> (then <code>daemon start</code>)</td> </tr> <tr> <td><code>Mellow Peek: Uninstall Harness Plugin…</code></td> <td>after a confirmation, <code>mellow-peek init --uninstall</code></td> </tr> <tr> <td><code>Mellow Peek: Publish Team File…</code></td> <td>teams about a repository, from the team's context menu or the palette: <code>PublishTeam</code> writes <code>.mellow/peek/team.toml</code> for contributors to discover</td> </tr> </tbody> </table> <p>Presence is opt-in; nothing about you is reported until <code>mellowPeek.presence</code> is <code>on</code>. Each window also checks its workspace folders: for a folder whose repository no joined team is about, it offers to join the team the repository announces in <code>.mellow/peek/team.toml</code>; every other such folder goes into one question, to add them all to one of your teams (a multi-select with them checked) or to create one (<code>mellowPeek.teams.suggest</code>). A question answered after another one settled it does nothing. "Never for these repositories" is remembered.</p> <p>Teams on a relay (<a href="https://github.com/mellow-build/peek/blob/HEAD/../../docs/RELAY.md" target=_blank rel="noreferrer noopener nofollow">docs/RELAY.md</a>) show a person icon for <strong>Show Team Members</strong> and an <strong>Invite</strong> action that takes handles. A repository whose <code>.mellow/peek/team.toml</code> names a relay offers <strong>Join</strong>; if you are not logged in to that relay yet, the extension offers to log in first, then opens the form again.</p> <p><strong>Available teams</strong>, a section of the Sessions view, holds what you could take part in on this device but have not activated (<code>TeamService.ListAvailableTeams</code>):</p> <ul> <li>each relay you are logged in to: its name, <code>as <handle></code>, or <code>log in again</code> / <code>unreachable</code>. Under it, the teams it admits you to and the invite-only teams that invited you (<code>invited</code>), or "Nothing to activate". Its menu has Log In Again, Refresh and Log Out;</li> <li>a team an open folder announces in <code>.mellow/peek/team.toml</code> that you have not joined;</li> <li>a team someone nearby offered you ("offered by nearby"): <strong>Review…</strong> or <strong>Decline</strong>;</li> <li><strong>Log in to a relay…</strong>.</li> </ul> <p><strong>Activate…</strong> on a team opens the join form; nothing is shared with a team until you join it. <strong>Mellow Peek: Show Invitations</strong> reveals the section. It refreshes after logins, joins and folder changes, and every <code>mellowPeek.availability.refreshSeconds</code>. When the relay advertises managed teams, Create Team also offers <strong>Managed on </strong>: facts go through the relay, which stores them (and can read them) so members need never be online together. A managed team's node reads "managed by · hub connected" or "hub offline".</p> <h2 id=settings>Settings</h2> <table> <thead> <tr> <th>Setting</th> <th>Default</th> <th>Meaning</th> </tr> </thead> <tbody> <tr> <td><code>mellowPeek.client</code></td> <td><code>daemon</code></td> <td><code>daemon</code> talks to the local daemon; <code>mock</code> replays the <code>mellow-peek-protocol</code> fixtures with no daemon. Reload after changing.</td> </tr> <tr> <td><code>mellowPeek.daemon.configDir</code></td> <td><code>""</code></td> <td>The daemon's config directory. Empty means <code>MELLOW_PEEK_CONFIG_DIR</code> or the platform default (<code>~/.config/mellow/peek</code>, <code>~/Library/Application Support/mellow/peek</code>, <code>%APPDATA%\mellow\peek</code>).</td> </tr> <tr> <td><code>mellowPeek.daemon.socket</code></td> <td><code>""</code></td> <td>Override the socket path or named pipe. Empty means <code><config dir>/daemon.sock</code>, or <code>\\.\pipe\mellow-peek-<user></code> on Windows.</td> </tr> <tr> <td><code>mellowPeek.binaryPath</code></td> <td><code>mellow-peek</code></td> <td>The binary the setup commands run.</td> </tr> <tr> <td><code>mellowPeek.presence</code></td> <td><code>off</code></td> <td><code>on</code> reports this window as a session; <code>off</code> never does.</td> </tr> <tr> <td><code>mellowPeek.feed.defaultToCurrentRepository</code></td> <td><code>true</code></td> <td>Start the feed filtered to the first workspace folder's repository, read from <code>.git/config</code>.</td> </tr> <tr> <td><code>mellowPeek.feed.showStatusChanges</code></td> <td><code>false</code></td> <td>Also show running/idle flips and file-only updates in the feed.</td> </tr> <tr> <td><code>mellowPeek.availability.refreshSeconds</code></td> <td><code>300</code></td> <td>How often the Available teams section asks each relay you are logged in to what you could activate; <code>0</code> refreshes only on demand, after logins and joins, and when folders change.</td> </tr> <tr> <td><code>mellowPeek.teams.relay</code></td> <td>empty</td> <td>A relay's base URL. Create Team then offers an invite-only, open or (when the relay offers it) managed team on it (the relay admits people while you are offline), Invite on such a team asks for handles, and Log In and Show Invitations default to it.</td> </tr> <tr> <td><code>mellowPeek.teams.suggest</code></td> <td><code>ask</code></td> <td><code>ask</code> offers, once per window, to join, add to or create a team for the folders whose repositories no joined team is about; <code>off</code> never asks.</td> </tr> <tr> <td><code>mellowPeek.sessions.showUnshared</code></td> <td><code>true</code></td> <td>Show the <strong>Unshared</strong> group: sessions no team binding admits. Off, only sessions bound to a team are listed.</td> </tr> <tr> <td><code>mellowPeek.mock.fixturesDir</code></td> <td><code>""</code></td> <td>Where the mock reads fixtures. Empty resolves <code>crates/mellow-peek-protocol/tests/fixtures</code> from the extension's checkout or the workspace.</td> </tr> </tbody> </table> <h2 id=how-it-talks-to-the-daemon>How it talks to the daemon</h2> <p>Per <code>crates/mellow-peek/SPEC.md</code> § Local API: the daemon's Connect services (<code>api/proto/mellow/peek/local/v1/</code>) over HTTP/1.1 on the Unix socket or Windows named pipe, with the token file's contents as <code>Authorization: Bearer</code> on every call. The feed uses one long-lived <code>TailFeed</code> stream in follow mode that reconnects with exponential backoff (1 s to 30 s) and resumes after the last feed item, so a daemon restart loses nothing. The <code>Mellow Peek</code> output channel logs connection changes and delivery failures.</p> <h2 id=development>Development</h2> <pre><code>pnpm install # from the repository root pnpm --filter mellow-peek run generate # api/protocol.schema.json -> src/generated/protocol.ts (or `task generate`) pnpm --filter mellow-peek run build # tsc --noEmit, vitest, esbuild -> dist/extension.js pnpm --filter mellow-peek run package # dist/mellow-peek-<version>.vsix pnpm --filter mellow-peek run e2e # extension-host suite in a downloaded VS Code (needs a display) pnpm --filter mellow-peek run e2e -- --editor /usr/share/cursor/cursor # the same suite inside Cursor pnpm --filter mellow-peek run e2e -- --daemon ../../target/debug/mellow-peek # against a real daemon </code></pre> <p>With <code>--daemon</code>, the launcher starts <code>mellow-peek daemon run</code> on a scratch config dir (networking off, template summarizer with one-second narration and summary windows) and the suite reports a session through the daemon's own socket. This is the phase 7 done-when (the dev host connects to the daemon, the feed updates live, the claimed file shows the <code>C</code> decoration) and the phase 9 one (three touches give the session a description under its harness title, an untitled session gains a generated title, the sessions view shows the description node and the file tree, and the feed shows a summary sentence). It passes in VS Code and Cursor.</p> <p>The e2e suite (<code>src/e2e/</code>) launches the editor with the extension from source, a scratch profile, and a scratch workspace whose settings select the mock backend, then checks activation, commands, view data, the claim index, and pause/resume. It is not part of <code>pnpm run build</code> because it needs a display.</p> <p>Open <code>extensions/vscode</code> in VS Code or Cursor and press F5 to launch the extension development host. With a running daemon the views fill from it; without one, set <code>mellowPeek.client</code> to <code>mock</code> and open this repository as the workspace so the mock finds the fixtures.</p> <p>To try the packaged extension: <code>code --install-extension dist/mellow-peek-*.vsix</code> or <code>cursor --install-extension dist/mellow-peek-*.vsix</code>. Publishing to the VS Code Marketplace and Open VSX is phase 8: <code>pnpm run publish:marketplace</code>, <code>pnpm run publish:openvsx</code>.</p> <p>Layout:</p> <table> <thead> <tr> <th>Path</th> <th>Role</th> </tr> </thead> <tbody> <tr> <td><code>src/generated/protocol.ts</code></td> <td>Generated from <code>api/protocol.schema.json</code>; never edit. A test fails if it drifts.</td> </tr> <tr> <td><code>src/generated/proto/</code></td> <td>Generated from <code>api/proto/mellow/peek/local/v1/</code> by <code>protoc-gen-es</code>: the local API's messages and Connect services; never edit.</td> </tr> <tr> <td><code>src/client/rpc.ts</code></td> <td>The generated local API in one import, and the decoding of the protocol types it carries as JSON text (<code>teamOf</code>, <code>envelopeOf</code>, <code>sessionOf</code>).</td> </tr> <tr> <td><code>src/client/daemon.ts</code></td> <td>The live client: the Connect services over the daemon's socket or pipe, the follow subscription, reconnect. Tested against <code>src/client/testing/fakeDaemon.ts</code>, a Connect server on a socket.</td> </tr> <tr> <td><code>src/client/paths.ts</code></td> <td>Config dir, socket, and token resolution per platform.</td> </tr> <tr> <td><code>src/client/mock.ts</code>, <code>fixtures.ts</code></td> <td>The fixture-replaying backend.</td> </tr> <tr> <td><code>src/model/state.ts</code></td> <td>Pure view-model: sessions deduped on <code>(person, device, session_id)</code>, feed items classified as what changed, directives, claims index. Unit-tested.</td> </tr> <tr> <td><code>src/model/compose.ts</code>, <code>src/model/tree.ts</code></td> <td>The consumer side of summaries (facts fold under the summary that covers them, ported from <code>mellow-peek-core</code>) and the file tree a session's paths become.</td> </tr> <tr> <td><code>src/presenceEvents.ts</code>, <code>src/presence.ts</code></td> <td>Human presence: pure event builders, and the editor wiring with debounce.</td> </tr> <tr> <td><code>src/cli.ts</code></td> <td>Runs the <code>mellow-peek</code> binary for the setup commands.</td> </tr> <tr> <td><code>src/e2e/</code>, <code>scripts/e2e.mjs</code></td> <td>Extension-host suite and its launcher.</td> </tr> <tr> <td><code>src/views/</code>, <code>src/decorations.ts</code>, <code>src/statusBar.ts</code></td> <td>The vscode-facing layer.</td> </tr> <tr> <td><code>scripts/protocol-generator.mjs</code></td> <td>Merges the per-root schema files and runs json-schema-to-typescript.</td> </tr> </tbody> </table> <p>The generated file is excluded from Biome; everything else must pass <code>pnpm exec biome check .</code>.</p> </div></div></td><td class="ux-itemdetails-right" role="complementary"><div class="screenshot-carousel-container"></div><div class="loader-container"><div class="loader"></div></div><div class="itemDetails-right"></div></td></tr></tbody></table></div></div><div id="versionHistoryTab" style="display:none"><div class="versionHistoryTab-loader-container"><div class="loader"></div></div><div id="version-history-tab-content"></div></div></div></div></div></div></div></div></div></div><div id="gallery-footer"><footer><div id="ux-footer" class="ltr" role="contentinfo"><div id="baseFooter"><div id="Fragment_BaseFooterLinks"><div class="linkList"><ul class="links horizontal"><li><a href="https://www.visualstudio.com/support/support-overview-vs" data-mscc-ic="false">Contact us</a></li><li><a href="https://careers.microsoft.com/" data-mscc-ic="false">Jobs</a></li><li><a href="https://go.microsoft.com/fwlink/?LinkID=521839" data-mscc-ic="false">Privacy</a></li><li><a id="mgtConsentCookie" data-mscc-ic="false">Manage cookies</a></li><li><a href="https://aka.ms/vsmarketplace-ToU" data-mscc-ic="false">Terms of use</a></li><li><a href="https://www.microsoft.com/trademarks" data-mscc-ic="false">Trademarks</a></li><li><a href="https://aka.ms/YourCaliforniaPrivacyChoices" data-mscc-ic="false"> <img src="https://cdn.vsassets.io/v/M280_20261006.4/_content/privacy-options.svg" alt="" class="footer-privacy-choices-icon"/>Your Privacy Choices </a></li><li><a href="https://go.microsoft.com/fwlink/?linkid=2259814" data-mscc-ic="false">Consumer Health Privacy</a></li></ul></div></div><div id="rightBaseFooter">©<!-- --> 2026 Microsoft<span class="microsoftLogo" title="Microsoft"></span></div><div class="clear"></div></div></div></footer></div></div></div></div> <div class="render-time"> <script class="server-side-render" defer="defer" type="application/json">3</script> </div> <div class="rhs-content"> <script class="jiContent" defer="defer" type="application/json">{"GitHubLink":"https://github.com/mellow-build/peek.git","ReleaseDateString":"Thu, 08 Oct 2026 08:57:10 GMT","LastUpdatedDateString":"Thu, 08 Oct 2026 16:39:58 GMT","GalleryUrl":"/","Categories":["Other"],"Tags":["agents","awareness","claude","codex","copilot","cursor","team"],"ExtensionProperties":{"Microsoft.VisualStudio.Services.Links.Getstarted":"https://github.com/mellow-build/peek.git","Microsoft.VisualStudio.Services.Links.Support":"https://github.com/mellow-build/peek/issues","Microsoft.VisualStudio.Services.Links.Learn":"https://github.com/mellow-build/peek#readme","Microsoft.VisualStudio.Services.Links.Source":"https://github.com/mellow-build/peek.git","Microsoft.VisualStudio.Services.Links.GitHub":"https://github.com/mellow-build/peek.git","Microsoft.VisualStudio.Code.Engine":"^1.120.0","Microsoft.VisualStudio.Services.GitHubFlavoredMarkdown":"true","Microsoft.VisualStudio.Code.ExtensionDependencies":"","Microsoft.VisualStudio.Code.ExtensionPack":"","Microsoft.VisualStudio.Code.LocalizedLanguages":"","Microsoft.VisualStudio.Code.ExtensionKind":"workspace","Microsoft.VisualStudio.Code.PreRelease":"true","Microsoft.VisualStudio.Services.Content.Pricing":"Free","Microsoft.VisualStudio.Code.EnabledApiProposals":"","Microsoft.VisualStudio.Code.ExecutesCode":"true","Microsoft.VisualStudio.Services.VsixSha256":"e146e1a0da783a011b0240d46c3977e87307aedcebf966861fec00cc69779f87"},"Resources":{"LicenseText":"License","ChangelogText":"","PublisherName":"Mellow","ExtensionName":"mellow-peek","Version":"0.0.9"},"MoreInfo":{"VersionValue":"0.0.9","PublisherValue":"Mellow","UniqueIdentifierValue":"Mellow.mellow-peek","TwitterShareContents":"Just%20discovered%20this%20on%20the%20%23VSMarketplace%3A%20https%3A%2F%2Fmarketplace.visualstudio.com%2Fitems%3FitemName%3DMellow.mellow-peek","EmailShareContents":"Hi%2C%20Just%20discovered%20this%20extension%20on%20the%20%23VSMarketplace%20that%20may%20be%20of%20interest%20to%20you.%20Check%20it%20out%20%40%20https%3A%2F%2Fmarketplace.visualstudio.com%2Fitems%3FitemName%3DMellow.mellow-peek%20%21","EmailShareSubject":"Check%20out%20-%20Mellow%20Peek%20for%20Visual%20Studio%20Code","IsPublic":true},"ResourcesPath":"https://cdn.vsassets.io/v/M280_20261006.4/_content/","AssetUri":"https://Mellow.gallerycdn.vsassets.io/extensions/mellow/mellow-peek/0.0.9/1791477158000","VsixManifestAssetType":"Microsoft.VisualStudio.Services.VsixManifest","StaticResourceVersion":"M280_20261006.4","AfdIdentifier":"Ref A: 4AE237AE02E2474BB0B5FED34ABE6D54 Ref B: CH1AA2030813052 Ref C: 2026-10-09T03:10:39Z","VsixId":null,"WorksWith":["Universal"],"ItemType":3,"IsMDPruned":false,"PrunedMDLength":0,"OverviewMDLength":23012,"IsRHSAsyncComponentsEnabled":true,"OfferDetails":null,"IsDetailsTabsEnabled":false,"ShowVersionHistory":true,"IsSeeMoreButtonOnVersionHistoryTab":false,"DisableVSCodeDownloadButtonEnabled":true,"IsReferralLinkRedirectionWarningPopupEnabled":true,"Versions":[{"version":"0.0.9","lastUpdated":"Thu, 08 Oct 2026 16:39:58 GMT","targetPlatform":null},{"version":"0.0.7","lastUpdated":"Thu, 08 Oct 2026 13:49:40 GMT","targetPlatform":null},{"version":"0.0.5","lastUpdated":"Thu, 08 Oct 2026 12:19:05 GMT","targetPlatform":null},{"version":"0.0.3","lastUpdated":"Thu, 08 Oct 2026 09:03:22 GMT","targetPlatform":null}],"IsCSRFeatureEnabled":false,"TargetPlatforms":{"win32-x64":"Windows x64","win32-arm64":"Windows ARM","linux-x64":"Linux x64","linux-arm64":"Linux ARM64","linux-armhf":"Linux ARM32","darwin-x64":"macOS Intel","darwin-arm64":"macOS Apple Silicon","alpine-x64":"Alpine Linux 64 bit","web":"Web","alpine-arm64":"Alpine Linux ARM64","win32-ia32":"Windows ia32"},"VisualStudioReleaseSurface":null}</script> </div> <div class="csp-user"> <script class="is-csp-user" defer="defer" type="application/json">false</script> </div> <script type="text/javascript" nonce="Otv+lqr5r3iN8l8m5PsjpQ=="> if (document) { try { if (window.performance && window.performance.timing) { window["marketplaceRenderTime"] = Date.now() - window.performance.timing.navigationStart; } } catch(e){ } } </script> <script type="text/javascript" nonce="Otv+lqr5r3iN8l8m5PsjpQ=="> var __vssPageContext = {"webContext":{"user":{"id":"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa","name":"Anonymous","email":"","uniqueName":"TEAM FOUNDATION\\Anonymous"},"host":{"id":"2663b13f-50e3-a655-a159-22f6f4725fab","name":"TEAM FOUNDATION","uri":"https://marketplace.visualstudio.com/","relativeUri":"/","hostType":"deployment","scheme":"https","authority":"marketplace.visualstudio.com"}},"moduleLoaderConfig":{"baseUrl":"https://cdn.vsassets.io/v/M280_20261006.4/_scripts/TFS/min/","paths":{"Charts/Resources":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","Gallery/Scripts/Gallery/Resources":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","ContentRendering/Resources":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","Engagement/Resources":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","VSS/Resources":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","VSSPreview/Resources":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","highcharts":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts.v11.4.6","highcharts/highcharts-more":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-more.v11.4.6","highcharts/modules/accessibility":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-accessibility.v11.4.6","highcharts/modules/funnel":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-funnel.v11.4.6","highcharts/modules/heatmap":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-heatmap.v11.4.6"},"map":{"*":{"office-ui-fabric-react/lib":"OfficeFabric"}},"contributionPaths":{"VSS":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/VSS","pathType":"default"},"VSS/Resources":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","pathType":"resource"},"q":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/q","pathType":"default"},"knockout":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/knockout","pathType":"default"},"mousetrap":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/mousetrap","pathType":"default"},"mustache":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/mustache","pathType":"default"},"react":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/react.15.3","pathType":"default"},"react-dom":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/react-dom.15.3","pathType":"default"},"react-transition-group":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/react-transition-group.15.3","pathType":"default"},"jQueryUI":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/jQueryUI","pathType":"default"},"jquery":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/jquery","pathType":"default"},"OfficeFabric":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/OfficeFabric","pathType":"default"},"tslib":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/tslib","pathType":"default"},"@uifabric":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/@uifabric","pathType":"default"},"VSSUI":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/VSSUI","pathType":"default"},"Charts":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/Charts","pathType":"default"},"Charts/Resources":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","pathType":"resource"},"ContentRendering":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/ContentRendering","pathType":"default"},"ContentRendering/Resources":{"value":"/_static/tfs/M280_20261006.4/_scripts/TFS/min/en-US","pathType":"resource"},"highcharts":{"value":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts.v11.4.6","pathType":"thirdParty"},"highcharts/highcharts-more":{"value":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-more.v11.4.6","pathType":"thirdParty"},"highcharts/modules/accessibility":{"value":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-accessibility.v11.4.6","pathType":"thirdParty"},"highcharts/modules/funnel":{"value":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-funnel.v11.4.6","pathType":"thirdParty"},"highcharts/modules/heatmap":{"value":"https://cdn.vsassets.io/3rdParty/_scripts/highcharts-heatmap.v11.4.6","pathType":"thirdParty"}},"shim":{"jquery":{"deps":[],"exports":"jQuery"}},"waitSeconds":30},"coreReferences":{"stylesheets":[{"url":"/_static/tfs/M280_20261006.4/_cssbundles/Default/vss-bundle-ext-core-css-vy56dBxIwQd7phb69QAn3RFxAgJ-RddGhGPdgi16Jpgk=","highContrastUrl":null,"isCoreStylesheet":true}],"scripts":[{"identifier":"JQuery","url":"https://cdn.vsassets.io/3rdParty/_scripts/jquery-3.6.0.min.js","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":true},{"identifier":"JQueryXDomain","url":"https://cdn.vsassets.io/3rdParty/_scripts/jquery.xdomainrequest.min.js","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":true},{"identifier":"Promise","url":"https://cdn.vsassets.io/v/M280_20261006.4/_scripts/TFS/min/promise.js","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":true},{"identifier":"GlobalScripts","url":"https://cdn.vsassets.io/v/M280_20261006.4/_scripts/TFS/min/global-scripts.js","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":true},{"identifier":"LoaderFixes","url":"https://cdn.vsassets.io/v/M280_20261006.4/_scripts/TFS/pre-loader-shim.min.js","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":false},{"identifier":"AMDLoader","url":"https://cdn.vsassets.io/3rdParty/_scripts/require.min.js","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":true},{"identifier":"LoaderFixes","url":"https://cdn.vsassets.io/v/M280_20261006.4/_scripts/TFS/post-loader-shim.min.js","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":false}],"coreScriptsBundle":{"identifier":"CoreBundle","url":"/_public/_Bundling/Content?bundle=vss-bundle-basejs-vh-5EDj0aiCZ8U3pbGPKlySQ9T_RAycY0i4geeP5oQDs=","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":true},"extensionCoreReferences":{"identifier":"CoreBundle","url":"/_public/_Bundling/Content?bundle=vss-bundle-ext-core-v18vIroK2kzteRVxkiKSQ0oZGCm7oXbiyaIpjvJbJ4UQ=","fallbackUrl":null,"fallbackCondition":null,"isCoreModule":true}},"webAccessConfiguration":{"isHosted":true,"paths":{"rootPath":"/","staticContentRootPath":"/","staticContentVersion":"M280_20261006.4","resourcesPath":"https://cdn.vsassets.io/v/M280_20261006.4/_content/","staticRootTfs":"https://cdn.vsassets.io/v/M280_20261006.4/","cdnFallbackStaticRootTfs":"/_static/tfs/M280_20261006.4/","staticRoot3rdParty":"https://cdn.vsassets.io/3rdParty/"},"api":{"webApiVersion":"1","areaPrefix":"_","controllerPrefix":"_"},"mailSettings":{"enabled":false},"registryItems":{}},"microsoftAjaxConfig":{"cultureInfo":{"name":"en-US","numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":".","IsReadOnly":true,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":",","CurrencySymbol":"$","NaNSymbol":"NaN","CurrencyNegativePattern":0,"NumberNegativePattern":1,"PercentPositivePattern":1,"PercentNegativePattern":1,"NegativeInfinitySymbol":"-∞","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":".","NumberGroupSeparator":",","CurrencyPositivePattern":0,"PositiveInfinitySymbol":"∞","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":".","PercentGroupSeparator":",","PercentSymbol":"%","PerMilleSymbol":"‰","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},"dateTimeFormat":{"AMDesignator":"AM","Calendar":{"MinSupportedDateTime":"0001-01-01T00:00:00","MaxSupportedDateTime":"9999-12-31T23:59:59.9999999","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2049,"IsReadOnly":true},"DateSeparator":"/","FirstDayOfWeek":0,"CalendarWeekRule":0,"FullDateTimePattern":"dddd, MMMM d, yyyy h:mm:ss tt","LongDatePattern":"dddd, MMMM d, yyyy","LongTimePattern":"h:mm:ss tt","MonthDayPattern":"MMMM d","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH\u0027:\u0027mm\u0027:\u0027ss \u0027GMT\u0027","ShortDatePattern":"M/d/yyyy","ShortTimePattern":"h:mm tt","SortableDateTimePattern":"yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy\u0027-\u0027MM\u0027-\u0027dd HH\u0027:\u0027mm\u0027:\u0027ss\u0027Z\u0027","YearMonthPattern":"MMMM yyyy","AbbreviatedDayNames":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"ShortestDayNames":["Su","Mo","Tu","We","Th","Fr","Sa"],"DayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"AbbreviatedMonthNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"IsReadOnly":true,"NativeCalendarName":"Gregorian Calendar","AbbreviatedMonthGenitiveNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthGenitiveNames":["January","February","March","April","May","June","July","August","September","October","November","December",""]},"numberShortForm":{"QuantitySymbols":["K","M","B"],"NumberGroupSize":1000,"ThousandSymbol":"K"},"eras":null}},"timeZonesConfiguration":{},"featureAvailability":{"featureStates":{"VisualStudio.Services.Contribution.EnableOnPremUnsecureBrowsers":false,"VisualStudio.Service.WebPlatform.ClientErrorReporting":true,"Microsoft.VisualStudio.Services.Gallery.Client.UseCdnAssetUri":false,"VisualStudio.Services.WebAccess.SubresourceIntegrity":false,"VisualStudio.Services.IdentityPicker.ReactProfileCard":true}},"appInsightsConfiguration":{"enabled":false,"instrumentationKey":"00000000-0000-0000-0000-000000000000","insightsScriptUrl":null},"diagnostics":{"sessionId":"3c964fe7-5854-43c8-a0bc-6da69bbc97d1","activityId":"3c964fe7-5854-43c8-a0bc-6da69bbc97d1","bundlingEnabled":true,"cdnAvailable":true,"cdnEnabled":true,"webPlatformVersion":"M280","serviceVersion":"Dev20.M280.1 (build: AzureDevOps_M280_20261006.4)"},"navigation":{"topMostLevel":"deployment","area":"","currentController":"Gallery","currentAction":"Details","commandName":"Gallery.Details","routeId":"ms.vss-gallery-web.gallery-route-details","routeTemplates":["items"],"routeValues":{"controller":"Gallery","action":"Details"}},"globalization":{"explicitTheme":"","theme":"Default","culture":"en-US","timezoneOffset":0,"timeZoneId":"UTC"},"serviceInstanceId":"00000029-0000-8888-8000-000000000000","hubsContext":{},"serviceLocations":{"locations":{"951917ac-a960-4999-8464-e3f0aa25b381":{"Application":"https://spsprodeus25.vssps.visualstudio.com/","Deployment":"https://spsprodeus25.vssps.visualstudio.com/"}}}};</script> <script defer="true" data-bundlelength="138887" data-bundlename="basejs" nonce="Otv+lqr5r3iN8l8m5PsjpQ==" src="/_public/_Bundling/Content?bundle=vss-bundle-basejs-vh-5EDj0aiCZ8U3pbGPKlySQ9T_RAycY0i4geeP5oQDs=" type="text/javascript"></script> <script defer="true" data-bundlelength="212268" data-bundlename="common" data-includedscripts="VSS/Bundling" nonce="Otv+lqr5r3iN8l8m5PsjpQ==" src="/_public/_Bundling/Content?bundle=vss-bundle-common-v80O346hktgek67U3mcoSrchBJeRNPddjRG0DE0rdL4o=" type="text/javascript"></script><script defer="true" data-bundlelength="2257599" data-bundlename="view" data-includedscripts="Gallery/Client/Pages/VSSItemDetailsSSR/VSSItemDetailsSSRAsync" nonce="Otv+lqr5r3iN8l8m5PsjpQ==" src="/_public/_Bundling/Content?bundle=vss-bundle-view-vAuwj5a1y3ufBziRInaM2n9IHfXr64swuYC_uMl0hyRU=" type="text/javascript"></script> <script defer=true nonce="Otv+lqr5r3iN8l8m5PsjpQ==" src="/_static/tfs/M280_20261006.4/_scripts/TFS/min/Gallery/Client/Pages/VSSItemDetailsSSR/SSRModuleWrappers.js"></script> <script nonce="Otv+lqr5r3iN8l8m5PsjpQ==" src="/_static/tfs/M280_20261006.4/_scripts/TFS/min/Gallery/Client/Common/ManageCookieDrop.js"></script> </body> </html>