kubeagent 0.1.9 → 0.1.10

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/dist/cli.js CHANGED
@@ -25,6 +25,7 @@ import { scanProjectDirectory, matchProjectsToWorkloads, bestMatches } from "./o
25
25
  import { scanCluster } from "./onboard/cluster-scan.js";
26
26
  import { formatProjectMarkdown } from "./onboard/code-scan.js";
27
27
  import { writeProjectKb, ensureKbDir } from "./kb/writer.js";
28
+ import { checkForUpdate } from "./update-notifier.js";
28
29
  const program = new Command();
29
30
  program
30
31
  .name("kubeagent")
@@ -462,3 +463,5 @@ program
462
463
  }
463
464
  });
464
465
  program.parse();
466
+ // Non-blocking update check — runs after command completes
467
+ checkForUpdate();
@@ -0,0 +1 @@
1
+ export declare function checkForUpdate(): Promise<void>;
@@ -0,0 +1,38 @@
1
+ import chalk from "chalk";
2
+ import { createRequire } from "node:module";
3
+ const require = createRequire(import.meta.url);
4
+ const { version: currentVersion } = require("../package.json");
5
+ const REGISTRY_URL = "https://registry.npmjs.org/kubeagent/latest";
6
+ function isNewer(latest, current) {
7
+ const parse = (v) => v.replace(/^v/, "").split(".").map(Number);
8
+ const [lMaj, lMin, lPatch] = parse(latest);
9
+ const [cMaj, cMin, cPatch] = parse(current);
10
+ if (lMaj !== cMaj)
11
+ return lMaj > cMaj;
12
+ if (lMin !== cMin)
13
+ return lMin > cMin;
14
+ return lPatch > cPatch;
15
+ }
16
+ export async function checkForUpdate() {
17
+ try {
18
+ const controller = new AbortController();
19
+ const timeout = setTimeout(() => controller.abort(), 3000);
20
+ const res = await fetch(REGISTRY_URL, { signal: controller.signal });
21
+ clearTimeout(timeout);
22
+ if (!res.ok)
23
+ return;
24
+ const data = (await res.json());
25
+ const latest = data.version;
26
+ if (!latest || !isNewer(latest, currentVersion))
27
+ return;
28
+ console.log("\n" +
29
+ chalk.yellow(` Update available: ${currentVersion} → ${latest}`) +
30
+ "\n" +
31
+ chalk.dim(" Run ") +
32
+ chalk.cyan("npm update -g kubeagent") +
33
+ chalk.dim(" to update\n"));
34
+ }
35
+ catch {
36
+ // Network errors, timeouts — silently ignore
37
+ }
38
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ // Mock chalk to return plain strings
3
+ vi.mock("chalk", () => {
4
+ const identity = (s) => s;
5
+ const handler = {
6
+ get: () => new Proxy(identity, handler),
7
+ apply: (_t, _this, args) => args[0],
8
+ };
9
+ return { default: new Proxy(identity, handler) };
10
+ });
11
+ describe("update-notifier", () => {
12
+ let originalFetch;
13
+ beforeEach(() => {
14
+ originalFetch = globalThis.fetch;
15
+ });
16
+ afterEach(() => {
17
+ globalThis.fetch = originalFetch;
18
+ vi.restoreAllMocks();
19
+ });
20
+ it("prints update message when newer version exists", async () => {
21
+ globalThis.fetch = vi.fn().mockResolvedValue({
22
+ ok: true,
23
+ json: () => Promise.resolve({ version: "99.0.0" }),
24
+ });
25
+ const spy = vi.spyOn(console, "log").mockImplementation(() => { });
26
+ const { checkForUpdate } = await import("./update-notifier.js");
27
+ await checkForUpdate();
28
+ expect(spy).toHaveBeenCalled();
29
+ const output = spy.mock.calls.map((c) => c.join(" ")).join("\n");
30
+ expect(output).toContain("Update available");
31
+ expect(output).toContain("99.0.0");
32
+ });
33
+ it("prints nothing when already up to date", async () => {
34
+ globalThis.fetch = vi.fn().mockResolvedValue({
35
+ ok: true,
36
+ json: () => Promise.resolve({ version: "0.0.1" }),
37
+ });
38
+ const spy = vi.spyOn(console, "log").mockImplementation(() => { });
39
+ const { checkForUpdate } = await import("./update-notifier.js");
40
+ await checkForUpdate();
41
+ expect(spy).not.toHaveBeenCalled();
42
+ });
43
+ it("prints nothing on network error", async () => {
44
+ globalThis.fetch = vi.fn().mockRejectedValue(new Error("offline"));
45
+ const spy = vi.spyOn(console, "log").mockImplementation(() => { });
46
+ const { checkForUpdate } = await import("./update-notifier.js");
47
+ await checkForUpdate();
48
+ expect(spy).not.toHaveBeenCalled();
49
+ });
50
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kubeagent",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "AI-powered Kubernetes management CLI",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",