@h-rig/runtime 0.0.6-alpha.31 → 0.0.6-alpha.33

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.
@@ -1651,11 +1651,287 @@ function readBuildConfig() {
1651
1651
  }
1652
1652
  }
1653
1653
 
1654
- // packages/runtime/src/control-plane/runtime/tooling/shell.ts
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 { basename as basename3, dirname as dirname7, resolve as resolve9 } from "path";
1657
- var sharedNativeShellOutputDir = resolve9(tmpdir2(), "rig-native");
1658
- var sharedNativeShellOutputPath = resolve9(sharedNativeShellOutputDir, `rig-shell-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
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 tmpdir3 } from "os";
1700
- import { basename as basename4, dirname as dirname8, resolve as resolve10 } from "path";
1701
- var sharedNativeToolsOutputDir = resolve10(tmpdir3(), "rig-native");
1702
- var sharedNativeToolsOutputPath = resolve10(sharedNativeToolsOutputDir, `rig-tools-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
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 resolve11 } from "path";
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 resolve11(trimmed);
2029
+ return resolve12(trimmed);
1754
2030
  }
1755
- return resolve11(projectRoot || process.cwd(), trimmed);
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 existsSync10 } from "fs";
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 (!existsSync10(packageJsonPath)) {
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 existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
1979
- import { dirname as dirname9, resolve as resolve12 } from "path";
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 = resolve12(projectRoot, ".claude", "settings.json");
1994
- const existing = existsSync11(settingsPath) ? safeReadJson(settingsPath) : {};
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
- mkdirSync8(dirname9(settingsPath), { recursive: true });
2037
- writeFileSync4(settingsPath, `${JSON.stringify(next, null, 2)}
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(readFileSync4(path, "utf-8"));
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 existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync5, readdirSync as readdirSync2, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
2051
- import { resolve as resolve13 } from "path";
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 = resolve13(projectRoot, ".pi", "skills");
2059
- if (existsSync12(skillsRoot)) {
2334
+ const skillsRoot = resolve14(projectRoot, ".pi", "skills");
2335
+ if (existsSync13(skillsRoot)) {
2060
2336
  for (const name of readdirSync2(skillsRoot)) {
2061
- const dir = resolve13(skillsRoot, name);
2062
- if (existsSync12(resolve13(dir, MARKER_FILENAME))) {
2063
- rmSync3(dir, { recursive: true, force: true });
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 = resolve13(projectRoot, skill.path);
2070
- if (!existsSync12(sourcePath)) {
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 = readFileSync5(sourcePath, "utf-8");
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 = resolve13(skillsRoot, skillDirName(skill.id));
2083
- mkdirSync9(dir, { recursive: true });
2084
- writeFileSync5(resolve13(dir, "SKILL.md"), body, "utf-8");
2085
- writeFileSync5(resolve13(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
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 existsSync14, readFileSync as readFileSync7, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
2153
- import { basename as basename5, join as join4, resolve as resolve15 } from "path";
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 existsSync13, readFileSync as readFileSync6 } from "fs";
2157
- import { resolve as resolve14 } from "path";
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 ?? resolve14(projectRoot, ".rig", "task-config.json");
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 = resolve14(projectRoot, ".rig", "task-config.json")) {
2192
- if (!existsSync13(configPath)) {
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(readFileSync6(configPath, "utf8"));
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 ?? resolve15(projectRoot, ".rig", "task-config.json");
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 = resolve15(projectRoot, "rig.config.json");
2368
- if (existsSync14(jsonPath)) {
2643
+ const jsonPath = resolve16(projectRoot, "rig.config.json");
2644
+ if (existsSync15(jsonPath)) {
2369
2645
  try {
2370
- const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
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 = resolve15(projectRoot, "rig.config.ts");
2380
- if (!existsSync14(tsPath)) {
2655
+ const tsPath = resolve16(projectRoot, "rig.config.ts");
2656
+ if (!existsSync15(tsPath)) {
2381
2657
  return null;
2382
2658
  }
2383
2659
  try {
2384
- const source = readFileSync7(tsPath, "utf8");
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 (!existsSync14(configPath)) {
2680
+ if (!existsSync15(configPath)) {
2405
2681
  return null;
2406
2682
  }
2407
- const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
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 = resolve15(projectRoot, sourcePath);
2416
- if (!existsSync14(directory)) {
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(resolve15(projectRoot, sourcePath), taskId);
2707
+ const file = findFileBackedTaskFile(resolve16(projectRoot, sourcePath), taskId);
2432
2708
  if (!file) {
2433
2709
  return null;
2434
2710
  }
2435
- const raw = JSON.parse(readFileSync7(file, "utf8"));
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 (!existsSync14(directory)) {
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(readFileSync7(file, "utf8"));
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";