name: extension-development description: >- Guides end-to-end feature development in the Kubernetes Dashboard Podman Desktop extension. Covers the extension lifecycle, 5-package architecture, RPC communication, Inversify DI, build system, and extension points. Triggers when adding features spanning extension and webview, understanding the extension lifecycle, or needing an architectural overview.
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.