0agent 1.0.33 → 1.0.35
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/bin/chat.js +63 -49
- package/dist/daemon.mjs +5 -1
- package/package.json +1 -1
package/bin/chat.js
CHANGED
|
@@ -354,8 +354,23 @@ async function runTask(input) {
|
|
|
354
354
|
// Catches completion when WS is disconnected (e.g. daemon just restarted).
|
|
355
355
|
let lastPolledStep = 0;
|
|
356
356
|
const sid = sessionId;
|
|
357
|
+
const sessionStart = Date.now();
|
|
357
358
|
const pollTimer = setInterval(async () => {
|
|
358
359
|
if (!pendingResolve || sessionId !== sid) { clearInterval(pollTimer); return; }
|
|
360
|
+
|
|
361
|
+
// Hard cap: if session runs for > 2 minutes, force-unblock the chat.
|
|
362
|
+
// The daemon session may still run in background, but the user gets their prompt back.
|
|
363
|
+
if (Date.now() - sessionStart > 120_000) {
|
|
364
|
+
clearInterval(pollTimer);
|
|
365
|
+
spinner.stop();
|
|
366
|
+
console.log(`\n \x1b[33m⚠\x1b[0m Session still running in background (> 2min). Chat unblocked.\n`);
|
|
367
|
+
const res = pendingResolve;
|
|
368
|
+
pendingResolve = null;
|
|
369
|
+
sessionId = null;
|
|
370
|
+
res();
|
|
371
|
+
rl.prompt();
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
359
374
|
try {
|
|
360
375
|
const r = await fetch(`${BASE_URL}/api/sessions/${sid}`, { signal: AbortSignal.timeout(2000) });
|
|
361
376
|
const session = await r.json();
|
|
@@ -391,7 +406,7 @@ async function runTask(input) {
|
|
|
391
406
|
rl.prompt();
|
|
392
407
|
}
|
|
393
408
|
} catch {}
|
|
394
|
-
},
|
|
409
|
+
}, 800);
|
|
395
410
|
|
|
396
411
|
return new Promise(resolve => { pendingResolve = resolve; });
|
|
397
412
|
} catch (e) {
|
|
@@ -758,62 +773,61 @@ async function _safeJsonFetch(url, opts) {
|
|
|
758
773
|
console.log(` ${fmt(C.yellow, '⚠')} LLM check failed: ${e.message}\n`);
|
|
759
774
|
}
|
|
760
775
|
|
|
761
|
-
// ──
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
776
|
+
// ── Auto-update: check npm, update silently, restart ─────────────────────
|
|
777
|
+
// Runs in background after prompt — never blocks startup.
|
|
778
|
+
// If update found: counts down 3s (press any key to skip), then auto-installs.
|
|
779
|
+
(async () => {
|
|
780
|
+
try {
|
|
781
|
+
const pkgPath = resolve(new URL(import.meta.url).pathname, '..', '..', 'package.json');
|
|
782
|
+
const currentVersion = existsSync(pkgPath)
|
|
783
|
+
? JSON.parse(readFileSync(pkgPath, 'utf8')).version
|
|
784
|
+
: null;
|
|
785
|
+
if (!currentVersion) return;
|
|
767
786
|
|
|
768
|
-
if (currentVersion) {
|
|
769
787
|
const reg = await fetch('https://registry.npmjs.org/0agent/latest', {
|
|
770
|
-
signal: AbortSignal.timeout(
|
|
788
|
+
signal: AbortSignal.timeout(5000),
|
|
771
789
|
}).then(r => r.json()).catch(() => null);
|
|
772
790
|
|
|
773
791
|
const latest = reg?.version;
|
|
774
|
-
if (latest
|
|
775
|
-
console.log(`\n ${fmt(C.yellow, '↑')} Update available: ${fmt(C.dim, currentVersion)} → ${fmt(C.bold + C.green, latest)}`);
|
|
776
|
-
process.stdout.write(` Update now? ${fmt(C.bold, '[y/N]')} `);
|
|
777
|
-
|
|
778
|
-
await new Promise((res) => {
|
|
779
|
-
const handler = async (buf) => {
|
|
780
|
-
const answer = buf.toString().trim().toLowerCase();
|
|
781
|
-
process.stdout.write(answer + '\n');
|
|
782
|
-
if (answer === 'y') {
|
|
783
|
-
process.stdout.write(`\n ${fmt(C.dim, 'Installing 0agent@latest...')}\n`);
|
|
784
|
-
try {
|
|
785
|
-
const { execSync: exs } = await import('node:child_process');
|
|
786
|
-
exs('npm install -g 0agent@latest', { stdio: 'inherit', timeout: 120_000 });
|
|
787
|
-
process.stdout.write(`\n ${fmt(C.green, '✓')} Updated to ${latest} — restarting...\n\n`);
|
|
788
|
-
// Restart: spawn new instance, exit current
|
|
789
|
-
const { spawn: sp } = await import('node:child_process');
|
|
790
|
-
const child = sp(process.argv[0], process.argv.slice(1), { stdio: 'inherit' });
|
|
791
|
-
child.on('close', (code) => process.exit(code ?? 0));
|
|
792
|
-
process.stdin.pause();
|
|
793
|
-
} catch (e) {
|
|
794
|
-
process.stdout.write(`\n ${fmt(C.red, '✗')} Update failed: ${e.message}\n Try manually: npm install -g 0agent@latest\n\n`);
|
|
795
|
-
rl.prompt();
|
|
796
|
-
}
|
|
797
|
-
} else {
|
|
798
|
-
process.stdout.write(` ${fmt(C.dim, `Skipping — run: npm install -g 0agent@${latest} to update later`)}\n\n`);
|
|
799
|
-
rl.prompt();
|
|
800
|
-
}
|
|
801
|
-
res();
|
|
802
|
-
};
|
|
792
|
+
if (!latest || !isNewerVersion(latest, currentVersion)) return;
|
|
803
793
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
794
|
+
// Show banner immediately above current prompt line
|
|
795
|
+
process.stdout.write(`\n ${fmt(C.yellow, '↑')} New version ${fmt(C.bold, latest)} available (you have ${currentVersion})\n`);
|
|
796
|
+
|
|
797
|
+
// 3-second countdown — press any key to skip, otherwise auto-updates
|
|
798
|
+
let skipped = false;
|
|
799
|
+
const skipHandler = () => { skipped = true; };
|
|
800
|
+
process.stdin.once('data', skipHandler);
|
|
801
|
+
|
|
802
|
+
for (let i = 3; i > 0; i--) {
|
|
803
|
+
if (skipped) break;
|
|
804
|
+
process.stdout.write(`\r ${fmt(C.dim, `Auto-updating in ${i}s — press any key to skip... `)}`);
|
|
805
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
806
|
+
}
|
|
807
|
+
process.stdin.removeListener('data', skipHandler);
|
|
808
|
+
process.stdout.write('\r\x1b[2K'); // clear countdown line
|
|
809
|
+
|
|
810
|
+
if (skipped) {
|
|
811
|
+
console.log(` ${fmt(C.dim, `Skipped. Run: npm install -g 0agent@${latest}`)}`);
|
|
812
|
+
rl.prompt(true);
|
|
813
|
+
return;
|
|
812
814
|
}
|
|
815
|
+
|
|
816
|
+
// Auto-install
|
|
817
|
+
console.log(` ${fmt(C.cyan, '↑')} Updating to ${latest}...`);
|
|
818
|
+
const { execSync: exs } = await import('node:child_process');
|
|
819
|
+
exs('npm install -g 0agent@latest --silent', { stdio: 'ignore', timeout: 120_000 });
|
|
820
|
+
process.stdout.write(` ${fmt(C.green, '✓')} Updated to ${latest} — restarting...\n\n`);
|
|
821
|
+
|
|
822
|
+
// Restart cleanly
|
|
823
|
+
const { spawn: sp } = await import('node:child_process');
|
|
824
|
+
const child = sp(process.argv[0], process.argv.slice(1), { stdio: 'inherit' });
|
|
825
|
+
child.on('close', (code) => process.exit(code ?? 0));
|
|
826
|
+
process.stdin.pause();
|
|
827
|
+
} catch {
|
|
828
|
+
// Non-fatal — update failure never crashes the agent
|
|
813
829
|
}
|
|
814
|
-
}
|
|
815
|
-
// Version check is non-fatal — never block startup
|
|
816
|
-
}
|
|
830
|
+
})();
|
|
817
831
|
|
|
818
832
|
rl.prompt();
|
|
819
833
|
})();
|
package/dist/daemon.mjs
CHANGED
|
@@ -2339,9 +2339,13 @@ var init_ShellCapability = __esm({
|
|
|
2339
2339
|
}
|
|
2340
2340
|
};
|
|
2341
2341
|
async execute(input, cwd) {
|
|
2342
|
-
|
|
2342
|
+
let command = String(input.command ?? "");
|
|
2343
2343
|
const timeout = Number(input.timeout_ms ?? 3e4);
|
|
2344
2344
|
const start = Date.now();
|
|
2345
|
+
if (/&\s*$/.test(command) && !/[>|].*&\s*$/.test(command)) {
|
|
2346
|
+
const logFile = `/tmp/0agent-bg-${Date.now()}.log`;
|
|
2347
|
+
command = command.replace(/\s*&\s*$/, ` > ${logFile} 2>&1 &`);
|
|
2348
|
+
}
|
|
2345
2349
|
return new Promise((resolve_) => {
|
|
2346
2350
|
const chunks = [];
|
|
2347
2351
|
let settled = false;
|