From 8c65e0dac9d7dee64bfa359d227232be8302bf60 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Thu, 29 Jan 2026 21:16:54 -0600 Subject: [PATCH 1/3] feat(#25): implement mosaic-plugin-tasks skill --- packages/skills/tasks/SKILL.md | 261 +++++++++++++++ packages/skills/tasks/scripts/tasks.js | 429 +++++++++++++++++++++++++ 2 files changed, 690 insertions(+) create mode 100644 packages/skills/tasks/SKILL.md create mode 100755 packages/skills/tasks/scripts/tasks.js diff --git a/packages/skills/tasks/SKILL.md b/packages/skills/tasks/SKILL.md new file mode 100644 index 0000000..6a6c879 --- /dev/null +++ b/packages/skills/tasks/SKILL.md @@ -0,0 +1,261 @@ +--- +name: mosaic-plugin-tasks +description: Integration with Mosaic Stack's Tasks API for task management. Use when the user wants to create, list, update, complete, or delete tasks, including queries like "add task", "create task", "what's in progress", "high priority tasks", "mark task as done", "overdue tasks", "show my tasks", or "delete task". +--- + +# Mosaic Tasks + +Integration with Mosaic Stack's Tasks API for comprehensive task management and tracking. + +## Quick Start + +Use `scripts/tasks.js` for all task operations. The script handles authentication and API communication automatically. + +### Creating Tasks + +```bash +node scripts/tasks.js create \ + --title "Review PR #123" \ + --description "Review the authentication refactor" \ + --priority HIGH \ + --status NOT_STARTED \ + --due "2024-02-01T17:00:00Z" +``` + +Natural language examples: +- "Add task: review PR #123" +- "Create a high priority task to fix the login bug" +- "Add a task to update documentation, due Friday" +- "Create task 'deploy to staging' assigned to Sarah" + +### Listing Tasks + +```bash +# List all tasks +node scripts/tasks.js list + +# Filter by status +node scripts/tasks.js list --status IN_PROGRESS + +# Filter by priority +node scripts/tasks.js list --priority HIGH + +# Filter by project +node scripts/tasks.js list --project-id "uuid-here" + +# Combine filters +node scripts/tasks.js list --status IN_PROGRESS --priority HIGH + +# Query overdue tasks +node scripts/tasks.js list --overdue +``` + +Natural language examples: +- "What tasks are in progress?" +- "Show me high priority tasks" +- "What do I need to do today?" +- "List overdue tasks" +- "What tasks are assigned to me?" +- "Show completed tasks from last week" + +### Getting a Specific Task + +```bash +node scripts/tasks.js get TASK_ID +``` + +Natural language examples: +- "Show me task details for abc-123" +- "What's the status of the deployment task?" + +### Updating Tasks + +```bash +# Update status +node scripts/tasks.js update TASK_ID --status COMPLETED + +# Update priority +node scripts/tasks.js update TASK_ID --priority HIGH + +# Update multiple fields +node scripts/tasks.js update TASK_ID \ + --title "Updated Title" \ + --status IN_PROGRESS \ + --priority MEDIUM +``` + +Natural language examples: +- "Mark task abc-123 as done" +- "Set PR review task to in progress" +- "Change priority of deployment task to high" +- "Update the description of task xyz-456" +- "Move task to completed" + +### Deleting Tasks + +```bash +node scripts/tasks.js delete TASK_ID +``` + +Natural language examples: +- "Delete task abc-123" +- "Remove the duplicate deployment task" +- "Delete all completed tasks from last month" + +## Task Fields + +### Required Fields + +- **title** (string, 1-255 characters): Task title or summary + +### Optional Fields + +- **description** (string, max 10,000 characters): Detailed task description +- **status** (enum): Task status + - `NOT_STARTED` - Task not yet started (default) + - `IN_PROGRESS` - Task is being worked on + - `PAUSED` - Task temporarily paused + - `COMPLETED` - Task finished + - `ARCHIVED` - Task archived for historical reference +- **priority** (enum): Task priority level + - `LOW` - Low priority + - `MEDIUM` - Medium priority (default) + - `HIGH` - High priority +- **dueDate** (string): ISO 8601 date string when task is due +- **assigneeId** (UUID): User ID of assigned team member +- **projectId** (UUID): Project this task belongs to +- **parentId** (UUID): Parent task ID for subtasks +- **sortOrder** (integer, min 0): Custom sort order within project/list +- **metadata** (object): Custom key-value data for extensions + +## Date Handling + +When processing natural language date/time requests: + +1. Convert to ISO 8601 format (e.g., "2024-01-30T17:00:00Z") +2. Handle relative dates ("tomorrow", "next week", "Friday", "end of month") +3. Default to end of business day (17:00) if time not specified +4. Use user's timezone (America/Chicago) unless specified otherwise +5. For "today", use current date at 17:00 local time +6. For "overdue", query tasks where `dueDate < now()` + +## Querying Overdue Tasks + +Overdue tasks are those with a due date in the past that aren't completed or archived: + +```bash +node scripts/tasks.js list --overdue +``` + +This filters to: +- `dueDate < current_datetime` +- `status NOT IN (COMPLETED, ARCHIVED)` + +Natural language examples: +- "What tasks are overdue?" +- "Show me late tasks" +- "Which tasks missed their deadline?" + +## Response Format + +Single task operations return a task object: + +```json +{ + "id": "uuid", + "title": "Review PR #123", + "description": "Review the authentication refactor", + "status": "IN_PROGRESS", + "priority": "HIGH", + "dueDate": "2024-02-01T17:00:00Z", + "assigneeId": "uuid", + "projectId": "uuid", + "parentId": null, + "sortOrder": 0, + "metadata": {}, + "workspaceId": "uuid", + "createdBy": "uuid", + "createdAt": "2024-01-29T10:00:00Z", + "updatedAt": "2024-01-29T15:30:00Z" +} +``` + +List queries return paginated results: + +```json +{ + "data": [...], + "pagination": { + "page": 1, + "limit": 50, + "total": 100, + "totalPages": 2 + } +} +``` + +## Task Status Workflow + +Typical task lifecycle: + +1. **NOT_STARTED** → Initial state when created +2. **IN_PROGRESS** → Work begins on task +3. **PAUSED** → Temporarily blocked or on hold +4. **IN_PROGRESS** → Resume work +5. **COMPLETED** → Task finished +6. **ARCHIVED** → Move to historical archive + +Tasks can transition to any status at any time based on needs. + +## Environment + +The script reads configuration from: +- `MOSAIC_API_URL` (default: http://localhost:3001) +- `MOSAIC_WORKSPACE_ID` (required) +- `MOSAIC_API_TOKEN` (required for authentication) + +Ensure these are set in the environment or `.env` file. + +## Error Handling + +Common errors: +- **401 Unauthorized**: Missing or invalid API token +- **403 Forbidden**: Insufficient workspace permissions (tasks require MEMBER role to create/update, ADMIN to delete) +- **404 Not Found**: Task ID doesn't exist in this workspace +- **400 Bad Request**: Invalid status/priority value, missing required fields, or invalid UUID format + +When operations fail, the script outputs clear error messages with guidance on resolution. + +## Permission Requirements + +Task operations require different permission levels: + +- **List/Get**: Any workspace member (including GUEST) +- **Create/Update**: MEMBER role or higher +- **Delete**: ADMIN role or higher + +## Integration with Projects + +Tasks can be linked to projects via `projectId`. This enables: +- Filtering tasks by project +- Project-based task organization +- Tracking project progress through task completion +- Sorting tasks within project context using `sortOrder` + +When creating tasks for a project, include the `--project-id` flag. + +## Subtasks + +Tasks support hierarchical organization via `parentId`: + +```bash +# Create parent task +node scripts/tasks.js create --title "Deploy v2.0" + +# Create subtask +node scripts/tasks.js create \ + --title "Run tests" \ + --parent-id PARENT_TASK_ID +``` + +Subtasks inherit project context from parent but can have independent status, priority, and due dates. diff --git a/packages/skills/tasks/scripts/tasks.js b/packages/skills/tasks/scripts/tasks.js new file mode 100755 index 0000000..4863ff2 --- /dev/null +++ b/packages/skills/tasks/scripts/tasks.js @@ -0,0 +1,429 @@ +#!/usr/bin/env node + +/** + * Mosaic Tasks CLI + * + * Command-line interface for Mosaic Stack's Tasks API + * Supports create, list, get, update, and delete operations + */ + +const https = require('https'); +const http = require('http'); +const { URL } = require('url'); + +// Configuration from environment +const MOSAIC_API_URL = process.env.MOSAIC_API_URL || 'http://localhost:3001'; +const MOSAIC_WORKSPACE_ID = process.env.MOSAIC_WORKSPACE_ID; +const MOSAIC_API_TOKEN = process.env.MOSAIC_API_TOKEN; + +// Valid enum values +const TASK_STATUSES = ['NOT_STARTED', 'IN_PROGRESS', 'PAUSED', 'COMPLETED', 'ARCHIVED']; +const TASK_PRIORITIES = ['LOW', 'MEDIUM', 'HIGH']; + +/** + * Make HTTP request to Mosaic API + */ +function apiRequest(method, path, body = null) { + return new Promise((resolve, reject) => { + if (!MOSAIC_API_TOKEN) { + reject(new Error('MOSAIC_API_TOKEN environment variable is required')); + return; + } + if (!MOSAIC_WORKSPACE_ID) { + reject(new Error('MOSAIC_WORKSPACE_ID environment variable is required')); + return; + } + + const url = new URL(path, MOSAIC_API_URL); + const isHttps = url.protocol === 'https:'; + const client = isHttps ? https : http; + + const options = { + method, + hostname: url.hostname, + port: url.port || (isHttps ? 443 : 80), + path: url.pathname + url.search, + headers: { + 'Authorization': `Bearer ${MOSAIC_API_TOKEN}`, + 'X-Workspace-ID': MOSAIC_WORKSPACE_ID, + 'Content-Type': 'application/json', + }, + }; + + const req = client.request(options, (res) => { + let data = ''; + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + try { + const parsed = data ? JSON.parse(data) : null; + + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(parsed); + } else { + const error = new Error( + parsed?.message || `HTTP ${res.statusCode}: ${res.statusMessage}` + ); + error.statusCode = res.statusCode; + error.response = parsed; + reject(error); + } + } catch (err) { + reject(new Error(`Failed to parse response: ${err.message}`)); + } + }); + }); + + req.on('error', (err) => { + reject(new Error(`Request failed: ${err.message}`)); + }); + + if (body) { + req.write(JSON.stringify(body)); + } + + req.end(); + }); +} + +/** + * Parse command-line arguments + */ +function parseArgs(argv) { + const args = {}; + const positional = []; + + for (let i = 0; i < argv.length; i++) { + const arg = argv[i]; + + if (arg.startsWith('--')) { + const key = arg.slice(2); + const value = argv[i + 1]; + + if (value && !value.startsWith('--')) { + args[key] = value; + i++; // Skip next arg since we consumed it + } else { + args[key] = true; // Flag without value + } + } else { + positional.push(arg); + } + } + + return { args, positional }; +} + +/** + * Build query string from filters + */ +function buildQueryString(filters) { + const params = new URLSearchParams(); + + for (const [key, value] of Object.entries(filters)) { + if (value !== undefined && value !== null) { + params.append(key, value); + } + } + + const qs = params.toString(); + return qs ? `?${qs}` : ''; +} + +/** + * Create a new task + */ +async function createTask(args) { + const body = { + title: args.title, + }; + + if (args.description) body.description = args.description; + if (args.status) { + if (!TASK_STATUSES.includes(args.status)) { + throw new Error(`Invalid status. Must be one of: ${TASK_STATUSES.join(', ')}`); + } + body.status = args.status; + } + if (args.priority) { + if (!TASK_PRIORITIES.includes(args.priority)) { + throw new Error(`Invalid priority. Must be one of: ${TASK_PRIORITIES.join(', ')}`); + } + body.priority = args.priority; + } + if (args.due) body.dueDate = args.due; + if (args['assignee-id']) body.assigneeId = args['assignee-id']; + if (args['project-id']) body.projectId = args['project-id']; + if (args['parent-id']) body.parentId = args['parent-id']; + if (args['sort-order']) body.sortOrder = parseInt(args['sort-order'], 10); + + if (!body.title) { + throw new Error('--title is required'); + } + + const result = await apiRequest('POST', '/api/tasks', body); + console.log(JSON.stringify(result, null, 2)); + return result; +} + +/** + * List tasks with optional filters + */ +async function listTasks(args) { + const filters = {}; + + if (args.status) { + if (!TASK_STATUSES.includes(args.status)) { + throw new Error(`Invalid status. Must be one of: ${TASK_STATUSES.join(', ')}`); + } + filters.status = args.status; + } + if (args.priority) { + if (!TASK_PRIORITIES.includes(args.priority)) { + throw new Error(`Invalid priority. Must be one of: ${TASK_PRIORITIES.join(', ')}`); + } + filters.priority = args.priority; + } + if (args['assignee-id']) filters.assigneeId = args['assignee-id']; + if (args['project-id']) filters.projectId = args['project-id']; + if (args['parent-id']) filters.parentId = args['parent-id']; + if (args.page) filters.page = args.page; + if (args.limit) filters.limit = args.limit; + + // Handle overdue filter + if (args.overdue) { + filters.dueDateTo = new Date().toISOString(); + // Exclude completed and archived + if (!filters.status) { + console.error('Note: Overdue filter shows tasks with due date < now, excluding COMPLETED and ARCHIVED'); + } + } + + if (args['due-from']) filters.dueDateFrom = args['due-from']; + if (args['due-to']) filters.dueDateTo = args['due-to']; + + const query = buildQueryString(filters); + const result = await apiRequest('GET', `/api/tasks${query}`); + + // Filter out completed/archived for overdue query + if (args.overdue && result.data) { + result.data = result.data.filter( + task => task.status !== 'COMPLETED' && task.status !== 'ARCHIVED' + ); + if (result.pagination) { + result.pagination.total = result.data.length; + } + } + + console.log(JSON.stringify(result, null, 2)); + return result; +} + +/** + * Get a single task by ID + */ +async function getTask(taskId) { + if (!taskId) { + throw new Error('Task ID is required'); + } + + const result = await apiRequest('GET', `/api/tasks/${taskId}`); + console.log(JSON.stringify(result, null, 2)); + return result; +} + +/** + * Update a task + */ +async function updateTask(taskId, args) { + if (!taskId) { + throw new Error('Task ID is required'); + } + + const body = {}; + + if (args.title) body.title = args.title; + if (args.description !== undefined) body.description = args.description; + if (args.status) { + if (!TASK_STATUSES.includes(args.status)) { + throw new Error(`Invalid status. Must be one of: ${TASK_STATUSES.join(', ')}`); + } + body.status = args.status; + } + if (args.priority) { + if (!TASK_PRIORITIES.includes(args.priority)) { + throw new Error(`Invalid priority. Must be one of: ${TASK_PRIORITIES.join(', ')}`); + } + body.priority = args.priority; + } + if (args.due !== undefined) body.dueDate = args.due || null; + if (args['assignee-id'] !== undefined) body.assigneeId = args['assignee-id'] || null; + if (args['project-id'] !== undefined) body.projectId = args['project-id'] || null; + if (args['parent-id'] !== undefined) body.parentId = args['parent-id'] || null; + if (args['sort-order']) body.sortOrder = parseInt(args['sort-order'], 10); + + if (Object.keys(body).length === 0) { + throw new Error('At least one field to update is required'); + } + + const result = await apiRequest('PATCH', `/api/tasks/${taskId}`, body); + console.log(JSON.stringify(result, null, 2)); + return result; +} + +/** + * Delete a task + */ +async function deleteTask(taskId) { + if (!taskId) { + throw new Error('Task ID is required'); + } + + const result = await apiRequest('DELETE', `/api/tasks/${taskId}`); + console.log(JSON.stringify(result || { success: true }, null, 2)); + return result; +} + +/** + * Show usage help + */ +function showHelp() { + console.log(` +Mosaic Tasks CLI + +Usage: + node tasks.js [options] + +Commands: + create Create a new task + list List tasks with optional filters + get Get a specific task by ID + update Update a task + delete Delete a task + help Show this help message + +Create Options: + --title Task title (required) + --description Task description + --status Status: ${TASK_STATUSES.join(', ')} + --priority Priority: ${TASK_PRIORITIES.join(', ')} + --due Due date (ISO 8601 format) + --assignee-id Assign to user ID + --project-id Link to project ID + --parent-id Parent task ID (for subtasks) + --sort-order Sort order (integer) + +List Options: + --status Filter by status + --priority Filter by priority + --assignee-id Filter by assignee + --project-id Filter by project + --parent-id Filter by parent task + --due-from Filter tasks due after this date + --due-to Filter tasks due before this date + --overdue Show only overdue tasks + --page Page number (default: 1) + --limit Results per page (default: 50, max: 100) + +Update Options: + --title Update title + --description Update description + --status Update status + --priority Update priority + --due Update due date (empty string to clear) + --assignee-id Update assignee (empty string to clear) + --project-id Update project (empty string to clear) + --parent-id Update parent (empty string to clear) + --sort-order Update sort order + +Environment Variables: + MOSAIC_API_URL API base URL (default: http://localhost:3001) + MOSAIC_WORKSPACE_ID Workspace ID (required) + MOSAIC_API_TOKEN Authentication token (required) + +Examples: + # Create a task + node tasks.js create --title "Review PR #123" --priority HIGH + + # List high priority tasks + node tasks.js list --priority HIGH + + # List overdue tasks + node tasks.js list --overdue + + # Get task details + node tasks.js get abc-123-def-456 + + # Mark task as completed + node tasks.js update abc-123-def-456 --status COMPLETED + + # Delete a task + node tasks.js delete abc-123-def-456 +`); +} + +/** + * Main entry point + */ +async function main() { + const { args, positional } = parseArgs(process.argv.slice(2)); + const command = positional[0]; + + try { + switch (command) { + case 'create': + await createTask(args); + break; + + case 'list': + await listTasks(args); + break; + + case 'get': + await getTask(positional[1]); + break; + + case 'update': + await updateTask(positional[1], args); + break; + + case 'delete': + await deleteTask(positional[1]); + break; + + case 'help': + case undefined: + showHelp(); + break; + + default: + console.error(`Unknown command: ${command}`); + console.error('Run "node tasks.js help" for usage information'); + process.exit(1); + } + } catch (error) { + console.error('Error:', error.message); + + if (error.statusCode === 401) { + console.error('\nAuthentication failed. Check your MOSAIC_API_TOKEN.'); + } else if (error.statusCode === 403) { + console.error('\nPermission denied. You may need higher workspace permissions.'); + } else if (error.statusCode === 404) { + console.error('\nTask not found. Check the task ID.'); + } else if (error.response) { + console.error('\nAPI Response:', JSON.stringify(error.response, null, 2)); + } + + process.exit(1); + } +} + +// Run if executed directly +if (require.main === module) { + main(); +} + +module.exports = { createTask, listTasks, getTask, updateTask, deleteTask }; From ce01b4c081d01a9ac21966a5cc3200940a8f6487 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Thu, 29 Jan 2026 21:19:52 -0600 Subject: [PATCH 2/3] fix(#25): rename tasks.js to tasks.cjs for CommonJS compatibility --- packages/skills/tasks/SKILL.md | 32 +++++++++---------- .../tasks/scripts/{tasks.js => tasks.cjs} | 16 +++++----- 2 files changed, 24 insertions(+), 24 deletions(-) rename packages/skills/tasks/scripts/{tasks.js => tasks.cjs} (96%) diff --git a/packages/skills/tasks/SKILL.md b/packages/skills/tasks/SKILL.md index 6a6c879..030980c 100644 --- a/packages/skills/tasks/SKILL.md +++ b/packages/skills/tasks/SKILL.md @@ -9,12 +9,12 @@ Integration with Mosaic Stack's Tasks API for comprehensive task management and ## Quick Start -Use `scripts/tasks.js` for all task operations. The script handles authentication and API communication automatically. +Use `scripts/tasks.cjs` for all task operations. The script handles authentication and API communication automatically. ### Creating Tasks ```bash -node scripts/tasks.js create \ +node scripts/tasks.cjs create \ --title "Review PR #123" \ --description "Review the authentication refactor" \ --priority HIGH \ @@ -32,22 +32,22 @@ Natural language examples: ```bash # List all tasks -node scripts/tasks.js list +node scripts/tasks.cjs list # Filter by status -node scripts/tasks.js list --status IN_PROGRESS +node scripts/tasks.cjs list --status IN_PROGRESS # Filter by priority -node scripts/tasks.js list --priority HIGH +node scripts/tasks.cjs list --priority HIGH # Filter by project -node scripts/tasks.js list --project-id "uuid-here" +node scripts/tasks.cjs list --project-id "uuid-here" # Combine filters -node scripts/tasks.js list --status IN_PROGRESS --priority HIGH +node scripts/tasks.cjs list --status IN_PROGRESS --priority HIGH # Query overdue tasks -node scripts/tasks.js list --overdue +node scripts/tasks.cjs list --overdue ``` Natural language examples: @@ -61,7 +61,7 @@ Natural language examples: ### Getting a Specific Task ```bash -node scripts/tasks.js get TASK_ID +node scripts/tasks.cjs get TASK_ID ``` Natural language examples: @@ -72,13 +72,13 @@ Natural language examples: ```bash # Update status -node scripts/tasks.js update TASK_ID --status COMPLETED +node scripts/tasks.cjs update TASK_ID --status COMPLETED # Update priority -node scripts/tasks.js update TASK_ID --priority HIGH +node scripts/tasks.cjs update TASK_ID --priority HIGH # Update multiple fields -node scripts/tasks.js update TASK_ID \ +node scripts/tasks.cjs update TASK_ID \ --title "Updated Title" \ --status IN_PROGRESS \ --priority MEDIUM @@ -94,7 +94,7 @@ Natural language examples: ### Deleting Tasks ```bash -node scripts/tasks.js delete TASK_ID +node scripts/tasks.cjs delete TASK_ID ``` Natural language examples: @@ -144,7 +144,7 @@ When processing natural language date/time requests: Overdue tasks are those with a due date in the past that aren't completed or archived: ```bash -node scripts/tasks.js list --overdue +node scripts/tasks.cjs list --overdue ``` This filters to: @@ -250,10 +250,10 @@ Tasks support hierarchical organization via `parentId`: ```bash # Create parent task -node scripts/tasks.js create --title "Deploy v2.0" +node scripts/tasks.cjs create --title "Deploy v2.0" # Create subtask -node scripts/tasks.js create \ +node scripts/tasks.cjs create \ --title "Run tests" \ --parent-id PARENT_TASK_ID ``` diff --git a/packages/skills/tasks/scripts/tasks.js b/packages/skills/tasks/scripts/tasks.cjs similarity index 96% rename from packages/skills/tasks/scripts/tasks.js rename to packages/skills/tasks/scripts/tasks.cjs index 4863ff2..a2a518d 100755 --- a/packages/skills/tasks/scripts/tasks.js +++ b/packages/skills/tasks/scripts/tasks.cjs @@ -295,7 +295,7 @@ function showHelp() { Mosaic Tasks CLI Usage: - node tasks.js [options] + node tasks.cjs [options] Commands: create Create a new task @@ -346,22 +346,22 @@ Environment Variables: Examples: # Create a task - node tasks.js create --title "Review PR #123" --priority HIGH + node tasks.cjs create --title "Review PR #123" --priority HIGH # List high priority tasks - node tasks.js list --priority HIGH + node tasks.cjs list --priority HIGH # List overdue tasks - node tasks.js list --overdue + node tasks.cjs list --overdue # Get task details - node tasks.js get abc-123-def-456 + node tasks.cjs get abc-123-def-456 # Mark task as completed - node tasks.js update abc-123-def-456 --status COMPLETED + node tasks.cjs update abc-123-def-456 --status COMPLETED # Delete a task - node tasks.js delete abc-123-def-456 + node tasks.cjs delete abc-123-def-456 `); } @@ -401,7 +401,7 @@ async function main() { default: console.error(`Unknown command: ${command}`); - console.error('Run "node tasks.js help" for usage information'); + console.error('Run "node tasks.cjs help" for usage information'); process.exit(1); } } catch (error) { From e82974cca3c2f8bf3abba81aba5451479398434d Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Thu, 29 Jan 2026 21:23:09 -0600 Subject: [PATCH 3/3] fix: address code review feedback - add metadata to SKILL.md frontmatter --- packages/skills/tasks/SKILL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/skills/tasks/SKILL.md b/packages/skills/tasks/SKILL.md index 030980c..741fa12 100644 --- a/packages/skills/tasks/SKILL.md +++ b/packages/skills/tasks/SKILL.md @@ -1,6 +1,8 @@ --- name: mosaic-plugin-tasks description: Integration with Mosaic Stack's Tasks API for task management. Use when the user wants to create, list, update, complete, or delete tasks, including queries like "add task", "create task", "what's in progress", "high priority tasks", "mark task as done", "overdue tasks", "show my tasks", or "delete task". +homepage: https://git.mosaicstack.dev/mosaic/stack +metadata: {"clawdbot":{"emoji":"✅","requires":{"bins":["node"],"env":["MOSAIC_API_TOKEN","MOSAIC_WORKSPACE_ID"]},"primaryEnv":"MOSAIC_API_TOKEN"}} --- # Mosaic Tasks