EXTEND IT YOURSELF
Your first plugin.
From a file to a button.
A complete example: list projects and open a diagnostic terminal in the right folder. Works with the installed app, without access to PrumoGrid source code.
- 01 / DECLARE
extension.json
Give the plugin an ID and declare the commands that will appear as buttons.
- 02 / CONNECT THE CODE
activate(api)
Use commands.register with the same IDs to define what each button does.
- 03 / INSTALL
Tools → Extensions
Install the .prumoplugin, review the requested capabilities and enable it. Its buttons appear on the extension card.
PrumoGrid 0.5.4+ · API 1 · Apache 2.0 · No agent or external service. The example and its code are downloadable; application source code remains unavailable.
How to create, register and test your plugin
Your plugin lives in your repository.
Just as developing an extension does not require contributing to the VS Code repository, your PrumoGrid plugin lives in your own folder or repository. No commit, pull request, approval or access to application source code is needed. The .prumoplugin format and API belong to PrumoGrid; VSIX is not supported.
Registration happens inside the plugin: declare commands in the manifest and connect their IDs to JavaScript functions. The recipient installs and enables the package through the interface. No server or Windows Registry registration is involved. Creating a development folder does not make PrumoGrid discover it automatically.
01 / PREPARE THE FOLDER
Three files. No application checkout.
Create a folder called meu-plugin. Save the files below in it, using the exact names and UTF-8. Node.js 22 or later is needed to run this packager; the installed app already includes the runtime needed to use the ready-made plugin.
meu-plugin/ ├── extension.json ├── index.cjs └── empacotar.mjs
02 / DECLARE THE PLUGIN
The manifest describes what appears in PrumoGrid.
{
"id": "exemplo.diagnostico",
"name": "Diagnóstico do projeto",
"publisher": "Exemplo PrumoGrid",
"version": "1.0.0",
"apiVersion": 1,
"description": "Lista projetos e abre um PowerShell de diagnóstico no Projeto-demo.",
"permissions": ["code.execute", "projects.read", "terminal.create"],
"commands": [
{ "id": "listar-projetos", "title": "1. Mostrar projetos" },
{ "id": "abrir-diagnostico", "title": "2. Abrir diagnóstico" }
]
}
| Field | Purpose |
|---|---|
id | Plugin identity: exemplo.diagnostico. Choose something like yourcompany.tools for your own plugin. Keep the ID across updates. |
version / apiVersion | 1.0.0 is your plugin version; 1 is the API version it uses. |
permissions | code.execute is required. projects.read allows project queries; terminal.create allows opening PowerShell. |
commands[].id | Local technical command key. listar-projetos must exactly match the string passed to commands.register. |
commands[].title | Button label: 1. Mostrar projetos. Changing the label does not require changing the ID. |
03 / REGISTER THE BEHAVIOR
Every declared ID gets a function.
PrumoGrid supplies api and calls activate when you execute the first command. Inside it, commands.register connects each ID to its callback. Register both commands from the manifest. Do not prefix command IDs with the plugin ID.
'use strict';
// SPDX-License-Identifier: Apache-2.0
// Troque pelo nome EXATO do projeto cadastrado no PrumoGrid.
const PROJECT_NAME = 'Projeto-demo';
exports.activate = (api) => {
// Mesmo ID declarado em extension.json → commands[].id.
api.commands.register('listar-projetos', async () => {
const projects = await api.projects.list();
const names = projects.map(project => project.name).join(', ');
await api.window.showMessage(
`Projetos: ${names || 'nenhum cadastrado'}`.slice(0, 900)
);
});
api.commands.register('abrir-diagnostico', async () => {
const projects = await api.projects.list();
const matches = projects.filter(project => project.name === PROJECT_NAME);
// Não escolhe outro projeto silenciosamente.
if (matches.length !== 1) {
await api.window.showMessage(
`Cadastre exatamente um projeto chamado ${PROJECT_NAME}. ` +
'Use Mostrar projetos para conferir os nomes.'
);
return;
}
// Abre um NOVO terminal, sem escrever nos que já estão em uso.
await api.terminal.create({
projectId: matches[0].id,
title: 'Diagnóstico por plugin',
command: "Write-Output 'PrumoGrid plugin OK'; Get-Location; $PSVersionTable.PSVersion"
});
});
};
This example looks for exactly Projeto-demo; it does not automatically use the selected project. It reports missing or duplicate names. To use another project, change PROJECT_NAME, rebuild the package and install it.
04 / BUILD THE PACKAGE
Combine manifest and code in a .prumoplugin.
Save the packager below too. It only uses built-in Node modules, checks basic fields, syntax and size, and creates a new file. PrumoGrid validates the package when you install it.
// SPDX-License-Identifier: Apache-2.0
// Node.js 22+. Sem dependências e sem acesso aos fontes do PrumoGrid.
import { readFileSync, writeFileSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { Script } from 'node:vm';
export function createPackage(directory = import.meta.dirname) {
const manifest = JSON.parse(readFileSync(join(directory, 'extension.json'), 'utf8'));
const source = readFileSync(join(directory, 'index.cjs'), 'utf8');
if (manifest.apiVersion !== 1 || !/^[a-z][a-z0-9-]{0,39}\.[a-z][a-z0-9-]{0,39}$/.test(manifest.id || '')
|| !/^\d+\.\d+\.\d+$/.test(manifest.version || '')) {
throw new Error('Confira id, version e apiVersion no extension.json.');
}
// Apenas verifica sintaxe. Não executa nem atesta a segurança do plugin.
new Script(source, { filename: 'index.cjs' });
const json = JSON.stringify({ manifest, source }, null, 2) + '\n';
if (Buffer.byteLength(json, 'utf8') > 2 * 1024 * 1024) {
throw new Error('O pacote excede o limite de 2 MiB.');
}
return { manifest, json };
}
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
const { manifest, json } = createPackage();
const filename = `${manifest.id.split('.')[1]}-${manifest.version}.prumoplugin`;
const output = join(import.meta.dirname, filename);
writeFileSync(output, json, { flag: 'wx' });
console.log(`Pacote criado: ${output}`);
}
In PowerShell, enter the meu-plugin folder and run:
node .empacotar.mjs
Result: diagnostico-1.0.0.prumoplugin in the same folder. No npm install, token or API key is needed. The package is JSON containing manifest and source, up to 2 MiB; renaming a ZIP does not work.
05 / INSTALL AND TEST
Now the app recognizes your plugin.
- Create a Projeto-demo folder and add it to PrumoGrid using + add projects…; check its name in the project panel.
- Open Tools → Extensions → Install package… and choose diagnostico-1.0.0.prumoplugin.
- The Diagnóstico do projeto card starts disabled. Click Enable, review its requested capabilities and confirm if you trust the code.
- Click 1. Mostrar projetos. The message should include Projeto-demo.
- Click 2. Abrir diagnóstico. Close Extensions, select Projeto-demo and check the new Diagnóstico por plugin terminal.
EXPECTED RESULT
PowerShell shows PrumoGrid plugin OK, the folder path and its version. Each click opens a new terminal. Command completed confirms the plugin returned; check the terminal output to verify the diagnostic.
06 / CHANGE AND DISTRIBUTE
Same ID. New version. Install again.
Edit the files, keep exemplo.diagnostico and increase version to 1.0.1. Run the packager, install diagnostico-1.0.1.prumoplugin and enable it again. Editing index.cjs does not change the installed copy. Refresh list only reloads installed packages; it does not rebuild your plugin.
Installation belongs to the current profile. You do not need to copy files into the application directory or edit internal storage. To distribute your own plugin, choose your own ID and share the .prumoplugin with instructions, a license and reviewable code. API 1 has no marketplace or automatic updates.
If it does not appear or run
- No Extensions menu: check that the running app is PrumoGrid 0.5.4 or later.
- Disabled buttons: enable the package, including after updates.
- Command not registered: compare commands[].id with commands.register exactly, and check exports.activate.
- Permission denied: declare the required API permission and install the new package.
- EEXIST while packaging: the output already exists. Increase the version to generate a new file.
Plugins run Node code with your account privileges. Manifest permissions control PrumoGrid APIs, not native Node capabilities. Only install code you trust. Do not put credentials in the package.
See also the plugin FAQ ↗