@h-rig/runtime 0.0.6-alpha.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/README.md +27 -0
- package/dist/bin/rig-agent-dispatch.js +9615 -0
- package/dist/bin/rig-agent.js +9512 -0
- package/dist/bin/rig-browser-tool.js +269 -0
- package/dist/src/agent-mode.js +48 -0
- package/dist/src/baked-secrets.js +121 -0
- package/dist/src/binary-build-worker.js +312 -0
- package/dist/src/binary-run.js +540 -0
- package/dist/src/boundaries.js +1 -0
- package/dist/src/build-time-config.js +25 -0
- package/dist/src/control-plane/agent-roles.js +27 -0
- package/dist/src/control-plane/agent-wrapper.js +9621 -0
- package/dist/src/control-plane/authority-files.js +582 -0
- package/dist/src/control-plane/browser-contract.js +135 -0
- package/dist/src/control-plane/controlled-bash.js +1111 -0
- package/dist/src/control-plane/errors.js +13 -0
- package/dist/src/control-plane/harness-main.js +10828 -0
- package/dist/src/control-plane/hook-materializer.js +75 -0
- package/dist/src/control-plane/hooks/audit-trail.js +353 -0
- package/dist/src/control-plane/hooks/completion-verification.js +7552 -0
- package/dist/src/control-plane/hooks/import-guard.js +890 -0
- package/dist/src/control-plane/hooks/inject-context.js +4189 -0
- package/dist/src/control-plane/hooks/post-edit-lint.js +43 -0
- package/dist/src/control-plane/hooks/safety-guard.js +910 -0
- package/dist/src/control-plane/hooks/scope-guard.js +907 -0
- package/dist/src/control-plane/hooks/shared.js +44 -0
- package/dist/src/control-plane/hooks/submodule-branch.js +7797 -0
- package/dist/src/control-plane/hooks/task-runtime-start.js +7799 -0
- package/dist/src/control-plane/hooks/test-integrity-guard.js +891 -0
- package/dist/src/control-plane/materialize-task-config.js +453 -0
- package/dist/src/control-plane/memory-sync/cli.js +2019 -0
- package/dist/src/control-plane/memory-sync/db.js +753 -0
- package/dist/src/control-plane/memory-sync/embed.js +281 -0
- package/dist/src/control-plane/memory-sync/index.js +2049 -0
- package/dist/src/control-plane/memory-sync/query.js +294 -0
- package/dist/src/control-plane/memory-sync/read.js +784 -0
- package/dist/src/control-plane/memory-sync/types.js +6 -0
- package/dist/src/control-plane/memory-sync/write.js +1547 -0
- package/dist/src/control-plane/native/git-native.js +490 -0
- package/dist/src/control-plane/native/git-ops.js +2860 -0
- package/dist/src/control-plane/native/harness-cli.js +9721 -0
- package/dist/src/control-plane/native/pr-automation.js +373 -0
- package/dist/src/control-plane/native/profile-ops.js +481 -0
- package/dist/src/control-plane/native/repo-ops.js +2342 -0
- package/dist/src/control-plane/native/root-resolver.js +66 -0
- package/dist/src/control-plane/native/run-ops.js +3281 -0
- package/dist/src/control-plane/native/runtime-native-sidecar.js +299 -0
- package/dist/src/control-plane/native/runtime-native.js +392 -0
- package/dist/src/control-plane/native/scope-rules.js +17 -0
- package/dist/src/control-plane/native/task-ops.js +6320 -0
- package/dist/src/control-plane/native/task-state.js +1512 -0
- package/dist/src/control-plane/native/utils.js +535 -0
- package/dist/src/control-plane/native/validator-binaries.js +889 -0
- package/dist/src/control-plane/native/validator.js +2197 -0
- package/dist/src/control-plane/native/verifier.js +3249 -0
- package/dist/src/control-plane/native/workspace-ops.js +1635 -0
- package/dist/src/control-plane/plugin-host-context.js +334 -0
- package/dist/src/control-plane/project-main-pre-run-sync.js +630 -0
- package/dist/src/control-plane/provider/claude-stream-records.js +158 -0
- package/dist/src/control-plane/provider/codex-app-server.js +885 -0
- package/dist/src/control-plane/provider/codex-exec-records.js +203 -0
- package/dist/src/control-plane/provider/rig-task-run-skill.js +39 -0
- package/dist/src/control-plane/provider/runtime-instructions.js +96 -0
- package/dist/src/control-plane/remote.js +854 -0
- package/dist/src/control-plane/repos/index.js +473 -0
- package/dist/src/control-plane/repos/layout.js +124 -0
- package/dist/src/control-plane/repos/mirror/bootstrap.js +268 -0
- package/dist/src/control-plane/repos/mirror/refresh.js +398 -0
- package/dist/src/control-plane/repos/mirror/state.js +167 -0
- package/dist/src/control-plane/repos/registry.js +77 -0
- package/dist/src/control-plane/repos/types.js +1 -0
- package/dist/src/control-plane/runtime/agent-mode.js +48 -0
- package/dist/src/control-plane/runtime/baked-secrets.js +120 -0
- package/dist/src/control-plane/runtime/claude-tool-router-binary.js +343 -0
- package/dist/src/control-plane/runtime/claude-tool-router.js +520 -0
- package/dist/src/control-plane/runtime/context.js +216 -0
- package/dist/src/control-plane/runtime/events.js +218 -0
- package/dist/src/control-plane/runtime/guard-types.js +6 -0
- package/dist/src/control-plane/runtime/guard.js +880 -0
- package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +1194 -0
- package/dist/src/control-plane/runtime/image/index.js +2255 -0
- package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +1191 -0
- package/dist/src/control-plane/runtime/image.js +2255 -0
- package/dist/src/control-plane/runtime/index.js +8511 -0
- package/dist/src/control-plane/runtime/isolation/discovery.js +599 -0
- package/dist/src/control-plane/runtime/isolation/home.js +1217 -0
- package/dist/src/control-plane/runtime/isolation/index.js +8193 -0
- package/dist/src/control-plane/runtime/isolation/runner.js +2651 -0
- package/dist/src/control-plane/runtime/isolation/shared.js +501 -0
- package/dist/src/control-plane/runtime/isolation/toolchain.js +1892 -0
- package/dist/src/control-plane/runtime/isolation/types.js +1 -0
- package/dist/src/control-plane/runtime/isolation/worktree.js +509 -0
- package/dist/src/control-plane/runtime/isolation.js +8193 -0
- package/dist/src/control-plane/runtime/overlay.js +67 -0
- package/dist/src/control-plane/runtime/plugin-mode.js +41 -0
- package/dist/src/control-plane/runtime/plugins.js +1131 -0
- package/dist/src/control-plane/runtime/provisioning-env.js +220 -0
- package/dist/src/control-plane/runtime/queue.js +8358 -0
- package/dist/src/control-plane/runtime/rig-shell.js +205 -0
- package/dist/src/control-plane/runtime/rig-tools.js +182 -0
- package/dist/src/control-plane/runtime/runner-context.js +1 -0
- package/dist/src/control-plane/runtime/runtime-paths.js +184 -0
- package/dist/src/control-plane/runtime/sandbox/backend-bwrap.js +311 -0
- package/dist/src/control-plane/runtime/sandbox/backend-none.js +21 -0
- package/dist/src/control-plane/runtime/sandbox/backend-seatbelt.js +268 -0
- package/dist/src/control-plane/runtime/sandbox/backend.js +1718 -0
- package/dist/src/control-plane/runtime/sandbox/orchestrator.js +1745 -0
- package/dist/src/control-plane/runtime/sandbox/utils.js +137 -0
- package/dist/src/control-plane/runtime/sandbox-backend-bwrap.js +311 -0
- package/dist/src/control-plane/runtime/sandbox-backend-none.js +21 -0
- package/dist/src/control-plane/runtime/sandbox-backend-seatbelt.js +268 -0
- package/dist/src/control-plane/runtime/sandbox-backend.js +1718 -0
- package/dist/src/control-plane/runtime/sandbox-orchestrator.js +1745 -0
- package/dist/src/control-plane/runtime/sandbox-utils.js +137 -0
- package/dist/src/control-plane/runtime/snapshot/index.js +454 -0
- package/dist/src/control-plane/runtime/snapshot/sidecar.js +502 -0
- package/dist/src/control-plane/runtime/snapshot/task-run.js +1578 -0
- package/dist/src/control-plane/runtime/snapshot-sidecar.js +498 -0
- package/dist/src/control-plane/runtime/snapshot.js +454 -0
- package/dist/src/control-plane/runtime/task-run-snapshot.js +1578 -0
- package/dist/src/control-plane/runtime/tool-gateway.js +422 -0
- package/dist/src/control-plane/runtime/tooling/browser-tools.js +32 -0
- package/dist/src/control-plane/runtime/tooling/claude-router-binary.js +343 -0
- package/dist/src/control-plane/runtime/tooling/claude-router.js +524 -0
- package/dist/src/control-plane/runtime/tooling/file-tools.js +182 -0
- package/dist/src/control-plane/runtime/tooling/gateway.js +422 -0
- package/dist/src/control-plane/runtime/tooling/index.js +1290 -0
- package/dist/src/control-plane/runtime/tooling/shell.js +205 -0
- package/dist/src/control-plane/runtime/types.js +1 -0
- package/dist/src/control-plane/setup-version.js +14 -0
- package/dist/src/control-plane/state-sync/index.js +1509 -0
- package/dist/src/control-plane/state-sync/read.js +856 -0
- package/dist/src/control-plane/state-sync/reconcile.js +260 -0
- package/dist/src/control-plane/state-sync/repo.js +302 -0
- package/dist/src/control-plane/state-sync/types.js +111 -0
- package/dist/src/control-plane/state-sync/write.js +1469 -0
- package/dist/src/control-plane/task-fields.js +38 -0
- package/dist/src/control-plane/task-source-bootstrap.js +46 -0
- package/dist/src/control-plane/task-source.js +30 -0
- package/dist/src/control-plane/tasks/legacy-task-config-source.js +130 -0
- package/dist/src/control-plane/tasks/plugin-task-source.js +103 -0
- package/dist/src/control-plane/tasks/source-aware-task-config-source.js +611 -0
- package/dist/src/control-plane/tasks/source-lifecycle.js +1093 -0
- package/dist/src/control-plane/tasks/task-record-reader.js +9 -0
- package/dist/src/control-plane/validators/boundary/public-apis.js +107 -0
- package/dist/src/control-plane/validators/integration/_shared.js +51 -0
- package/dist/src/control-plane/validators/integration/adm-audit-http.js +85 -0
- package/dist/src/control-plane/validators/integration/adm-auth-http.js +78 -0
- package/dist/src/control-plane/validators/integration/adm-issuer-http.js +80 -0
- package/dist/src/control-plane/validators/integration/adm-migration.js +78 -0
- package/dist/src/control-plane/validators/integration/adm-scaffold.js +78 -0
- package/dist/src/control-plane/validators/runtime-registration.js +64 -0
- package/dist/src/control-plane/validators/shared.js +683 -0
- package/dist/src/events.js +218 -0
- package/dist/src/execution.js +35 -0
- package/dist/src/index.js +1633 -0
- package/dist/src/layout.js +145 -0
- package/dist/src/local-server.js +202 -0
- package/dist/src/plugins.js +329 -0
- package/dist/src/remote-http.js +83 -0
- package/dist/src/runtime-context.js +216 -0
- package/dist/src/types.js +1 -0
- package/native/darwin-arm64/bin/rig-git +0 -0
- package/native/darwin-arm64/bin/rig-shell +0 -0
- package/native/darwin-arm64/bin/rig-tools +0 -0
- package/native/darwin-arm64/lib/runtime-native-darwin-arm64.dylib +0 -0
- package/native/darwin-arm64/lib/runtime-native.dylib +0 -0
- package/native/darwin-arm64/manifest.json +1 -0
- package/native/linux-x64/bin/rig-git +0 -0
- package/native/linux-x64/bin/rig-shell +0 -0
- package/native/linux-x64/bin/rig-tools +0 -0
- package/native/linux-x64/lib/runtime-native-linux-x64.so +0 -0
- package/native/linux-x64/lib/runtime-native.so +0 -0
- package/native/linux-x64/manifest.json +1 -0
- package/package.json +74 -0
- package/skills/rig-task-run.md +71 -0
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/native/git-native.ts
|
|
3
|
+
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
|
+
import { dirname, isAbsolute, resolve } from "path";
|
|
6
|
+
import { createHash } from "crypto";
|
|
7
|
+
function isTextTreeCommitUpdate(update) {
|
|
8
|
+
return typeof update.content === "string";
|
|
9
|
+
}
|
|
10
|
+
var sharedGitNativeOutputDir = resolve(tmpdir(), "rig-native");
|
|
11
|
+
var sharedGitNativeOutputPath = resolve(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
12
|
+
var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
|
|
13
|
+
function temporaryGitBinaryOutputPath(outputPath) {
|
|
14
|
+
const suffix = process.platform === "win32" ? ".exe" : "";
|
|
15
|
+
return resolve(dirname(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix}`);
|
|
16
|
+
}
|
|
17
|
+
function publishGitBinary(tempOutputPath, outputPath) {
|
|
18
|
+
try {
|
|
19
|
+
renameSync(tempOutputPath, outputPath);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
if (process.platform === "win32" && existsSync(outputPath)) {
|
|
22
|
+
rmSync(outputPath, { force: true });
|
|
23
|
+
renameSync(tempOutputPath, outputPath);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function runtimeRigGitFileName() {
|
|
30
|
+
return `rig-git${process.platform === "win32" ? ".exe" : ""}`;
|
|
31
|
+
}
|
|
32
|
+
function rigGitSourceCandidates() {
|
|
33
|
+
const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
|
|
34
|
+
const cwd = process.cwd()?.trim() || "";
|
|
35
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
36
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
37
|
+
const moduleRelativeSource = resolve(import.meta.dir, "../../../native/rig-git.zig");
|
|
38
|
+
return [...new Set([
|
|
39
|
+
process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
|
|
40
|
+
moduleRelativeSource,
|
|
41
|
+
projectRoot ? resolve(projectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
42
|
+
hostProjectRoot ? resolve(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
43
|
+
cwd ? resolve(cwd, "packages/runtime/native/rig-git.zig") : "",
|
|
44
|
+
execDir ? resolve(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
|
|
45
|
+
execDir ? resolve(execDir, "..", "native", "rig-git.zig") : ""
|
|
46
|
+
].filter(Boolean))];
|
|
47
|
+
}
|
|
48
|
+
function nativePackageBinaryCandidates(fromDir, fileName) {
|
|
49
|
+
const candidates = [];
|
|
50
|
+
let cursor = resolve(fromDir);
|
|
51
|
+
for (let index = 0;index < 8; index += 1) {
|
|
52
|
+
candidates.push(resolve(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve(cursor, "native", fileName), resolve(cursor, "native", "bin", fileName));
|
|
53
|
+
const parent = dirname(cursor);
|
|
54
|
+
if (parent === cursor)
|
|
55
|
+
break;
|
|
56
|
+
cursor = parent;
|
|
57
|
+
}
|
|
58
|
+
return candidates;
|
|
59
|
+
}
|
|
60
|
+
function rigGitBinaryCandidates() {
|
|
61
|
+
const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
|
|
62
|
+
const fileName = runtimeRigGitFileName();
|
|
63
|
+
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
64
|
+
return [...new Set([
|
|
65
|
+
explicit,
|
|
66
|
+
...nativePackageBinaryCandidates(import.meta.dir, fileName),
|
|
67
|
+
execDir ? resolve(execDir, fileName) : "",
|
|
68
|
+
execDir ? resolve(execDir, "..", fileName) : "",
|
|
69
|
+
execDir ? resolve(execDir, "..", "bin", fileName) : "",
|
|
70
|
+
sharedGitNativeOutputPath
|
|
71
|
+
].filter(Boolean))];
|
|
72
|
+
}
|
|
73
|
+
function resolveGitSourcePath() {
|
|
74
|
+
for (const candidate of rigGitSourceCandidates()) {
|
|
75
|
+
if (candidate && existsSync(candidate)) {
|
|
76
|
+
return candidate;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
function resolveGitBinaryPath() {
|
|
82
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
for (const candidate of rigGitBinaryCandidates()) {
|
|
86
|
+
if (candidate && existsSync(candidate)) {
|
|
87
|
+
return candidate;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function preferredGitBinaryOutputPath() {
|
|
93
|
+
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
94
|
+
return explicit || sharedGitNativeOutputPath;
|
|
95
|
+
}
|
|
96
|
+
function binarySupportsTrackerCommandsSync(binaryPath) {
|
|
97
|
+
try {
|
|
98
|
+
const probe = Bun.spawnSync([binaryPath, "fetch-ref", "."], {
|
|
99
|
+
stdout: "pipe",
|
|
100
|
+
stderr: "pipe"
|
|
101
|
+
});
|
|
102
|
+
const stdout = probe.stdout.toString().trim();
|
|
103
|
+
const stderr = probe.stderr.toString().trim();
|
|
104
|
+
if (stdout.includes('"error":"unknown command"')) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
return probe.exitCode === 2 && stderr.includes(trackerCommandUsageProbe);
|
|
108
|
+
} catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function nativeBuildManifestPath(outputPath) {
|
|
113
|
+
return `${outputPath}.build-manifest.json`;
|
|
114
|
+
}
|
|
115
|
+
async function hasMatchingNativeBuildManifest(manifestPath, buildKey) {
|
|
116
|
+
if (!existsSync(manifestPath)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const manifest = await Bun.file(manifestPath).json();
|
|
121
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function hasMatchingNativeBuildManifestSync(manifestPath, buildKey) {
|
|
127
|
+
if (!existsSync(manifestPath)) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
132
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
133
|
+
} catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function sha256File(path) {
|
|
138
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
139
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
140
|
+
return hasher.digest("hex");
|
|
141
|
+
}
|
|
142
|
+
function sha256FileSync(path) {
|
|
143
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
144
|
+
}
|
|
145
|
+
async function ensureRigGitBinaryPath(outputPath = sharedGitNativeOutputPath) {
|
|
146
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
147
|
+
throw new Error("Zig native git is disabled via RIG_DISABLE_ZIG_NATIVE=1");
|
|
148
|
+
}
|
|
149
|
+
const sourcePath = resolveGitSourcePath();
|
|
150
|
+
if (!sourcePath) {
|
|
151
|
+
const binaryPath = resolveGitBinaryPath();
|
|
152
|
+
if (binaryPath) {
|
|
153
|
+
return binaryPath;
|
|
154
|
+
}
|
|
155
|
+
throw new Error("rig-git.zig source file not found.");
|
|
156
|
+
}
|
|
157
|
+
const zigBinary = Bun.which("zig");
|
|
158
|
+
if (!zigBinary) {
|
|
159
|
+
throw new Error("zig is required to build native Rig git tools.");
|
|
160
|
+
}
|
|
161
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
162
|
+
const sourceDigest = await sha256File(sourcePath);
|
|
163
|
+
const buildKey = JSON.stringify({
|
|
164
|
+
version: 1,
|
|
165
|
+
zigBinary,
|
|
166
|
+
platform: process.platform,
|
|
167
|
+
arch: process.arch,
|
|
168
|
+
sourcePath,
|
|
169
|
+
sourceDigest
|
|
170
|
+
});
|
|
171
|
+
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
172
|
+
const needsBuild = !existsSync(outputPath) || !await hasMatchingNativeBuildManifest(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
173
|
+
if (!needsBuild) {
|
|
174
|
+
chmodSync(outputPath, 493);
|
|
175
|
+
return outputPath;
|
|
176
|
+
}
|
|
177
|
+
const tempOutputPath = temporaryGitBinaryOutputPath(outputPath);
|
|
178
|
+
const build = Bun.spawn([
|
|
179
|
+
zigBinary,
|
|
180
|
+
"build-exe",
|
|
181
|
+
sourcePath,
|
|
182
|
+
"-O",
|
|
183
|
+
"ReleaseFast",
|
|
184
|
+
`-femit-bin=${tempOutputPath}`
|
|
185
|
+
], {
|
|
186
|
+
cwd: dirname(sourcePath),
|
|
187
|
+
stdout: "pipe",
|
|
188
|
+
stderr: "pipe"
|
|
189
|
+
});
|
|
190
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
191
|
+
build.exited,
|
|
192
|
+
new Response(build.stdout).text(),
|
|
193
|
+
new Response(build.stderr).text()
|
|
194
|
+
]);
|
|
195
|
+
if (exitCode !== 0 || !existsSync(tempOutputPath)) {
|
|
196
|
+
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
|
|
197
|
+
`);
|
|
198
|
+
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${exitCode}`}`);
|
|
199
|
+
}
|
|
200
|
+
chmodSync(tempOutputPath, 493);
|
|
201
|
+
if (existsSync(outputPath) && await hasMatchingNativeBuildManifest(manifestPath, buildKey)) {
|
|
202
|
+
rmSync(tempOutputPath, { force: true });
|
|
203
|
+
chmodSync(outputPath, 493);
|
|
204
|
+
return outputPath;
|
|
205
|
+
}
|
|
206
|
+
publishGitBinary(tempOutputPath, outputPath);
|
|
207
|
+
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
208
|
+
rmSync(outputPath, { force: true });
|
|
209
|
+
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
210
|
+
}
|
|
211
|
+
await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
212
|
+
`);
|
|
213
|
+
return outputPath;
|
|
214
|
+
}
|
|
215
|
+
function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath()) {
|
|
216
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
217
|
+
throw new Error("Zig native git is disabled via RIG_DISABLE_ZIG_NATIVE=1");
|
|
218
|
+
}
|
|
219
|
+
const sourcePath = resolveGitSourcePath();
|
|
220
|
+
if (!sourcePath) {
|
|
221
|
+
const binaryPath = resolveGitBinaryPath();
|
|
222
|
+
if (binaryPath) {
|
|
223
|
+
return binaryPath;
|
|
224
|
+
}
|
|
225
|
+
throw new Error("rig-git.zig source file not found.");
|
|
226
|
+
}
|
|
227
|
+
const zigBinary = Bun.which("zig");
|
|
228
|
+
if (!zigBinary) {
|
|
229
|
+
throw new Error("zig is required to build native Rig git tools.");
|
|
230
|
+
}
|
|
231
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
232
|
+
const sourceDigest = sha256FileSync(sourcePath);
|
|
233
|
+
const buildKey = JSON.stringify({
|
|
234
|
+
version: 1,
|
|
235
|
+
zigBinary,
|
|
236
|
+
platform: process.platform,
|
|
237
|
+
arch: process.arch,
|
|
238
|
+
sourcePath,
|
|
239
|
+
sourceDigest
|
|
240
|
+
});
|
|
241
|
+
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
242
|
+
const needsBuild = !existsSync(outputPath) || !hasMatchingNativeBuildManifestSync(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
243
|
+
if (!needsBuild) {
|
|
244
|
+
chmodSync(outputPath, 493);
|
|
245
|
+
return outputPath;
|
|
246
|
+
}
|
|
247
|
+
const tempOutputPath = temporaryGitBinaryOutputPath(outputPath);
|
|
248
|
+
const build = Bun.spawnSync([
|
|
249
|
+
zigBinary,
|
|
250
|
+
"build-exe",
|
|
251
|
+
sourcePath,
|
|
252
|
+
"-O",
|
|
253
|
+
"ReleaseFast",
|
|
254
|
+
`-femit-bin=${tempOutputPath}`
|
|
255
|
+
], {
|
|
256
|
+
cwd: dirname(sourcePath),
|
|
257
|
+
stdout: "pipe",
|
|
258
|
+
stderr: "pipe"
|
|
259
|
+
});
|
|
260
|
+
if (build.exitCode !== 0 || !existsSync(tempOutputPath)) {
|
|
261
|
+
const stderr = build.stderr.toString().trim();
|
|
262
|
+
const stdout = build.stdout.toString().trim();
|
|
263
|
+
const details = [stderr, stdout].filter(Boolean).join(`
|
|
264
|
+
`);
|
|
265
|
+
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${build.exitCode}`}`);
|
|
266
|
+
}
|
|
267
|
+
chmodSync(tempOutputPath, 493);
|
|
268
|
+
if (existsSync(outputPath) && hasMatchingNativeBuildManifestSync(manifestPath, buildKey)) {
|
|
269
|
+
rmSync(tempOutputPath, { force: true });
|
|
270
|
+
chmodSync(outputPath, 493);
|
|
271
|
+
return outputPath;
|
|
272
|
+
}
|
|
273
|
+
publishGitBinary(tempOutputPath, outputPath);
|
|
274
|
+
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
275
|
+
rmSync(outputPath, { force: true });
|
|
276
|
+
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
277
|
+
}
|
|
278
|
+
writeFileSync(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
279
|
+
`, "utf8");
|
|
280
|
+
return outputPath;
|
|
281
|
+
}
|
|
282
|
+
async function materializeRigGitBinary(targetDir) {
|
|
283
|
+
const sourcePath = await ensureRigGitBinaryPath();
|
|
284
|
+
const targetPath = resolve(targetDir, runtimeRigGitFileName());
|
|
285
|
+
mkdirSync(targetDir, { recursive: true });
|
|
286
|
+
const sourceDigest = await sha256File(sourcePath);
|
|
287
|
+
const buildKey = JSON.stringify({
|
|
288
|
+
version: 1,
|
|
289
|
+
sourcePath,
|
|
290
|
+
sourceDigest
|
|
291
|
+
});
|
|
292
|
+
const needsCopy = !existsSync(targetPath) || !await hasMatchingNativeBuildManifest(nativeBuildManifestPath(targetPath), buildKey);
|
|
293
|
+
if (needsCopy) {
|
|
294
|
+
copyFileSync(sourcePath, targetPath);
|
|
295
|
+
chmodSync(targetPath, 493);
|
|
296
|
+
await Bun.write(nativeBuildManifestPath(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
297
|
+
`);
|
|
298
|
+
}
|
|
299
|
+
return targetPath;
|
|
300
|
+
}
|
|
301
|
+
function runGitNative(command, args) {
|
|
302
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
303
|
+
return { ok: false, error: "rig-git native disabled" };
|
|
304
|
+
}
|
|
305
|
+
const trackerCommand = command === "fetch-ref" || command === "read-blob-at-ref" || command === "write-tree-commit" || command === "push-ref-with-lease";
|
|
306
|
+
let binaryPath = null;
|
|
307
|
+
if (trackerCommand) {
|
|
308
|
+
try {
|
|
309
|
+
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
310
|
+
} catch (error) {
|
|
311
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
312
|
+
if (message.includes("rig-git.zig source file not found")) {
|
|
313
|
+
return { ok: false, error: "rig-git binary not found" };
|
|
314
|
+
}
|
|
315
|
+
return { ok: false, error: message };
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
const explicitBinaryPath = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
319
|
+
binaryPath = explicitBinaryPath && existsSync(explicitBinaryPath) ? explicitBinaryPath : !explicitBinaryPath ? resolveGitBinaryPath() : null;
|
|
320
|
+
if (!binaryPath) {
|
|
321
|
+
try {
|
|
322
|
+
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
323
|
+
} catch (error) {
|
|
324
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
325
|
+
if (message.includes("rig-git.zig source file not found")) {
|
|
326
|
+
return { ok: false, error: "rig-git binary not found" };
|
|
327
|
+
}
|
|
328
|
+
return { ok: false, error: message };
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
const proc = Bun.spawnSync([binaryPath, command, ...args], {
|
|
334
|
+
stdout: "pipe",
|
|
335
|
+
stderr: "pipe",
|
|
336
|
+
env: process.env
|
|
337
|
+
});
|
|
338
|
+
if (proc.exitCode !== 0) {
|
|
339
|
+
const stdoutText = proc.stdout.toString().trim();
|
|
340
|
+
if (stdoutText) {
|
|
341
|
+
try {
|
|
342
|
+
const parsed = JSON.parse(stdoutText);
|
|
343
|
+
if (!parsed.ok) {
|
|
344
|
+
return parsed;
|
|
345
|
+
}
|
|
346
|
+
} catch {}
|
|
347
|
+
}
|
|
348
|
+
const errText = proc.stderr.toString().trim() || `exit code ${proc.exitCode}`;
|
|
349
|
+
return { ok: false, error: errText };
|
|
350
|
+
}
|
|
351
|
+
const output = proc.stdout.toString().trim();
|
|
352
|
+
return JSON.parse(output);
|
|
353
|
+
} catch (err) {
|
|
354
|
+
return { ok: false, error: String(err) };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function requireGitNative(command, args) {
|
|
358
|
+
const result = runGitNative(command, args);
|
|
359
|
+
if (!result.ok) {
|
|
360
|
+
throw new Error(`rig-git ${command} failed: ${result.error}`);
|
|
361
|
+
}
|
|
362
|
+
return result;
|
|
363
|
+
}
|
|
364
|
+
function requireGitNativeString(command, args) {
|
|
365
|
+
const result = requireGitNative(command, args);
|
|
366
|
+
if ("value" in result && typeof result.value === "string") {
|
|
367
|
+
return result.value;
|
|
368
|
+
}
|
|
369
|
+
throw new Error(`rig-git ${command} returned an unexpected result payload`);
|
|
370
|
+
}
|
|
371
|
+
function nativeBranchName(repoPath) {
|
|
372
|
+
const result = runGitNative("branch-name", [repoPath]);
|
|
373
|
+
if (!result.ok)
|
|
374
|
+
return null;
|
|
375
|
+
if ("value" in result && typeof result.value === "string")
|
|
376
|
+
return result.value;
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
function nativeHeadOid(repoPath) {
|
|
380
|
+
const result = runGitNative("head-oid", [repoPath]);
|
|
381
|
+
if (!result.ok)
|
|
382
|
+
return null;
|
|
383
|
+
if ("value" in result && typeof result.value === "string")
|
|
384
|
+
return result.value;
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
387
|
+
function nativeChangeCount(repoPath) {
|
|
388
|
+
const result = runGitNative("change-count", [repoPath]);
|
|
389
|
+
if (!result.ok)
|
|
390
|
+
return null;
|
|
391
|
+
if ("count" in result && typeof result.count === "number")
|
|
392
|
+
return result.count;
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
function nativePendingFiles(repoPath) {
|
|
396
|
+
const result = runGitNative("pending-files", [repoPath]);
|
|
397
|
+
if (!result.ok)
|
|
398
|
+
return null;
|
|
399
|
+
if ("files" in result && Array.isArray(result.files)) {
|
|
400
|
+
return result.files.map((f) => ({ path: f.path, status: f.status }));
|
|
401
|
+
}
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
404
|
+
function nativeFileHasChanges(repoPath, filePath) {
|
|
405
|
+
const result = runGitNative("file-has-changes", [repoPath, filePath]);
|
|
406
|
+
if (!result.ok)
|
|
407
|
+
return null;
|
|
408
|
+
if ("has_changes" in result && typeof result.has_changes === "boolean")
|
|
409
|
+
return result.has_changes;
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
function nativeFetchRef(repoPath, remote, branch) {
|
|
413
|
+
return requireGitNativeString("fetch-ref", [repoPath, remote, branch]);
|
|
414
|
+
}
|
|
415
|
+
function nativeReadBlobAtRef(repoPath, ref, path) {
|
|
416
|
+
const requestDir = resolve(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
417
|
+
mkdirSync(requestDir, { recursive: true });
|
|
418
|
+
const outputPath = resolve(requestDir, "blob.txt");
|
|
419
|
+
try {
|
|
420
|
+
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
421
|
+
return readFileSync(outputPath, "utf8");
|
|
422
|
+
} finally {
|
|
423
|
+
rmSync(requestDir, { recursive: true, force: true });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function nativeReadBlobBytesAtRef(repoPath, ref, path) {
|
|
427
|
+
const requestDir = resolve(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
428
|
+
mkdirSync(requestDir, { recursive: true });
|
|
429
|
+
const outputPath = resolve(requestDir, "blob.bin");
|
|
430
|
+
try {
|
|
431
|
+
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
432
|
+
return readFileSync(outputPath);
|
|
433
|
+
} finally {
|
|
434
|
+
rmSync(requestDir, { recursive: true, force: true });
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function serializeTreeCommitUpdates(updates) {
|
|
438
|
+
return updates.map((update) => {
|
|
439
|
+
if (isTextTreeCommitUpdate(update)) {
|
|
440
|
+
return { path: update.path, kind: "text", content: update.content };
|
|
441
|
+
}
|
|
442
|
+
if (!isAbsolute(update.sourceFilePath)) {
|
|
443
|
+
throw new Error("tree commit binary updates require an absolute sourceFilePath");
|
|
444
|
+
}
|
|
445
|
+
return { path: update.path, kind: "file", sourceFilePath: update.sourceFilePath };
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
function buildTreeCommitUpdatesJson(updates) {
|
|
449
|
+
return `${JSON.stringify(serializeTreeCommitUpdates(updates), null, 2)}
|
|
450
|
+
`;
|
|
451
|
+
}
|
|
452
|
+
function nativeWriteTreeCommit(repoPath, baseRef, updates, message) {
|
|
453
|
+
const requestDir = resolve(sharedGitNativeOutputDir, "requests", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
454
|
+
mkdirSync(requestDir, { recursive: true });
|
|
455
|
+
const messagePath = resolve(requestDir, "message.txt");
|
|
456
|
+
const updatesPath = resolve(requestDir, "updates.json");
|
|
457
|
+
try {
|
|
458
|
+
writeFileSync(messagePath, message, "utf8");
|
|
459
|
+
writeFileSync(updatesPath, buildTreeCommitUpdatesJson(updates), "utf8");
|
|
460
|
+
return requireGitNativeString("write-tree-commit", [repoPath, baseRef, messagePath, updatesPath]);
|
|
461
|
+
} finally {
|
|
462
|
+
rmSync(requestDir, { recursive: true, force: true });
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function nativePushRefWithLease(repoPath, localOid, remoteRef, expectedOldOid, remote = "origin") {
|
|
466
|
+
return requireGitNativeString("push-ref-with-lease", [
|
|
467
|
+
repoPath,
|
|
468
|
+
localOid,
|
|
469
|
+
remoteRef,
|
|
470
|
+
expectedOldOid,
|
|
471
|
+
remote
|
|
472
|
+
]);
|
|
473
|
+
}
|
|
474
|
+
export {
|
|
475
|
+
runtimeRigGitFileName,
|
|
476
|
+
nativeWriteTreeCommit,
|
|
477
|
+
nativeReadBlobBytesAtRef,
|
|
478
|
+
nativeReadBlobAtRef,
|
|
479
|
+
nativePushRefWithLease,
|
|
480
|
+
nativePendingFiles,
|
|
481
|
+
nativeHeadOid,
|
|
482
|
+
nativeFileHasChanges,
|
|
483
|
+
nativeFetchRef,
|
|
484
|
+
nativeChangeCount,
|
|
485
|
+
nativeBranchName,
|
|
486
|
+
materializeRigGitBinary,
|
|
487
|
+
ensureRigGitBinaryPathSync,
|
|
488
|
+
ensureRigGitBinaryPath,
|
|
489
|
+
buildTreeCommitUpdatesJson
|
|
490
|
+
};
|