@este.systems/dsc 0.2.2 → 0.3.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.
- package/dist/api.js +63 -0
- package/dist/api.js.map +1 -1
- package/dist/approval.js +58 -27
- package/dist/approval.js.map +1 -1
- package/dist/clipboard.js +59 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/history.js +106 -0
- package/dist/history.js.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/slash.js +5 -0
- package/dist/slash.js.map +1 -1
- package/dist/store.js.map +1 -1
- package/dist/tools.js +73 -32
- package/dist/tools.js.map +1 -1
- package/dist/tui/ApprovalDialog.js +41 -1
- package/dist/tui/ApprovalDialog.js.map +1 -1
- package/dist/tui/History.js +14 -1
- package/dist/tui/History.js.map +1 -1
- package/dist/tui/Input.js +17 -0
- package/dist/tui/Input.js.map +1 -1
- package/dist/tui.js +239 -14
- package/dist/tui.js.map +1 -1
- package/dist/ui.js +7 -1
- package/dist/ui.js.map +1 -1
- package/dist/update.js +163 -0
- package/dist/update.js.map +1 -0
- package/package.json +1 -1
package/dist/update.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { promises as fsp } from "node:fs";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { VERSION } from "./version.js";
|
|
6
|
+
const PACKAGE_NAME = "@este.systems/dsc";
|
|
7
|
+
const REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
8
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24h — npm's once-a-day cadence
|
|
9
|
+
function stateDir() {
|
|
10
|
+
const xdg = process.env.XDG_STATE_HOME;
|
|
11
|
+
const base = xdg && xdg.length ? xdg : path.join(homedir(), ".local", "state");
|
|
12
|
+
return path.join(base, "dsc");
|
|
13
|
+
}
|
|
14
|
+
function cachePath() {
|
|
15
|
+
return path.join(stateDir(), "version-check.json");
|
|
16
|
+
}
|
|
17
|
+
async function readCache() {
|
|
18
|
+
try {
|
|
19
|
+
const txt = await fsp.readFile(cachePath(), "utf8");
|
|
20
|
+
const parsed = JSON.parse(txt);
|
|
21
|
+
if (typeof parsed?.latest === "string" && typeof parsed?.fetched_at === "number") {
|
|
22
|
+
return parsed;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// missing / invalid — treat as no cache
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
async function writeCache(c) {
|
|
31
|
+
try {
|
|
32
|
+
await fsp.mkdir(stateDir(), { recursive: true });
|
|
33
|
+
await fsp.writeFile(cachePath(), JSON.stringify(c, null, 2), "utf8");
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// best-effort
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function fetchLatestVersion(signal) {
|
|
40
|
+
const res = await fetch(REGISTRY_URL, {
|
|
41
|
+
headers: { Accept: "application/json" },
|
|
42
|
+
signal,
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok)
|
|
45
|
+
throw new Error(`registry returned ${res.status}`);
|
|
46
|
+
const data = (await res.json());
|
|
47
|
+
if (typeof data.version !== "string")
|
|
48
|
+
throw new Error("malformed registry response");
|
|
49
|
+
return data.version;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Compare two semver-ish strings (X.Y.Z, ignoring pre-release tails). Returns
|
|
53
|
+
* -1 if a < b, 0 if equal, 1 if a > b. Non-numeric segments compare as 0
|
|
54
|
+
* so we don't accidentally flag "0.3.0-beta.1" as newer than "0.3.0".
|
|
55
|
+
*/
|
|
56
|
+
export function compareSemver(a, b) {
|
|
57
|
+
const parse = (s) => s.split(/[.+-]/, 3).map((p) => {
|
|
58
|
+
const n = parseInt(p, 10);
|
|
59
|
+
return Number.isFinite(n) ? n : 0;
|
|
60
|
+
});
|
|
61
|
+
const pa = parse(a);
|
|
62
|
+
const pb = parse(b);
|
|
63
|
+
for (let i = 0; i < 3; i++) {
|
|
64
|
+
const x = pa[i] ?? 0;
|
|
65
|
+
const y = pb[i] ?? 0;
|
|
66
|
+
if (x < y)
|
|
67
|
+
return -1;
|
|
68
|
+
if (x > y)
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns the latest published version from npm, with a 24h on-disk cache so
|
|
75
|
+
* we don't hammer the registry every launch. Resolves on network failure too
|
|
76
|
+
* — falls back to whatever cached value exists, or just reports current as
|
|
77
|
+
* latest. Designed to be called fire-and-forget at startup.
|
|
78
|
+
*
|
|
79
|
+
* When `force` is true the cache is ignored and a fresh fetch happens. Use
|
|
80
|
+
* for `/update`-style explicit checks.
|
|
81
|
+
*/
|
|
82
|
+
export async function checkForUpdate(opts = {}) {
|
|
83
|
+
const current = VERSION;
|
|
84
|
+
const cache = await readCache();
|
|
85
|
+
const fresh = cache && Date.now() - cache.fetched_at < CACHE_TTL_MS;
|
|
86
|
+
if (fresh && !opts.force && cache) {
|
|
87
|
+
return {
|
|
88
|
+
current,
|
|
89
|
+
latest: cache.latest,
|
|
90
|
+
newerAvailable: compareSemver(cache.latest, current) > 0,
|
|
91
|
+
fromCache: true,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const latest = await fetchLatestVersion(opts.signal);
|
|
96
|
+
await writeCache({ latest, fetched_at: Date.now() });
|
|
97
|
+
return {
|
|
98
|
+
current,
|
|
99
|
+
latest,
|
|
100
|
+
newerAvailable: compareSemver(latest, current) > 0,
|
|
101
|
+
fromCache: false,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Network down / registry hiccup — surface whatever we last knew. If we
|
|
106
|
+
// never knew, claim "up to date" so we don't false-positive an upgrade.
|
|
107
|
+
const latest = cache?.latest ?? current;
|
|
108
|
+
return {
|
|
109
|
+
current,
|
|
110
|
+
latest,
|
|
111
|
+
newerAvailable: compareSemver(latest, current) > 0,
|
|
112
|
+
fromCache: !!cache,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Runs `npm install -g <package>@latest`. Streams nothing — we wait for the
|
|
118
|
+
* whole install to finish and return its combined output. Suitable behind
|
|
119
|
+
* the /update slash command, where the user has explicitly asked.
|
|
120
|
+
*
|
|
121
|
+
* The currently-running dsc process keeps running on the old code (Node
|
|
122
|
+
* has already loaded everything into memory). The caller should advise a
|
|
123
|
+
* restart after success.
|
|
124
|
+
*/
|
|
125
|
+
export function runUpdate(signal) {
|
|
126
|
+
return new Promise((resolve) => {
|
|
127
|
+
// shell: true so Windows finds npm.cmd; on POSIX it's just `sh -c` which
|
|
128
|
+
// is harmless. Single quoted argv so spaces in package names don't bite.
|
|
129
|
+
const child = spawn("npm", ["install", "-g", `${PACKAGE_NAME}@latest`], {
|
|
130
|
+
shell: true,
|
|
131
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
132
|
+
windowsHide: true,
|
|
133
|
+
});
|
|
134
|
+
let out = "";
|
|
135
|
+
let aborted = false;
|
|
136
|
+
const onAbort = () => {
|
|
137
|
+
aborted = true;
|
|
138
|
+
child.kill();
|
|
139
|
+
};
|
|
140
|
+
if (signal) {
|
|
141
|
+
if (signal.aborted)
|
|
142
|
+
onAbort();
|
|
143
|
+
else
|
|
144
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
145
|
+
}
|
|
146
|
+
child.stdout.on("data", (d) => (out += d.toString()));
|
|
147
|
+
child.stderr.on("data", (d) => (out += d.toString()));
|
|
148
|
+
let settled = false;
|
|
149
|
+
const settle = (ok) => {
|
|
150
|
+
if (settled)
|
|
151
|
+
return;
|
|
152
|
+
settled = true;
|
|
153
|
+
signal?.removeEventListener("abort", onAbort);
|
|
154
|
+
resolve({ ok: ok && !aborted, output: out.trim() });
|
|
155
|
+
};
|
|
156
|
+
child.on("exit", (code) => settle(code === 0));
|
|
157
|
+
child.on("error", (e) => {
|
|
158
|
+
out += `\nspawn error: ${e.message}`;
|
|
159
|
+
settle(false);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"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"}
|