mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-23 02:36:05 +00:00
feat: cleanup plugins
This commit is contained in:
parent
62d2b0334f
commit
0145f28d50
12 changed files with 69 additions and 354 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -84,7 +84,10 @@ electron-builder.win-store.yaml
|
|||
.aider*
|
||||
|
||||
/packages/plugin-api/dist/**/*.*
|
||||
/packages/plugin-api/src/**/*.js
|
||||
/packages/plugin-api/src/**/*.js.map
|
||||
|
||||
#
|
||||
perf-metrics-create-tasks.json
|
||||
perf-metrics-initial-load.json
|
||||
/packages/plugin-dev/procrastination-buster/procrastination-buster-v1.0.0.zip
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
"name": "@super-productivity/plugin-api",
|
||||
"version": "1.0.0",
|
||||
"description": "TypeScript definitions for Super Productivity plugin development",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build:watch": "tsc --watch",
|
||||
"prepublishOnly": "npm run build"
|
||||
"build": "tsc --emitDeclarationOnly",
|
||||
"build:watch": "tsc --emitDeclarationOnly --watch",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"keywords": [
|
||||
"super-productivity",
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/johannesjo/super-productivity#readme",
|
||||
"files": [
|
||||
"dist/**/*",
|
||||
"src/**/*.ts",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"lib": ["ES2020", "DOM"],
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
|
|
@ -13,7 +14,8 @@
|
|||
"forceConsistentCasingInFileNames": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"noEmitOnError": true
|
||||
"noEmitOnError": true,
|
||||
"noEmit": false
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
|
|
|
|||
12
packages/plugin-dev/api-test-plugin/package-lock.json
generated
Normal file
12
packages/plugin-dev/api-test-plugin/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "api-test-plugin",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "api-test-plugin",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
85
packages/plugin-dev/package-lock.json
generated
85
packages/plugin-dev/package-lock.json
generated
|
|
@ -858,18 +858,6 @@
|
|||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/source-map": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
|
||||
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
|
|
@ -1237,20 +1225,6 @@
|
|||
"node": ">=6.5"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
|
|
@ -1565,14 +1539,6 @@
|
|||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001724",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz",
|
||||
|
|
@ -1611,14 +1577,6 @@
|
|||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
|
|
@ -2331,17 +2289,6 @@
|
|||
"solid-js": "^1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
|
|
@ -2438,38 +2385,6 @@
|
|||
"streamx": "^2.15.0"
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.43.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
|
||||
"integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
"acorn": "^8.14.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
"bin": {
|
||||
"terser": "bin/terser"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/terser/node_modules/source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/text-decoder": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
|
||||
|
|
|
|||
|
|
@ -6,10 +6,6 @@
|
|||
"scripts": {
|
||||
"build": "node scripts/build-all.js",
|
||||
"build:all": "node scripts/build-all.js",
|
||||
"build:minimal": "cd minimal-plugin && zip -r ../minimal-plugin.zip manifest.json plugin.js README.md && cd .. && echo '✓ Built minimal-plugin.zip'",
|
||||
"build:simple": "cd simple-typescript-plugin && npm install && npm run build && cd .. && echo '✓ Built simple-typescript-plugin'",
|
||||
"build:example": "cd example-plugin && npm install && npm run build && npm run package && cd .. && echo '✓ Built example-plugin'",
|
||||
"build:procrastination": "cd procrastination-buster && npm install && npm run build && npm run package && cd .. && echo '✓ Built procrastination-buster'",
|
||||
"clean": "rm -rf */node_modules */dist minimal-plugin.zip",
|
||||
"clean:dist": "rm -rf */dist minimal-plugin.zip",
|
||||
"install:all": "node scripts/install-all.js",
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
// This file has been removed. Functionality integrated into App.tsx for simplicity.
|
||||
|
|
@ -1 +0,0 @@
|
|||
// This file has been removed. Functionality integrated into App.tsx for simplicity.
|
||||
|
|
@ -1,151 +0,0 @@
|
|||
// Procrastination Buster Plugin for Super Productivity
|
||||
|
||||
// Constants
|
||||
const PluginMessageType = {
|
||||
ADD_STRATEGY_TASK: 'ADD_STRATEGY_TASK',
|
||||
START_POMODORO: 'START_POMODORO',
|
||||
START_FOCUS_MODE: 'START_FOCUS_MODE',
|
||||
QUICK_ADD_TASK: 'QUICK_ADD_TASK',
|
||||
};
|
||||
|
||||
const SPActionType = {
|
||||
SHOW_ADD_TASK_BAR: '[Layout] Show AddTaskBar',
|
||||
SET_CURRENT_TASK: '[Task] SetCurrentTask',
|
||||
START_POMODORO: '[Pomodoro] Start Pomodoro',
|
||||
SHOW_FOCUS_OVERLAY: '[FocusMode] Show Focus Overlay',
|
||||
};
|
||||
|
||||
const SnackType = {
|
||||
SUCCESS: 'SUCCESS',
|
||||
ERROR: 'ERROR',
|
||||
INFO: 'INFO',
|
||||
};
|
||||
|
||||
const WindowMessageType = {
|
||||
PLUGIN_MESSAGE: 'PLUGIN_MESSAGE',
|
||||
PLUGIN_MESSAGE_RESPONSE: 'PLUGIN_MESSAGE_RESPONSE',
|
||||
PLUGIN_MESSAGE_ERROR: 'PLUGIN_MESSAGE_ERROR',
|
||||
};
|
||||
|
||||
// Message handler for plugin messages
|
||||
const messageHandler = async (message) => {
|
||||
switch (message.type) {
|
||||
case PluginMessageType.ADD_STRATEGY_TASK:
|
||||
const taskTitle = `Strategy: ${message.strategy}`;
|
||||
const taskNotes = `Strategy for ${message.blockerType}: ${message.strategy}`;
|
||||
|
||||
try {
|
||||
const taskId = await PluginAPI.addTask({
|
||||
title: taskTitle,
|
||||
notes: taskNotes,
|
||||
});
|
||||
|
||||
// Show the add task bar to allow quick editing
|
||||
PluginAPI.dispatchAction({
|
||||
type: SPActionType.SHOW_ADD_TASK_BAR,
|
||||
});
|
||||
|
||||
// Set the new task as current
|
||||
PluginAPI.dispatchAction({
|
||||
type: SPActionType.SET_CURRENT_TASK,
|
||||
id: taskId,
|
||||
});
|
||||
|
||||
PluginAPI.showSnack({
|
||||
msg: 'Strategy task created! You can edit it in the task bar.',
|
||||
type: SnackType.SUCCESS,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to create task:', error);
|
||||
PluginAPI.showSnack({
|
||||
msg: 'Failed to create task',
|
||||
type: SnackType.ERROR,
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case PluginMessageType.START_POMODORO:
|
||||
PluginAPI.dispatchAction({
|
||||
type: SPActionType.SHOW_FOCUS_OVERLAY,
|
||||
});
|
||||
|
||||
PluginAPI.showSnack({
|
||||
msg: 'Focus mode activated! Distractions minimized.',
|
||||
type: SnackType.SUCCESS,
|
||||
});
|
||||
break;
|
||||
|
||||
case PluginMessageType.START_FOCUS_MODE:
|
||||
PluginAPI.dispatchAction({
|
||||
type: SPActionType.SHOW_FOCUS_OVERLAY,
|
||||
});
|
||||
|
||||
PluginAPI.showSnack({
|
||||
msg: 'Focus mode activated! Distractions minimized.',
|
||||
type: SnackType.SUCCESS,
|
||||
});
|
||||
break;
|
||||
|
||||
case PluginMessageType.QUICK_ADD_TASK:
|
||||
PluginAPI.dispatchAction({
|
||||
type: SPActionType.SHOW_ADD_TASK_BAR,
|
||||
});
|
||||
|
||||
PluginAPI.showSnack({
|
||||
msg: 'Add task bar opened. Create your task!',
|
||||
type: SnackType.INFO,
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn('Unknown message type:', message.type);
|
||||
}
|
||||
};
|
||||
|
||||
// Register the handler with PluginAPI
|
||||
PluginAPI.onMessage(messageHandler);
|
||||
|
||||
// Expose the handler to the iframe for debugging purposes
|
||||
window.__pluginMessageHandler = messageHandler;
|
||||
|
||||
// Listen for messages from the iframe
|
||||
window.addEventListener('message', async (event) => {
|
||||
// Handle PLUGIN_MESSAGE events from our iframe
|
||||
if (event.data?.type === WindowMessageType.PLUGIN_MESSAGE && event.data.message) {
|
||||
try {
|
||||
// Process the message through our handler
|
||||
const result = await messageHandler(event.data.message);
|
||||
|
||||
// Send response back to iframe if needed
|
||||
if (event.source && event.data.messageId) {
|
||||
event.source.postMessage(
|
||||
{
|
||||
type: WindowMessageType.PLUGIN_MESSAGE_RESPONSE,
|
||||
messageId: event.data.messageId,
|
||||
result,
|
||||
},
|
||||
'*',
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error handling iframe message:', error);
|
||||
|
||||
if (event.source && event.data.messageId) {
|
||||
event.source.postMessage(
|
||||
{
|
||||
type: WindowMessageType.PLUGIN_MESSAGE_ERROR,
|
||||
messageId: event.data.messageId,
|
||||
error: error.message,
|
||||
},
|
||||
'*',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Show a snack on plugin load
|
||||
PluginAPI.showSnack({
|
||||
msg: 'Procrastination Buster loaded successfully!',
|
||||
type: SnackType.SUCCESS,
|
||||
});
|
||||
|
|
@ -1,79 +1,3 @@
|
|||
// Procrastination Buster Plugin for Super Productivity
|
||||
import { PluginInterface } from '@super-productivity/plugin-api';
|
||||
|
||||
declare const plugin: PluginInterface;
|
||||
|
||||
// Register a header button
|
||||
plugin.registerHeaderButton({
|
||||
icon: 'psychology',
|
||||
tooltip: 'Open Procrastination Buster',
|
||||
action: () => {
|
||||
plugin.showIndexHtmlAsView();
|
||||
},
|
||||
});
|
||||
|
||||
// Register a side panel button
|
||||
plugin.registerSidePanelButton({
|
||||
icon: 'psychology',
|
||||
tooltip: 'Procrastination Help',
|
||||
action: () => {
|
||||
plugin.showIndexHtmlAsView();
|
||||
},
|
||||
});
|
||||
|
||||
// Handle messages from the iframe
|
||||
plugin.onMessage(
|
||||
'ADD_STRATEGY_TASK',
|
||||
async (data: { strategy: string; blockerType: string }) => {
|
||||
const taskTitle = `Strategy: ${data.strategy}`;
|
||||
const taskNotes = `Strategy for ${data.blockerType}: ${data.strategy}`;
|
||||
|
||||
try {
|
||||
const newTask = await plugin.addTask({
|
||||
title: taskTitle,
|
||||
notes: taskNotes,
|
||||
});
|
||||
|
||||
plugin.showSnack({
|
||||
msg: 'Strategy task created!',
|
||||
type: 'SUCCESS',
|
||||
});
|
||||
|
||||
return { success: true, taskId: newTask.id };
|
||||
} catch (error) {
|
||||
console.error('Failed to create task:', error);
|
||||
plugin.showSnack({
|
||||
msg: 'Failed to create task',
|
||||
type: 'ERROR',
|
||||
});
|
||||
return { success: false, error: 'Failed to create task' };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
plugin.onMessage('START_POMODORO', async () => {
|
||||
plugin.showSnack({
|
||||
msg: 'Focus mode activated! Distractions minimized.',
|
||||
type: 'SUCCESS',
|
||||
});
|
||||
return { success: true };
|
||||
});
|
||||
|
||||
plugin.onMessage('START_FOCUS_MODE', async () => {
|
||||
plugin.showSnack({
|
||||
msg: 'Focus mode activated! Distractions minimized.',
|
||||
type: 'SUCCESS',
|
||||
});
|
||||
return { success: true };
|
||||
});
|
||||
|
||||
plugin.onMessage('QUICK_ADD_TASK', async () => {
|
||||
plugin.showSnack({
|
||||
msg: 'Use the add task button in the app to create a task.',
|
||||
type: 'INFO',
|
||||
});
|
||||
return { success: true };
|
||||
});
|
||||
|
||||
// Log when plugin loads
|
||||
plugin.log('Procrastination Buster plugin loaded successfully!');
|
||||
// import { PluginInterface } from '@super-productivity/plugin-api';
|
||||
// declare const plugin: PluginInterface;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ const plugins = [
|
|||
name: 'procrastination-buster',
|
||||
path: 'procrastination-buster',
|
||||
needsInstall: true,
|
||||
copyToAssets: true,
|
||||
buildCommand: async (pluginPath) => {
|
||||
await execAsync(`cd ${pluginPath} && npm run build && npm run package`);
|
||||
return 'Built and packaged';
|
||||
|
|
@ -36,6 +37,7 @@ const plugins = [
|
|||
{
|
||||
name: 'api-test-plugin',
|
||||
path: 'api-test-plugin',
|
||||
needsInstall: true,
|
||||
copyToAssets: true,
|
||||
buildCommand: async (pluginPath) => {
|
||||
// Copy to assets directory
|
||||
|
|
@ -54,36 +56,38 @@ const plugins = [
|
|||
return 'Copied to assets';
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'sync-md-plugin',
|
||||
path: 'sync-md-plugin',
|
||||
copyToAssets: true,
|
||||
buildCommand: async (pluginPath) => {
|
||||
// Copy to assets directory
|
||||
const targetDir = path.join(__dirname, '../../../src/assets/sync-md-plugin');
|
||||
if (!fs.existsSync(targetDir)) {
|
||||
fs.mkdirSync(targetDir, { recursive: true });
|
||||
}
|
||||
const files = [
|
||||
'manifest.json',
|
||||
'plugin.js',
|
||||
'index.html',
|
||||
'iframe-script.js',
|
||||
'sync-md-icon.svg',
|
||||
];
|
||||
for (const file of files) {
|
||||
const src = path.join(pluginPath, file);
|
||||
const dest = path.join(targetDir, file);
|
||||
if (fs.existsSync(src)) {
|
||||
fs.copyFileSync(src, dest);
|
||||
}
|
||||
}
|
||||
return 'Copied to assets';
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name: 'sync-md-plugin',
|
||||
// path: 'sync-md-plugin',
|
||||
// needsInstall: true,
|
||||
// copyToAssets: true,
|
||||
// buildCommand: async (pluginPath) => {
|
||||
// // Copy to assets directory
|
||||
// const targetDir = path.join(__dirname, '../../../src/assets/sync-md-plugin');
|
||||
// if (!fs.existsSync(targetDir)) {
|
||||
// fs.mkdirSync(targetDir, { recursive: true });
|
||||
// }
|
||||
// const files = [
|
||||
// 'manifest.json',
|
||||
// 'plugin.js',
|
||||
// 'index.html',
|
||||
// 'iframe-script.js',
|
||||
// 'sync-md-icon.svg',
|
||||
// ];
|
||||
// for (const file of files) {
|
||||
// const src = path.join(pluginPath, file);
|
||||
// const dest = path.join(targetDir, file);
|
||||
// if (fs.existsSync(src)) {
|
||||
// fs.copyFileSync(src, dest);
|
||||
// }
|
||||
// }
|
||||
// return 'Copied to assets';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
name: 'yesterday-tasks-plugin',
|
||||
path: 'yesterday-tasks-plugin',
|
||||
needsInstall: true,
|
||||
copyToAssets: true,
|
||||
buildCommand: async (pluginPath) => {
|
||||
// Copy to assets directory
|
||||
|
|
|
|||
12
packages/plugin-dev/yesterday-tasks-plugin/package-lock.json
generated
Normal file
12
packages/plugin-dev/yesterday-tasks-plugin/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "yesterday-tasks-plugin",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "yesterday-tasks-plugin",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue