chore(vendor): import pi 1.3.0

Imported as a linear vendor commit so forge rebases do not replay the upstream root tree.

git-subtree-dir: third_party/pi

git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
This commit is contained in:
2026-10-15 17:58:48 -04:00
parent 719370c8f7
commit 6081e3e325
1743 changed files with 205460 additions and 131705 deletions

180
third_party/pi/nix/package.nix vendored Normal file
View File

@@ -0,0 +1,180 @@
{
autoPatchelfHook,
fd,
fetchurl,
importNpmLock,
lib,
libxcb,
makeWrapper,
nodejs_22,
ripgrep,
source,
stdenv,
wl-clipboard,
xclip,
}:
let
nodejs = nodejs_22;
packageJson = lib.importJSON (source + "/packages/coding-agent/package.json");
# Lockfile root used by the pi.dev installer. It pins the coding agent's
# runtime dependency tree and is kept in sync with package-lock.json by
# `npm run check`.
installLock = source + "/packages/coding-agent/install-lock";
modelCatalogPin = lib.importJSON ./model-catalog.json;
modelCatalog = fetchurl {
name = "pi-model-catalog.json";
# The typed catalog is the representation whose bytes the revision hashes.
url = "https://pi.dev/api/models/revisions/${modelCatalogPin.revision}?types=chat,image,classifier";
sha256 = lib.removePrefix "sha256-" modelCatalogPin.revision;
};
workspacePackages = stdenv.mkDerivation {
pname = "pi-workspace-packages";
inherit (packageJson) version;
src = source;
npmDeps = importNpmLock { npmRoot = source; };
npmRebuildFlags = [ "--ignore-scripts" ];
nativeBuildInputs = [
nodejs
importNpmLock.npmConfigHook
];
buildPhase = ''
runHook preBuild
node packages/ai/scripts/hydrate-model-catalog.ts ${modelCatalog}
npm run build:offline
runHook postBuild
'';
installPhase = ''
runHook preInstall
pack_package() {
local package_dir="$1"
local output_name="$2"
local tarball
tarball="$(cd "$package_dir" && npm pack --ignore-scripts --silent --pack-destination "$TMPDIR")"
mv "$TMPDIR/$tarball" "$out/$output_name.tgz"
}
mkdir -p "$out"
pack_package packages/telemetry telemetry
pack_package packages/ai ai
pack_package packages/tui tui
pack_package packages/agent agent
pack_package packages/codemode codemode
pack_package packages/mcp mcp
pack_package packages/coding-agent coding-agent
runHook postInstall
'';
};
npmDeps = importNpmLock {
npmRoot = installLock;
# The install lock points internal packages at registry releases. Replace
# them with the packages built from this checkout.
packageSourceOverrides = {
"node_modules/@earendil-works/pi-agent-core" = workspacePackages + "/agent.tgz";
"node_modules/@earendil-works/pi-ai" = workspacePackages + "/ai.tgz";
"node_modules/@earendil-works/pi-codemode" = workspacePackages + "/codemode.tgz";
"node_modules/@earendil-works/pi-coding-agent" = workspacePackages + "/coding-agent.tgz";
"node_modules/@earendil-works/pi-mcp" = workspacePackages + "/mcp.tgz";
"node_modules/@earendil-works/pi-telemetry" = workspacePackages + "/telemetry.tgz";
"node_modules/@earendil-works/pi-tui" = workspacePackages + "/tui.tgz";
};
};
in
stdenv.mkDerivation {
pname = "pi";
inherit (packageJson) version;
src = installLock;
inherit npmDeps;
npmRebuildFlags = [ "--ignore-scripts" ];
nativeBuildInputs = [
nodejs
importNpmLock.npmConfigHook
makeWrapper
]
++ lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
buildInputs = [ nodejs ] ++ lib.optionals stdenv.hostPlatform.isLinux [
stdenv.cc.cc.lib
libxcb
];
dontBuild = true;
dontStrip = true;
installPhase = ''
runHook preInstall
mkdir -p "$out/lib/pi" "$out/bin"
cp -R . "$out/lib/pi"
# The wrapper runs Pi with an absolute Node path. Node is only on PATH so Pi can
# find npm for package installs; append it so that shells started by the
# bash tool keep the user's node/npm (e.g. from mise or nvm). fd, ripgrep,
# and the clipboard tools are Pi's own dependencies and take precedence.
makeWrapper ${nodejs}/bin/node "$out/bin/pi" \
--add-flags "$out/lib/pi/node_modules/@earendil-works/pi-coding-agent/dist/bundle/cli.js" \
--suffix PATH : ${lib.makeBinPath [ nodejs ]} \
--prefix PATH : ${
lib.makeBinPath (
[
fd
ripgrep
]
++ lib.optionals stdenv.hostPlatform.isLinux [
wl-clipboard
xclip
]
)
}
runHook postInstall
'';
doInstallCheck = true;
installCheckPhase = ''
runHook preInstallCheck
test "$("$out/bin/pi" --version)" = "${packageJson.version}"
# Load host-platform TUI helpers directly so missing native dependencies
# fail the build rather than silently disabling clipboard support.
${nodejs}/bin/node -e \
"const fs = require('node:fs');
const path = require('node:path');
const dir = '$out/lib/pi/node_modules/@earendil-works/pi-tui/native/' + process.platform + '/prebuilds/' + process.platform + '-' + process.arch;
if (fs.existsSync(dir)) {
for (const file of fs.readdirSync(dir)) {
if (file.endsWith('.node')) require(path.join(dir, file));
}
}"
${nodejs}/bin/node -e \
"require('$out/lib/pi/node_modules/@silvia-odwyer/photon-node')"
runHook postInstallCheck
'';
meta = {
description = packageJson.description;
homepage = "https://pi.dev";
license = lib.licenses.mit;
mainProgram = "pi";
platforms = [
"aarch64-darwin"
"aarch64-linux"
"x86_64-darwin"
"x86_64-linux"
];
sourceProvenance = with lib.sourceTypes; [
fromSource
binaryNativeCode
];
};
}