Skip to content

Commit fca94e6

Browse files
Merge pull request #1546 from eyaltoledano/next (Release 0.41.0)
2 parents f961235 + 98087ac commit fca94e6

26 files changed

Lines changed: 804 additions & 316 deletions

.changeset/afraid-rocks-add.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"task-master-ai": patch
3+
---
4+
5+
Codex cli Validate reasoning effort against model capabilities
6+
7+
- Add provider-level reasoning effort validation for OpenAI models
8+
- Automatically cap unsupported effort levels (e.g., 'xhigh' on gpt-5.1 and gpt-5 becomes 'high')

.changeset/hip-pots-study.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"task-master-ai": patch
3+
---
4+
5+
Improve CLI startup speed by 2x

.changeset/lazy-lies-argue.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"task-master-ai": patch
3+
---
4+
5+
Smarter project root detection with boundary markers
6+
7+
- Prevents Task Master from incorrectly detecting `.taskmaster` folders in your home directory when working inside a different project
8+
- Now stops at project boundaries (`.git`, `package.json`, lock files) instead of searching all the way up to the filesystem root
9+
- Adds support for monorepo markers (`lerna.json`, `nx.json`, `turbo.json`) and additional lock files (`bun.lockb`, `deno.lock`)

.changeset/new-grapes-accept.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"task-master-ai": patch
3+
---
4+
5+
Improve json schemas for ai-related commands making it more compatible with openai models
6+
7+
- Fixes #1541 #1542

.changeset/violet-colts-sip.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"task-master-ai": patch
3+
---
4+
5+
Fixed vertex-ai authentication when using service account and vertex location env variable.

.github/workflows/claude-docs-updater.yml

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,11 @@ jobs:
2626
permissions:
2727
contents: write
2828
pull-requests: write
29-
issues: write
3029
steps:
3130
- name: Checkout repository
3231
uses: actions/checkout@v4
3332
with:
3433
ref: next
35-
fetch-depth: 0 # Need full history to checkout specific commit
36-
37-
- name: Create docs update branch
38-
id: create-branch
39-
run: |
40-
BRANCH_NAME="docs/auto-update-$(date +%Y%m%d-%H%M%S)"
41-
git checkout -b $BRANCH_NAME
42-
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
4334

4435
- name: Run Claude Code to Update Documentation
4536
uses: anthropics/claude-code-action@v1
@@ -79,47 +70,34 @@ jobs:
7970
8071
Only make changes if the documentation truly needs updating based on the code changes.
8172
82-
- name: Check if changes were made
83-
id: check-changes
84-
run: |
85-
if git diff --quiet; then
86-
echo "has_changes=false" >> $GITHUB_OUTPUT
87-
else
88-
echo "has_changes=true" >> $GITHUB_OUTPUT
89-
git add -A
90-
git config --local user.email "github-actions[bot]@users.noreply.github.com"
91-
git config --local user.name "github-actions[bot]"
92-
git commit -m "docs: auto-update documentation based on changes in next branch
73+
- name: Create Pull Request
74+
uses: peter-evans/create-pull-request@v8
75+
with:
76+
token: ${{ secrets.GITHUB_TOKEN }}
77+
branch: docs/auto-update-${{ github.run_id }}
78+
base: next
79+
title: "docs: update documentation for recent changes"
80+
commit-message: |
81+
docs: auto-update documentation based on changes in next branch
9382
9483
This PR was automatically generated to update documentation based on recent changes.
95-
96-
Original commit: ${{ inputs.commit_message }}
97-
98-
Co-authored-by: Claude <claude-assistant@anthropic.com>"
99-
fi
10084
101-
- name: Push changes and create PR
102-
if: steps.check-changes.outputs.has_changes == 'true'
103-
env:
104-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
105-
run: |
106-
git push origin ${{ steps.create-branch.outputs.branch_name }}
85+
Original commit: ${{ inputs.commit_message }}
10786
108-
# Create PR using GitHub CLI
109-
gh pr create \
110-
--title "docs: update documentation for recent changes" \
111-
--body "## 📚 Documentation Update
87+
Co-authored-by: Claude <claude-assistant@anthropic.com>
88+
body: |
89+
## 📚 Documentation Update
11290
113-
This PR automatically updates documentation based on recent changes merged to the \`next\` branch.
91+
This PR automatically updates documentation based on recent changes merged to the `next` branch.
11492
11593
### Original Changes
11694
**Commit:** ${{ inputs.commit_sha }}
11795
**Message:** ${{ inputs.commit_message }}
118-
96+
11997
### Changed Files in Original Commit
120-
\`\`\`
98+
```
12199
${{ inputs.changed_files }}
122-
\`\`\`
100+
```
123101
124102
### Documentation Updates
125103
This PR includes documentation updates to reflect the changes above. Please review to ensure:
@@ -129,8 +107,9 @@ jobs:
129107
- [ ] Style is consistent with existing documentation
130108
131109
---
132-
*This PR was automatically generated by Claude Code GitHub Action*" \
133-
--base next \
134-
--head ${{ steps.create-branch.outputs.branch_name }} \
135-
--label "documentation" \
136-
--label "automated"
110+
*This PR was automatically generated by Claude Code GitHub Action*
111+
labels: |
112+
documentation
113+
automated
114+
author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
115+
delete-branch: true
Lines changed: 162 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,187 @@
11
/**
2-
* @fileoverview Check npm registry for package updates
2+
* @fileoverview Check npm registry for package updates with caching
3+
*
4+
* Uses a simple file-based cache in the OS temp directory to avoid
5+
* hitting npm on every CLI invocation. Cache expires after 1 hour.
36
*/
47

8+
import fs from 'node:fs';
59
import https from 'https';
10+
import os from 'node:os';
11+
import path from 'node:path';
612

713
import { fetchChangelogHighlights } from './changelog.js';
814
import type { UpdateInfo } from './types.js';
915
import { compareVersions, getCurrentVersion } from './version.js';
1016

17+
// ============================================================================
18+
// Cache Configuration
19+
// ============================================================================
20+
21+
/** Cache TTL: 1 hour in milliseconds */
22+
const CACHE_TTL_MS = 60 * 60 * 1000;
23+
24+
/** Cache file name */
25+
const CACHE_FILENAME = 'taskmaster-update-cache.json';
26+
27+
interface UpdateCache {
28+
timestamp: number;
29+
latestVersion: string;
30+
highlights?: string[];
31+
}
32+
33+
// ============================================================================
34+
// Cache Operations (Single Responsibility: cache I/O)
35+
// ============================================================================
36+
1137
/**
12-
* Check for newer version of task-master-ai
38+
* Get the path to the update cache file in OS temp directory
1339
*/
14-
export async function checkForUpdate(
15-
currentVersionOverride?: string
16-
): Promise<UpdateInfo> {
17-
const currentVersion = currentVersionOverride || getCurrentVersion();
40+
const getCachePath = (): string => path.join(os.tmpdir(), CACHE_FILENAME);
1841

19-
return new Promise((resolve) => {
20-
const options = {
21-
hostname: 'registry.npmjs.org',
22-
path: '/task-master-ai',
23-
method: 'GET',
24-
headers: {
25-
Accept: 'application/vnd.npm.install-v1+json',
26-
'User-Agent': `task-master-ai/${currentVersion}`
27-
}
28-
};
42+
/**
43+
* Read cached update info if still valid
44+
* @returns Cached data or null if expired/missing/invalid
45+
*/
46+
function readCache(): UpdateCache | null {
47+
try {
48+
const cachePath = getCachePath();
49+
if (!fs.existsSync(cachePath)) return null;
2950

30-
const req = https.request(options, (res) => {
31-
let data = '';
51+
const data: UpdateCache = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
52+
const isExpired = Date.now() - data.timestamp > CACHE_TTL_MS;
3253

33-
res.on('data', (chunk) => {
34-
data += chunk;
35-
});
54+
return isExpired ? null : data;
55+
} catch {
56+
return null;
57+
}
58+
}
3659

37-
res.on('end', async () => {
38-
try {
39-
if (res.statusCode !== 200)
40-
throw new Error(`npm registry status ${res.statusCode}`);
41-
const npmData = JSON.parse(data);
42-
const latestVersion = npmData['dist-tags']?.latest || currentVersion;
60+
/**
61+
* Write update info to cache
62+
*/
63+
function writeCache(latestVersion: string, highlights?: string[]): void {
64+
try {
65+
fs.writeFileSync(
66+
getCachePath(),
67+
JSON.stringify(
68+
{
69+
timestamp: Date.now(),
70+
latestVersion,
71+
highlights
72+
} satisfies UpdateCache,
73+
null,
74+
2
75+
)
76+
);
77+
} catch {
78+
// Cache write failures are non-critical - silently ignore
79+
}
80+
}
4381

44-
const needsUpdate =
45-
compareVersions(currentVersion, latestVersion) < 0;
82+
// ============================================================================
83+
// NPM Registry Operations (Single Responsibility: npm API)
84+
// ============================================================================
4685

47-
// Fetch highlights if update is needed
48-
let highlights: string[] | undefined;
49-
if (needsUpdate) {
50-
highlights = await fetchChangelogHighlights(latestVersion);
51-
}
86+
/** Request timeout for npm registry */
87+
const NPM_TIMEOUT_MS = 3000;
5288

53-
resolve({
54-
currentVersion,
55-
latestVersion,
56-
needsUpdate,
57-
highlights
58-
});
59-
} catch {
60-
resolve({
61-
currentVersion,
62-
latestVersion: currentVersion,
63-
needsUpdate: false
64-
});
89+
/**
90+
* Fetch latest version from npm registry
91+
* @returns Latest version string or null on failure
92+
*/
93+
function fetchLatestVersion(currentVersion: string): Promise<string | null> {
94+
return new Promise((resolve) => {
95+
const req = https.request(
96+
{
97+
hostname: 'registry.npmjs.org',
98+
path: '/task-master-ai',
99+
method: 'GET',
100+
headers: {
101+
Accept: 'application/vnd.npm.install-v1+json',
102+
'User-Agent': `task-master-ai/${currentVersion}`
65103
}
66-
});
67-
});
68-
69-
req.on('error', () => {
70-
resolve({
71-
currentVersion,
72-
latestVersion: currentVersion,
73-
needsUpdate: false
74-
});
75-
});
104+
},
105+
(res) => {
106+
let data = '';
107+
res.on('data', (chunk) => (data += chunk));
108+
res.on('end', () => {
109+
try {
110+
if (res.statusCode !== 200) {
111+
resolve(null);
112+
return;
113+
}
114+
const npmData = JSON.parse(data);
115+
resolve(npmData['dist-tags']?.latest || null);
116+
} catch {
117+
resolve(null);
118+
}
119+
});
120+
}
121+
);
76122

77-
req.setTimeout(3000, () => {
123+
req.on('error', () => resolve(null));
124+
req.setTimeout(NPM_TIMEOUT_MS, () => {
78125
req.destroy();
79-
resolve({
80-
currentVersion,
81-
latestVersion: currentVersion,
82-
needsUpdate: false
83-
});
126+
resolve(null);
84127
});
85-
86128
req.end();
87129
});
88130
}
131+
132+
// ============================================================================
133+
// Public API
134+
// ============================================================================
135+
136+
/**
137+
* Build UpdateInfo response
138+
*/
139+
function buildUpdateInfo(
140+
currentVersion: string,
141+
latestVersion: string,
142+
highlights?: string[]
143+
): UpdateInfo {
144+
return {
145+
currentVersion,
146+
latestVersion,
147+
needsUpdate: compareVersions(currentVersion, latestVersion) < 0,
148+
highlights
149+
};
150+
}
151+
152+
/**
153+
* Check for newer version of task-master-ai
154+
* Uses a 1-hour cache to avoid hitting npm on every CLI invocation
155+
*/
156+
export async function checkForUpdate(
157+
currentVersionOverride?: string
158+
): Promise<UpdateInfo> {
159+
const currentVersion = currentVersionOverride || getCurrentVersion();
160+
161+
// Return cached result if valid
162+
const cached = readCache();
163+
if (cached) {
164+
return buildUpdateInfo(
165+
currentVersion,
166+
cached.latestVersion,
167+
cached.highlights
168+
);
169+
}
170+
171+
// Fetch from npm registry
172+
const latestVersion = await fetchLatestVersion(currentVersion);
173+
if (!latestVersion) {
174+
return buildUpdateInfo(currentVersion, currentVersion);
175+
}
176+
177+
// Fetch changelog highlights if update available
178+
const needsUpdate = compareVersions(currentVersion, latestVersion) < 0;
179+
const highlights = needsUpdate
180+
? await fetchChangelogHighlights(latestVersion)
181+
: undefined;
182+
183+
// Cache result
184+
writeCache(latestVersion, highlights);
185+
186+
return buildUpdateInfo(currentVersion, latestVersion, highlights);
187+
}

0 commit comments

Comments
 (0)