Creating Your First Addon
A practical step-by-step guide to creating, configuring, and testing your first addon with the Mr. Tick SDK.
Creating Your First Addon
This guide walks through building a complete Mr. Tick addon from scratch with TypeScript and the official @mr-tick/sdk package.
1. Project Setup
Create a directory for your plugin and initialize the project with its dependencies:
mkdir mr-tick-meu-addon
cd mr-tick-meu-addon
npm init -y
npm install @mr-tick/sdk
npm install -D typescript tsup @types/nodeConfigure tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}2. Addon Structure
Every Mr. Tick addon has a manifest.yaml metadata file and a default-exported class implementing IAddon.
2.1 Manifest (manifest.yaml)
Create manifest.yaml in your addon root:
id: meu-primeiro-addon
name: Meu Primeiro Addon
version: 1.0.0
description: Exemplo prático de extensão para o Mr-tick
author: Seu Nome ou Empresa2.2 Main Code (src/index.ts)
Create src/index.ts:
import type { IAddon, AddonContext } from '@mr-tick/sdk'
export default class MeuPrimeiroAddon implements IAddon {
// Ciclo de Vida: Executado quando o plugin é ativado no Mr-tick
public async activate(context: AddonContext): Promise<void> {
console.log('[MeuPrimeiroAddon] Addon ativado com sucesso!')
// Registrando formulário de configurações dinamicamente com abas e grupos
context.contributions.settings.register([
{
id: 'geral',
label: 'Geral',
groups: [
{
id: 'conexao',
label: 'Parâmetros de Conexão',
fields: [
{
id: 'servidorUrl',
label: 'URL do Servidor',
type: 'text',
scope: 'configuration',
required: true,
description: 'Endereço da API ou instância corporativa.',
},
{
id: 'apiKey',
label: 'Chave de Acesso / Token',
type: 'password',
scope: 'credential',
required: true,
description: 'Token de autenticação gerado nas preferências da sua conta.',
},
{
id: 'notificarEventos',
label: 'Exibir Notificações',
type: 'boolean',
defaultValue: true,
},
],
},
],
},
])
// Registrando comandos e ações disponíveis
context.contributions.commands.register('testar-conexao', async () => {
await context.host.notifications.success('Conexão testada com sucesso!', 'Mr-tick Addon')
return { isSuccess: true }
})
// O workspace vem do evento; nunca da seleção implícita da UI.
context.host.events.on('timer:start', async (data) => {
if (data.workspaceId === undefined) return
const value = await context.host.vault.get(
{ kind: 'workspace', workspaceId: data.workspaceId },
'notificarEventos',
)
if (value.isFailure()) return
if (value.success !== 'true') return
await context.host.notifications.info('Timer iniciado', 'Meu addon')
})
context.host.events.on('timer:stop', (data) => {
console.log('Timer finalizado. Duração:', data.currentSeconds)
})
}
// Ciclo de Vida: Executado ao desativar o addon; troca de workspace não o desativa
public async deactivate(): Promise<void> {
console.log('[MeuPrimeiroAddon] Addon desativado. Limpando recursos...')
}
}3. Dynamic Settings (context.contributions.settings.register)
Calling context.contributions.settings.register(schema) in activate defines preference forms without writing interface code. Mr. Tick generates and validates the fields natively.
Supported Field Types:
text: Plain text input.password: Masked input for tokens, passwords, and keys.number: Numeric input.boolean: A true/false toggle.select: A dropdown with{ label, value }pairs.button: An action button.
4. Addon Context (AddonContext)
When activating an addon, Mr. Tick injects AddonContext with the available APIs and tools:
| Property | Description |
|---|---|
context.contributions.settings | Declarative registration of addon form and settings schemas. |
context.contributions.menus | Registration of sidebar or timerbar menu items. |
context.contributions.dataSources | Registration of external data sources (Tasks, Time Entries, Members, Metadata). |
context.contributions.commands | Registration and execution of universal Mr. Tick commands. |
context.host.vault | Secure key-value storage isolated by workspace. |
context.host.events | Real-time system events (timer start/stop, idle, workspace changes). |
context.host.notifications | System toasts and notifications. |
context.core.timer | Reading and controlling the active timer. |
context.host.oauth | Secure OAuth 2.0 PKCE authentication without secrets. |
5. Building the Addon
Add a build script to package.json:
{
"scripts": {
"build": "tsup src/index.ts --format esm,cjs --dts --clean"
}
}Run the build:
npm run buildThe resulting compiled file can be imported directly in Mr. Tick's Addon settings.