noterai 0.1.2 → 0.1.3
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/noter.js +113 -2
- package/package.json +1 -2
- package/packages/client/dist/assets/index-0MZHpTJK.js +309 -0
- package/packages/client/dist/index.html +1 -1
- package/packages/server/dist/index.d.ts.map +1 -1
- package/packages/server/dist/index.js +12 -1
- package/packages/server/dist/index.js.map +1 -1
- package/packages/server/dist/persistence.js +1 -1
- package/packages/server/dist/persistence.js.map +1 -1
- package/bin/noter.js.map +0 -1
- package/packages/client/dist/assets/index-Cb3fyk6D.js +0 -264
package/bin/noter.js
CHANGED
|
@@ -11,9 +11,11 @@ import { loadConfig } from '../packages/server/dist/config.js';
|
|
|
11
11
|
import { resolveRepoContext } from '../packages/server/dist/repoContext.js';
|
|
12
12
|
import { stateManager } from '../packages/server/dist/stateManager.js';
|
|
13
13
|
import { execSync } from 'child_process';
|
|
14
|
-
import {
|
|
14
|
+
import { request } from 'node:https';
|
|
15
|
+
import { resolve, dirname, basename, join } from 'path';
|
|
16
|
+
import { homedir } from 'node:os';
|
|
15
17
|
import { fileURLToPath } from 'url';
|
|
16
|
-
import { existsSync, readFileSync } from 'fs';
|
|
18
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
17
19
|
const __filename = fileURLToPath(import.meta.url);
|
|
18
20
|
const __dirname = dirname(__filename);
|
|
19
21
|
const ROOT = resolve(__dirname, '..');
|
|
@@ -30,6 +32,106 @@ function getVersion() {
|
|
|
30
32
|
const pkg = JSON.parse(raw);
|
|
31
33
|
return pkg.version ?? '0.0.1';
|
|
32
34
|
}
|
|
35
|
+
/** Cache path for the npm update check so we don't hit the registry on every launch. */
|
|
36
|
+
const UPDATE_CACHE_DIR = process.env.NOTER_UPDATE_CACHE_DIR ?? join(homedir(), '.noter');
|
|
37
|
+
const UPDATE_CACHE_FILE = join(UPDATE_CACHE_DIR, 'update-check.json');
|
|
38
|
+
const UPDATE_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
39
|
+
const UPDATE_CHECK_TIMEOUT_MS = 2500;
|
|
40
|
+
const NPM_PACKAGE = 'noterai';
|
|
41
|
+
function readUpdateCache() {
|
|
42
|
+
try {
|
|
43
|
+
const raw = readFileSync(UPDATE_CACHE_FILE, 'utf-8');
|
|
44
|
+
const parsed = JSON.parse(raw);
|
|
45
|
+
if (typeof parsed.lastChecked === 'number') {
|
|
46
|
+
return { lastChecked: parsed.lastChecked, latestVersion: parsed.latestVersion ?? null };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// ignore missing/corrupt cache
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function writeUpdateCache(cache) {
|
|
55
|
+
try {
|
|
56
|
+
if (!existsSync(UPDATE_CACHE_DIR))
|
|
57
|
+
mkdirSync(UPDATE_CACHE_DIR, { recursive: true });
|
|
58
|
+
writeFileSync(UPDATE_CACHE_FILE, JSON.stringify(cache));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// cache is best-effort; never block launch on it
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Fetch latest published version from the npm registry. Resolves to null on any error. */
|
|
65
|
+
function fetchLatestVersion() {
|
|
66
|
+
return new Promise((resolvePromise) => {
|
|
67
|
+
let settled = false;
|
|
68
|
+
const finish = (v) => {
|
|
69
|
+
if (!settled) {
|
|
70
|
+
settled = true;
|
|
71
|
+
resolvePromise(v);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const timer = setTimeout(() => finish(null), UPDATE_CHECK_TIMEOUT_MS);
|
|
75
|
+
try {
|
|
76
|
+
const req = request({
|
|
77
|
+
hostname: 'registry.npmjs.org',
|
|
78
|
+
path: `/${NPM_PACKAGE}/latest`,
|
|
79
|
+
method: 'GET',
|
|
80
|
+
headers: { 'accept': 'application/json' },
|
|
81
|
+
}, (res) => {
|
|
82
|
+
let body = '';
|
|
83
|
+
res.setEncoding('utf-8');
|
|
84
|
+
res.on('data', (chunk) => { body += chunk; });
|
|
85
|
+
res.on('end', () => {
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
try {
|
|
88
|
+
const data = JSON.parse(body);
|
|
89
|
+
finish(typeof data.version === 'string' ? data.version : null);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
finish(null);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
req.on('error', () => { clearTimeout(timer); finish(null); });
|
|
97
|
+
req.end();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
clearTimeout(timer);
|
|
101
|
+
finish(null);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/** Simple semver "is b newer than a" comparator (major.minor.patch, no pre-release). */
|
|
106
|
+
function isNewerVersion(current, latest) {
|
|
107
|
+
const parse = (v) => v.split('-')[0].split('.').map((n) => parseInt(n, 10) || 0);
|
|
108
|
+
const [a0, a1, a2] = parse(current);
|
|
109
|
+
const [b0, b1, b2] = parse(latest);
|
|
110
|
+
if (b0 !== a0)
|
|
111
|
+
return b0 > a0;
|
|
112
|
+
if (b1 !== a1)
|
|
113
|
+
return b1 > a1;
|
|
114
|
+
return b2 > a2;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Non-blocking launch-time update check. Checks the npm registry at most once per
|
|
118
|
+
* UPDATE_CACHE_TTL_MS and prints an upgrade hint if a newer version of `noterai`
|
|
119
|
+
* is published. Never throws or blocks startup.
|
|
120
|
+
*/
|
|
121
|
+
async function checkForUpdate() {
|
|
122
|
+
const current = getVersion();
|
|
123
|
+
const cache = readUpdateCache();
|
|
124
|
+
let latest = cache?.latestVersion ?? null;
|
|
125
|
+
const stale = !cache || Date.now() - cache.lastChecked > UPDATE_CACHE_TTL_MS;
|
|
126
|
+
if (stale) {
|
|
127
|
+
latest = await fetchLatestVersion();
|
|
128
|
+
writeUpdateCache({ lastChecked: Date.now(), latestVersion: latest });
|
|
129
|
+
}
|
|
130
|
+
if (latest && isNewerVersion(current, latest)) {
|
|
131
|
+
console.log(`update noterai v${latest} available (you have v${current})`);
|
|
132
|
+
console.log(' run `npm install -g noterai` to upgrade');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
33
135
|
function showHelp() {
|
|
34
136
|
const version = getVersion();
|
|
35
137
|
const help = `
|
|
@@ -46,6 +148,12 @@ Commands:
|
|
|
46
148
|
help Show this help message
|
|
47
149
|
version Print the version number
|
|
48
150
|
|
|
151
|
+
Update Behavior:
|
|
152
|
+
On launch, noter checks the npm registry (at most once per 24h) for a newer
|
|
153
|
+
"noterai" release and prints an upgrade hint. Disable by deleting
|
|
154
|
+
~/.noter/update-check.json or setting NOTER_UPDATE_CACHE_DIR. To upgrade:
|
|
155
|
+
npm install -g noterai
|
|
156
|
+
|
|
49
157
|
Options:
|
|
50
158
|
serve --open Open the browser after starting the server
|
|
51
159
|
serve --no-open Do not open the browser (default for 'serve')
|
|
@@ -182,6 +290,9 @@ async function serve(openBrowser) {
|
|
|
182
290
|
console.log(`port ${portLine}`);
|
|
183
291
|
console.log(divider);
|
|
184
292
|
console.log('ready. press ctrl+c to stop.');
|
|
293
|
+
// Non-blocking update check — prints an upgrade hint if a newer noterai is on npm.
|
|
294
|
+
// Fire-and-forget so it never delays startup; output may land just after "ready".
|
|
295
|
+
void checkForUpdate();
|
|
185
296
|
if (openBrowser) {
|
|
186
297
|
const url = `http://localhost:${resolvedPort}`;
|
|
187
298
|
const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noterai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Locally-run, browser-based AI agent dashboard for developers using LLM coding assistants",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"bin/noter.js",
|
|
31
|
-
"bin/noter.js.map",
|
|
32
31
|
"packages/client/dist",
|
|
33
32
|
"packages/server/dist",
|
|
34
33
|
"packages/shared/dist",
|