feat(core,server,web,cli): show version in the web UI with update check and admin self-update (#74)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
033d526f9f
commit
e1141ca010
27 files changed
+1375
-40
No files matched your search
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Drift guard for the server's self-update classifier.
|
||||
*
|
||||
* POST /api/version/update (packages/server/src/http/routes/version.ts) tells a refusal
|
||||
* ("unsupported") apart from a successful run by matching `penguin update` output against
|
||||
* REFUSAL_MARKERS — five English fragments duplicated from this package's i18n catalog.
|
||||
* The server cannot import the CLI (the dependency runs the other way), so the fragments
|
||||
* are hardcoded here too, on purpose: editing a refusal message without updating
|
||||
* REFUSAL_MARKERS would silently misclassify refusals as "updated", and this test turns
|
||||
* that drift into a loud failure at edit time. If it fails, change the marker in
|
||||
* packages/server/src/http/routes/version.ts REFUSAL_MARKERS together with the string
|
||||
* (or keep the fragment intact in the new wording).
|
||||
*/
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getMessages } from "../src/i18n.js";
|
||||
|
||||
const en = getMessages("en").update;
|
||||
|
||||
/**
|
||||
* Keep in sync with REFUSAL_MARKERS in packages/server/src/http/routes/version.ts —
|
||||
* one marker per refusal message, paired with the en output that must contain it.
|
||||
* (`needsYes` / `cancelled` are not refusals the server can see: it always runs with
|
||||
* `--yes`.) The argument values are arbitrary; markers must not depend on them.
|
||||
*/
|
||||
const MARKERS: ReadonlyArray<{ marker: string; name: string; message: string }> = [
|
||||
{
|
||||
marker: "runs from a source checkout",
|
||||
name: "sourceCheckout",
|
||||
message: en.sourceCheckout(),
|
||||
},
|
||||
{
|
||||
marker: "Cannot tell how this penguin was installed",
|
||||
name: "unknownInstall",
|
||||
message: en.unknownInstall("/opt/penguin/cli.js"),
|
||||
},
|
||||
{
|
||||
marker: "could not be identified",
|
||||
name: "npmUnknownManager",
|
||||
message: en.npmUnknownManager("/usr/lib/node_modules", "1.2.3"),
|
||||
},
|
||||
{
|
||||
marker: "does not run on Windows",
|
||||
name: "windowsUnsupported",
|
||||
message: en.windowsUnsupported(),
|
||||
},
|
||||
{
|
||||
marker: "cannot run your package manager for you",
|
||||
name: "windowsGlobalInstall",
|
||||
message: en.windowsGlobalInstall("npm install -g @prismshadow/penguin-cli@1.2.3"),
|
||||
},
|
||||
];
|
||||
|
||||
describe("update refusal markers (server classifier contract)", () => {
|
||||
for (const { marker, name, message } of MARKERS) {
|
||||
it(`en update.${name} still contains its server-side marker`, () => {
|
||||
expect(message).toContain(marker);
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user