@bramblex/codex-workbench 0.1.16 → 0.1.17
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bramblex/codex-workbench",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Terminal workbench for browsing and managing local and SSH Codex sessions.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"LICENSE"
|
|
34
34
|
],
|
|
35
35
|
"scripts": {
|
|
36
|
-
"test": "node -e \"const fs=require('fs'),{spawnSync}=require('child_process');function files(d){return fs.readdirSync(d,{withFileTypes:true}).flatMap(e=>e.isDirectory()?files(d+'/'+e.name):e.name.endsWith('.js')?[d+'/'+e.name]:[])}for(const f of files('src')){const r=spawnSync(process.execPath,['--check',f],{stdio:'inherit'});if(r.status)process.exit(r.status)}\" && node --check bin/codex-workbench && node --check scripts/pty-codex.js && node --check scripts/tui-pty-codex.js && node --check scripts/blessed-xterm-codex.js && node test/codex-bin.test.js && node test/blessed-compat.test.js && node test/config-paths.test.js && node test/session-sources.test.js && node test/workbench-config.test.js && node test/smoke.js",
|
|
36
|
+
"test": "node -e \"const fs=require('fs'),{spawnSync}=require('child_process');function files(d){return fs.readdirSync(d,{withFileTypes:true}).flatMap(e=>e.isDirectory()?files(d+'/'+e.name):e.name.endsWith('.js')?[d+'/'+e.name]:[])}for(const f of files('src')){const r=spawnSync(process.execPath,['--check',f],{stdio:'inherit'});if(r.status)process.exit(r.status)}\" && node --check bin/codex-workbench && node --check scripts/pty-codex.js && node --check scripts/tui-pty-codex.js && node --check scripts/blessed-xterm-codex.js && node test/codex-bin.test.js && node test/blessed-compat.test.js && node test/config-paths.test.js && node test/session-sources.test.js && node test/update-checker.test.js && node test/workbench-config.test.js && node test/smoke.js",
|
|
37
37
|
"pty:codex": "node scripts/pty-codex.js",
|
|
38
38
|
"tui:codex": "node scripts/tui-pty-codex.js",
|
|
39
39
|
"xterm:codex": "node scripts/blessed-xterm-codex.js"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const pkg = require('../../package.json');
|
|
5
|
+
|
|
6
|
+
const REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(pkg.name).replace(/^%40/, '@')}/latest`;
|
|
7
|
+
|
|
8
|
+
function parseVersion(version) {
|
|
9
|
+
return String(version || '')
|
|
10
|
+
.replace(/^v/, '')
|
|
11
|
+
.split('.')
|
|
12
|
+
.map((part) => Number.parseInt(part, 10))
|
|
13
|
+
.map((part) => (Number.isFinite(part) ? part : 0));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function compareVersions(a, b) {
|
|
17
|
+
const left = parseVersion(a);
|
|
18
|
+
const right = parseVersion(b);
|
|
19
|
+
const length = Math.max(left.length, right.length);
|
|
20
|
+
for (let i = 0; i < length; i += 1) {
|
|
21
|
+
const delta = (left[i] || 0) - (right[i] || 0);
|
|
22
|
+
if (delta !== 0) return delta;
|
|
23
|
+
}
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function fetchLatestVersion(timeoutMs = 1500) {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
const req = https.get(REGISTRY_URL, {
|
|
30
|
+
headers: { accept: 'application/json', 'user-agent': `${pkg.name}/${pkg.version}` },
|
|
31
|
+
timeout: timeoutMs,
|
|
32
|
+
}, (res) => {
|
|
33
|
+
if (res.statusCode !== 200) {
|
|
34
|
+
res.resume();
|
|
35
|
+
resolve(null);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
let body = '';
|
|
39
|
+
res.setEncoding('utf8');
|
|
40
|
+
res.on('data', (chunk) => { body += chunk; });
|
|
41
|
+
res.on('end', () => {
|
|
42
|
+
try {
|
|
43
|
+
const payload = JSON.parse(body);
|
|
44
|
+
resolve(payload && payload.version ? String(payload.version) : null);
|
|
45
|
+
} catch {
|
|
46
|
+
resolve(null);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
req.on('timeout', () => {
|
|
52
|
+
req.destroy();
|
|
53
|
+
resolve(null);
|
|
54
|
+
});
|
|
55
|
+
req.on('error', () => resolve(null));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function checkForUpdate(currentVersion = pkg.version) {
|
|
60
|
+
const latestVersion = await fetchLatestVersion();
|
|
61
|
+
if (!latestVersion || compareVersions(latestVersion, currentVersion) <= 0) return null;
|
|
62
|
+
return {
|
|
63
|
+
currentVersion,
|
|
64
|
+
latestVersion,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = {
|
|
69
|
+
checkForUpdate,
|
|
70
|
+
compareVersions,
|
|
71
|
+
fetchLatestVersion,
|
|
72
|
+
};
|
package/src/ui/workbench.js
CHANGED
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
updateSourceMetadata,
|
|
22
22
|
} = require('../services/session-sources');
|
|
23
23
|
const { usableCwd } = require('../services/codex-runner');
|
|
24
|
+
const { checkForUpdate } = require('../services/update-checker');
|
|
24
25
|
const { createDirectoryPicker } = require('./directory-picker');
|
|
25
26
|
|
|
26
27
|
async function runWorkbench() {
|
|
@@ -42,6 +43,7 @@ async function runWorkbench() {
|
|
|
42
43
|
let activePanel = 'projects';
|
|
43
44
|
let remoteLoadId = 0;
|
|
44
45
|
let remoteLoading = false;
|
|
46
|
+
let updateInfo = null;
|
|
45
47
|
let closed = false;
|
|
46
48
|
|
|
47
49
|
const screen = blessed.screen({
|
|
@@ -466,7 +468,8 @@ async function runWorkbench() {
|
|
|
466
468
|
const render = () => {
|
|
467
469
|
applyLayout();
|
|
468
470
|
const visible = currentSessions();
|
|
469
|
-
|
|
471
|
+
const updateText = updateInfo ? ` Update available: v${updateInfo.latestVersion}` : '';
|
|
472
|
+
header.setContent(` ${appTitle}${updateText}\n ${visible.length}/${sessions.length} visible ${groupDisplayName(currentGroup())}`);
|
|
470
473
|
detailBox.setContent(detailContent(selectedSession()));
|
|
471
474
|
updateFocusStyles();
|
|
472
475
|
screen.render();
|
|
@@ -891,6 +894,11 @@ async function runWorkbench() {
|
|
|
891
894
|
projectsList.focus();
|
|
892
895
|
render();
|
|
893
896
|
startRemoteReload(true);
|
|
897
|
+
checkForUpdate(pkg.version).then((nextUpdateInfo) => {
|
|
898
|
+
if (closed || !nextUpdateInfo) return;
|
|
899
|
+
updateInfo = nextUpdateInfo;
|
|
900
|
+
render();
|
|
901
|
+
});
|
|
894
902
|
|
|
895
903
|
return new Promise(() => {});
|
|
896
904
|
}
|