const fs = require('fs'); const path = require('path'); // 1. Get arguments const args = process.argv.slice(2); if (args.length < 2) { console.error("Usage: node sync_vikunja.js "); process.exit(1); } const taskId = args[0]; const message = args[1]; // 2. Load configuration from .env.agent const envPath = path.join(__dirname, '../config/.env.agent'); if (!fs.existsSync(envPath)) { console.error("Error: .agent/config/.env.agent file not found. Please create it from the template."); process.exit(1); } const envContent = fs.readFileSync(envPath, 'utf8'); const env = {}; envContent.split('\n').forEach(line => { const match = line.match(/^([^#=]+)="?(.*?)"?$/); if (match) { env[match[1].trim()] = match[2].trim(); } }); const apiUrl = env.VIKUNJA_API_URL; const apiToken = env.VIKUNJA_API_TOKEN; if (!apiUrl || !apiToken || apiUrl.includes('[YOUR_')) { console.error("Error: VIKUNJA_API_URL or VIKUNJA_API_TOKEN is not configured correctly in .env.agent."); process.exit(1); } if (env.AGENT_OPERATING_MODE === "TEST") { console.log("⚠️ TEST Mode Active: Skipping Vikunja Webhook connection."); process.exit(0); } // 3. Helper to make API calls using native fetch (Node 18+) async function markTaskDoneAndComment(taskId, message) { try { console.log(`Connecting to Vikunja API for Task ${taskId}...`); // Update task status to done const patchRes = await fetch(`${apiUrl}/tasks/${taskId}`, { method: 'POST', // Vikunja uses POST to task endpoint for updates headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ done: true }) }); if (!patchRes.ok) { throw new Error(`Failed to mark task as done: ${patchRes.statusText}`); } console.log(`✅ Task ${taskId} successfully marked as Done.`); // Add comment const commentRes = await fetch(`${apiUrl}/tasks/${taskId}/comments`, { method: 'PUT', headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ text: `[Agent Automator] Phase completed.\nReason/Hash: ${message}` }) }); if (!commentRes.ok) { console.error(`Warning: Task marked as done, but failed to attach comment: ${commentRes.statusText}`); } else { console.log("✅ Comment attached successfully."); } } catch (error) { console.error("❌ Failed to sync with Vikunja:"); // Mask the token if it somehow leaks via error message const secureErr = error.message.replace(new RegExp(apiToken, 'g'), "********"); console.error(secureErr); process.exit(1); } } markTaskDoneAndComment(taskId, message);