simple-task-master
Version:
A simple command-line task management tool
161 lines • 5.97 kB
JavaScript
;
/**
* Add task command
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.addCommand = void 0;
const commander_1 = require("commander");
const task_manager_1 = require("../lib/task-manager");
const output_1 = require("../lib/output");
const errors_1 = require("../lib/errors");
const utils_1 = require("../lib/utils");
const markdown_sections_1 = require("../lib/markdown-sections");
/**
* Parse tags from a comma-separated string
*/
function parseTags(tagsStr) {
if (!tagsStr.trim()) {
return [];
}
return tagsStr
.split(',')
.map((tag) => tag.trim())
.filter((tag) => tag.length > 0);
}
/**
* Parse dependencies from a comma-separated string
*/
function parseDependencies(depsStr) {
if (!depsStr.trim()) {
return [];
}
return depsStr.split(',').map((dep) => {
const id = parseInt(dep.trim(), 10);
if (isNaN(id) || id <= 0) {
throw new errors_1.ValidationError(`Invalid dependency ID: ${dep.trim()}`);
}
return id;
});
}
/**
* Add a new task
*/
async function addTask(title, options) {
try {
const taskManager = await task_manager_1.TaskManager.create();
// Parse options
const tags = options.tags ? parseTags(options.tags) : [];
const dependencies = options.deps ? parseDependencies(options.deps) : [];
// Validate status if provided
const status = options.status || 'pending';
if (!['pending', 'in-progress', 'done'].includes(status)) {
throw new errors_1.ValidationError(`Invalid status: ${status}. Status must be one of: pending, in-progress, done`);
}
// Process description, details, and validation sections with stdin support
let content = '';
let hasAnySections = false;
// Process description
let description = '';
if (options.description !== undefined) {
try {
const descContent = await (0, utils_1.readInput)(options.description, false, '', 30000);
description = descContent || '';
hasAnySections = true;
}
catch (error) {
if (error instanceof Error) {
throw new errors_1.ValidationError(`Failed to read description input: ${error.message}`);
}
throw new errors_1.ValidationError('Failed to read description input');
}
}
// Process details
let details;
if (options.details !== undefined) {
try {
const detailsContent = await (0, utils_1.readInput)(options.details, false, '', 30000);
details = detailsContent || undefined;
hasAnySections = true;
}
catch (error) {
if (error instanceof Error) {
throw new errors_1.ValidationError(`Failed to read details input: ${error.message}`);
}
throw new errors_1.ValidationError('Failed to read details input');
}
}
// Process validation
let validation;
if (options.validation !== undefined) {
try {
const validationContent = await (0, utils_1.readInput)(options.validation, false, '', 30000);
validation = validationContent || undefined;
hasAnySections = true;
}
catch (error) {
if (error instanceof Error) {
throw new errors_1.ValidationError(`Failed to read validation input: ${error.message}`);
}
throw new errors_1.ValidationError('Failed to read validation input');
}
}
// Build the content from sections
if (hasAnySections) {
content = (0, markdown_sections_1.buildMarkdownContent)({
description,
details,
validation
});
}
// Create task input
const taskInput = {
title,
content,
status: status,
tags,
dependencies
};
// Create the task (TaskManager handles locking internally)
const task = await taskManager.create(taskInput);
// Output the task ID
(0, output_1.printOutput)(task.id.toString());
}
catch (error) {
if (error instanceof errors_1.ValidationError ||
error instanceof errors_1.FileSystemError ||
error instanceof errors_1.ConfigurationError ||
error instanceof Error) {
(0, output_1.printError)(error.message);
process.exit(1);
}
throw error;
}
}
/**
* Create the add command
*/
exports.addCommand = new commander_1.Command('add')
.description('Add a new task')
.argument('<title>', 'Task title')
.option('-d, --description <desc>', 'Why & what: problem context, solution overview, and acceptance criteria (use - for stdin)')
.option('--details <text>', 'How: implementation approach, technical design, and architecture notes (use - for stdin)')
.option('--validation <text>', 'Validation: testing strategy, verification steps, and quality checks (use - for stdin)')
.option('-t, --tags <tags>', 'Comma-separated list of tags')
.option('--deps <dependencies>', 'Comma-separated list of dependency task IDs')
.option('-s, --status <status>', 'Task status (pending, in-progress, done)', 'pending')
.action(async (title, options) => {
try {
await addTask(title, options);
}
catch (error) {
// Ensure all errors result in non-zero exit
if (error instanceof Error) {
(0, output_1.printError)(error.message);
}
else {
(0, output_1.printError)(String(error));
}
process.exit(1);
}
});
//# sourceMappingURL=add.js.map