Plugin API Reference
This document provides complete reference documentation for
the TeamIDE Plugin API, available via
window.__teamide.
Overview
The Plugin API is the official interface for plugins to interact with TeamIDE. It provides safe, controlled access to IDE functionality without exposing internal implementation details.
// Access the API
if (window.__teamide) {
// API is available
const projectId = window.__teamide.getProjectId();
}
Important: Always check if
window.__teamide exists before using it. During
development or in certain contexts, it may not be available.
API Methods
openFile
Opens a file in the Code module editor.
openFile(path: string, projectId?: string): Promise<void>
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
path |
string |
Yes | Path to the file (relative to repository root) |
projectId |
string |
No | Environment/project ID. Defaults to current project |
Returns: Promise<void> -
Resolves when the file is opened
Behavior: - Switches to the Code module automatically - Opens the file in the editor - If no project is selected, logs a warning and returns
Example:
// Open a file in the current project
await window.__teamide.openFile('/src/index.ts');
// Open a file in a specific project
await window.__teamide.openFile('/README.md', 'project-123');
// Handle case where no project is selected
const projectId = window.__teamide.getProjectId();
if (projectId) {
await window.__teamide.openFile('/package.json');
} else {
console.log('Please select a project first');
}
getProjectId
Gets the current environment/project ID.
getProjectId(): string | null
Parameters: None
Returns: string | null - The
current project ID, or null if no project is
selected
Example:
const projectId = window.__teamide.getProjectId();
if (projectId) {
console.log('Current project:', projectId);
// Proceed with project-specific operations
} else {
console.log('No project selected');
// Show a message or disable functionality
}
Notes: - The project ID is also called
“environment ID” internally - It identifies the current working
context (cloned repository) - Returns null when
viewing “Local” or “All Owners” without a specific repo
switchModule
Switches to a different module tab.
switchModule(moduleId: string): void
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
moduleId |
string |
Yes | The ID of the module to switch to |
Returns: void
Built-in Module IDs:
| Module ID | Description |
|---|---|
code |
Code editor and file explorer |
terminal |
Terminal overlay |
browser |
Embedded web browser |
Example:
// Switch to the terminal
window.__teamide.switchModule('terminal');
// Switch to the code editor
window.__teamide.switchModule('code');
// Switch to another plugin (if installed)
window.__teamide.switchModule('my-other-plugin');
Notes: - For overlay modules (like Terminal), this toggles the overlay visibility - Switching to a non-existent module ID has no effect - Plugins can switch to other plugins using their plugin ID
getGitHubToken
Gets the GitHub access token for the current owner.
getGitHubToken(): string | null
Parameters: None
Returns: string | null - The
GitHub access token, or null if not available
Example:
const token = window.__teamide.getGitHubToken();
if (token) {
// Make authenticated GitHub API calls
const response = await fetch('https://api.github.com/user', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const user = await response.json();
console.log('Logged in as:', user.login);
} else {
console.log('No GitHub account connected');
}
Notes: - Returns null if no
owner is selected in the top bar - Returns null if
the owner doesn’t have a GitHub token - Tokens are managed
through Settings > Accounts - Use responsibly - don’t expose
tokens in logs or UI
getGitHubUsername
Gets the GitHub username of the current owner.
getGitHubUsername(): string | null
Parameters: None
Returns: string | null - The
GitHub username, or null if not available
Example:
const username = window.__teamide.getGitHubUsername();
if (username) {
console.log('Current GitHub user:', username);
} else {
console.log('No GitHub account selected');
}
Notes: - Returns null if no
owner is selected - This is the login/username, not the display
name
getPluginSettings
Retrieves persisted settings for a plugin.
getPluginSettings(pluginId: string): Promise<Record<string, unknown> | null>
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
pluginId |
string |
Yes | The plugin ID to get settings for |
Returns:
Promise<Record<string, unknown> | null>
- The settings object, or null if none exist
Example:
// Load settings when plugin activates
async function loadSettings() {
const settings = await window.__teamide.getPluginSettings('my-plugin');
if (settings) {
console.log('Loaded settings:', settings);
applyTheme(settings.theme as string);
setRefreshInterval(settings.refreshInterval as number);
} else {
console.log('No saved settings, using defaults');
applyTheme('light');
setRefreshInterval(60);
}
}
Notes: - Settings are stored persistently on
the local machine - Returns null if no settings
have been saved - Settings are specific to each plugin ID - The
return type is generic - cast values as needed
savePluginSettings
Saves settings for a plugin.
savePluginSettings(pluginId: string, settings: Record<string, unknown>): Promise<void>
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
pluginId |
string |
Yes | The plugin ID to save settings for |
settings |
Record<string, unknown> |
Yes | The settings object to save |
Returns: Promise<void> -
Resolves when saved, rejects on error
Example:
// Save settings when user changes preferences
async function saveSettings(theme: string, refreshInterval: number) {
try {
await window.__teamide.savePluginSettings('my-plugin', {
theme,
refreshInterval,
lastUpdated: Date.now()
});
console.log('Settings saved');
} catch (error) {
console.error('Failed to save settings:', error);
}
}
// Usage
await saveSettings('dark', 30);
Notes: - Settings are saved persistently - Overwrites any existing settings for the plugin - Keep settings small - avoid storing large data - Use serializable values (no functions, circular references)
Available Global Libraries
Plugins have access to these libraries without bundling them:
Vue 3
import { ref, computed, defineComponent, h } from 'vue';
// All Vue 3 Composition API features are available
const count = ref(0);
const doubled = computed(() => count.value * 2);
Available exports: All of Vue 3’s public API including: -
Reactivity: ref, reactive,
computed, watch,
watchEffect - Components:
defineComponent, h,
createApp - Lifecycle: onMounted,
onUnmounted, onActivated - And
more…
Pinia
import { defineStore } from 'pinia';
const useMyStore = defineStore('my-plugin', {
state: () => ({ items: [] }),
actions: {
addItem(item) {
this.items.push(item);
}
}
});
Available exports: Full Pinia API including: -
defineStore - storeToRefs -
mapState, mapActions (Options API
helpers)
Quasar
import { useQuasar, QBtn, QCard } from 'quasar';
// Use Quasar utilities
const $q = useQuasar();
$q.notify('Hello!');
Available exports: Full Quasar component library including: -
All components (QBtn, QCard,
QInput, etc.) - Composables
(useQuasar, useDialogPluginComponent)
- Utilities (date, format,
colors)
Module Definition Interface
When creating a plugin, export a
ModuleDefinition object:
interface ModuleDefinition {
// Required
id: string; // Unique identifier
name: string; // Display name
icon: string; // Material icon name
version: string; // Semantic version
navigationComponent: Component; // Left panel
mainComponent: Component; // Center panel
// Optional
contextComponent?: Component; // Right panel
order?: number; // Tab order (lower = first)
renderMode?: 'default' | 'overlay'; // How to render
requiresRepository?: boolean; // Disable without repo
dependencies?: string[]; // Required plugins/modules
// Lifecycle hooks
onRegister?: () => void | Promise<void>;
onActivate?: () => void | Promise<void>;
onDeactivate?: () => void | Promise<void>;
}
Properties
| Property | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Unique identifier matching manifest |
name |
string |
Yes | Display name in UI |
icon |
string |
Yes | Material Design icon name |
version |
string |
Yes | Semantic version (e.g., “1.0.0”) |
navigationComponent |
Component |
Yes | Vue component for left panel |
mainComponent |
Component |
Yes | Vue component for center area |
contextComponent |
Component |
No | Vue component for right panel |
order |
number |
No | Tab sort order (default: 100) |
renderMode |
string |
No | ‘default’ or ‘overlay’ |
requiresRepository |
boolean |
No | If true, tab disabled without repo |
dependencies |
string[] |
No | IDs of required modules |
Lifecycle Hooks
| Hook | When Called | Async | Description |
|---|---|---|---|
onRegister |
Plugin loads | Yes | One-time initialization |
onActivate |
Tab becomes active | Yes | Setup when tab is shown |
onDeactivate |
Tab becomes inactive | Yes | Cleanup when tab is hidden |
Feature Toggle Integration
Check if features are enabled using the features system:
// In your plugin code
import { isFeatureEnabled } from '@teamide/features';
// Check feature state
if (isFeatureEnabled('my-plugin-dark-mode')) {
applyDarkTheme();
}
Note: The features API is injected at
runtime. Define features in features.json.
TypeScript Definitions
Add this to your plugin’s types.d.ts:
interface PluginAPI {
openFile: (path: string, projectId?: string) => Promise<void>;
getProjectId: () => string | null;
switchModule: (moduleId: string) => void;
getGitHubToken: () => string | null;
getGitHubUsername: () => string | null;
getPluginSettings: (pluginId: string) => Promise<Record<string, unknown> | null>;
savePluginSettings: (pluginId: string, settings: Record<string, unknown>) => Promise<void>;
}
declare global {
interface Window {
__teamide?: PluginAPI;
}
}
export {};
Error Handling
All API methods handle errors gracefully:
// getPluginSettings returns null on error
const settings = await window.__teamide.getPluginSettings('my-plugin');
// settings is null if there was an error
// savePluginSettings throws on error
try {
await window.__teamide.savePluginSettings('my-plugin', data);
} catch (error) {
console.error('Save failed:', error);
}
// Synchronous methods return null if unavailable
const token = window.__teamide.getGitHubToken(); // null if not available
Best Practices
Always Check API Availability
// Good
if (window.__teamide) {
await window.__teamide.openFile(path);
}
// Better - with fallback
async function openFile(path: string) {
if (window.__teamide) {
await window.__teamide.openFile(path);
} else {
console.warn('TeamIDE API not available');
}
}
Handle Null Returns
const projectId = window.__teamide?.getProjectId();
if (!projectId) {
// Show user-friendly message
showNotification('Please select a repository first');
return;
}
Cache API References
// Cache the API reference for cleaner code
const api = window.__teamide;
if (api) {
const projectId = api.getProjectId();
const username = api.getGitHubUsername();
await api.openFile('/README.md');
}
Type Your Settings
interface MyPluginSettings {
theme: 'light' | 'dark';
refreshInterval: number;
showNotifications: boolean;
}
async function loadSettings(): Promise<MyPluginSettings> {
const settings = await window.__teamide?.getPluginSettings('my-plugin');
return {
theme: (settings?.theme as MyPluginSettings['theme']) ?? 'light',
refreshInterval: (settings?.refreshInterval as number) ?? 60,
showNotifications: (settings?.showNotifications as boolean) ?? true
};
}
Related
- Plugin System - Plugin system overview
- Creating Plugins - Step-by-step guide
Changelog
| Date | Change |
|---|---|
| 2026-02-02 | Initial documentation |