- Mark `onDidChangeSessions` as deprecated in `ICopilotCLISessionService`.
- Enhance session deletion logic in `ChatSessionMetadataStore`.
- Update `CopilotCLIChatSessionInitializer` to support new branch creation.
- Refine session option group handling in `SessionOptionGroupBuilder`, ensuring previous selections persist.
- Adjust tests to validate new folder handling and session state persistence.
* chat: use supportedTypes instead of unsupportedTypes
Inverted to match the vscode API change. Providers now declare what
they support (whitelist) instead of what they don't (blacklist).
- Claude: Agent, Skill, Instructions, Hook
- CLI: Agent, Skill, Instructions
* fix: use 'builtin' groupKey matching vscode BUILTIN_STORAGE constant
SDK agents with synthetic URIs (no real file) use groupKey 'builtin'
so they appear under a 'Built-in' group header in the UI.
* test: add parity tests for supportedTypes and groupKey consistency
- Verify all returned items have a type matching supportedTypes
- Verify items with synthetic URIs (non-file scheme) use groupKey 'builtin'
* fix: improve CLI agent dedup with normalized name matching
The previous dedup logic did exact name matching between SDK agents
and file agents, which failed when:
- SDK uses underscores, files use hyphens (apple_docs vs apple-docs)
- SDK appends suffixes (apple_docs_investigator vs apple-docs)
- Files have .md extension instead of .agent.md
Now normalizes names by removing hyphens/underscores and uses
startsWith matching. Also preserves file URIs when matched so
workspace agents show their real file paths instead of synthetic URIs.
* refactor: remove explicit groupKey from providers, let vscode infer
groupKey should only be used for business-logic categories that vscode
can't infer (e.g. instruction sub-categories like 'loaded on demand').
For agents, skills, etc. vscode reliably infers the group from the URI:
- file: under workspace → Workspace
- file: elsewhere → User
- vscode-userdata: → Extensions (read-only)
- non-file schemes → Built-in
* fix: use exact name matching and URI dedup for CLI agents
- Replace startsWith prefix matching with exact normalized name lookup
to prevent two CLI agents from matching the same file agent
- Add URI-based dedup so multiple CLI agents resolving to the same
file produce only one item (first wins)
- Filter unmatched file agents through isCLIPath() to prevent agents
from non-CLI directories (e.g. .claude/) from leaking into output
- Add tests for dedup, exact matching, and isCLIPath filtering
* refactor: split provideChatSessionCustomizations into per-type methods
Extract getAgentItems(), getInstructionItems(), getSkillItems() from the
monolithic provideChatSessionCustomizations. Also extract normalizeName()
helper for reuse.
* rename CLI_SUBPATHS/CLI_HOME_SUBPATHS to CLI_WORKSPACE_PREFIXES/CLI_HOME_PREFIXES
* refactor: add sourceUri to CLIAgentInfo, eliminate provider cross-referencing
Introduce CLIAgentInfo type wrapping SweCustomAgent + sourceUri.
CopilotCLIAgents.getAgentsImpl() now captures URIs at the merge point:
- SDK agents get synthetic copilotcli: URIs
- Prompt file agents get their real file: URIs
This eliminates the entire cross-referencing dance in the customization
provider's getAgentItems(), which collapsed from ~40 lines to a simple
map() call. Dedup and matching now happen once in CopilotCLIAgents
instead of being duplicated in the provider.
* simplify: remove isCLIPath filtering from customization provider
The prompt file service returns the right items — no need to
second-guess with path filtering. Removes isCLIPath(), the
CLI_WORKSPACE_PREFIXES/CLI_HOME_PREFIXES constants, and the
IWorkspaceService/INativeEnvService constructor dependencies.
* revert test version
* run npm run vscode-dts:update
* Add Repository properties
* Store workspace changes per session so that we can have multiple sessions with their individual changes
* Update src/extension/chatSessions/vscode-node/chatSessionWorkspaceFolderServiceImpl.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Pull request feedback
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Revert "Background - include repositoryPath for folder sessions (#4829)"
This reverts commit ad31f89dfa.
* Background - store workspace folder information
On Windows, passing 'NUL' as a relative path to Node's fs.openSync
creates a literal file named 'NUL' in the cwd (the VS Code install dir)
instead of opening the Windows null device. This caused a 1.4MB telemetry
data file to appear in the app install folder, triggering update errors.
Replace the platform-conditional string with os.devNull which correctly
returns '\\.\\nul' on Windows and '/dev/null' on Unix.
Set OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true before
SDK init so the debug panel always shows full prompts, responses,
and tool arguments. Without this, users without the env var set
see empty content in the debug panel.
When user OTel is disabled, SDK spans go to /dev/null so captured
content never leaves the process.
* add OTel instrumentation spec and plan for all agents
* feat: OTel instrumentation for Copilot CLI background agent
- Add agentOTelEnv.ts config derivation helpers (CLI + Claude)
- Enable SDK OtelLifecycle via env vars before LocalSessionManager ctor
- Add invoke_agent copilotcli wrapper span with traceparent propagation
- Forward OTel env vars to terminal CLI sessions
- Update spec and plan docs for all agents
- 33 tests passing (14 new + 19 existing)
* feat: filter debug-panel-only spans from OTLP export
Spans with non-standard gen_ai.operation.name values (content_event,
user_message) are excluded from external OTLP export while remaining
visible in the Agent Debug Log panel via onDidCompleteSpan.
Only GenAI-conventional operations (invoke_agent, chat, execute_tool,
embeddings, execute_hook) are exported to the user's collector.
* fix: add IOTelService to CopilotCLISessionService ctor in participant test
* fix: pass chatSessionId to CapturingToken for debug panel routing
The CapturingToken was created without chatSessionId, so the debug panel
couldn't route copilotcli OTel spans to the correct session view.
Also: Copilot CLI runtime only supports otlp-http (not gRPC). Terminal
CLI sessions require an HTTP-compatible OTLP endpoint.
* docs: add CLI HTTP-only limitation to spec and dual-port Aspire setup to test plan
* fix: forward OTel env vars to CLI terminal sessions
- Include OTel env vars in terminal profile provider path (dropdown)
which previously only set shell info without auth/OTel env
- Pass empty env to deriveCopilotCliOTelEnv for terminal sessions so
vars are always included regardless of process.env pollution from
the in-process background agent
- Update test plan to use Grafana LGTM stack
* fix: add CHAT_SESSION_ID to attributes in CopilotCLISession
* docs: update OTel instrumentation specification for Copilot CLI and Claude Code
* feat: bridge SDK native OTel spans to Agent Debug panel
Replace synthetic span approach (PR #4494) with a bridge SpanProcessor
that forwards SDK-native spans from the Copilot CLI runtime's
BasicTracerProvider into the extension's IOTelService event stream.
This gives the debug panel the full SDK span hierarchy (subagents,
permissions, hooks, nested tool calls) — identical to what Grafana shows.
Architecture:
- Add injectCompletedSpan() to IOTelService interface for external span
injection without OTLP re-export
- Create CopilotCliBridgeSpanProcessor that converts ReadableSpan to
ICompletedSpanData, injects copilot_chat.chat_session_id from a
traceId→sessionId map, and fires onDidCompleteSpan
- Install bridge on SDK's TracerProvider via internal
MultiSpanProcessor._spanProcessors array (OTel SDK v2 removed the
public addSpanProcessor API, but this internal array is the same
pattern the SDK itself uses in forceFlush)
- Propagate traceparent from extension root span to SDK via
otelLifecycle.updateParentTraceContext() so all spans share a traceId
- Filter bridge to only forward spans from registered CLI sessions
Code changes:
- copilotCliBridgeSpanProcessor.ts: new bridge processor
- copilotcliSession.ts: remove all synthetic spans (chat, tool, error),
keep root invoke_agent span + traceparent propagation + bridge wiring
- copilotcliSessionService.ts: install bridge after first session
creation, wire bridge + SDK trace context updater to sessions
- IOTelService: add injectCompletedSpan to interface + all impls
- Remove outdated synthetic span tests
- Add OTel data flow architecture diagram (HTML)
* fix: update span processing to use parent span context and enhance subagent event identification
* display names for tool call and subagent events
* docs: merge arch and spec into single developer guide
Combine agent_monitoring_arch.md (foreground-only) and agent-otel-spec.md
(all agents) into a single comprehensive developer reference covering all
four agent paths, bridge architecture, and SDK internal access warnings.
* docs: fix stale addSpanProcessor reference in data flow diagram
* chore: move plan and test docs to offline archive
These documents are reference material for the OTel sprint, not needed
in the shipped PR. Archived to ~/Documents/copilot-otel-archive/.
* test: add bridge SpanProcessor unit tests
13 tests covering: traceId filtering, parentSpanContext conversion,
CHAT_SESSION_ID injection, attribute flattening, event conversion,
HrTime→ms conversion, unregister/shutdown behavior.
* test: add span event identification and naming tests
7 tests covering invoke_agent identification logic: top-level skip,
SDK wrapper skip (no agent name), subagent detection (name attribute
and span name parsing), unknown/missing operation name handling.
* fix: always enable SDK OTel for debug panel regardless of user config
The CLI SDK's OtelLifecycle must always initialize so the bridge
processor can forward native spans to the debug panel. When user
OTel is disabled, COPILOT_OTEL_ENABLED is still set but no OTLP
endpoint is configured — the SDK creates spans (for debug panel)
but doesn't export to any external collector.
The bridge installation is also now unconditional — it installs
even when user OTel is disabled.
* chore: remove transient sprint plan
* fix: suppress SDK OTLP export when user OTel is disabled
When user OTel is disabled, force the SDK to use file exporter to
/dev/null instead of letting it default to OTLP. Also clear any
leftover OTEL_EXPORTER_OTLP_ENDPOINT from previous sessions to
prevent orphaned traces in Grafana.
* docs: add background agents section to user monitoring guide
Cover Copilot CLI (background + terminal) and Claude Code agent
tracing in the user-facing guide. Includes span hierarchy examples,
service.name filtering table, and CLI HTTP-only limitation note.
* docs: remove Claude Code from user guide (not yet supported)
* fixup! feat: OTel instrumentation for Copilot CLI background agent
* fix: address PR review comments
- Use GenAiOperationName constants in EXPORTABLE_OPERATION_NAMES (avoids drift)
- Remove unnecessary delete of OTEL_EXPORTER_OTLP_ENDPOINT from process.env
- Replace 'as any' OTel mocks with typed NoopOTelService in terminal tests
- Clarify comment on empty env arg for terminal OTel env derivation
- Add ExportResultCode.SUCCESS comment for clarity
* fixup! fix: always enable SDK OTel for debug panel regardless of user config
* fix: handle SDK native hook spans in debug panel
The SDK's OtelSessionTracker creates 'hook {type}' spans with
github.copilot.hook.type attributes (not gen_ai.operation.name).
These were silently dropped by completedSpanToDebugEvent. Now
detected by span name prefix and converted to Hook: {type} events.
* add execute_hook spans for Claude hook executions in monitoring documentation
* docs: add hook spans to CLI trace hierarchy in user guide
* Add first user message tracking to chat session metadata store
* Updates
* Fix tests
* Fixes
* Refactor titleService variable name for consistency in CopilotCLISessionService tests
* Refactor Copilot CLI session handling to utilize workspace information
- Introduced IWorkspaceInfo interface to encapsulate workspace-related data.
- Updated session creation and retrieval methods to accept workspaceInfo instead of individual parameters.
- Refactored tests to align with the new workspaceInfo structure.
- Enhanced session management by ensuring consistent handling of working directories and isolation settings.
- Improved prompt resolution by passing workspaceInfo to relevant methods.
* Updates
* Refactor CopilotCLISessionOptions to remove workingDirectory property and streamline working directory retrieval
* Fixes