feat: introduced nix packaging and path-based binary resolution

- Add comprehensive Nix flake definitions, derivations, modules, and CI workflows.
- Update tests and executables to resolve binaries from PATH rather than absolute paths.
- Ensure byte reproducibility and zeroed timestamps in embedded dashboard archives.
- Add handling for Nix-managed installations in CLI update checks.
This commit is contained in:
can1357
2026-08-13 03:52:47 +02:00
parent 2e492a3076
commit b60bef961c
33 changed files with 3515 additions and 89 deletions
@@ -1,5 +1,5 @@
import { afterEach, describe, expect, it, vi } from "bun:test";
import { runUpdateCommand } from "../../src/cli/update-cli";
import { getLatestRelease, runUpdateCommand } from "../../src/cli/update-cli";
type FetchInput = string | URL | Request;
type FetchInit = RequestInit | BunFetchRequestInit;
@@ -26,3 +26,66 @@ describe("runUpdateCommand fetch cancellation", () => {
expect(requestSignal).toBeInstanceOf(AbortSignal);
});
});
describe("getLatestRelease rename pointers", () => {
afterEach(() => {
vi.restoreAllMocks();
});
function stubRegistry(manifests: Record<string, unknown>): string[] {
const urls: string[] = [];
const fetchStub = Object.assign(
async (input: FetchInput) => {
const url = String(input);
urls.push(url);
let manifest: unknown;
for (const pkg in manifests) {
if (url.includes(pkg)) {
manifest = manifests[pkg];
break;
}
}
if (!manifest) return new Response(null, { status: 404, statusText: "Not Found" });
return Response.json(manifest);
},
{ preconnect: globalThis.fetch.preconnect },
);
vi.spyOn(globalThis, "fetch").mockImplementation(fetchStub);
return urls;
}
it("follows omp.rename to the new package and resolves version, dist, and names from its manifest", async () => {
const urls = stubRegistry({
"@new/omp": { version: "999.1.0", omp: { dist: "npm" } },
"@oh-my-pi/pi-coding-agent": {
version: "999.0.0",
omp: { dist: "binary", rename: { package: "@new/omp", natives: "@new/natives" } },
},
});
const release = await getLatestRelease();
expect(release.version).toBe("999.1.0");
expect(release.dist).toBe("npm");
expect(release.packages).toEqual({ pkg: "@new/omp", natives: "@new/natives" });
expect(urls).toEqual([
"https://registry.npmjs.org/@oh-my-pi/pi-coding-agent/latest",
"https://registry.npmjs.org/@new/omp/latest",
]);
});
it("ignores a rename pointer that cycles back to an already-visited package", async () => {
const urls = stubRegistry({
"@oh-my-pi/pi-coding-agent": {
version: "999.0.0",
omp: { rename: { package: "@oh-my-pi/pi-coding-agent" } },
},
});
const release = await getLatestRelease();
expect(urls).toHaveLength(1);
expect(release.version).toBe("999.0.0");
expect(release.packages).toEqual({ pkg: "@oh-my-pi/pi-coding-agent", natives: "@oh-my-pi/pi-natives" });
});
});