fix: Correct TTY check for AI progress indicator in CLI

Addresses `process.stdout.clearLine is not a function` error when running AI-dependent commands non-interactively (e.g., `update-subtask`).

Adds `process.stdout.isTTY` check before attempting to use terminal-specific output manipulations.

feat: Implement initial config manager for AI models

Adds `scripts/modules/config-manager.js` to handle reading/writing model selections from/to `.taskmasterconfig`.

Implements core functions: findProjectRoot, read/writeConfig, validateModel, get/setModel.

Defines valid model lists. Completes initial work for Subtask 61.1.
This commit is contained in:
Eyal Toledano
2025-04-14 18:53:41 -04:00
parent c7fefb0549
commit 329839aeb8
5 changed files with 331 additions and 23 deletions

View File

@@ -587,15 +587,18 @@ Note on dependencies: Subtasks can depend on other subtasks with lower IDs. Use
try {
// Update loading indicator to show streaming progress
let dotCount = 0;
const readline = await import('readline');
streamingInterval = setInterval(() => {
readline.cursorTo(process.stdout, 0);
process.stdout.write(
`Generating subtasks for task ${task.id}${'.'.repeat(dotCount)}`
);
dotCount = (dotCount + 1) % 4;
}, 500);
// Only create interval if not silent and stdout is a TTY
if (!isSilentMode() && process.stdout.isTTY) {
let dotCount = 0;
const readline = await import('readline');
streamingInterval = setInterval(() => {
readline.cursorTo(process.stdout, 0);
process.stdout.write(
`Generating subtasks for task ${task.id}${'.'.repeat(dotCount)}`
);
dotCount = (dotCount + 1) % 4;
}, 500);
}
// TODO: MOVE THIS TO THE STREAM REQUEST FUNCTION (DRY)
@@ -808,8 +811,8 @@ Note on dependencies: Subtasks can depend on other subtasks with lower IDs. Use
try {
// Update loading indicator to show streaming progress
// Only create if not in silent mode
if (!isSilent) {
// Only create interval if not silent and stdout is a TTY
if (!isSilentMode() && process.stdout.isTTY) {
let dotCount = 0;
const readline = await import('readline');
streamingInterval = setInterval(() => {
@@ -1389,15 +1392,18 @@ Return a JSON object with the following structure:
try {
// Update loading indicator to show streaming progress
let dotCount = 0;
const readline = await import('readline');
streamingInterval = setInterval(() => {
readline.cursorTo(process.stdout, 0);
process.stdout.write(
`Generating research-backed task description${'.'.repeat(dotCount)}`
);
dotCount = (dotCount + 1) % 4;
}, 500);
// Only create interval if not silent and stdout is a TTY
if (!isSilentMode() && process.stdout.isTTY) {
let dotCount = 0;
const readline = await import('readline');
streamingInterval = setInterval(() => {
readline.cursorTo(process.stdout, 0);
process.stdout.write(
`Generating research-backed task description${'.'.repeat(dotCount)}`
);
dotCount = (dotCount + 1) % 4;
}, 500);
}
// Use streaming API call
const stream = await anthropic.messages.create({