mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2026-01-30 06:12:05 +00:00
chore: apply nitpicks of 0.36.0 post-merge
This commit is contained in:
@@ -70,6 +70,7 @@ export function parseChangelogHighlights(
|
||||
}
|
||||
|
||||
// Find the version section
|
||||
// Version validated above (semver format), safe to construct regex
|
||||
const versionRegex = new RegExp(
|
||||
`## ${version.replace(/\./g, '\\.')}\\s*\\n`,
|
||||
'i'
|
||||
|
||||
@@ -101,7 +101,7 @@ export async function downloadTarballWithProgress(
|
||||
|
||||
const options = {
|
||||
hostname: url.hostname,
|
||||
path: url.pathname,
|
||||
path: url.pathname + url.search,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'User-Agent': `task-master-ai/${version}`
|
||||
|
||||
@@ -26,6 +26,9 @@ const INSTALL_PHASES = [
|
||||
/** Total weight for percentage calculation */
|
||||
const TOTAL_WEIGHT = INSTALL_PHASES.reduce((sum, p) => sum + p.weight, 0);
|
||||
|
||||
/** Timeout for npm install operations (5 minutes) */
|
||||
const INSTALL_TIMEOUT_MS = 5 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Parse npm output to determine current installation phase index
|
||||
*/
|
||||
@@ -152,6 +155,21 @@ async function installFromTarball(tarballPath: string): Promise<boolean> {
|
||||
);
|
||||
|
||||
let errorOutput = '';
|
||||
let completed = false;
|
||||
|
||||
// Set timeout for npm install
|
||||
const installTimeout = setTimeout(() => {
|
||||
if (completed) return;
|
||||
completed = true;
|
||||
installProcess.kill('SIGTERM');
|
||||
clearInterval(progressInterval);
|
||||
progressBar.stop();
|
||||
console.log(chalk.red('✖') + chalk.red(' Installation timed out'));
|
||||
if (fs.existsSync(tarballPath)) {
|
||||
fs.unlink(tarballPath, () => {});
|
||||
}
|
||||
resolve(false);
|
||||
}, INSTALL_TIMEOUT_MS);
|
||||
|
||||
// Parse stdout for progress hints
|
||||
installProcess.stdout.on('data', (data) => {
|
||||
@@ -188,6 +206,9 @@ async function installFromTarball(tarballPath: string): Promise<boolean> {
|
||||
});
|
||||
|
||||
installProcess.on('close', (code) => {
|
||||
if (completed) return;
|
||||
completed = true;
|
||||
clearTimeout(installTimeout);
|
||||
clearInterval(progressInterval);
|
||||
|
||||
// Complete the progress bar
|
||||
@@ -227,6 +248,9 @@ async function installFromTarball(tarballPath: string): Promise<boolean> {
|
||||
});
|
||||
|
||||
installProcess.on('error', (error) => {
|
||||
if (completed) return;
|
||||
completed = true;
|
||||
clearTimeout(installTimeout);
|
||||
clearInterval(progressInterval);
|
||||
progressBar.stop();
|
||||
|
||||
@@ -270,6 +294,21 @@ async function performDirectNpmInstall(
|
||||
);
|
||||
|
||||
let errorOutput = '';
|
||||
let completed = false;
|
||||
|
||||
// Set timeout for npm install
|
||||
const installTimeout = setTimeout(() => {
|
||||
if (completed) return;
|
||||
completed = true;
|
||||
updateProcess.kill('SIGTERM');
|
||||
spinner.fail(chalk.red('Auto-update timed out'));
|
||||
console.log(
|
||||
chalk.cyan(
|
||||
`Please run manually: npm install -g task-master-ai@${latestVersion}`
|
||||
)
|
||||
);
|
||||
resolve(false);
|
||||
}, INSTALL_TIMEOUT_MS);
|
||||
|
||||
updateProcess.stdout.on('data', () => {
|
||||
spinner.text = chalk.blue(
|
||||
@@ -282,6 +321,10 @@ async function performDirectNpmInstall(
|
||||
});
|
||||
|
||||
updateProcess.on('close', (code) => {
|
||||
if (completed) return;
|
||||
completed = true;
|
||||
clearTimeout(installTimeout);
|
||||
|
||||
if (code === 0) {
|
||||
spinner.succeed(
|
||||
chalk.green(
|
||||
@@ -304,6 +347,10 @@ async function performDirectNpmInstall(
|
||||
});
|
||||
|
||||
updateProcess.on('error', (error) => {
|
||||
if (completed) return;
|
||||
completed = true;
|
||||
clearTimeout(installTimeout);
|
||||
|
||||
spinner.fail(chalk.red('Auto-update failed'));
|
||||
console.log(chalk.red('Error:'), error.message);
|
||||
console.log(
|
||||
|
||||
@@ -77,6 +77,11 @@ describe('generate MCP tool', () => {
|
||||
|
||||
// Parse the MCP protocol response: { content: [{ type: "text", text: "<json>" }] }
|
||||
const mcpResponse = JSON.parse(output);
|
||||
if (!mcpResponse.content?.[0]?.text) {
|
||||
throw new Error(
|
||||
`Unexpected MCP response format: ${JSON.stringify(mcpResponse)}`
|
||||
);
|
||||
}
|
||||
const resultText = mcpResponse.content[0].text;
|
||||
return JSON.parse(resultText);
|
||||
};
|
||||
|
||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "task-master-ai",
|
||||
"version": "0.35.0",
|
||||
"version": "0.36.0-rc.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "task-master-ai",
|
||||
"version": "0.35.0",
|
||||
"version": "0.36.0-rc.0",
|
||||
"license": "MIT WITH Commons-Clause",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
@@ -194,7 +194,7 @@
|
||||
"react-dom": "^19.0.0",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwindcss": "4.1.11",
|
||||
"task-master-ai": "*",
|
||||
"task-master-ai": "0.36.0-rc.0",
|
||||
"typescript": "^5.9.2"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -49,6 +49,15 @@ describe('createAPICallError', () => {
|
||||
expect(error.message).toBe('Simple error');
|
||||
expect(error.isRetryable).toBe(false);
|
||||
});
|
||||
|
||||
it('should set requestBodyValues when promptExcerpt is provided', () => {
|
||||
const error = createAPICallError({
|
||||
message: 'Test error',
|
||||
promptExcerpt: 'Sample prompt'
|
||||
});
|
||||
|
||||
expect(error.requestBodyValues).toEqual({ prompt: 'Sample prompt' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('createAuthenticationError', () => {
|
||||
|
||||
@@ -334,6 +334,8 @@ export class TaskFileGeneratorService {
|
||||
return ' ✗';
|
||||
case 'deferred':
|
||||
return ' ⏸';
|
||||
case 'review':
|
||||
return ' 👁';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -809,9 +809,12 @@ export class TaskService {
|
||||
* Releases file locks and other storage resources
|
||||
*/
|
||||
async close(): Promise<void> {
|
||||
if (this.storage) {
|
||||
if (!this.storage) return;
|
||||
|
||||
try {
|
||||
await this.storage.close();
|
||||
} finally {
|
||||
this.initialized = false;
|
||||
}
|
||||
this.initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +70,9 @@ describe('Hamster Rules Distribution', () => {
|
||||
});
|
||||
|
||||
describe('Rules add command distributes hamster file', () => {
|
||||
// Test each profile that should receive hamster rules
|
||||
PROFILES_WITH_DEFAULT_RULES.forEach((profile) => {
|
||||
test(`${profile} profile receives hamster rules via 'rules add'`, () => {
|
||||
test.each(PROFILES_WITH_DEFAULT_RULES)(
|
||||
'%s profile receives hamster rules via "rules add"',
|
||||
(profile) => {
|
||||
// Create a unique temp directory for this test
|
||||
const tempDir = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), `tm-hamster-test-${profile}-`)
|
||||
@@ -104,15 +104,16 @@ describe('Hamster Rules Distribution', () => {
|
||||
// Cleanup temp directory
|
||||
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('Profiles without default rules', () => {
|
||||
// These profiles use different mechanisms (CLAUDE.md, AGENTS.md, etc.)
|
||||
// and don't include the defaultFileMap rules
|
||||
PROFILES_WITHOUT_DEFAULT_RULES.forEach((profile) => {
|
||||
test(`${profile} profile does not use defaultFileMap (has custom mechanism)`, async () => {
|
||||
test.each(PROFILES_WITHOUT_DEFAULT_RULES)(
|
||||
'%s profile does not use defaultFileMap (has custom mechanism)',
|
||||
async (profile) => {
|
||||
// Dynamically import the profile to check its configuration
|
||||
const profileModule = await import(
|
||||
`../../../src/profiles/${profile}.js`
|
||||
@@ -122,7 +123,7 @@ describe('Hamster Rules Distribution', () => {
|
||||
// These profiles should have includeDefaultRules: false
|
||||
// which means they won't automatically get hamster files via defaultFileMap
|
||||
expect(profileExport.includeDefaultRules).toBe(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user