simple-task-master
Version:
A simple command-line task management tool
277 lines (265 loc) • 11.9 kB
JavaScript
;
/**
* Config command for managing Simple Task Master configuration
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.configCommand = void 0;
const commander_1 = require("commander");
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const config_1 = require("../lib/config");
const lock_manager_1 = require("../lib/lock-manager");
const workspace_1 = require("../lib/workspace");
const output_1 = require("../lib/output");
const errors_1 = require("../lib/errors");
/**
* Parse and validate configuration values from string input
*/
function parseValue(key, value) {
if (key === 'lockTimeoutMs' || key === 'maxTaskSizeBytes') {
const num = parseInt(value, 10);
if (isNaN(num)) {
throw new errors_1.ValidationError(`${key} must be a number`);
}
return num;
}
// tasksDir remains as string
return value;
}
/**
* Handle command errors with appropriate exit codes
*/
function handleCommandError(error) {
if (error instanceof errors_1.ValidationError) {
(0, output_1.printError)(error.message);
process.exit(2); // Invalid input
}
if (error instanceof errors_1.NotFoundError) {
(0, output_1.printError)(error.message);
process.exit(3); // Resource not found
}
if (error instanceof errors_1.FileSystemError) {
(0, output_1.printError)(error.message);
process.exit(1); // File system error
}
if (error instanceof errors_1.ConfigurationError) {
(0, output_1.printError)(error.message);
process.exit(1); // Configuration error
}
// Unknown error
const message = error instanceof Error ? error.message : String(error);
(0, output_1.printError)(`Unexpected error: ${message}`);
process.exit(1);
}
async function configAction(options) {
try {
const workspaceRoot = await (0, workspace_1.getWorkspaceRoot)();
const configManager = new config_1.ConfigManager(workspaceRoot);
const lockManager = new lock_manager_1.LockManager(workspaceRoot);
// Handle --get
if (options.get) {
const config = await configManager.load();
const value = config[options.get];
if (value === undefined) {
throw new errors_1.ValidationError(`Unknown configuration key: ${options.get}`);
}
(0, output_1.printOutput)(String(value));
return;
}
// Handle --list
if (options.list) {
const config = await configManager.load();
(0, output_1.printOutput)(JSON.stringify(config, null, 2));
return;
}
// Handle --set (requires lock)
if (options.set) {
await lockManager.acquire();
try {
const [key, ...valueParts] = options.set.split('=');
const value = valueParts.join('='); // Rejoin in case value contains '='
if (!key || value === '') {
throw new errors_1.ValidationError('Invalid format. Use: --set key=value');
}
// Validate the key is a known configuration option
const validKeys = ['tasksDir', 'lockTimeoutMs', 'maxTaskSizeBytes'];
if (!validKeys.includes(key)) {
throw new errors_1.ValidationError(`Unknown configuration key: ${key}. Valid keys: ${validKeys.join(', ')}`);
}
// Check if we're changing tasksDir with existing tasks
if (key === 'tasksDir') {
const currentTasksDir = configManager.getTasksDir();
const newTasksDir = path.isAbsolute(value)
? value
: path.join(workspaceRoot, value);
if (currentTasksDir !== newTasksDir) {
try {
const files = await fs.readdir(currentTasksDir);
const taskFiles = files.filter((f) => f.endsWith('.md'));
if (taskFiles.length > 0) {
(0, output_1.printWarning)(`Current tasks directory contains ${taskFiles.length} task(s). ` +
'Tasks will NOT be automatically migrated to the new location.');
}
}
catch {
// Current tasks dir doesn't exist, no warning needed
}
}
}
const updates = { [key]: parseValue(key, value) };
await configManager.update(updates);
(0, output_1.printSuccess)('Configuration updated successfully');
}
finally {
await lockManager.release();
}
return;
}
// Handle --reset (requires lock)
if (options.reset) {
await lockManager.acquire();
try {
const key = options.reset;
const validKeys = ['tasksDir', 'lockTimeoutMs', 'maxTaskSizeBytes'];
if (!validKeys.includes(key)) {
throw new errors_1.ValidationError(`Unknown configuration key: ${key}. Valid keys: ${validKeys.join(', ')}`);
}
// Reset the specific key
await configManager.reset([key]);
// Get the default value for the success message
let defaultValue;
if (key === 'tasksDir') {
defaultValue = '.simple-task-master/tasks (default location)';
}
else if (key === 'lockTimeoutMs') {
defaultValue = `${config_1.CONFIG_DEFAULTS.lockTimeoutMs} (${config_1.CONFIG_DEFAULTS.lockTimeoutMs / 1000} seconds)`;
}
else if (key === 'maxTaskSizeBytes') {
const mb = config_1.CONFIG_DEFAULTS.maxTaskSizeBytes / 1048576;
defaultValue = `${config_1.CONFIG_DEFAULTS.maxTaskSizeBytes} (${mb} MB)`;
}
else {
// This case should never happen due to validation above
defaultValue = 'unknown';
}
(0, output_1.printSuccess)(`Configuration key '${key}' reset to default value: ${defaultValue}`);
}
finally {
await lockManager.release();
}
return;
}
// Handle --reset-all (requires lock)
if (options.resetAll) {
await lockManager.acquire();
try {
// Reset all resettable keys
const resettableKeys = ['tasksDir', 'lockTimeoutMs', 'maxTaskSizeBytes'];
await configManager.reset(resettableKeys);
(0, output_1.printSuccess)('All configuration values reset to defaults:');
(0, output_1.printOutput)(' tasksDir: .simple-task-master/tasks (default location)');
(0, output_1.printOutput)(` lockTimeoutMs: ${config_1.CONFIG_DEFAULTS.lockTimeoutMs} (${config_1.CONFIG_DEFAULTS.lockTimeoutMs / 1000} seconds)`);
const mb = config_1.CONFIG_DEFAULTS.maxTaskSizeBytes / 1048576;
(0, output_1.printOutput)(` maxTaskSizeBytes: ${config_1.CONFIG_DEFAULTS.maxTaskSizeBytes} (${mb} MB)`);
}
finally {
await lockManager.release();
}
return;
}
// No options provided - show help
(0, output_1.printOutput)('Usage: stm config [options]');
(0, output_1.printOutput)('Use "stm config --help" for more information');
}
catch (error) {
handleCommandError(error);
}
}
/**
* Create the config command
*/
exports.configCommand = new commander_1.Command('config')
.description('Manage Simple Task Master configuration')
.option('--get <key>', 'Get a configuration value (tasksDir, lockTimeoutMs, maxTaskSizeBytes)')
.option('--set <key=value>', 'Set a configuration value')
.option('--list', 'List all configuration values as JSON')
.option('--reset <key>', 'Reset a configuration value to its default')
.option('--reset-all', 'Reset all configuration values to defaults')
.addHelpText('after', `
Configuration Keys:
tasksDir - Directory where task files are stored
Default: .simple-task-master/tasks
Valid: Any valid directory path (relative or absolute)
Note: Tasks won't be migrated when changing this value
lockTimeoutMs - Lock acquisition timeout in milliseconds
Default: 30000 (30 seconds)
Valid: 1 - 300000 (max 5 minutes)
Usage: Prevents concurrent task modifications
maxTaskSizeBytes - Maximum allowed task file size in bytes
Default: 1048576 (1 MB)
Valid: 1 - 10485760 (max 10 MB)
Usage: Prevents oversized task files
Examples:
# View all configuration
stm config --list
# Get specific value
stm config --get tasksDir
stm config --get lockTimeoutMs
# Change tasks directory (relative path)
stm config --set tasksDir=docs/tasks
stm config --set tasksDir=.stm/tasks
# Change tasks directory (absolute path)
stm config --set tasksDir=/home/user/project/tasks
# Adjust lock timeout for slower systems
stm config --set lockTimeoutMs=60000 # 1 minute
stm config --set lockTimeoutMs=120000 # 2 minutes
# Increase max task size for large documentation
stm config --set maxTaskSizeBytes=2097152 # 2 MB
stm config --set maxTaskSizeBytes=5242880 # 5 MB
Restoring Defaults:
# Reset individual configuration values to defaults
stm config --reset tasksDir # Reset to .simple-task-master/tasks
stm config --reset lockTimeoutMs # Reset to 30000 (30 seconds)
stm config --reset maxTaskSizeBytes # Reset to 1048576 (1 MB)
# Reset all configuration values at once
stm config --reset-all
# Alternative: Delete config.json to use all defaults
rm .simple-task-master/config.json
Configuration Storage:
Settings are stored in: .simple-task-master/config.json
Format: JSON with schema version for future compatibility`)
.action(configAction);
//# sourceMappingURL=config.js.map