@masslessai/push-todo 4.2.5 → 4.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/agent-versions.js +70 -1
- package/lib/daemon.js +12 -1
- package/package.json +1 -1
package/lib/agent-versions.js
CHANGED
|
@@ -279,6 +279,8 @@ export function checkForAgentUpdate(agentType) {
|
|
|
279
279
|
|
|
280
280
|
/**
|
|
281
281
|
* Install a specific version of an agent CLI globally.
|
|
282
|
+
* For claude-code: tries npm first, falls back to `claude update` which
|
|
283
|
+
* handles non-npm installations (brew, app installer, happy-coder wrapper).
|
|
282
284
|
*
|
|
283
285
|
* @param {string} agentType
|
|
284
286
|
* @param {string} targetVersion
|
|
@@ -288,6 +290,7 @@ export function performAgentUpdate(agentType, targetVersion) {
|
|
|
288
290
|
const agent = AGENTS[agentType];
|
|
289
291
|
if (!agent?.npmPackage) return false;
|
|
290
292
|
|
|
293
|
+
// Try npm install first (works for standard npm global installs)
|
|
291
294
|
try {
|
|
292
295
|
execFileSync('npm', ['install', '-g', `${agent.npmPackage}@${targetVersion}`], {
|
|
293
296
|
timeout: 120000,
|
|
@@ -295,8 +298,29 @@ export function performAgentUpdate(agentType, targetVersion) {
|
|
|
295
298
|
});
|
|
296
299
|
return true;
|
|
297
300
|
} catch {
|
|
298
|
-
|
|
301
|
+
// npm failed — fall through to agent-specific fallbacks
|
|
299
302
|
}
|
|
303
|
+
|
|
304
|
+
// Fallback: use the agent's own update command (handles non-npm installs)
|
|
305
|
+
if (agentType === 'claude-code') {
|
|
306
|
+
try {
|
|
307
|
+
const env = { ...process.env };
|
|
308
|
+
delete env.CLAUDECODE;
|
|
309
|
+
delete env.CLAUDE_CODE_ENTRYPOINT;
|
|
310
|
+
execFileSync('claude', ['update'], {
|
|
311
|
+
timeout: 120000,
|
|
312
|
+
stdio: 'pipe',
|
|
313
|
+
env,
|
|
314
|
+
});
|
|
315
|
+
// Verify the update actually worked
|
|
316
|
+
const after = detectAgentVersion('claude-code');
|
|
317
|
+
return after.installed && after.version != null;
|
|
318
|
+
} catch {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return false;
|
|
300
324
|
}
|
|
301
325
|
|
|
302
326
|
/**
|
|
@@ -333,6 +357,51 @@ export function checkAllAgentUpdates({ force = false } = {}) {
|
|
|
333
357
|
return results;
|
|
334
358
|
}
|
|
335
359
|
|
|
360
|
+
/**
|
|
361
|
+
* Pre-flight check: verify an agent meets minimum version before task execution.
|
|
362
|
+
* If below minimum, attempts an immediate update and rechecks.
|
|
363
|
+
*
|
|
364
|
+
* @param {string} agentType
|
|
365
|
+
* @returns {{ ok: boolean, version: string|null, error: string|null }}
|
|
366
|
+
*/
|
|
367
|
+
export function ensureAgentReady(agentType) {
|
|
368
|
+
const agent = AGENTS[agentType];
|
|
369
|
+
if (!agent) {
|
|
370
|
+
return { ok: false, version: null, error: `Unknown agent type: ${agentType}` };
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const info = detectAgentVersion(agentType);
|
|
374
|
+
if (!info.installed) {
|
|
375
|
+
return { ok: false, version: null, error: `${agentType} CLI not found` };
|
|
376
|
+
}
|
|
377
|
+
if (!info.version) {
|
|
378
|
+
return { ok: false, version: null, error: `${agentType} installed but version unknown` };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Check minimum version
|
|
382
|
+
if (agent.minVersion && compareSemver(info.version, agent.minVersion) < 0) {
|
|
383
|
+
// Attempt immediate update
|
|
384
|
+
const latest = fetchLatestAgentVersion(agentType);
|
|
385
|
+
if (latest?.version) {
|
|
386
|
+
const updated = performAgentUpdate(agentType, latest.version);
|
|
387
|
+
if (updated) {
|
|
388
|
+
// Recheck after update
|
|
389
|
+
const after = detectAgentVersion(agentType);
|
|
390
|
+
if (after.version && compareSemver(after.version, agent.minVersion) >= 0) {
|
|
391
|
+
return { ok: true, version: after.version, error: null };
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
ok: false,
|
|
397
|
+
version: info.version,
|
|
398
|
+
error: `${agentType} v${info.version} is below minimum v${agent.minVersion} (needs --worktree support). Update with: claude update`,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return { ok: true, version: info.version, error: null };
|
|
403
|
+
}
|
|
404
|
+
|
|
336
405
|
// ==================== Version Parity ====================
|
|
337
406
|
|
|
338
407
|
/**
|
package/lib/daemon.js
CHANGED
|
@@ -25,7 +25,7 @@ import { getProjectContext, buildSmartPrompt, invalidateCache } from './context-
|
|
|
25
25
|
import { sendMacNotification } from './utils/notify.js';
|
|
26
26
|
import { checkAndRunDueJobs } from './cron.js';
|
|
27
27
|
import { runHeartbeatChecks } from './heartbeat.js';
|
|
28
|
-
import { getAgentVersions, formatAgentVersionSummary, checkAllAgentUpdates, performAgentUpdate, checkVersionParity } from './agent-versions.js';
|
|
28
|
+
import { getAgentVersions, formatAgentVersionSummary, checkAllAgentUpdates, performAgentUpdate, checkVersionParity, ensureAgentReady } from './agent-versions.js';
|
|
29
29
|
import { checkAllProjectsFreshness } from './project-freshness.js';
|
|
30
30
|
import { getStatus as getLaunchAgentStatus, install as refreshLaunchAgent } from './launchagent.js';
|
|
31
31
|
|
|
@@ -2261,6 +2261,17 @@ async function executeTask(task) {
|
|
|
2261
2261
|
log(`Task #${displayNumber}: Project ${gitRemote} -> ${projectPath}`);
|
|
2262
2262
|
}
|
|
2263
2263
|
|
|
2264
|
+
// Pre-flight: verify agent CLI meets minimum version (attempts auto-update if not)
|
|
2265
|
+
const agentType = taskActionType || 'claude-code';
|
|
2266
|
+
const readiness = ensureAgentReady(agentType);
|
|
2267
|
+
if (!readiness.ok) {
|
|
2268
|
+
logError(`Task #${displayNumber}: ${readiness.error}`);
|
|
2269
|
+
await updateTaskStatus(displayNumber, 'failed', {
|
|
2270
|
+
error: readiness.error
|
|
2271
|
+
}, taskId);
|
|
2272
|
+
return null;
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2264
2275
|
// Pre-assign session ID so we can store it at claim time (not rely on parsing stdout)
|
|
2265
2276
|
const preAssignedSessionId = randomUUID();
|
|
2266
2277
|
|