Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
76 changes: 76 additions & 0 deletions .github/instructions/sessions.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,76 @@ When working on files under `src/vs/sessions/`, use these skills for detailed gu

- **`sessions`** skill — covers the full architecture: layering, folder structure, chat widget, menus, contributions, entry points, and development guidelines

## Architecture at a Glance

```
vs/sessions (Agents Window) ← this layer
↓ imports from
vs/workbench ← standard VS Code
vs/editor → vs/platform → vs/base
```

**Layer rule:** `vs/sessions` imports from `vs/workbench` and below. `vs/workbench` must **never** import from `vs/sessions`.

**Internal layers** (see `src/vs/sessions/LAYERS.md`):
```
Entry Points → contrib/* / contrib/providers/* / services/* → browser/ & common/ (core)
```

**Key constraint:** `contrib/*` must NOT import from `contrib/providers/*`. Providers are the most permissive contrib layer and may import from non-provider contribs, services, core, and sibling providers.

## Core Services

| Service | Interface file | Purpose |
|---------|---------------|---------|
| `ISessionsManagementService` | `services/sessions/common/sessionsManagement.ts` | Active session tracking, navigation, CRUD operations |
| `ISessionsProvidersService` | `services/sessions/common/sessionsProvider.ts` | Provider registry (register/unregister/lookup) |
Comment thread
sandy081 marked this conversation as resolved.
| `ISession` / `IChat` | `services/sessions/common/session.ts` | Session and chat data interfaces with observable properties |

## Key Development Patterns

### Registering Contributions

All features register through the contribution model and must be imported in entry points:
- `sessions.common.main.ts` — cross-platform contributions
- `sessions.desktop.main.ts` — desktop/Electron-specific
- `sessions.web.main.ts` — web-specific

### Menu Registration

Always use `Menus.*` from `browser/menus.ts` — never `MenuId.*` from `vs/platform/actions`:
- `Menus.TitleBarLeftLayout` / `Menus.TitleBarRightLayout` — titlebar actions
- `Menus.SidebarTitle` — sidebar header actions
- `Menus.AuxiliaryBarTitle` — auxiliary bar header actions
- `Menus.ChatBarTitle` — chat bar header actions

### Context Keys

All sessions-specific context keys live in `common/contextkeys.ts`:
- `IsNewChatSessionContext` — whether showing the new session view
- `ActiveSessionProviderIdContext` — which provider owns the active session
- `ActiveSessionTypeContext` — session type of the active session
- `IsPhoneLayoutContext` — whether in phone layout mode
- `ChatBarVisibleContext` / `ChatBarFocusContext` — chat bar state
Comment thread
sandy081 marked this conversation as resolved.

### Observable Patterns

```typescript
// Subscribe to session state changes
this._register(autorun(reader => {
const session = this.sessionsManagementService.activeSession.read(reader);
const title = session?.title.read(reader);
// React to changes
}));

// Batch updates
transaction(tx => {
this._title.set(newTitle, tx);
this._status.set(newStatus, tx);
});
```

## Mobile Component Architecture

The Agents window has an established mobile architecture (documented in `src/vs/sessions/MOBILE.md`). When adding phone-specific UI — bottom sheets, action sheets, mobile pickers, or any interaction that differs from desktop — follow these rules:
Expand All @@ -34,3 +104,9 @@ The Agents window can run on touch-capable platforms (notably iOS). Follow these
- Do not use `EventType.MOUSE_DOWN`, `EventType.MOUSE_UP`, or `EventType.MOUSE_MOVE` with `addDisposableListener` directly — on iOS, these events don't fire because the platform uses pointer events. Use `addDisposableGenericMouseDownListener`, `addDisposableGenericMouseUpListener`, or `addDisposableGenericMouseMoveListener` instead, which automatically select the correct event type per platform.
- For custom clickable elements (e.g. picker triggers, title bar pills, or other `<div>`/`<span>` elements styled as buttons) that open pickers or menus on click, listen to **both** `EventType.CLICK` and `TouchEventType.Tap` and call `Gesture.addTarget` on the element. On touch devices, including iOS, VS Code relies on the gesture system to emit `TouchEventType.Tap`, and `EventType.CLICK` alone may not reliably fire there. The base `Button` class already does this correctly, so this rule applies to custom non-`<button>` trigger elements.
- Add `touch-action: manipulation` in CSS on custom clickable elements (e.g. picker triggers, title bar pills, or other `<div>`/`<span>` elements styled as buttons) to eliminate the 300ms tap delay on touch devices. This is not needed for native `<button>` elements or standard VS Code widgets (quick picks, context menus, action bar items) which already handle touch behavior.

## Learnings

- Always check `src/vs/sessions/LAYERS.md` before adding cross-module imports — layering violations are enforced by ESLint and will fail CI.
- When creating new views, remember to import the contribution in the entry point — missing this causes the view to not appear.
- Session state flows through observables, not events. If you find yourself adding `onDid*` events for session state, convert to `IObservable` instead.
77 changes: 24 additions & 53 deletions .github/skills/sessions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,38 @@ name: sessions
description: Agents window architecture — covers the agents-first app, layering, folder structure, chat widget, menus, contributions, entry points, and development guidelines. Use when implementing features or fixing issues in the Agents window.
---

When working on the Agents window (`src/vs/sessions/`), always read the relevant specification document before making changes. If you modify the implementation, you **must** update the corresponding spec to keep it in sync.
## Before Making Any Changes

## Specification Documents

| Document | Path | Covers |
|----------|------|--------|
| Overview | `src/vs/sessions/README.md` | Architecture overview, folder conventions |
| Layer rules | `src/vs/sessions/LAYERS.md` | Import restriction rules for all sessions layers (enforced by ESLint) |
| Layout spec | `src/vs/sessions/LAYOUT.md` | Grid structure, parts, titlebar, per-session layout state, CSS |
| Mobile spec | `src/vs/sessions/MOBILE.md` | Mobile component architecture, phone-specific UI patterns |
| Sessions spec | `src/vs/sessions/SESSIONS.md` | Sessions architecture — layers, provider model, core interfaces, data flow |
| AI Customizations | `src/vs/sessions/AI_CUSTOMIZATIONS.md` | AI customization editor and tree view design |

## Engineering Principles

### Layering and Dependencies

- **Respect the layer hierarchy.** `vs/sessions` sits above `vs/workbench` — it may import from workbench and below, but workbench must never import from sessions. See `LAYERS.md` for the full internal layer rules.
- **Keep providers isolated.** Session providers (`contrib/providers/*`) are implementation details of specific backends. Non-provider contributions (`contrib/*`) must not import from providers — extract shared symbols to `services/` or `common/` instead.
- **Validate layers before committing.** Run `npm run valid-layers-check` to catch violations. Run `npm run compile-check-ts-native` for TypeScript errors — never use raw `tsc`.

### Separation of Concerns

- **Use the contribution model.** Features register through `registerWorkbenchContribution2` and `registerAction2`, imported by entry points (`sessions.common.main.ts`, `sessions.desktop.main.ts`). Don't wire features directly into core workbench code.
- **Prefer composition over modification.** Extend existing classes (e.g., `AgentSessionsChatWidget` wraps `ChatWidget`) rather than modifying shared workbench components. This keeps the sessions layer decoupled.
- **Use services for cross-cutting concerns.** Shared state belongs in services (`ISessionsManagementService`, `ISessionsProvidersService`), not passed through component hierarchies. Declare service dependencies in constructors via dependency injection.
**MANDATORY:** Before writing or modifying any code in `src/vs/sessions/`, you **must** read these documents:

### Reactive State and Observables
1. **`.github/instructions/coding-guidelines.instructions.md`** — Naming conventions, code style, string localization, disposable management, and DI patterns.
2. **`.github/instructions/source-code-organization.instructions.md`** — Layers, target environments, dependency injection, and folder structure conventions.

- **Expose mutable state as observables.** Session properties (`title`, `status`, `changes`, etc.) use `IObservable` for reactive UI binding. Use `observableValue`, `derived`, and `autorun` — not events — for state that drives UI updates.
- **Batch related state changes in transactions.** When updating multiple observables together, wrap in `transaction(tx => { ... })` to avoid intermediate renders.
Then read the relevant spec for the area you are changing (see table below). If you modify the implementation, you **must** update the corresponding spec to keep it in sync.

### Window Isolation

- **Scope registrations to the Agents window.** Views and contributions that should not appear in regular VS Code use `WindowVisibility.Sessions` in their registration.
- **Use dedicated menu IDs.** The Agents window defines its own menus in `browser/menus.ts` (`Menus.*`). Never use shared `MenuId.*` constants for Agents window UI.
- **Use dedicated storage keys.** Prefix with `workbench.agentsession.*` or `workbench.chatbar.*` to avoid conflicts with regular workbench state.

### Layout Stability

- **Maintain fixed positions.** The Agents layout is intentionally non-configurable — no settings-based position customization. New parts go in the right section of the grid.
- **Preserve no-op stubs.** Unsupported workbench features (zen mode, centered layout, etc.) remain as no-ops — never throw errors for unsupported API calls.
- **Manage pane composite lifecycle.** When toggling part visibility, always manage the associated pane composites (open default view container on show, dispose on hide).

### Code Organization

- **Core** (layout, parts, shell services) → `browser/`
- **Feature contributions** (views, actions, editors) → `contrib/<featureName>/browser/`
- **Session providers** (compute backends) → `contrib/providers/<providerName>/`
- **Shared service interfaces** → `services/<serviceName>/common/`
## Specification Documents

## General VS Code Guidelines
| Document | Path | When to read |
|----------|------|-------------|
| Layer rules | `src/vs/sessions/LAYERS.md` | Before adding any cross-module imports. Defines the internal layer hierarchy (`core` → `services` → `contrib` → `providers`) with ESLint-enforced import restrictions. Key rule: `contrib/*` must NOT import from `contrib/providers/*`. |
| Layout spec | `src/vs/sessions/LAYOUT.md` | Before changing any part, grid structure, titlebar, or CSS. Documents the fixed grid layout (Sidebar \| ChatBar \| AuxiliaryBar), part positions, the modal editor system, per-session layout state persistence, and the titlebar's three-section design. |
| Sessions spec | `src/vs/sessions/SESSIONS.md` | Before changing session/provider interfaces or data flow. Covers the pluggable provider model (`ISessionsProvider` → `ISessionsProvidersService` → `ISessionsManagementService`), `ISession`/`IChat` interfaces, observable state propagation, workspace/folder model, and session type system. |
| Sessions list spec | `src/vs/sessions/SESSIONS_LIST.md` | Before changing the sessions sidebar list. Covers the tree widget (`WorkbenchObjectTree`), renderers, grouping (workspace/date), filtering (type/status/archived/read), pinning, read/unread state, workspace capping, mobile adaptations, storage keys, and registered actions. |
| Mobile spec | `src/vs/sessions/MOBILE.md` | Before adding any phone-specific UI. Covers the mobile part subclass architecture, viewport classification (phone < 640px), `MobileTitlebarPart`, drawer-based sidebar, `MobilePickerSheet`, view/action gating with `IsPhoneLayoutContext`, and the desktop → mobile component mapping. |
| AI Customizations | `src/vs/sessions/AI_CUSTOMIZATIONS.md` | Before working on the customization editor or tree view. Documents the management editor (in `vs/workbench`) and the tree view/overview (in `vs/sessions/contrib/aiCustomizationTreeView`). |

The Agents window follows all standard VS Code engineering practices. See these instruction files for the full rules:
## Common Pitfalls

- **Source Code Organization** — `.github/instructions/source-code-organization.instructions.md` (layers, target environments, DI, contribution rules)
- **Coding Guidelines** — `.github/instructions/coding-guidelines.instructions.md` (naming conventions, code style, string localization, disposable management, DI patterns)
- **Writing Tests** — `.github/instructions/writing-tests.instructions.md` (unit/integration tests, `ensureNoDisposablesAreLeakedInTestSuite`, snapshot testing, clean teardown)
- **Wrong menu IDs**: Never use `MenuId.*` from `vs/platform/actions` for Agents window UI. Always use `Menus.*` from `browser/menus.ts`.
- **Events instead of observables**: Session state must flow through `IObservable`, not `Event`. Use `autorun`/`derived` for reactive UI, not `onDid*` event listeners.
- **Importing from providers**: Non-provider `contrib/*` code must never import from `contrib/providers/*`. Extract shared interfaces to `services/` or `common/`.
- **Missing entry point import**: New contribution files must be imported in the appropriate `sessions.*.main.ts` entry point to be loaded (for example `sessions.common.main.ts`, `sessions.desktop.main.ts`, `sessions.web.main.ts`, or `sessions.web.main.internal.ts`).
- **Modifying workbench code**: Prefer extending/wrapping workbench classes in the sessions layer over modifying shared workbench components.

## Validating Changes

You **must** run these checks before declaring work complete:

1. `npm run compile-check-ts-native` — TypeScript compilation check. **Do not run `tsc` directly.**
2. `npm run valid-layers-check` — layering violations (see `LAYERS.md`)
3. `scripts/test.sh --grep <pattern>` — unit tests (see Writing Tests instructions)
2. `npm run valid-layers-check` — **MANDATORY.** Catches layering violations. If this fails, fix the imports before proceeding.
3. `scripts/test.sh --grep <pattern>` — unit tests for affected areas
4 changes: 4 additions & 0 deletions src/vs/sessions/SESSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ Providers can import from all layers below them (core, services, non-provider co
- [Copilot Chat Sessions Provider](contrib/providers/copilotChatSessions/COPILOT_CHAT_SESSIONS_PROVIDER.md) — wraps `ChatSessionsService`, metadata contract, workspace derivation
- [Remote Agent Host Provider](contrib/providers/remoteAgentHost/REMOTE_AGENT_HOST_SESSIONS_PROVIDER.md) — remote connections, per-host provider instances

### Related Specifications

- [Sessions List](SESSIONS_LIST.md) — UI surface for browsing sessions: tree widget, grouping, filtering, pinning, read/unread state, mobile adaptations

---

## Key Concepts
Expand Down
Loading
Loading