Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions jupyterlab_commands_toolkit/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,26 +85,53 @@ def handle_command_result(event_data):
future.set_result(event_data)


async def list_all_commands() -> dict:
async def list_all_commands(query: Optional[str] = None) -> dict:
"""
Retrieve a list of all available JupyterLab commands.

This function emits a request to the JupyterLab frontend to retrieve all
registered commands in the application. It waits for the response and
returns the complete list of available commands with their metadata.

Args:
query (Optional[str], optional): An optional search query to filter commands.
When provided, only commands whose ID, label,
caption, or description contain the query string
(case-insensitive) will be returned. If None or
omitted, all commands will be returned.
Defaults to None.

Returns:
dict: A dictionary containing the command list response from JupyterLab.
The structure typically includes:
- success (bool): Whether the operation succeeded
- commands (list): List of available command objects, with arguments and types
- commandCount (int): Number of commands returned
- commands (list): List of available command objects, each with:
- id (str): The command identifier
- label (str, optional): Human-readable command label
- caption (str, optional): Short description
- description (str, optional): Detailed usage information
- args (dict, optional): Command argument schema
- error (str, optional): Error message if the operation failed

Raises:
asyncio.TimeoutError: If the frontend doesn't respond within the timeout period

Examples:
>>> # Get all commands
>>> await list_all_commands()
{'success': True, 'commandCount': 150, 'commands': [...]}

>>> # Filter commands by query
>>> await list_all_commands(query="notebook")
{'success': True, 'commandCount': 25, 'commands': [...]}
"""
args = {}
if query is not None:
args["query"] = query

return await emit_and_wait_for_result(
{"name": "jupyterlab-commands-toolkit:list-all-commands", "args": {}}
{"name": "jupyterlab-commands-toolkit:list-all-commands", "args": args}
)


Expand Down
32 changes: 28 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ const plugin: JupyterFrontEndPlugin<void> = {
describedBy: {
args: {}
},
execute: async () => {
execute: async (args: any) => {
const query = args['query'] as string | undefined;

const commandList: Array<{
id: string;
label?: string;
Expand All @@ -112,23 +114,45 @@ const plugin: JupyterFrontEndPlugin<void> = {
args?: any;
}> = [];

// Get all command IDs
const commandIds = commands.listCommands();

for (const id of commandIds) {
// Get command metadata using various CommandRegistry methods
const description = await commands.describedBy(id);
const label = commands.label(id);
const caption = commands.caption(id);
const usage = commands.usage(id);

commandList.push({
const command = {
id,
label: label || undefined,
caption: caption || undefined,
description: usage || undefined,
args: description?.args || undefined
});
};

// Filter by query if provided
if (query) {
const searchTerm = query.toLowerCase();
const matchesQuery =
id.toLowerCase().includes(searchTerm) ||
label?.toLowerCase().includes(searchTerm) ||
caption?.toLowerCase().includes(searchTerm) ||
usage?.toLowerCase().includes(searchTerm);

if (matchesQuery) {
commandList.push(command);
}
} else {
commandList.push(command);
}
}
return commandList;
return {
success: true,
commandCount: commandList.length,
commands: commandList
};
}
});
}
Expand Down