prior-cli 1.7.13 → 1.7.14

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.
Files changed (2) hide show
  1. package/bin/prior.js +115 -0
  2. package/package.json +1 -1
package/bin/prior.js CHANGED
@@ -15,6 +15,36 @@ const { renderMarkdown } = require('../lib/render');
15
15
  const { getToken, getUsername, saveAuth, clearAuth } = require('../lib/config');
16
16
  const { runAgent, CONFIRM_TOOLS } = require('../lib/agent');
17
17
 
18
+ // ── Packaged-executable detection + self-update support ─────────
19
+ // True when running as a bundled single-file binary (pkg) rather than via Node+npm.
20
+ const _execBase = path.basename(process.execPath).toLowerCase();
21
+ const IS_EXE = !!process.pkg || (_execBase !== 'node.exe' && _execBase !== 'node');
22
+ const GH_REPO = 'PriorNetwork/prior-cli';
23
+
24
+ // Best-effort cleanup of a leftover *.old.exe from a previous self-update.
25
+ if (IS_EXE) {
26
+ try {
27
+ const oldExe = process.execPath.replace(/\.exe$/i, '') + '.old.exe';
28
+ if (fs.existsSync(oldExe)) fs.unlinkSync(oldExe);
29
+ } catch { /* still locked from last run — retry next launch */ }
30
+ }
31
+
32
+ // Download the latest release exe and swap it in (Windows lets us rename a
33
+ // running exe, so: current → .old, downloaded → current; .old is deleted next launch).
34
+ async function selfUpdateExe(assetUrl) {
35
+ const _fetch = require('node-fetch');
36
+ const exePath = process.execPath;
37
+ const stem = exePath.replace(/\.exe$/i, '');
38
+ const tmp = stem + '.new.exe';
39
+ const old = stem + '.old.exe';
40
+ const res = await _fetch(assetUrl, { timeout: 180000, redirect: 'follow', headers: { 'User-Agent': 'prior-cli' } });
41
+ if (!res.ok) throw new Error(`download HTTP ${res.status}`);
42
+ fs.writeFileSync(tmp, Buffer.from(await res.arrayBuffer()));
43
+ try { if (fs.existsSync(old)) fs.unlinkSync(old); } catch {}
44
+ fs.renameSync(exePath, old); // rename the running exe out of the way
45
+ fs.renameSync(tmp, exePath); // move the new build into place
46
+ }
47
+
18
48
  function decodeToken(token) {
19
49
  try {
20
50
  const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
@@ -1649,6 +1679,49 @@ Keep it under 350 words. Write prior.md now.`;
1649
1679
  console.log('');
1650
1680
  process.stdout.write(c.dim(' Checking for updates…'));
1651
1681
  const _fetch = require('node-fetch');
1682
+
1683
+ // ── Standalone exe → self-update from GitHub Releases ──
1684
+ if (IS_EXE) {
1685
+ let _rel;
1686
+ try {
1687
+ const _r = await _fetch(`https://api.github.com/repos/${GH_REPO}/releases/latest`,
1688
+ { timeout: 8000, headers: { 'User-Agent': 'prior-cli', Accept: 'application/vnd.github+json' } });
1689
+ if (!_r.ok) throw new Error(`HTTP ${_r.status}`);
1690
+ _rel = await _r.json();
1691
+ } catch (err) {
1692
+ process.stdout.clearLine(0); process.stdout.cursorTo(0);
1693
+ console.log(c.err(` ✗ Could not reach GitHub Releases: ${err.message}\n`));
1694
+ return loop();
1695
+ }
1696
+ const _ghLatest = (_rel.tag_name || '').replace(/^v/, '');
1697
+ process.stdout.clearLine(0); process.stdout.cursorTo(0);
1698
+ if (!_ghLatest || _ghLatest === version) {
1699
+ console.log(c.ok(' ✓ Already up to date ') + c.muted(`v${version}\n`));
1700
+ return loop();
1701
+ }
1702
+ const _asset = (_rel.assets || []).find(a => /prior.*\.exe$/i.test(a.name));
1703
+ if (!_asset) {
1704
+ console.log(c.err(' ✗ Latest release has no .exe asset'));
1705
+ console.log(c.muted(` Get it manually: https://github.com/${GH_REPO}/releases/latest\n`));
1706
+ return loop();
1707
+ }
1708
+ console.log(` ${c.muted('Current :')} ${c.white(`v${version}`)}`);
1709
+ console.log(` ${c.muted('Latest :')} ${c.bold(`v${_ghLatest}`)}`);
1710
+ console.log('');
1711
+ process.stdout.write(c.dim(' Downloading update…'));
1712
+ try {
1713
+ await selfUpdateExe(_asset.browser_download_url);
1714
+ process.stdout.clearLine(0); process.stdout.cursorTo(0);
1715
+ console.log(c.ok(` ✓ Updated to v${_ghLatest} `) + c.muted('restart prior to apply\n'));
1716
+ } catch (err) {
1717
+ process.stdout.clearLine(0); process.stdout.cursorTo(0);
1718
+ console.log(c.err(` ✗ Update failed: ${err.message}`));
1719
+ console.log(c.muted(` Download manually: https://github.com/${GH_REPO}/releases/latest\n`));
1720
+ }
1721
+ return loop();
1722
+ }
1723
+
1724
+ // ── npm install → update via npm ──────────────────────
1652
1725
  let _latest;
1653
1726
  try {
1654
1727
  const _res = await _fetch('https://registry.npmjs.org/prior-cli/latest', { timeout: 8000 });
@@ -2285,6 +2358,48 @@ program
2285
2358
  process.stdout.write(c.dim(' Checking for updates…'));
2286
2359
 
2287
2360
  const fetch = require('node-fetch');
2361
+
2362
+ // Standalone exe → self-update from GitHub Releases
2363
+ if (IS_EXE) {
2364
+ let rel;
2365
+ try {
2366
+ const r = await fetch(`https://api.github.com/repos/${GH_REPO}/releases/latest`,
2367
+ { timeout: 8000, headers: { 'User-Agent': 'prior-cli', Accept: 'application/vnd.github+json' } });
2368
+ if (!r.ok) throw new Error(`HTTP ${r.status}`);
2369
+ rel = await r.json();
2370
+ } catch (err) {
2371
+ clearLine();
2372
+ console.error(c.err(` ✗ Could not reach GitHub Releases: ${err.message}\n`));
2373
+ return;
2374
+ }
2375
+ const ghLatest = (rel.tag_name || '').replace(/^v/, '');
2376
+ clearLine();
2377
+ if (!ghLatest || ghLatest === version) {
2378
+ console.log(c.ok(' ✓ Already up to date ') + c.muted(`v${version}\n`));
2379
+ return;
2380
+ }
2381
+ const asset = (rel.assets || []).find(a => /prior.*\.exe$/i.test(a.name));
2382
+ if (!asset) {
2383
+ console.error(c.err(' ✗ Latest release has no .exe asset'));
2384
+ console.error(c.muted(` Get it manually: https://github.com/${GH_REPO}/releases/latest\n`));
2385
+ return;
2386
+ }
2387
+ console.log(` ${c.muted('Current :')} ${c.white(`v${version}`)}`);
2388
+ console.log(` ${c.muted('Latest :')} ${c.bold(`v${ghLatest}`)}`);
2389
+ console.log('');
2390
+ process.stdout.write(c.dim(' Downloading update…'));
2391
+ try {
2392
+ await selfUpdateExe(asset.browser_download_url);
2393
+ clearLine();
2394
+ console.log(c.ok(` ✓ Updated to v${ghLatest} `) + c.muted('restart prior to apply\n'));
2395
+ } catch (err) {
2396
+ clearLine();
2397
+ console.error(c.err(` ✗ Update failed: ${err.message}`));
2398
+ console.error(c.muted(` Download manually: https://github.com/${GH_REPO}/releases/latest\n`));
2399
+ }
2400
+ return;
2401
+ }
2402
+
2288
2403
  let latest;
2289
2404
  try {
2290
2405
  const res = await fetch('https://registry.npmjs.org/prior-cli/latest', { timeout: 8000 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prior-cli",
3
- "version": "1.7.13",
3
+ "version": "1.7.14",
4
4
  "description": "Prior Network AI — command-line interface",
5
5
  "author": "Prior Network",
6
6
  "homepage": "https://priornetwork.com",