@h-rig/runtime 0.0.6-alpha.32 → 0.0.6-alpha.34
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/bin/rig-agent-dispatch.js +12 -0
- package/dist/bin/rig-agent.js +13 -15
- package/dist/src/control-plane/agent-wrapper.js +12 -0
- package/dist/src/control-plane/harness-main.js +1354 -1399
- package/dist/src/control-plane/hooks/completion-verification.js +510 -511
- package/dist/src/control-plane/hooks/inject-context.js +333 -333
- package/dist/src/control-plane/hooks/submodule-branch.js +1600 -1600
- package/dist/src/control-plane/hooks/task-runtime-start.js +1600 -1600
- package/dist/src/control-plane/native/git-ops.js +79 -152
- package/dist/src/control-plane/native/harness-cli.js +1354 -1399
- package/dist/src/control-plane/native/repo-ops.js +50 -50
- package/dist/src/control-plane/native/task-ops.js +1467 -1503
- package/dist/src/control-plane/native/verifier.js +34 -34
- package/dist/src/control-plane/pi-sessiond/bin.js +65 -2
- package/dist/src/control-plane/pi-sessiond/launcher.js +12 -0
- package/dist/src/control-plane/pi-sessiond/server.js +65 -2
- package/dist/src/control-plane/pi-sessiond/session-service.js +65 -2
- package/package.json +8 -8
|
@@ -1651,11 +1651,287 @@ function readBuildConfig() {
|
|
|
1651
1651
|
}
|
|
1652
1652
|
}
|
|
1653
1653
|
|
|
1654
|
-
// packages/runtime/src/control-plane/
|
|
1654
|
+
// packages/runtime/src/control-plane/native/git-native.ts
|
|
1655
|
+
import { chmodSync as chmodSync2, copyFileSync as copyFileSync3, existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync4, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
1655
1656
|
import { tmpdir as tmpdir2 } from "os";
|
|
1656
|
-
import {
|
|
1657
|
-
|
|
1658
|
-
var
|
|
1657
|
+
import { dirname as dirname7, isAbsolute, resolve as resolve9 } from "path";
|
|
1658
|
+
import { createHash as createHash2 } from "crypto";
|
|
1659
|
+
var sharedGitNativeOutputDir = resolve9(tmpdir2(), "rig-native");
|
|
1660
|
+
var sharedGitNativeOutputPath = resolve9(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1661
|
+
var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
|
|
1662
|
+
function temporaryGitBinaryOutputPath(outputPath) {
|
|
1663
|
+
const suffix2 = process.platform === "win32" ? ".exe" : "";
|
|
1664
|
+
return resolve9(dirname7(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix2}`);
|
|
1665
|
+
}
|
|
1666
|
+
function publishGitBinary(tempOutputPath, outputPath) {
|
|
1667
|
+
try {
|
|
1668
|
+
renameSync2(tempOutputPath, outputPath);
|
|
1669
|
+
} catch (error) {
|
|
1670
|
+
if (process.platform === "win32" && existsSync10(outputPath)) {
|
|
1671
|
+
rmSync3(outputPath, { force: true });
|
|
1672
|
+
renameSync2(tempOutputPath, outputPath);
|
|
1673
|
+
return;
|
|
1674
|
+
}
|
|
1675
|
+
throw error;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
function runtimeRigGitFileName() {
|
|
1679
|
+
return `rig-git${process.platform === "win32" ? ".exe" : ""}`;
|
|
1680
|
+
}
|
|
1681
|
+
function rigGitSourceCandidates() {
|
|
1682
|
+
const execDir = process.execPath?.trim() ? dirname7(process.execPath.trim()) : "";
|
|
1683
|
+
const cwd = process.cwd()?.trim() || "";
|
|
1684
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
1685
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
1686
|
+
const moduleRelativeSource = resolve9(import.meta.dir, "../../../native/rig-git.zig");
|
|
1687
|
+
return [...new Set([
|
|
1688
|
+
process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
|
|
1689
|
+
moduleRelativeSource,
|
|
1690
|
+
projectRoot ? resolve9(projectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
1691
|
+
hostProjectRoot ? resolve9(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
1692
|
+
cwd ? resolve9(cwd, "packages/runtime/native/rig-git.zig") : "",
|
|
1693
|
+
execDir ? resolve9(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
|
|
1694
|
+
execDir ? resolve9(execDir, "..", "native", "rig-git.zig") : ""
|
|
1695
|
+
].filter(Boolean))];
|
|
1696
|
+
}
|
|
1697
|
+
function nativePackageBinaryCandidates(fromDir, fileName) {
|
|
1698
|
+
const candidates = [];
|
|
1699
|
+
let cursor = resolve9(fromDir);
|
|
1700
|
+
for (let index = 0;index < 8; index += 1) {
|
|
1701
|
+
candidates.push(resolve9(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve9(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve9(cursor, "native", fileName), resolve9(cursor, "native", "bin", fileName));
|
|
1702
|
+
const parent = dirname7(cursor);
|
|
1703
|
+
if (parent === cursor)
|
|
1704
|
+
break;
|
|
1705
|
+
cursor = parent;
|
|
1706
|
+
}
|
|
1707
|
+
return candidates;
|
|
1708
|
+
}
|
|
1709
|
+
function rigGitBinaryCandidates() {
|
|
1710
|
+
const execDir = process.execPath?.trim() ? dirname7(process.execPath.trim()) : "";
|
|
1711
|
+
const fileName = runtimeRigGitFileName();
|
|
1712
|
+
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
1713
|
+
return [...new Set([
|
|
1714
|
+
explicit,
|
|
1715
|
+
...nativePackageBinaryCandidates(import.meta.dir, fileName),
|
|
1716
|
+
execDir ? resolve9(execDir, fileName) : "",
|
|
1717
|
+
execDir ? resolve9(execDir, "..", fileName) : "",
|
|
1718
|
+
execDir ? resolve9(execDir, "..", "bin", fileName) : "",
|
|
1719
|
+
sharedGitNativeOutputPath
|
|
1720
|
+
].filter(Boolean))];
|
|
1721
|
+
}
|
|
1722
|
+
function resolveGitSourcePath() {
|
|
1723
|
+
for (const candidate of rigGitSourceCandidates()) {
|
|
1724
|
+
if (candidate && existsSync10(candidate)) {
|
|
1725
|
+
return candidate;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
return null;
|
|
1729
|
+
}
|
|
1730
|
+
function resolveGitBinaryPath() {
|
|
1731
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
1732
|
+
return null;
|
|
1733
|
+
}
|
|
1734
|
+
for (const candidate of rigGitBinaryCandidates()) {
|
|
1735
|
+
if (candidate && existsSync10(candidate)) {
|
|
1736
|
+
return candidate;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
return null;
|
|
1740
|
+
}
|
|
1741
|
+
function preferredGitBinaryOutputPath() {
|
|
1742
|
+
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
1743
|
+
return explicit || sharedGitNativeOutputPath;
|
|
1744
|
+
}
|
|
1745
|
+
function binarySupportsTrackerCommandsSync(binaryPath) {
|
|
1746
|
+
try {
|
|
1747
|
+
const probe = Bun.spawnSync([binaryPath, "fetch-ref", "."], {
|
|
1748
|
+
stdout: "pipe",
|
|
1749
|
+
stderr: "pipe"
|
|
1750
|
+
});
|
|
1751
|
+
const stdout = probe.stdout.toString().trim();
|
|
1752
|
+
const stderr = probe.stderr.toString().trim();
|
|
1753
|
+
if (stdout.includes('"error":"unknown command"')) {
|
|
1754
|
+
return false;
|
|
1755
|
+
}
|
|
1756
|
+
return probe.exitCode === 2 && stderr.includes(trackerCommandUsageProbe);
|
|
1757
|
+
} catch {
|
|
1758
|
+
return false;
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
function nativeBuildManifestPath(outputPath) {
|
|
1762
|
+
return `${outputPath}.build-manifest.json`;
|
|
1763
|
+
}
|
|
1764
|
+
function hasMatchingNativeBuildManifestSync(manifestPath, buildKey) {
|
|
1765
|
+
if (!existsSync10(manifestPath)) {
|
|
1766
|
+
return false;
|
|
1767
|
+
}
|
|
1768
|
+
try {
|
|
1769
|
+
const manifest = JSON.parse(readFileSync4(manifestPath, "utf8"));
|
|
1770
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
1771
|
+
} catch {
|
|
1772
|
+
return false;
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
function sha256FileSync(path) {
|
|
1776
|
+
return createHash2("sha256").update(readFileSync4(path)).digest("hex");
|
|
1777
|
+
}
|
|
1778
|
+
function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath()) {
|
|
1779
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
1780
|
+
throw new Error("Zig native git is disabled via RIG_DISABLE_ZIG_NATIVE=1");
|
|
1781
|
+
}
|
|
1782
|
+
const sourcePath = resolveGitSourcePath();
|
|
1783
|
+
if (!sourcePath) {
|
|
1784
|
+
const binaryPath = resolveGitBinaryPath();
|
|
1785
|
+
if (binaryPath) {
|
|
1786
|
+
return binaryPath;
|
|
1787
|
+
}
|
|
1788
|
+
throw new Error("rig-git.zig source file not found.");
|
|
1789
|
+
}
|
|
1790
|
+
const zigBinary = Bun.which("zig");
|
|
1791
|
+
if (!zigBinary) {
|
|
1792
|
+
throw new Error("zig is required to build native Rig git tools.");
|
|
1793
|
+
}
|
|
1794
|
+
mkdirSync8(dirname7(outputPath), { recursive: true });
|
|
1795
|
+
const sourceDigest = sha256FileSync(sourcePath);
|
|
1796
|
+
const buildKey = JSON.stringify({
|
|
1797
|
+
version: 1,
|
|
1798
|
+
zigBinary,
|
|
1799
|
+
platform: process.platform,
|
|
1800
|
+
arch: process.arch,
|
|
1801
|
+
sourcePath,
|
|
1802
|
+
sourceDigest
|
|
1803
|
+
});
|
|
1804
|
+
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
1805
|
+
const needsBuild = !existsSync10(outputPath) || !hasMatchingNativeBuildManifestSync(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
1806
|
+
if (!needsBuild) {
|
|
1807
|
+
chmodSync2(outputPath, 493);
|
|
1808
|
+
return outputPath;
|
|
1809
|
+
}
|
|
1810
|
+
const tempOutputPath = temporaryGitBinaryOutputPath(outputPath);
|
|
1811
|
+
const build = Bun.spawnSync([
|
|
1812
|
+
zigBinary,
|
|
1813
|
+
"build-exe",
|
|
1814
|
+
sourcePath,
|
|
1815
|
+
"-O",
|
|
1816
|
+
"ReleaseFast",
|
|
1817
|
+
`-femit-bin=${tempOutputPath}`
|
|
1818
|
+
], {
|
|
1819
|
+
cwd: dirname7(sourcePath),
|
|
1820
|
+
stdout: "pipe",
|
|
1821
|
+
stderr: "pipe"
|
|
1822
|
+
});
|
|
1823
|
+
if (build.exitCode !== 0 || !existsSync10(tempOutputPath)) {
|
|
1824
|
+
const stderr = build.stderr.toString().trim();
|
|
1825
|
+
const stdout = build.stdout.toString().trim();
|
|
1826
|
+
const details = [stderr, stdout].filter(Boolean).join(`
|
|
1827
|
+
`);
|
|
1828
|
+
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${build.exitCode}`}`);
|
|
1829
|
+
}
|
|
1830
|
+
chmodSync2(tempOutputPath, 493);
|
|
1831
|
+
if (existsSync10(outputPath) && hasMatchingNativeBuildManifestSync(manifestPath, buildKey)) {
|
|
1832
|
+
rmSync3(tempOutputPath, { force: true });
|
|
1833
|
+
chmodSync2(outputPath, 493);
|
|
1834
|
+
return outputPath;
|
|
1835
|
+
}
|
|
1836
|
+
publishGitBinary(tempOutputPath, outputPath);
|
|
1837
|
+
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
1838
|
+
rmSync3(outputPath, { force: true });
|
|
1839
|
+
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
1840
|
+
}
|
|
1841
|
+
writeFileSync4(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
1842
|
+
`, "utf8");
|
|
1843
|
+
return outputPath;
|
|
1844
|
+
}
|
|
1845
|
+
function runGitNative(command, args) {
|
|
1846
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
1847
|
+
return { ok: false, error: "rig-git native disabled" };
|
|
1848
|
+
}
|
|
1849
|
+
const trackerCommand = command === "fetch-ref" || command === "read-blob-at-ref" || command === "write-tree-commit" || command === "push-ref-with-lease";
|
|
1850
|
+
let binaryPath = null;
|
|
1851
|
+
if (trackerCommand) {
|
|
1852
|
+
try {
|
|
1853
|
+
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
1854
|
+
} catch (error) {
|
|
1855
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1856
|
+
if (message.includes("rig-git.zig source file not found")) {
|
|
1857
|
+
return { ok: false, error: "rig-git binary not found" };
|
|
1858
|
+
}
|
|
1859
|
+
return { ok: false, error: message };
|
|
1860
|
+
}
|
|
1861
|
+
} else {
|
|
1862
|
+
const explicitBinaryPath = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
1863
|
+
binaryPath = explicitBinaryPath && existsSync10(explicitBinaryPath) ? explicitBinaryPath : !explicitBinaryPath ? resolveGitBinaryPath() : null;
|
|
1864
|
+
if (!binaryPath) {
|
|
1865
|
+
try {
|
|
1866
|
+
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
1867
|
+
} catch (error) {
|
|
1868
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1869
|
+
if (message.includes("rig-git.zig source file not found")) {
|
|
1870
|
+
return { ok: false, error: "rig-git binary not found" };
|
|
1871
|
+
}
|
|
1872
|
+
return { ok: false, error: message };
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
try {
|
|
1877
|
+
const proc = Bun.spawnSync([binaryPath, command, ...args], {
|
|
1878
|
+
stdout: "pipe",
|
|
1879
|
+
stderr: "pipe",
|
|
1880
|
+
env: process.env
|
|
1881
|
+
});
|
|
1882
|
+
if (proc.exitCode !== 0) {
|
|
1883
|
+
const stdoutText = proc.stdout.toString().trim();
|
|
1884
|
+
if (stdoutText) {
|
|
1885
|
+
try {
|
|
1886
|
+
const parsed = JSON.parse(stdoutText);
|
|
1887
|
+
if (!parsed.ok) {
|
|
1888
|
+
return parsed;
|
|
1889
|
+
}
|
|
1890
|
+
} catch {}
|
|
1891
|
+
}
|
|
1892
|
+
const errText = proc.stderr.toString().trim() || `exit code ${proc.exitCode}`;
|
|
1893
|
+
return { ok: false, error: errText };
|
|
1894
|
+
}
|
|
1895
|
+
const output = proc.stdout.toString().trim();
|
|
1896
|
+
return JSON.parse(output);
|
|
1897
|
+
} catch (err) {
|
|
1898
|
+
return { ok: false, error: String(err) };
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
function requireGitNative(command, args) {
|
|
1902
|
+
const result = runGitNative(command, args);
|
|
1903
|
+
if (!result.ok) {
|
|
1904
|
+
throw new Error(`rig-git ${command} failed: ${result.error}`);
|
|
1905
|
+
}
|
|
1906
|
+
return result;
|
|
1907
|
+
}
|
|
1908
|
+
function requireGitNativeString(command, args) {
|
|
1909
|
+
const result = requireGitNative(command, args);
|
|
1910
|
+
if ("value" in result && typeof result.value === "string") {
|
|
1911
|
+
return result.value;
|
|
1912
|
+
}
|
|
1913
|
+
throw new Error(`rig-git ${command} returned an unexpected result payload`);
|
|
1914
|
+
}
|
|
1915
|
+
function nativeFetchRef(repoPath, remote, branch) {
|
|
1916
|
+
return requireGitNativeString("fetch-ref", [repoPath, remote, branch]);
|
|
1917
|
+
}
|
|
1918
|
+
function nativeReadBlobAtRef(repoPath, ref, path) {
|
|
1919
|
+
const requestDir = resolve9(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
1920
|
+
mkdirSync8(requestDir, { recursive: true });
|
|
1921
|
+
const outputPath = resolve9(requestDir, "blob.txt");
|
|
1922
|
+
try {
|
|
1923
|
+
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
1924
|
+
return readFileSync4(outputPath, "utf8");
|
|
1925
|
+
} finally {
|
|
1926
|
+
rmSync3(requestDir, { recursive: true, force: true });
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
// packages/runtime/src/control-plane/runtime/tooling/shell.ts
|
|
1931
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
1932
|
+
import { basename as basename3, dirname as dirname8, resolve as resolve10 } from "path";
|
|
1933
|
+
var sharedNativeShellOutputDir = resolve10(tmpdir3(), "rig-native");
|
|
1934
|
+
var sharedNativeShellOutputPath = resolve10(sharedNativeShellOutputDir, `rig-shell-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1659
1935
|
function runtimeToolGatewayNames() {
|
|
1660
1936
|
return [
|
|
1661
1937
|
"bash",
|
|
@@ -1696,10 +1972,10 @@ function runtimeToolGatewayNames() {
|
|
|
1696
1972
|
];
|
|
1697
1973
|
}
|
|
1698
1974
|
// packages/runtime/src/control-plane/runtime/tooling/file-tools.ts
|
|
1699
|
-
import { tmpdir as
|
|
1700
|
-
import { basename as basename4, dirname as
|
|
1701
|
-
var sharedNativeToolsOutputDir =
|
|
1702
|
-
var sharedNativeToolsOutputPath =
|
|
1975
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
1976
|
+
import { basename as basename4, dirname as dirname9, resolve as resolve11 } from "path";
|
|
1977
|
+
var sharedNativeToolsOutputDir = resolve11(tmpdir4(), "rig-native");
|
|
1978
|
+
var sharedNativeToolsOutputPath = resolve11(sharedNativeToolsOutputDir, `rig-tools-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1703
1979
|
function runtimeFileToolNames() {
|
|
1704
1980
|
return [
|
|
1705
1981
|
"rig-read",
|
|
@@ -1715,7 +1991,7 @@ function runtimeGatewayToolNames() {
|
|
|
1715
1991
|
return runtimeToolGatewayNames();
|
|
1716
1992
|
}
|
|
1717
1993
|
// packages/runtime/src/control-plane/browser-contract.ts
|
|
1718
|
-
import { resolve as
|
|
1994
|
+
import { resolve as resolve12 } from "path";
|
|
1719
1995
|
var DEFAULT_BROWSER_ATTACH_URL = "http://127.0.0.1:9333";
|
|
1720
1996
|
var DEFAULT_BROWSER_MODE = "persistent";
|
|
1721
1997
|
var RUNTIME_BROWSER_HELPERS = {
|
|
@@ -1750,9 +2026,9 @@ function sanitizeRuntimeSuffix(runtimeId) {
|
|
|
1750
2026
|
function resolveBrowserStateDir(projectRoot, configuredStateDir) {
|
|
1751
2027
|
const trimmed = configuredStateDir?.trim() || ".tmp/rig-browser";
|
|
1752
2028
|
if (trimmed.startsWith("/")) {
|
|
1753
|
-
return
|
|
2029
|
+
return resolve12(trimmed);
|
|
1754
2030
|
}
|
|
1755
|
-
return
|
|
2031
|
+
return resolve12(projectRoot || process.cwd(), trimmed);
|
|
1756
2032
|
}
|
|
1757
2033
|
function resolveTaskBrowserContext(browser, options = {}) {
|
|
1758
2034
|
if (!browser?.required) {
|
|
@@ -1914,7 +2190,7 @@ function createTaskFieldRegistry(extensions) {
|
|
|
1914
2190
|
}
|
|
1915
2191
|
|
|
1916
2192
|
// packages/runtime/src/control-plane/validators/runtime-registration.ts
|
|
1917
|
-
import { existsSync as
|
|
2193
|
+
import { existsSync as existsSync11 } from "fs";
|
|
1918
2194
|
import { join as join3 } from "path";
|
|
1919
2195
|
function createValidatorRegistry() {
|
|
1920
2196
|
const map = new Map;
|
|
@@ -1947,7 +2223,7 @@ function registerBuiltInValidators(registry) {
|
|
|
1947
2223
|
}
|
|
1948
2224
|
async function runStdTypecheck(ctx) {
|
|
1949
2225
|
const packageJsonPath = join3(ctx.workspaceRoot, "package.json");
|
|
1950
|
-
if (!
|
|
2226
|
+
if (!existsSync11(packageJsonPath)) {
|
|
1951
2227
|
return {
|
|
1952
2228
|
id: "std:typecheck",
|
|
1953
2229
|
passed: false,
|
|
@@ -1975,8 +2251,8 @@ async function runStdTypecheck(ctx) {
|
|
|
1975
2251
|
}
|
|
1976
2252
|
|
|
1977
2253
|
// packages/runtime/src/control-plane/hook-materializer.ts
|
|
1978
|
-
import { existsSync as
|
|
1979
|
-
import { dirname as
|
|
2254
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
2255
|
+
import { dirname as dirname10, resolve as resolve13 } from "path";
|
|
1980
2256
|
var MARKER_PLUGIN = "_rigPlugin";
|
|
1981
2257
|
var MARKER_HOOK_ID = "_rigHookId";
|
|
1982
2258
|
function matcherToString(matcher) {
|
|
@@ -1990,8 +2266,8 @@ function isPluginOwned(cmd) {
|
|
|
1990
2266
|
return typeof cmd[MARKER_PLUGIN] === "string";
|
|
1991
2267
|
}
|
|
1992
2268
|
function materializeHooks(projectRoot, entries) {
|
|
1993
|
-
const settingsPath =
|
|
1994
|
-
const existing =
|
|
2269
|
+
const settingsPath = resolve13(projectRoot, ".claude", "settings.json");
|
|
2270
|
+
const existing = existsSync12(settingsPath) ? safeReadJson(settingsPath) : {};
|
|
1995
2271
|
const hooks = existing.hooks ?? {};
|
|
1996
2272
|
for (const event of Object.keys(hooks)) {
|
|
1997
2273
|
const groups = hooks[event] ?? [];
|
|
@@ -2033,56 +2309,56 @@ function materializeHooks(projectRoot, entries) {
|
|
|
2033
2309
|
} else {
|
|
2034
2310
|
delete next.hooks;
|
|
2035
2311
|
}
|
|
2036
|
-
|
|
2037
|
-
|
|
2312
|
+
mkdirSync9(dirname10(settingsPath), { recursive: true });
|
|
2313
|
+
writeFileSync5(settingsPath, `${JSON.stringify(next, null, 2)}
|
|
2038
2314
|
`, "utf-8");
|
|
2039
2315
|
return settingsPath;
|
|
2040
2316
|
}
|
|
2041
2317
|
function safeReadJson(path) {
|
|
2042
2318
|
try {
|
|
2043
|
-
return JSON.parse(
|
|
2319
|
+
return JSON.parse(readFileSync5(path, "utf-8"));
|
|
2044
2320
|
} catch {
|
|
2045
2321
|
return {};
|
|
2046
2322
|
}
|
|
2047
2323
|
}
|
|
2048
2324
|
|
|
2049
2325
|
// packages/runtime/src/control-plane/skill-materializer.ts
|
|
2050
|
-
import { existsSync as
|
|
2051
|
-
import { resolve as
|
|
2326
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync6, readdirSync as readdirSync2, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
2327
|
+
import { resolve as resolve14 } from "path";
|
|
2052
2328
|
import { loadSkill } from "@rig/skill-loader";
|
|
2053
2329
|
var MARKER_FILENAME = ".rig-plugin";
|
|
2054
2330
|
function skillDirName(id) {
|
|
2055
2331
|
return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
2056
2332
|
}
|
|
2057
2333
|
async function materializeSkills(projectRoot, entries) {
|
|
2058
|
-
const skillsRoot =
|
|
2059
|
-
if (
|
|
2334
|
+
const skillsRoot = resolve14(projectRoot, ".pi", "skills");
|
|
2335
|
+
if (existsSync13(skillsRoot)) {
|
|
2060
2336
|
for (const name of readdirSync2(skillsRoot)) {
|
|
2061
|
-
const dir =
|
|
2062
|
-
if (
|
|
2063
|
-
|
|
2337
|
+
const dir = resolve14(skillsRoot, name);
|
|
2338
|
+
if (existsSync13(resolve14(dir, MARKER_FILENAME))) {
|
|
2339
|
+
rmSync4(dir, { recursive: true, force: true });
|
|
2064
2340
|
}
|
|
2065
2341
|
}
|
|
2066
2342
|
}
|
|
2067
2343
|
const written = [];
|
|
2068
2344
|
for (const { pluginName, skill } of entries) {
|
|
2069
|
-
const sourcePath =
|
|
2070
|
-
if (!
|
|
2345
|
+
const sourcePath = resolve14(projectRoot, skill.path);
|
|
2346
|
+
if (!existsSync13(sourcePath)) {
|
|
2071
2347
|
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
|
|
2072
2348
|
continue;
|
|
2073
2349
|
}
|
|
2074
2350
|
let body;
|
|
2075
2351
|
try {
|
|
2076
2352
|
await loadSkill(sourcePath);
|
|
2077
|
-
body =
|
|
2353
|
+
body = readFileSync6(sourcePath, "utf-8");
|
|
2078
2354
|
} catch (err) {
|
|
2079
2355
|
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
|
|
2080
2356
|
continue;
|
|
2081
2357
|
}
|
|
2082
|
-
const dir =
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2358
|
+
const dir = resolve14(skillsRoot, skillDirName(skill.id));
|
|
2359
|
+
mkdirSync10(dir, { recursive: true });
|
|
2360
|
+
writeFileSync6(resolve14(dir, "SKILL.md"), body, "utf-8");
|
|
2361
|
+
writeFileSync6(resolve14(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
|
|
2086
2362
|
`, "utf-8");
|
|
2087
2363
|
written.push({ id: skill.id, pluginName, directory: dir });
|
|
2088
2364
|
}
|
|
@@ -2149,12 +2425,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2149
2425
|
|
|
2150
2426
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
2151
2427
|
import { spawnSync } from "child_process";
|
|
2152
|
-
import { existsSync as
|
|
2153
|
-
import { basename as basename5, join as join4, resolve as
|
|
2428
|
+
import { existsSync as existsSync15, readFileSync as readFileSync8, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync7 } from "fs";
|
|
2429
|
+
import { basename as basename5, join as join4, resolve as resolve16 } from "path";
|
|
2154
2430
|
|
|
2155
2431
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
2156
|
-
import { existsSync as
|
|
2157
|
-
import { resolve as
|
|
2432
|
+
import { existsSync as existsSync14, readFileSync as readFileSync7 } from "fs";
|
|
2433
|
+
import { resolve as resolve15 } from "path";
|
|
2158
2434
|
|
|
2159
2435
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
2160
2436
|
async function findTaskById(reader, id) {
|
|
@@ -2177,7 +2453,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
2177
2453
|
}
|
|
2178
2454
|
}
|
|
2179
2455
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2180
|
-
const configPath = options.configPath ??
|
|
2456
|
+
const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
|
|
2181
2457
|
const reader = {
|
|
2182
2458
|
async listTasks() {
|
|
2183
2459
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -2188,8 +2464,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
2188
2464
|
};
|
|
2189
2465
|
return reader;
|
|
2190
2466
|
}
|
|
2191
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
2192
|
-
if (!
|
|
2467
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve15(projectRoot, ".rig", "task-config.json")) {
|
|
2468
|
+
if (!existsSync14(configPath)) {
|
|
2193
2469
|
return [];
|
|
2194
2470
|
}
|
|
2195
2471
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -2197,7 +2473,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve14(projectRoot,
|
|
|
2197
2473
|
}
|
|
2198
2474
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
2199
2475
|
try {
|
|
2200
|
-
const parsed = JSON.parse(
|
|
2476
|
+
const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
2201
2477
|
if (isPlainRecord(parsed)) {
|
|
2202
2478
|
return parsed;
|
|
2203
2479
|
}
|
|
@@ -2281,7 +2557,7 @@ function isPlainRecord(candidate) {
|
|
|
2281
2557
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
2282
2558
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
2283
2559
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2284
|
-
const configPath = options.configPath ??
|
|
2560
|
+
const configPath = options.configPath ?? resolve16(projectRoot, ".rig", "task-config.json");
|
|
2285
2561
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
2286
2562
|
const spawnFn = options.spawn ?? spawnSync;
|
|
2287
2563
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -2364,10 +2640,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
2364
2640
|
return metadata;
|
|
2365
2641
|
}
|
|
2366
2642
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
2367
|
-
const jsonPath =
|
|
2368
|
-
if (
|
|
2643
|
+
const jsonPath = resolve16(projectRoot, "rig.config.json");
|
|
2644
|
+
if (existsSync15(jsonPath)) {
|
|
2369
2645
|
try {
|
|
2370
|
-
const parsed = JSON.parse(
|
|
2646
|
+
const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
|
|
2371
2647
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
2372
2648
|
const source = parsed.taskSource;
|
|
2373
2649
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -2376,12 +2652,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
2376
2652
|
return null;
|
|
2377
2653
|
}
|
|
2378
2654
|
}
|
|
2379
|
-
const tsPath =
|
|
2380
|
-
if (!
|
|
2655
|
+
const tsPath = resolve16(projectRoot, "rig.config.ts");
|
|
2656
|
+
if (!existsSync15(tsPath)) {
|
|
2381
2657
|
return null;
|
|
2382
2658
|
}
|
|
2383
2659
|
try {
|
|
2384
|
-
const source =
|
|
2660
|
+
const source = readFileSync8(tsPath, "utf8");
|
|
2385
2661
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
2386
2662
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
2387
2663
|
if (kind !== "files") {
|
|
@@ -2401,10 +2677,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
2401
2677
|
return isPlainRecord2(entry) ? entry : null;
|
|
2402
2678
|
}
|
|
2403
2679
|
function readRawTaskConfig(configPath) {
|
|
2404
|
-
if (!
|
|
2680
|
+
if (!existsSync15(configPath)) {
|
|
2405
2681
|
return null;
|
|
2406
2682
|
}
|
|
2407
|
-
const parsed = JSON.parse(
|
|
2683
|
+
const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
|
|
2408
2684
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
2409
2685
|
}
|
|
2410
2686
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -2412,8 +2688,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
2412
2688
|
return tasks;
|
|
2413
2689
|
}
|
|
2414
2690
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
2415
|
-
const directory =
|
|
2416
|
-
if (!
|
|
2691
|
+
const directory = resolve16(projectRoot, sourcePath);
|
|
2692
|
+
if (!existsSync15(directory)) {
|
|
2417
2693
|
return [];
|
|
2418
2694
|
}
|
|
2419
2695
|
const tasks = [];
|
|
@@ -2428,11 +2704,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
2428
2704
|
return tasks;
|
|
2429
2705
|
}
|
|
2430
2706
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
2431
|
-
const file = findFileBackedTaskFile(
|
|
2707
|
+
const file = findFileBackedTaskFile(resolve16(projectRoot, sourcePath), taskId);
|
|
2432
2708
|
if (!file) {
|
|
2433
2709
|
return null;
|
|
2434
2710
|
}
|
|
2435
|
-
const raw = JSON.parse(
|
|
2711
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
2436
2712
|
if (!isPlainRecord2(raw)) {
|
|
2437
2713
|
return null;
|
|
2438
2714
|
}
|
|
@@ -2445,7 +2721,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
2445
2721
|
};
|
|
2446
2722
|
}
|
|
2447
2723
|
function findFileBackedTaskFile(directory, taskId) {
|
|
2448
|
-
if (!
|
|
2724
|
+
if (!existsSync15(directory)) {
|
|
2449
2725
|
return null;
|
|
2450
2726
|
}
|
|
2451
2727
|
for (const name of readdirSync3(directory)) {
|
|
@@ -2455,7 +2731,7 @@ function findFileBackedTaskFile(directory, taskId) {
|
|
|
2455
2731
|
try {
|
|
2456
2732
|
if (!statSync3(file).isFile())
|
|
2457
2733
|
continue;
|
|
2458
|
-
const raw = JSON.parse(
|
|
2734
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
2459
2735
|
const inferredId = basename5(file).replace(FILE_TASK_PATTERN, "");
|
|
2460
2736
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
2461
2737
|
if (id === taskId) {
|
|
@@ -2621,282 +2897,6 @@ import { basename as basename6, resolve as resolve19 } from "path";
|
|
|
2621
2897
|
import { existsSync as existsSync17, readFileSync as readFileSync9 } from "fs";
|
|
2622
2898
|
import { resolve as resolve18 } from "path";
|
|
2623
2899
|
|
|
2624
|
-
// packages/runtime/src/control-plane/native/git-native.ts
|
|
2625
|
-
import { chmodSync as chmodSync2, copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync8, renameSync as renameSync2, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
2626
|
-
import { tmpdir as tmpdir4 } from "os";
|
|
2627
|
-
import { dirname as dirname10, isAbsolute, resolve as resolve16 } from "path";
|
|
2628
|
-
import { createHash as createHash2 } from "crypto";
|
|
2629
|
-
var sharedGitNativeOutputDir = resolve16(tmpdir4(), "rig-native");
|
|
2630
|
-
var sharedGitNativeOutputPath = resolve16(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
2631
|
-
var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
|
|
2632
|
-
function temporaryGitBinaryOutputPath(outputPath) {
|
|
2633
|
-
const suffix2 = process.platform === "win32" ? ".exe" : "";
|
|
2634
|
-
return resolve16(dirname10(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix2}`);
|
|
2635
|
-
}
|
|
2636
|
-
function publishGitBinary(tempOutputPath, outputPath) {
|
|
2637
|
-
try {
|
|
2638
|
-
renameSync2(tempOutputPath, outputPath);
|
|
2639
|
-
} catch (error) {
|
|
2640
|
-
if (process.platform === "win32" && existsSync15(outputPath)) {
|
|
2641
|
-
rmSync4(outputPath, { force: true });
|
|
2642
|
-
renameSync2(tempOutputPath, outputPath);
|
|
2643
|
-
return;
|
|
2644
|
-
}
|
|
2645
|
-
throw error;
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2648
|
-
function runtimeRigGitFileName() {
|
|
2649
|
-
return `rig-git${process.platform === "win32" ? ".exe" : ""}`;
|
|
2650
|
-
}
|
|
2651
|
-
function rigGitSourceCandidates() {
|
|
2652
|
-
const execDir = process.execPath?.trim() ? dirname10(process.execPath.trim()) : "";
|
|
2653
|
-
const cwd = process.cwd()?.trim() || "";
|
|
2654
|
-
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
2655
|
-
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
2656
|
-
const moduleRelativeSource = resolve16(import.meta.dir, "../../../native/rig-git.zig");
|
|
2657
|
-
return [...new Set([
|
|
2658
|
-
process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
|
|
2659
|
-
moduleRelativeSource,
|
|
2660
|
-
projectRoot ? resolve16(projectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
2661
|
-
hostProjectRoot ? resolve16(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
2662
|
-
cwd ? resolve16(cwd, "packages/runtime/native/rig-git.zig") : "",
|
|
2663
|
-
execDir ? resolve16(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
|
|
2664
|
-
execDir ? resolve16(execDir, "..", "native", "rig-git.zig") : ""
|
|
2665
|
-
].filter(Boolean))];
|
|
2666
|
-
}
|
|
2667
|
-
function nativePackageBinaryCandidates(fromDir, fileName) {
|
|
2668
|
-
const candidates = [];
|
|
2669
|
-
let cursor = resolve16(fromDir);
|
|
2670
|
-
for (let index = 0;index < 8; index += 1) {
|
|
2671
|
-
candidates.push(resolve16(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve16(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve16(cursor, "native", fileName), resolve16(cursor, "native", "bin", fileName));
|
|
2672
|
-
const parent = dirname10(cursor);
|
|
2673
|
-
if (parent === cursor)
|
|
2674
|
-
break;
|
|
2675
|
-
cursor = parent;
|
|
2676
|
-
}
|
|
2677
|
-
return candidates;
|
|
2678
|
-
}
|
|
2679
|
-
function rigGitBinaryCandidates() {
|
|
2680
|
-
const execDir = process.execPath?.trim() ? dirname10(process.execPath.trim()) : "";
|
|
2681
|
-
const fileName = runtimeRigGitFileName();
|
|
2682
|
-
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
2683
|
-
return [...new Set([
|
|
2684
|
-
explicit,
|
|
2685
|
-
...nativePackageBinaryCandidates(import.meta.dir, fileName),
|
|
2686
|
-
execDir ? resolve16(execDir, fileName) : "",
|
|
2687
|
-
execDir ? resolve16(execDir, "..", fileName) : "",
|
|
2688
|
-
execDir ? resolve16(execDir, "..", "bin", fileName) : "",
|
|
2689
|
-
sharedGitNativeOutputPath
|
|
2690
|
-
].filter(Boolean))];
|
|
2691
|
-
}
|
|
2692
|
-
function resolveGitSourcePath() {
|
|
2693
|
-
for (const candidate of rigGitSourceCandidates()) {
|
|
2694
|
-
if (candidate && existsSync15(candidate)) {
|
|
2695
|
-
return candidate;
|
|
2696
|
-
}
|
|
2697
|
-
}
|
|
2698
|
-
return null;
|
|
2699
|
-
}
|
|
2700
|
-
function resolveGitBinaryPath() {
|
|
2701
|
-
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
2702
|
-
return null;
|
|
2703
|
-
}
|
|
2704
|
-
for (const candidate of rigGitBinaryCandidates()) {
|
|
2705
|
-
if (candidate && existsSync15(candidate)) {
|
|
2706
|
-
return candidate;
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
return null;
|
|
2710
|
-
}
|
|
2711
|
-
function preferredGitBinaryOutputPath() {
|
|
2712
|
-
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
2713
|
-
return explicit || sharedGitNativeOutputPath;
|
|
2714
|
-
}
|
|
2715
|
-
function binarySupportsTrackerCommandsSync(binaryPath) {
|
|
2716
|
-
try {
|
|
2717
|
-
const probe = Bun.spawnSync([binaryPath, "fetch-ref", "."], {
|
|
2718
|
-
stdout: "pipe",
|
|
2719
|
-
stderr: "pipe"
|
|
2720
|
-
});
|
|
2721
|
-
const stdout = probe.stdout.toString().trim();
|
|
2722
|
-
const stderr = probe.stderr.toString().trim();
|
|
2723
|
-
if (stdout.includes('"error":"unknown command"')) {
|
|
2724
|
-
return false;
|
|
2725
|
-
}
|
|
2726
|
-
return probe.exitCode === 2 && stderr.includes(trackerCommandUsageProbe);
|
|
2727
|
-
} catch {
|
|
2728
|
-
return false;
|
|
2729
|
-
}
|
|
2730
|
-
}
|
|
2731
|
-
function nativeBuildManifestPath(outputPath) {
|
|
2732
|
-
return `${outputPath}.build-manifest.json`;
|
|
2733
|
-
}
|
|
2734
|
-
function hasMatchingNativeBuildManifestSync(manifestPath, buildKey) {
|
|
2735
|
-
if (!existsSync15(manifestPath)) {
|
|
2736
|
-
return false;
|
|
2737
|
-
}
|
|
2738
|
-
try {
|
|
2739
|
-
const manifest = JSON.parse(readFileSync8(manifestPath, "utf8"));
|
|
2740
|
-
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
2741
|
-
} catch {
|
|
2742
|
-
return false;
|
|
2743
|
-
}
|
|
2744
|
-
}
|
|
2745
|
-
function sha256FileSync(path) {
|
|
2746
|
-
return createHash2("sha256").update(readFileSync8(path)).digest("hex");
|
|
2747
|
-
}
|
|
2748
|
-
function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath()) {
|
|
2749
|
-
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
2750
|
-
throw new Error("Zig native git is disabled via RIG_DISABLE_ZIG_NATIVE=1");
|
|
2751
|
-
}
|
|
2752
|
-
const sourcePath = resolveGitSourcePath();
|
|
2753
|
-
if (!sourcePath) {
|
|
2754
|
-
const binaryPath = resolveGitBinaryPath();
|
|
2755
|
-
if (binaryPath) {
|
|
2756
|
-
return binaryPath;
|
|
2757
|
-
}
|
|
2758
|
-
throw new Error("rig-git.zig source file not found.");
|
|
2759
|
-
}
|
|
2760
|
-
const zigBinary = Bun.which("zig");
|
|
2761
|
-
if (!zigBinary) {
|
|
2762
|
-
throw new Error("zig is required to build native Rig git tools.");
|
|
2763
|
-
}
|
|
2764
|
-
mkdirSync10(dirname10(outputPath), { recursive: true });
|
|
2765
|
-
const sourceDigest = sha256FileSync(sourcePath);
|
|
2766
|
-
const buildKey = JSON.stringify({
|
|
2767
|
-
version: 1,
|
|
2768
|
-
zigBinary,
|
|
2769
|
-
platform: process.platform,
|
|
2770
|
-
arch: process.arch,
|
|
2771
|
-
sourcePath,
|
|
2772
|
-
sourceDigest
|
|
2773
|
-
});
|
|
2774
|
-
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
2775
|
-
const needsBuild = !existsSync15(outputPath) || !hasMatchingNativeBuildManifestSync(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
2776
|
-
if (!needsBuild) {
|
|
2777
|
-
chmodSync2(outputPath, 493);
|
|
2778
|
-
return outputPath;
|
|
2779
|
-
}
|
|
2780
|
-
const tempOutputPath = temporaryGitBinaryOutputPath(outputPath);
|
|
2781
|
-
const build = Bun.spawnSync([
|
|
2782
|
-
zigBinary,
|
|
2783
|
-
"build-exe",
|
|
2784
|
-
sourcePath,
|
|
2785
|
-
"-O",
|
|
2786
|
-
"ReleaseFast",
|
|
2787
|
-
`-femit-bin=${tempOutputPath}`
|
|
2788
|
-
], {
|
|
2789
|
-
cwd: dirname10(sourcePath),
|
|
2790
|
-
stdout: "pipe",
|
|
2791
|
-
stderr: "pipe"
|
|
2792
|
-
});
|
|
2793
|
-
if (build.exitCode !== 0 || !existsSync15(tempOutputPath)) {
|
|
2794
|
-
const stderr = build.stderr.toString().trim();
|
|
2795
|
-
const stdout = build.stdout.toString().trim();
|
|
2796
|
-
const details = [stderr, stdout].filter(Boolean).join(`
|
|
2797
|
-
`);
|
|
2798
|
-
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${build.exitCode}`}`);
|
|
2799
|
-
}
|
|
2800
|
-
chmodSync2(tempOutputPath, 493);
|
|
2801
|
-
if (existsSync15(outputPath) && hasMatchingNativeBuildManifestSync(manifestPath, buildKey)) {
|
|
2802
|
-
rmSync4(tempOutputPath, { force: true });
|
|
2803
|
-
chmodSync2(outputPath, 493);
|
|
2804
|
-
return outputPath;
|
|
2805
|
-
}
|
|
2806
|
-
publishGitBinary(tempOutputPath, outputPath);
|
|
2807
|
-
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
2808
|
-
rmSync4(outputPath, { force: true });
|
|
2809
|
-
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
2810
|
-
}
|
|
2811
|
-
writeFileSync7(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
2812
|
-
`, "utf8");
|
|
2813
|
-
return outputPath;
|
|
2814
|
-
}
|
|
2815
|
-
function runGitNative(command, args) {
|
|
2816
|
-
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
2817
|
-
return { ok: false, error: "rig-git native disabled" };
|
|
2818
|
-
}
|
|
2819
|
-
const trackerCommand = command === "fetch-ref" || command === "read-blob-at-ref" || command === "write-tree-commit" || command === "push-ref-with-lease";
|
|
2820
|
-
let binaryPath = null;
|
|
2821
|
-
if (trackerCommand) {
|
|
2822
|
-
try {
|
|
2823
|
-
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
2824
|
-
} catch (error) {
|
|
2825
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2826
|
-
if (message.includes("rig-git.zig source file not found")) {
|
|
2827
|
-
return { ok: false, error: "rig-git binary not found" };
|
|
2828
|
-
}
|
|
2829
|
-
return { ok: false, error: message };
|
|
2830
|
-
}
|
|
2831
|
-
} else {
|
|
2832
|
-
const explicitBinaryPath = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
2833
|
-
binaryPath = explicitBinaryPath && existsSync15(explicitBinaryPath) ? explicitBinaryPath : !explicitBinaryPath ? resolveGitBinaryPath() : null;
|
|
2834
|
-
if (!binaryPath) {
|
|
2835
|
-
try {
|
|
2836
|
-
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
2837
|
-
} catch (error) {
|
|
2838
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2839
|
-
if (message.includes("rig-git.zig source file not found")) {
|
|
2840
|
-
return { ok: false, error: "rig-git binary not found" };
|
|
2841
|
-
}
|
|
2842
|
-
return { ok: false, error: message };
|
|
2843
|
-
}
|
|
2844
|
-
}
|
|
2845
|
-
}
|
|
2846
|
-
try {
|
|
2847
|
-
const proc = Bun.spawnSync([binaryPath, command, ...args], {
|
|
2848
|
-
stdout: "pipe",
|
|
2849
|
-
stderr: "pipe",
|
|
2850
|
-
env: process.env
|
|
2851
|
-
});
|
|
2852
|
-
if (proc.exitCode !== 0) {
|
|
2853
|
-
const stdoutText = proc.stdout.toString().trim();
|
|
2854
|
-
if (stdoutText) {
|
|
2855
|
-
try {
|
|
2856
|
-
const parsed = JSON.parse(stdoutText);
|
|
2857
|
-
if (!parsed.ok) {
|
|
2858
|
-
return parsed;
|
|
2859
|
-
}
|
|
2860
|
-
} catch {}
|
|
2861
|
-
}
|
|
2862
|
-
const errText = proc.stderr.toString().trim() || `exit code ${proc.exitCode}`;
|
|
2863
|
-
return { ok: false, error: errText };
|
|
2864
|
-
}
|
|
2865
|
-
const output = proc.stdout.toString().trim();
|
|
2866
|
-
return JSON.parse(output);
|
|
2867
|
-
} catch (err) {
|
|
2868
|
-
return { ok: false, error: String(err) };
|
|
2869
|
-
}
|
|
2870
|
-
}
|
|
2871
|
-
function requireGitNative(command, args) {
|
|
2872
|
-
const result = runGitNative(command, args);
|
|
2873
|
-
if (!result.ok) {
|
|
2874
|
-
throw new Error(`rig-git ${command} failed: ${result.error}`);
|
|
2875
|
-
}
|
|
2876
|
-
return result;
|
|
2877
|
-
}
|
|
2878
|
-
function requireGitNativeString(command, args) {
|
|
2879
|
-
const result = requireGitNative(command, args);
|
|
2880
|
-
if ("value" in result && typeof result.value === "string") {
|
|
2881
|
-
return result.value;
|
|
2882
|
-
}
|
|
2883
|
-
throw new Error(`rig-git ${command} returned an unexpected result payload`);
|
|
2884
|
-
}
|
|
2885
|
-
function nativeFetchRef(repoPath, remote, branch) {
|
|
2886
|
-
return requireGitNativeString("fetch-ref", [repoPath, remote, branch]);
|
|
2887
|
-
}
|
|
2888
|
-
function nativeReadBlobAtRef(repoPath, ref, path) {
|
|
2889
|
-
const requestDir = resolve16(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
2890
|
-
mkdirSync10(requestDir, { recursive: true });
|
|
2891
|
-
const outputPath = resolve16(requestDir, "blob.txt");
|
|
2892
|
-
try {
|
|
2893
|
-
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
2894
|
-
return readFileSync8(outputPath, "utf8");
|
|
2895
|
-
} finally {
|
|
2896
|
-
rmSync4(requestDir, { recursive: true, force: true });
|
|
2897
|
-
}
|
|
2898
|
-
}
|
|
2899
|
-
|
|
2900
2900
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
2901
2901
|
import { existsSync as existsSync16 } from "fs";
|
|
2902
2902
|
import { resolve as resolve17 } from "path";
|