Kubernetes Dashboard Extension Development Guide
Extension Lifecycle
Entry Point (packages/extension/src/main.ts)
activate() creates a DashboardExtension and returns a
KubernetesDashboardExtensionApi. deactivate() cleans up.
Activation Sequence (packages/extension/src/dashboard-extension.ts)
- Create webview panel (loads
media/index.html) - Initialize RPC (
new RpcExtension(panel.webview)+rpcExtension.init()) - Setup Inversify DI container (
InversifyBinding.initBindings()) - Load all managers, dispatchers, subscribers from container
- Register RPC instances for each channel (API_CONTEXTS, API_SUBSCRIBE, etc.)
- Start kubeconfig watcher, health checks, port forwarding
- Return extension API for external consumers
5-Package Architecture
Extension (Node.js) <--RPC--> Channels (shared interfaces) <--RPC--> Webview (Svelte 5)
|
RPC (transport)
|
API (external)
packages/extension/— Node.js backend. Entry:src/main.ts. Uses@podman-desktop/api,@kubernetes/client-node, Inversify DI.packages/webview/— Svelte 5 UI. Entry:src/main.ts, root:src/Main.svelte. Uses@podman-desktop/ui-svelte, Inversify DI, RpcBrowser.packages/channels/— Shared RPC channel definitions, API interfaces, and data models. The contract between extension and webview.packages/rpc/— Transport layer.RpcExtension(backend) andRpcBrowser(webview) over webview postMessage.packages/api/— Public API for other Podman Desktop extensions.
Build Order
RPC and Channels must build first (they are dependencies):
pnpm build:rpc && pnpm build:channels && pnpm build
Adding a New Feature (End-to-End)
- Define the channel interface in
packages/channels/src/interface/. Create or extend an API interface (e.g.,MyFeatureApi). - Define data models in
packages/channels/src/model/if needed. - Create the RPC channel in
packages/channels/src/channels.ts:export const API_MY_FEATURE = createRpcChannel<MyFeatureApi>('MyFeatureApi'); - Implement the backend in
packages/extension/src/:- Create
@injectable()service implementing the interface - Bind in the appropriate DI module (
_manager-module.ts) - Register with RPC in
dashboard-extension.ts:rpcExtension.registerInstance(API_MY_FEATURE, container.get(MyFeatureApiImpl));
- Create
- Build the webview UI in
packages/webview/src/:- Access via
remote.getProxy(API_MY_FEATURE) - For state broadcasting, create a StateObject + DispatcherObject pair
- Access via
- Write tests — unit tests for both extension and webview, update E2E if needed.
RPC Communication
Request-Response (webview calls extension)
// Webview: get proxy, call methods
const myApi = remote.getProxy(API_MY_FEATURE);
const result = await myApi.doSomething(args);
Broadcasting (extension pushes to webview)
// Extension: fire broadcast
rpcExtension.fire(MY_CHANNEL, data);
// Webview: listen for broadcasts
const disposable = rpcBrowser.on(MY_CHANNEL, data => {
/* handle */
});
Timeout
Default 5 seconds. For long-running operations:
const proxy = remote.getProxy(API_MY_FEATURE, {
noTimeoutMethods: ['longRunningMethod'],
});
Extension Points
Extension points (commands, menus, configuration, icons, views) are defined in
packages/extension/package.json under contributes.
Development Watch Mode
cd packages/webview && pnpm watch # Rebuilds webview on changes
The extension is rebuilt by Podman Desktop when webview output changes.