feat: update task remote (#1345)

This commit is contained in:
Ralph Khreish
2025-10-25 19:25:17 +02:00
committed by GitHub
parent 03b7ef9a0e
commit 486ed40215
31 changed files with 1463 additions and 159 deletions

View File

@@ -1,5 +1,4 @@
import fs from 'fs';
import path from 'path';
import chalk from 'chalk';
import boxen from 'boxen';
import Table from 'cli-table3';
@@ -34,11 +33,12 @@ import {
import { getPromptManager } from '../prompt-manager.js';
import { ContextGatherer } from '../utils/contextGatherer.js';
import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';
import { tryUpdateViaRemote } from '@tm/bridge';
/**
* Update a task by ID with new information using the unified AI service.
* @param {string} tasksPath - Path to the tasks.json file
* @param {number} taskId - ID of the task to update
* @param {string|number} taskId - ID of the task to update (supports numeric, alphanumeric like HAM-123, and subtask IDs like 1.2)
* @param {string} prompt - Prompt for generating updated task information
* @param {boolean} [useResearch=false] - Whether to use the research AI role.
* @param {Object} context - Context object containing session and mcpLog.
@@ -76,13 +76,21 @@ async function updateTaskById(
try {
report('info', `Updating single task ${taskId} with prompt: "${prompt}"`);
// --- Input Validations (Keep existing) ---
if (!Number.isInteger(taskId) || taskId <= 0)
throw new Error(
`Invalid task ID: ${taskId}. Task ID must be a positive integer.`
);
// --- Input Validations ---
// Note: taskId can be a number (1), string with dot (1.2), or display ID (HAM-123)
// So we don't validate it as strictly anymore
if (taskId === null || taskId === undefined || String(taskId).trim() === '')
throw new Error('Task ID cannot be empty.');
if (!prompt || typeof prompt !== 'string' || prompt.trim() === '')
throw new Error('Prompt cannot be empty.');
// Determine project root first (needed for API key checks)
const projectRoot = providedProjectRoot || findProjectRoot();
if (!projectRoot) {
throw new Error('Could not determine project root directory');
}
if (useResearch && !isApiKeySet('perplexity', session)) {
report(
'warn',
@@ -94,22 +102,48 @@ async function updateTaskById(
);
useResearch = false;
}
// --- BRIDGE: Try remote update first (API storage) ---
const remoteResult = await tryUpdateViaRemote({
taskId,
prompt,
projectRoot,
tag,
appendMode,
useResearch,
isMCP,
outputFormat,
report
});
// If remote handled it, return the result
if (remoteResult) {
return remoteResult;
}
// Otherwise fall through to file-based logic below
// --- End BRIDGE ---
// For file storage, ensure the tasks file exists
if (!fs.existsSync(tasksPath))
throw new Error(`Tasks file not found: ${tasksPath}`);
// --- End Input Validations ---
// Determine project root
const projectRoot = providedProjectRoot || findProjectRoot();
if (!projectRoot) {
throw new Error('Could not determine project root directory');
}
// --- Task Loading and Status Check (Keep existing) ---
const data = readJSON(tasksPath, projectRoot, tag);
if (!data || !data.tasks)
throw new Error(`No valid tasks found in ${tasksPath}.`);
const taskIndex = data.tasks.findIndex((task) => task.id === taskId);
if (taskIndex === -1) throw new Error(`Task with ID ${taskId} not found.`);
// File storage requires a strict numeric task ID
const idStr = String(taskId).trim();
if (!/^\d+$/.test(idStr)) {
throw new Error(
'For file storage, taskId must be a positive integer. ' +
'Use update-subtask-by-id for IDs like "1.2", or run in API storage for display IDs (e.g., "HAM-123").'
);
}
const numericTaskId = Number(idStr);
const taskIndex = data.tasks.findIndex((task) => task.id === numericTaskId);
if (taskIndex === -1)
throw new Error(`Task with ID ${numericTaskId} not found.`);
const taskToUpdate = data.tasks[taskIndex];
if (taskToUpdate.status === 'done' || taskToUpdate.status === 'completed') {
report(