Skip to content

Telemetry: central command dispatcher #902

@EhabY

Description

@EhabY

Part of the Telemetry Phase A rollout. See the RFC in Linear: AIGOV-154.

Introduce a command dispatcher modeled after contextManager in src/core/contextManager.ts so every coder.* command goes through one place. This gives us uniform command.invoked instrumentation at registration time (no per-command wrapping), a single choke point for error handling, and a harder path for commands to be registered outside the service container.

Scope

  • Implement CommandManager in src/core/commandManager.ts exposing register(id: CoderCommandId, handler: CommandHandler): Disposable.
  • CoderCommandId is a string literal union validated against the command list in package.json. Attempts to register an unknown id throw at dev time.
  • Internally the manager wraps every handler with TelemetryService.time("command.invoked", handler, { commandId }) so duration and success/error are captured once.
  • Register CommandManager in ServiceContainer. Inject where commands are wired.
  • Migrate all existing vscode.commands.registerCommand("coder.*", ...) sites to use CommandManager. Currently around 25 registrations in src/extension.ts.
  • Add a guard (lint rule or runtime check) that flags direct vscode.commands.registerCommand("coder.*", ...) usage going forward. Exact mechanism is the implementer's call.

Tests

  • Registering a valid id dispatches through the wrapped handler.
  • Registering an unknown id throws.
  • Handler success emits command.invoked with result: "success" and a durationMs.
  • Handler throwing emits command.invoked with result: "error" and the error re-propagates to the caller.
  • Disposing the returned Disposable unregisters the command.

Out of scope

  • Other cross-cutting concerns beyond telemetry.

Depends on AIGOV-243.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions