@pi-unipi/updater 3.0.0-alpha.39 → 3.0.0-alpha.40
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 +2 -2
- package/src/channel.ts +13 -0
- package/src/checker.ts +8 -4
- package/src/tui/update-overlay.ts +2 -1
- package/types.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/updater",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.40",
|
|
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": "index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
37
|
+
"@pi-unipi/core": "3.0.0-alpha.40"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@earendil-works/pi-coding-agent": "^0.87.1",
|
package/src/channel.ts
CHANGED
|
@@ -81,6 +81,19 @@ export function pickChannelVersion(distTags: Record<string, string> | undefined,
|
|
|
81
81
|
return candidates.reduce((best, v) => (compareVersions(v, best) > 0 ? v : best));
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* UNI-272: which dist-tag the picked version came from. An alpha install
|
|
86
|
+
* offered 3.0.0 from `latest` (graduation) must install `latest` — installing
|
|
87
|
+
* `@alpha` again would reinstall the alpha it already has, and keep the
|
|
88
|
+
* install on the alpha channel forever. Ties go to the install's own channel.
|
|
89
|
+
*/
|
|
90
|
+
export function pickInstallTag(distTags: Record<string, string> | undefined, channel: string): string {
|
|
91
|
+
const picked = pickChannelVersion(distTags, channel);
|
|
92
|
+
if (!picked || !distTags) return channel;
|
|
93
|
+
if (distTags[channel] === picked) return channel;
|
|
94
|
+
return distTags.latest === picked ? "latest" : channel;
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
/** The `pi install` source for this channel. */
|
|
85
98
|
export function installSpec(channel: string): string {
|
|
86
99
|
return channel === "latest" ? `npm:${UNIPI_PACKAGE}` : `npm:${UNIPI_PACKAGE}@${channel}`;
|
package/src/checker.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { getInstalledPackageVersion } from "@pi-unipi/core";
|
|
|
12
12
|
import { loadConfig } from "./settings.js";
|
|
13
13
|
import { readLastCheck, writeLastCheck, isCheckDue } from "./cache.js";
|
|
14
14
|
import { compareVersions, isNewerVersion } from "./version.js";
|
|
15
|
-
import { pickChannelVersion, readUnipiPackageSpec, resolveChannel, UNIPI_PACKAGE } from "./channel.js";
|
|
15
|
+
import { pickChannelVersion, pickInstallTag, readUnipiPackageSpec, resolveChannel, UNIPI_PACKAGE } from "./channel.js";
|
|
16
16
|
import type { UpdateCheckResult } from "../types.js";
|
|
17
17
|
|
|
18
18
|
/** npm registry base; `UNIPI_UPDATER_REGISTRY` overrides it (tests / mirrors). */
|
|
@@ -34,12 +34,13 @@ export function currentChannel(currentVersion = getInstalledVersion()): string {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/** Build an update result without ever reporting downgrades as updates. */
|
|
37
|
-
function toUpdateResult(latestVersion: string, currentVersion: string, channel: string): UpdateCheckResult {
|
|
37
|
+
function toUpdateResult(latestVersion: string, currentVersion: string, channel: string, installTag?: string): UpdateCheckResult {
|
|
38
38
|
return {
|
|
39
39
|
updateAvailable: isNewerVersion(latestVersion, currentVersion),
|
|
40
40
|
latestVersion,
|
|
41
41
|
currentVersion,
|
|
42
42
|
channel,
|
|
43
|
+
installTag: installTag ?? channel,
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -69,7 +70,7 @@ export async function checkForUpdates(opts: CheckOptions = {}): Promise<UpdateCh
|
|
|
69
70
|
const cache = readLastCheck();
|
|
70
71
|
if (!opts.force && cache && (cache.channel ?? "latest") === channel && !isCheckDue(config.checkIntervalMs)) {
|
|
71
72
|
if (compareVersions(cache.latestVersion, currentVersion) >= 0) {
|
|
72
|
-
return toUpdateResult(cache.latestVersion, currentVersion, channel);
|
|
73
|
+
return toUpdateResult(cache.latestVersion, currentVersion, channel, cache.installTag);
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -87,6 +88,7 @@ export async function checkForUpdates(opts: CheckOptions = {}): Promise<UpdateCh
|
|
|
87
88
|
// The dist-tags endpoint returns the map itself; the full packument nests it.
|
|
88
89
|
const tags = (body["dist-tags"] ?? body) as Record<string, string>;
|
|
89
90
|
const latestVersion = pickChannelVersion(tags, channel);
|
|
91
|
+
const installTag = pickInstallTag(tags, channel);
|
|
90
92
|
|
|
91
93
|
if (!latestVersion) {
|
|
92
94
|
throw new Error(`No dist-tag "${channel}" in npm response`);
|
|
@@ -96,10 +98,11 @@ export async function checkForUpdates(opts: CheckOptions = {}): Promise<UpdateCh
|
|
|
96
98
|
lastCheck: new Date().toISOString(),
|
|
97
99
|
latestVersion,
|
|
98
100
|
channel,
|
|
101
|
+
installTag,
|
|
99
102
|
skippedVersion: cache?.skippedVersion,
|
|
100
103
|
});
|
|
101
104
|
|
|
102
|
-
return toUpdateResult(latestVersion, currentVersion, channel);
|
|
105
|
+
return toUpdateResult(latestVersion, currentVersion, channel, installTag);
|
|
103
106
|
} catch (err: unknown) {
|
|
104
107
|
// Network error — reuse cached info for this channel only, and never
|
|
105
108
|
// suggest a downgrade from a stale cache.
|
|
@@ -110,6 +113,7 @@ export async function checkForUpdates(opts: CheckOptions = {}): Promise<UpdateCh
|
|
|
110
113
|
latestVersion: usable?.latestVersion ?? "",
|
|
111
114
|
currentVersion,
|
|
112
115
|
channel,
|
|
116
|
+
installTag: usable?.installTag ?? channel,
|
|
113
117
|
error: err instanceof Error ? err.message : String(err) || "Unknown error",
|
|
114
118
|
};
|
|
115
119
|
}
|
|
@@ -93,7 +93,8 @@ export function renderUpdateOverlay(checkResult: UpdateCheckResult, providedNewe
|
|
|
93
93
|
state.installing = true;
|
|
94
94
|
tui.requestRender();
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
// UNI-272: the tag the offered version came from (alpha → 3.0.0 stable installs `latest`).
|
|
97
|
+
const result = await installUpdate(state.result.installTag ?? state.result.channel ?? "latest");
|
|
97
98
|
if (result.success) {
|
|
98
99
|
done({ updated: true });
|
|
99
100
|
} else {
|
package/types.ts
CHANGED
|
@@ -22,6 +22,8 @@ export interface LastCheckCache {
|
|
|
22
22
|
skippedVersion?: string;
|
|
23
23
|
/** npm dist-tag the check followed (absent in pre-UNI-262 caches = "latest") */
|
|
24
24
|
channel?: string;
|
|
25
|
+
/** UNI-272: dist-tag to install the offered version from (≠ channel on graduation). */
|
|
26
|
+
installTag?: string;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
/** A parsed changelog version entry */
|
|
@@ -58,6 +60,9 @@ export interface UpdateCheckResult {
|
|
|
58
60
|
currentVersion: string;
|
|
59
61
|
/** npm dist-tag this install follows ("alpha", "latest", …) */
|
|
60
62
|
channel?: string;
|
|
63
|
+
/** UNI-272: the dist-tag the offered version comes from — install from this
|
|
64
|
+
* (an alpha install offered 3.0.0 stable installs `latest`, leaving alpha). */
|
|
65
|
+
installTag?: string;
|
|
61
66
|
/** Error message if check failed */
|
|
62
67
|
error?: string;
|
|
63
68
|
}
|