limbo-ai 1.23.5 → 1.23.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/cli.js +53 -17
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -1481,7 +1481,7 @@ function installDocker() {
|
|
|
1481
1481
|
}
|
|
1482
1482
|
}
|
|
1483
1483
|
|
|
1484
|
-
function extractWizardUrl(maxWaitSecs =
|
|
1484
|
+
function extractWizardUrl(maxWaitSecs = 30) {
|
|
1485
1485
|
const deadline = Date.now() + maxWaitSecs * 1000;
|
|
1486
1486
|
while (Date.now() < deadline) {
|
|
1487
1487
|
try {
|
|
@@ -1514,7 +1514,7 @@ ${c.green}${c.bold}╚═══════════════════
|
|
|
1514
1514
|
`);
|
|
1515
1515
|
|
|
1516
1516
|
if (tunnel) {
|
|
1517
|
-
const tunnelUrl = `${tunnel.url}/?token=${token}
|
|
1517
|
+
const tunnelUrl = token ? `${tunnel.url}/?token=${token}` : tunnel.url;
|
|
1518
1518
|
console.log(` ${c.green}Public URL (works from any browser):${c.reset}
|
|
1519
1519
|
${c.cyan}${c.bold}${tunnelUrl}${c.reset}
|
|
1520
1520
|
`);
|
|
@@ -1670,21 +1670,20 @@ async function cmdStart() {
|
|
|
1670
1670
|
// ── Route: Wizard reconfigure (--reconfigure, no --cli) ───────────────────
|
|
1671
1671
|
if (reconfig && hasProviderConfig) {
|
|
1672
1672
|
log('Resetting configuration for setup wizard...');
|
|
1673
|
-
//
|
|
1674
|
-
|
|
1673
|
+
// Write minimal .env with FORCE_SETUP_MODE — the entrypoint will handle
|
|
1674
|
+
// clearing internal config files. This is more reliable than running
|
|
1675
|
+
// `docker compose run` to delete files inside the volume, which can fail
|
|
1676
|
+
// silently due to permissions or Docker state issues.
|
|
1677
|
+
const minimalContent = `CLI_LANGUAGE=${existingEnv.CLI_LANGUAGE || 'en'}\nLIMBO_PORT=${PORT}\nFORCE_SETUP_MODE=true\n`;
|
|
1675
1678
|
fs.writeFileSync(ENV_FILE, minimalContent, { mode: 0o600 });
|
|
1676
1679
|
// Keep gateway token secret intact
|
|
1677
1680
|
ensureGatewayToken(existingEnv);
|
|
1678
|
-
// Clean config inside the Docker volume so entrypoint re-enters setup mode
|
|
1679
|
-
try {
|
|
1680
|
-
runDockerCompose(['run', '--rm', '--no-deps', '--entrypoint', 'sh', 'limbo',
|
|
1681
|
-
'-c', 'rm -f /data/config/.env /home/limbo/.zeroclaw/config.toml'], { stdio: 'pipe' });
|
|
1682
|
-
} catch {}
|
|
1683
1681
|
}
|
|
1684
1682
|
|
|
1685
1683
|
// ── Route: Wizard (default for fresh install or wizard reconfigure) ───────
|
|
1686
1684
|
log('Starting Limbo with setup wizard...');
|
|
1687
|
-
if (!alreadyHasEnv
|
|
1685
|
+
if (!alreadyHasEnv && !reconfig) {
|
|
1686
|
+
// Fresh install only — reconfigure already wrote its own .env above
|
|
1688
1687
|
writeMinimalEnv();
|
|
1689
1688
|
}
|
|
1690
1689
|
|
|
@@ -1711,7 +1710,20 @@ async function cmdStart() {
|
|
|
1711
1710
|
// Always show the wizard URL with tunnel/SSH info, even if we couldn't
|
|
1712
1711
|
// extract the token-authenticated URL from logs.
|
|
1713
1712
|
const displayUrl = wizardUrl || `http://127.0.0.1:${PORT}`;
|
|
1713
|
+
if (!wizardUrl) {
|
|
1714
|
+
warn('Could not extract setup token from container logs. The wizard may need a moment to start.');
|
|
1715
|
+
warn(`If the URL below doesn't work, try: ${c.cyan}limbo logs${c.reset} to check container status.`);
|
|
1716
|
+
}
|
|
1714
1717
|
printWizardUrl(displayUrl, tunnel);
|
|
1718
|
+
|
|
1719
|
+
// Remove FORCE_SETUP_MODE from .env so the container doesn't re-enter setup
|
|
1720
|
+
// mode on restart after the wizard completes. The entrypoint uses a marker
|
|
1721
|
+
// file as a safety net, but cleaning the env is the primary mechanism.
|
|
1722
|
+
try {
|
|
1723
|
+
const envContent = fs.readFileSync(ENV_FILE, 'utf8');
|
|
1724
|
+
const cleaned = envContent.replace(/^FORCE_SETUP_MODE=.*\n?/m, '');
|
|
1725
|
+
if (cleaned !== envContent) fs.writeFileSync(ENV_FILE, cleaned, { mode: 0o600 });
|
|
1726
|
+
} catch {}
|
|
1715
1727
|
}
|
|
1716
1728
|
|
|
1717
1729
|
// Shared path for headless, CLI-prompt, and existing-config routes
|
|
@@ -1770,20 +1782,40 @@ function selfUpdateCli() {
|
|
|
1770
1782
|
(lat[0] === cur[0] && lat[1] === cur[1] && lat[2] > cur[2]);
|
|
1771
1783
|
if (!isNewer) return;
|
|
1772
1784
|
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1785
|
+
const isGlobal = !process.argv[1].includes('npx') && !process.argv[1].includes('node_modules/.cache');
|
|
1786
|
+
|
|
1787
|
+
if (isGlobal) {
|
|
1788
|
+
log(`Updating CLI: ${pkg.version} → ${latest}...`);
|
|
1789
|
+
execSync('npm install -g limbo-ai@latest', { stdio: 'inherit', timeout: 60000 });
|
|
1790
|
+
ok(`CLI updated to ${latest}.`);
|
|
1791
|
+
} else {
|
|
1792
|
+
// npx served a stale cached version — clear it
|
|
1793
|
+
warn(`CLI is outdated (${pkg.version} → ${latest}). npx served a cached version.`);
|
|
1794
|
+
try {
|
|
1795
|
+
const npxCacheBase = path.join(os.homedir(), '.npm', '_npx');
|
|
1796
|
+
if (fs.existsSync(npxCacheBase)) {
|
|
1797
|
+
for (const entry of fs.readdirSync(npxCacheBase)) {
|
|
1798
|
+
const pkgPath = path.join(npxCacheBase, entry, 'node_modules', 'limbo-ai');
|
|
1799
|
+
if (fs.existsSync(pkgPath)) {
|
|
1800
|
+
fs.rmSync(path.join(npxCacheBase, entry), { recursive: true, force: true });
|
|
1801
|
+
log('Cleared stale npx cache.');
|
|
1802
|
+
break;
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
} catch {}
|
|
1807
|
+
log(`Re-run: ${c.cyan}npx limbo-ai@latest update${c.reset}`);
|
|
1808
|
+
}
|
|
1776
1809
|
} catch {
|
|
1777
|
-
warn('Could not
|
|
1810
|
+
warn('Could not check for CLI updates. Run: npm install -g limbo-ai@latest');
|
|
1778
1811
|
}
|
|
1779
1812
|
}
|
|
1780
1813
|
|
|
1781
1814
|
function cmdUpdate() {
|
|
1782
1815
|
if (!fs.existsSync(COMPOSE_FILE)) die(t('en', 'installMissing'));
|
|
1783
1816
|
|
|
1784
|
-
//
|
|
1785
|
-
|
|
1786
|
-
if (isGlobal) selfUpdateCli();
|
|
1817
|
+
// Always attempt CLI self-update, regardless of install method
|
|
1818
|
+
selfUpdateCli();
|
|
1787
1819
|
|
|
1788
1820
|
// Patch image tag to :latest in existing compose files (handles upgrades from pinned tags)
|
|
1789
1821
|
let compose = fs.readFileSync(COMPOSE_FILE, 'utf8');
|
|
@@ -1801,6 +1833,10 @@ function cmdUpdate() {
|
|
|
1801
1833
|
run(`docker compose -f "${COMPOSE_FILE}" pull -q`);
|
|
1802
1834
|
log('Restarting...');
|
|
1803
1835
|
run(`docker compose -f "${COMPOSE_FILE}" up -d --remove-orphans`);
|
|
1836
|
+
|
|
1837
|
+
// Clear update-check cache so the banner doesn't persist after a successful update
|
|
1838
|
+
try { fs.unlinkSync(UPDATE_CHECK_FILE); } catch {}
|
|
1839
|
+
|
|
1804
1840
|
ok('Updated and restarted.');
|
|
1805
1841
|
}
|
|
1806
1842
|
|