// Zoho Tasks Plugin v2.2.0 // EU data center: accounts.zoho.eu // Action-based tool surface, mirroring the ShadowMan C++ builtin style // (see manage_mcp, kb, skill, office etc. — one tool per resource, with // an `action` enum that picks a sub-operation). var auth = require('./lib/auth'); var tasks = require('./lib/tasks'); shadowman.log.info('Zoho Tasks plugin v2.2.0 loaded'); function requireAuth() { var token = auth.getValidToken(); if (!token) return { token: null, error: 'Not authenticated. Run zoho_auth action=setup with a grant token first.' }; return { token: token }; } function missing(field) { return { error: 'Missing ' + field + ' parameter' }; } // ──────────────────────────────────────────────────────────────────────── // zoho_auth — actions: setup, status, resolve_portal // ──────────────────────────────────────────────────────────────────────── shadowman.tools.register('zoho_auth', function(args, context) { var action = args.action; if (!action) return missing('action'); if (action === 'setup') { if (!args.grant_token) return missing('grant_token'); shadowman.storage.set('auth_conversation_id', context.conversationId); return auth.setupAuth(args.grant_token); } if (action === 'status') { return auth.getStatus(); } if (action === 'resolve_portal') { var a = requireAuth(); if (a.error) return { error: a.error }; return auth.resolvePortal(a.token, args); } return { error: 'Unknown action: ' + action }; }); // ──────────────────────────────────────────────────────────────────────── // zoho_project — actions: list, get, users, statuses // ──────────────────────────────────────────────────────────────────────── shadowman.tools.register('zoho_project', function(args) { var a = requireAuth(); if (a.error) return { error: a.error }; var action = args.action; if (!action) return missing('action'); if (action === 'list') { return tasks.listProjects(a.token, args.index || 1); } if (action === 'get') { if (!args.project_id) return missing('project_id'); return tasks.getProject(a.token, args.project_id); } if (action === 'users') { return tasks.listUsers(a.token, args); } if (action === 'statuses') { if (!args.project_id) return missing('project_id'); return tasks.listTaskStatuses(a.token, args.project_id); } return { error: 'Unknown action: ' + action }; }); // ──────────────────────────────────────────────────────────────────────── // zoho_task — actions: list, get, create, update, delete, subtasks, my, search // ──────────────────────────────────────────────────────────────────────── shadowman.tools.register('zoho_task', function(args) { var a = requireAuth(); if (a.error) return { error: a.error }; var action = args.action; if (!action) return missing('action'); if (action === 'my') { return tasks.getMyTasks(a.token, args); } if (action === 'search') { if (!args.query) return missing('query'); return tasks.searchTasks(a.token, args); } if (!args.project_id) return missing('project_id'); if (action === 'list') { return tasks.listTasks(a.token, args.project_id, args); } if (action === 'get') { if (!args.task_id) return missing('task_id'); return tasks.getTask(a.token, args.project_id, args.task_id); } if (action === 'create') { if (!args.name) return missing('name'); return tasks.createTask(a.token, args.project_id, args); } if (action === 'update') { if (!args.task_id) return missing('task_id'); return tasks.updateTask(a.token, args.project_id, args.task_id, args); } if (action === 'delete') { if (!args.task_id) return missing('task_id'); return tasks.deleteTask(a.token, args.project_id, args.task_id); } if (action === 'subtasks') { if (!args.task_id) return missing('task_id'); return tasks.listSubtasks(a.token, args.project_id, args.task_id); } return { error: 'Unknown action: ' + action }; }); // ──────────────────────────────────────────────────────────────────────── // zoho_comment — actions: list, add, update, delete // ──────────────────────────────────────────────────────────────────────── shadowman.tools.register('zoho_comment', function(args) { var a = requireAuth(); if (a.error) return { error: a.error }; var action = args.action; if (!action) return missing('action'); if (!args.project_id) return missing('project_id'); if (!args.task_id) return missing('task_id'); if (action === 'list') { return tasks.listComments(a.token, args.project_id, args.task_id, args.index); } if (action === 'add') { if (!args.content) return missing('content'); return tasks.addComment(a.token, args.project_id, args.task_id, args.content); } if (action === 'update') { if (!args.comment_id) return missing('comment_id'); if (!args.content) return missing('content'); return tasks.updateComment(a.token, args.project_id, args.task_id, args.comment_id, args.content); } if (action === 'delete') { if (!args.comment_id) return missing('comment_id'); return tasks.deleteComment(a.token, args.project_id, args.task_id, args.comment_id); } return { error: 'Unknown action: ' + action }; }); // ──────────────────────────────────────────────────────────────────────── // zoho_milestone — actions: list, create, update, delete // ──────────────────────────────────────────────────────────────────────── shadowman.tools.register('zoho_milestone', function(args) { var a = requireAuth(); if (a.error) return { error: a.error }; var action = args.action; if (!action) return missing('action'); if (!args.project_id) return missing('project_id'); if (action === 'list') { return tasks.listMilestones(a.token, args.project_id, args); } if (action === 'create') { if (!args.name) return missing('name'); return tasks.createMilestone(a.token, args.project_id, args); } if (action === 'update') { if (!args.milestone_id) return missing('milestone_id'); return tasks.updateMilestone(a.token, args.project_id, args.milestone_id, args); } if (action === 'delete') { if (!args.milestone_id) return missing('milestone_id'); return tasks.deleteMilestone(a.token, args.project_id, args.milestone_id); } return { error: 'Unknown action: ' + action }; }); // ──────────────────────────────────────────────────────────────────────── // zoho_tasklist — actions: list, get, create, update, delete // ──────────────────────────────────────────────────────────────────────── shadowman.tools.register('zoho_tasklist', function(args) { var a = requireAuth(); if (a.error) return { error: a.error }; var action = args.action; if (!action) return missing('action'); if (action === 'list') { return tasks.listTasklists(a.token, args.project_id, args); } if (!args.project_id) return missing('project_id'); if (action === 'get') { if (!args.tasklist_id) return missing('tasklist_id'); return tasks.getTasklist(a.token, args.project_id, args.tasklist_id); } if (action === 'create') { if (!args.name) return missing('name'); return tasks.createTasklist(a.token, args.project_id, args); } if (action === 'update') { if (!args.tasklist_id) return missing('tasklist_id'); return tasks.updateTasklist(a.token, args.project_id, args.tasklist_id, args); } if (action === 'delete') { if (!args.tasklist_id) return missing('tasklist_id'); return tasks.deleteTasklist(a.token, args.project_id, args.tasklist_id); } return { error: 'Unknown action: ' + action }; }); // ──────────────────────────────────────────────────────────────────────── // zoho_timesheet — actions: list, create, update, delete // ──────────────────────────────────────────────────────────────────────── shadowman.tools.register('zoho_timesheet', function(args) { var a = requireAuth(); if (a.error) return { error: a.error }; var action = args.action; if (!action) return missing('action'); if (!args.project_id) return missing('project_id'); if (action === 'list') { return tasks.listTimesheets(a.token, args.project_id, args); } if (action === 'create') { if (!args.task_id) return missing('task_id'); if (args.hours === undefined) return missing('hours'); return tasks.logTime(a.token, args.project_id, args); } if (action === 'update') { if (!args.log_id) return missing('log_id'); return tasks.updateTimesheet(a.token, args.project_id, args.log_id, args); } if (action === 'delete') { if (!args.log_id) return missing('log_id'); return tasks.deleteTimesheet(a.token, args.project_id, args.log_id); } return { error: 'Unknown action: ' + action }; });