@pi-unipi/updater 2.1.3 → 2.2.1
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": "@pi-unipi/updater",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Auto-updater, changelog browser, and readme browser for Unipi — checks npm registry, renders CHANGELOG.md and README.md files in TUI overlays",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "2.
|
|
36
|
+
"@pi-unipi/core": "2.2.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-coding-agent": "^0.80.0",
|
package/src/changelog.ts
CHANGED
|
@@ -6,8 +6,35 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { existsSync, readFileSync } from "fs";
|
|
9
|
+
import { dirname, join } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { findPackageRoot } from "@pi-unipi/core";
|
|
12
|
+
import { isNewerVersion } from "./version.js";
|
|
9
13
|
import type { ChangelogEntry } from "../types.js";
|
|
10
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Locate the shipped CHANGELOG.md.
|
|
17
|
+
*
|
|
18
|
+
* Resolving from `process.cwd()` only works when pi happens to be running
|
|
19
|
+
* inside the UniPi checkout — for everyone else the update prompt and
|
|
20
|
+
* `/unipi:changelog` came up empty. Resolve from this module's own location
|
|
21
|
+
* instead, and fall back to the working directory so a repo checkout still
|
|
22
|
+
* shows its local (possibly unreleased) notes.
|
|
23
|
+
*/
|
|
24
|
+
export function resolveChangelogPath(): string {
|
|
25
|
+
try {
|
|
26
|
+
const dir = dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
const root = findPackageRoot(dir, "@pi-unipi/unipi");
|
|
28
|
+
if (root) {
|
|
29
|
+
const packaged = join(root, "CHANGELOG.md");
|
|
30
|
+
if (existsSync(packaged)) return packaged;
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// Fall through to the working directory.
|
|
34
|
+
}
|
|
35
|
+
return join(process.cwd(), "CHANGELOG.md");
|
|
36
|
+
}
|
|
37
|
+
|
|
11
38
|
/** Regex for version headers: ## [x.y.z] — YYYY-MM-DD or ## [Unreleased] */
|
|
12
39
|
const VERSION_HEADER_RE = /^## \[(.+?)\](?:\s*[-—–]\s*(.+))?$/;
|
|
13
40
|
|
|
@@ -119,7 +146,11 @@ export function getNewerVersions(
|
|
|
119
146
|
result.push(entry);
|
|
120
147
|
continue;
|
|
121
148
|
}
|
|
122
|
-
|
|
149
|
+
// Compare rather than test for equality. Stopping only on an exact match
|
|
150
|
+
// meant that when the installed version was absent from the changelog
|
|
151
|
+
// (a local build, a yanked release, or simply a newer version) every
|
|
152
|
+
// historical entry was reported as "new".
|
|
153
|
+
if (!isNewerVersion(entry.version, installedVersion)) break;
|
|
123
154
|
result.push(entry);
|
|
124
155
|
}
|
|
125
156
|
return result;
|
|
@@ -9,9 +9,9 @@ import { existsSync } from "fs";
|
|
|
9
9
|
import { join } from "path";
|
|
10
10
|
import { Key, matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
11
11
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
12
|
-
import { parseChangelog } from "../changelog.js";
|
|
12
|
+
import { parseChangelog, resolveChangelogPath } from "../changelog.js";
|
|
13
13
|
import { renderMarkdown } from "../markdown.js";
|
|
14
|
-
import { getInstalledPackageVersion } from "@pi-unipi/core";
|
|
14
|
+
import { getInstalledPackageVersion, boxInnerWidth } from "@pi-unipi/core";
|
|
15
15
|
import type { ChangelogEntry } from "../../types.js";
|
|
16
16
|
|
|
17
17
|
type View = "list" | "detail";
|
|
@@ -62,7 +62,7 @@ export function renderChangelogOverlay() {
|
|
|
62
62
|
let loaded = false;
|
|
63
63
|
const ensureLoaded = () => {
|
|
64
64
|
if (loaded) return;
|
|
65
|
-
const changelogPath =
|
|
65
|
+
const changelogPath = resolveChangelogPath();
|
|
66
66
|
if (existsSync(changelogPath)) {
|
|
67
67
|
state.entries = parseChangelog(changelogPath);
|
|
68
68
|
}
|
|
@@ -72,7 +72,7 @@ export function renderChangelogOverlay() {
|
|
|
72
72
|
const render = (width: number): string[] => {
|
|
73
73
|
ensureLoaded();
|
|
74
74
|
|
|
75
|
-
const innerWidth =
|
|
75
|
+
const innerWidth = boxInnerWidth(width);
|
|
76
76
|
const lines: string[] = [];
|
|
77
77
|
|
|
78
78
|
// ── Header ──────────────────────────────────────────────────────
|
|
@@ -12,6 +12,7 @@ import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
|
12
12
|
import { discoverReadmes, resolveReadmePath } from "../readme.js";
|
|
13
13
|
import { renderMarkdown } from "../markdown.js";
|
|
14
14
|
import type { ReadmeEntry } from "../../types.js";
|
|
15
|
+
import { boxInnerWidth } from "@pi-unipi/core";
|
|
15
16
|
|
|
16
17
|
type View = "list" | "content";
|
|
17
18
|
|
|
@@ -71,7 +72,7 @@ export function renderReadmeOverlay(params?: { openDirect?: string }) {
|
|
|
71
72
|
const render = (width: number): string[] => {
|
|
72
73
|
ensureLoaded();
|
|
73
74
|
|
|
74
|
-
const innerWidth =
|
|
75
|
+
const innerWidth = boxInnerWidth(width);
|
|
75
76
|
const lines: string[] = [];
|
|
76
77
|
|
|
77
78
|
// ── Header ──────────────────────────────────────────────────────
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
import { join } from "path";
|
|
10
10
|
import { Key, matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
11
11
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
12
|
-
import { parseChangelog, getNewerVersions } from "../changelog.js";
|
|
12
|
+
import { parseChangelog, getNewerVersions, resolveChangelogPath } from "../changelog.js";
|
|
13
13
|
import { renderMarkdown } from "../markdown.js";
|
|
14
14
|
import { installUpdate } from "../installer.js";
|
|
15
15
|
import { writeSkippedVersion } from "../cache.js";
|
|
16
16
|
import { loadConfig } from "../settings.js";
|
|
17
17
|
import type { ChangelogEntry, UpdateCheckResult } from "../../types.js";
|
|
18
|
+
import { boxInnerWidth } from "@pi-unipi/core";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Pad content to exact visible width.
|
|
@@ -50,7 +51,7 @@ export function renderUpdateOverlay(checkResult: UpdateCheckResult) {
|
|
|
50
51
|
|
|
51
52
|
// Load changelog for newer versions
|
|
52
53
|
let newerVersions: ChangelogEntry[] = [];
|
|
53
|
-
const changelogPath =
|
|
54
|
+
const changelogPath = resolveChangelogPath();
|
|
54
55
|
try {
|
|
55
56
|
const entries = parseChangelog(changelogPath);
|
|
56
57
|
newerVersions = getNewerVersions(entries, checkResult.currentVersion);
|
|
@@ -119,7 +120,7 @@ export function renderUpdateOverlay(checkResult: UpdateCheckResult) {
|
|
|
119
120
|
};
|
|
120
121
|
|
|
121
122
|
const render = (width: number): string[] => {
|
|
122
|
-
const innerWidth =
|
|
123
|
+
const innerWidth = boxInnerWidth(width);
|
|
123
124
|
const lines: string[] = [];
|
|
124
125
|
|
|
125
126
|
// ── Header ──────────────────────────────────────────────────────
|