@koalaauto/agentchannel 3.0.0 → 3.1.0

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.
@@ -71,5 +71,7 @@ export declare function shadowFix(other: {
71
71
  }, ours: {
72
72
  path: string;
73
73
  } | undefined, self: string): string;
74
+ /** True when version a is newer than b (x.y.z, a release beats its own prereleases; prerelease parts compared by number when numeric). */
75
+ export declare function newerVersion(a: string, b: string): boolean;
74
76
  /** Grouped report: hub, front door (only when there is one), key, this machine; each problem with a one-line fix. */
75
77
  export declare function formatDoctor(checks: DoctorCheck[]): string;
@@ -174,6 +174,33 @@ export async function runDoctor(o) {
174
174
  add('hub login', 'fail', `the hub refused the key: ${why}`, 'key', NEW_LINE_FIX);
175
175
  }
176
176
  }
177
+ // which release the hub runs (public; through the front door with the stored pass)
178
+ if (reachable) {
179
+ try {
180
+ const r = await fetchFn(`${cfg.hub}/api/ach/auth/config`, { method: 'GET', headers: { accept: 'application/json', ...pass } });
181
+ const c = r.ok ? await r.json() : null;
182
+ if (c && typeof c.version === 'string')
183
+ add('hub version', 'info', `AgentChannel ${c.version}${c.commit ? ` (${c.commit})` : ''}`, 'hub');
184
+ }
185
+ catch {
186
+ /* informational only */
187
+ }
188
+ }
189
+ }
190
+ // a newer CLI on npm (the release line this CLI is on: `latest` for a release, `next` for a prerelease)
191
+ try {
192
+ const fetchFn = o.fetch ?? ((u, i) => fetch(u, i));
193
+ const r = await fetchFn(`https://registry.npmjs.org/-/package/${PKG_NAME.replace('/', '%2f')}/dist-tags`, { method: 'GET', headers: { accept: 'application/json' } });
194
+ const tags = r.ok ? await r.json() : null;
195
+ const newest = tags && typeof tags[VERSION.includes('-') ? 'next' : 'latest'] === 'string' ? tags[VERSION.includes('-') ? 'next' : 'latest'] : '';
196
+ if (newest && newerVersion(newest, VERSION)) {
197
+ add('update', 'warn', `${PKG_NAME} ${newest} is out (this is ${VERSION})`, 'machine', `run the join line from the panel again (Settings > Agents > New join command), or: npm install -g ${PKG_NAME}@${VERSION.includes('-') ? 'next' : 'latest'}`);
198
+ }
199
+ else if (newest)
200
+ add('update', 'ok', `${VERSION} is the newest ${PKG_NAME}`);
201
+ }
202
+ catch {
203
+ /* offline: nothing to say */
177
204
  }
178
205
  // Which `ach` runs
179
206
  const self = o.self ?? thisCliPath();
@@ -354,6 +381,31 @@ const SECTIONS = [
354
381
  { id: 'key', title: 'Key' },
355
382
  { id: 'machine', title: 'This machine' },
356
383
  ];
384
+ /** True when version a is newer than b (x.y.z, a release beats its own prereleases; prerelease parts compared by number when numeric). */
385
+ export function newerVersion(a, b) {
386
+ const parse = (v) => {
387
+ const [core, pre = ''] = v.split('-', 2);
388
+ return { n: core.split('.').map((x) => Number(x) || 0), pre: pre ? pre.split('.') : [] };
389
+ };
390
+ const x = parse(a);
391
+ const y = parse(b);
392
+ for (let i = 0; i < 3; i++)
393
+ if (x.n[i] !== y.n[i])
394
+ return x.n[i] > y.n[i];
395
+ if (!x.pre.length || !y.pre.length)
396
+ return !x.pre.length && !!y.pre.length;
397
+ for (let i = 0; i < Math.max(x.pre.length, y.pre.length); i++) {
398
+ const p = x.pre[i];
399
+ const q = y.pre[i];
400
+ if (p === undefined)
401
+ return false;
402
+ if (q === undefined)
403
+ return true;
404
+ if (p !== q)
405
+ return /^\d+$/.test(p) && /^\d+$/.test(q) ? Number(p) > Number(q) : p > q;
406
+ }
407
+ return false;
408
+ }
357
409
  /** Grouped report: hub, front door (only when there is one), key, this machine; each problem with a one-line fix. */
358
410
  export function formatDoctor(checks) {
359
411
  const mark = { ok: '[ok] ', warn: '[warn]', fail: '[FAIL]', info: '[info]' };
@@ -1,3 +1,3 @@
1
- export declare const VERSION = "3.0.0";
1
+ export declare const VERSION = "3.1.0";
2
2
  /** The npm package (scripts/release.mjs keeps it and VERSION in step with package.json). */
3
3
  export declare const PKG_NAME = "@koalaauto/agentchannel";
@@ -1,3 +1,3 @@
1
- export const VERSION = '3.0.0';
1
+ export const VERSION = '3.1.0';
2
2
  /** The npm package (scripts/release.mjs keeps it and VERSION in step with package.json). */
3
3
  export const PKG_NAME = '@koalaauto/agentchannel';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koalaauto/agentchannel",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Hand work between your team's agents (Claude Code, Codex) and follow it in one panel: the ach CLI, MCP server and runner for AgentChannel v2",
5
5
  "keywords": [
6
6
  "agentchannel",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "scripts": {
33
33
  "build": "tsc -p tsconfig.json",
34
- "test": "npm run build && node scripts/test-sandbox.mjs node --test dist/test/*.test.js",
34
+ "test": "npm run build && node scripts/test-sandbox.mjs node --test dist/test/*.test.js && node --test scripts/semver.test.mjs",
35
35
  "test:e2e": "npm run build && node scripts/test-sandbox.mjs node --test --test-concurrency=4 test-e2e/*.test.mjs",
36
36
  "prepack": "npm run build"
37
37
  },