@h-rig/core 0.0.6-alpha.16 → 0.0.6-alpha.161
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/src/agent-role-registry.d.ts +4 -0
- package/dist/src/agent-role-registry.js +27 -0
- package/dist/src/authority-paths.d.ts +15 -0
- package/dist/src/authority-paths.js +80 -0
- package/dist/src/baked-secrets.d.ts +6 -0
- package/dist/src/baked-secrets.js +121 -0
- package/dist/src/build-time-config.d.ts +12 -0
- package/dist/src/build-time-config.js +25 -0
- package/dist/src/build-time-config.macro.d.ts +1 -0
- package/dist/src/capability-loaders.d.ts +51 -0
- package/dist/src/capability-loaders.js +749 -0
- package/dist/src/capability.d.ts +79 -0
- package/dist/src/capability.js +63 -0
- package/dist/src/checkout-root.d.ts +1 -0
- package/dist/src/checkout-root.js +30 -0
- package/dist/src/config-env.d.ts +4 -0
- package/dist/src/config-env.js +23 -0
- package/dist/src/config.d.ts +3 -0
- package/dist/src/config.js +44 -0
- package/dist/src/declarative-config.d.ts +14 -0
- package/dist/src/declarative-config.js +82 -0
- package/dist/src/define-config.d.ts +20 -0
- package/dist/src/define-config.js +28 -15
- package/dist/src/define-plugin.d.ts +13 -0
- package/dist/src/define-plugin.js +4 -43
- package/dist/src/embedded-plugins.d.ts +59 -0
- package/dist/src/embedded-plugins.js +22 -0
- package/dist/src/exec.d.ts +13 -0
- package/dist/src/exec.js +101 -0
- package/dist/src/harness-paths.d.ts +18 -0
- package/dist/src/harness-paths.js +141 -0
- package/dist/src/hook-materializer.d.ts +72 -0
- package/dist/src/hook-materializer.js +274 -0
- package/dist/src/hook-runner.d.ts +48 -0
- package/dist/src/hook-runner.js +752 -0
- package/dist/src/hook-runtime.d.ts +11 -0
- package/dist/src/hook-runtime.js +307 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +210 -2499
- package/dist/src/json-files.d.ts +9 -0
- package/dist/src/json-files.js +125 -0
- package/dist/src/kernel-entrypoint.d.ts +22 -0
- package/dist/src/kernel-entrypoint.js +537 -0
- package/dist/src/layout.d.ts +10 -0
- package/dist/src/layout.js +144 -0
- package/dist/src/load-config.d.ts +2 -0
- package/dist/src/load-config.js +421 -28
- package/dist/src/placement.d.ts +50 -0
- package/dist/src/placement.js +996 -0
- package/dist/src/plugin-host-context.d.ts +66 -0
- package/dist/src/plugin-host-context.js +1276 -0
- package/dist/src/plugin-host-registries.d.ts +31 -0
- package/dist/src/plugin-host-registries.js +79 -0
- package/dist/src/plugin-host.d.ts +77 -0
- package/dist/src/plugin-host.js +127 -63
- package/dist/src/plugin-runtime.d.ts +173 -0
- package/dist/src/profile-ops.d.ts +9 -0
- package/dist/src/profile-ops.js +252 -0
- package/dist/src/project-plugins.d.ts +63 -0
- package/dist/src/project-plugins.js +783 -0
- package/dist/src/remote-config.d.ts +183 -0
- package/dist/src/remote-config.js +574 -0
- package/dist/src/root-resolver.d.ts +5 -0
- package/dist/src/root-resolver.js +69 -0
- package/dist/src/run-provisioning.d.ts +58 -0
- package/dist/src/run-provisioning.js +128 -0
- package/dist/src/runtime-context.d.ts +20 -0
- package/dist/src/runtime-context.js +257 -0
- package/dist/src/runtime-events.d.ts +44 -0
- package/dist/src/runtime-events.js +212 -0
- package/dist/src/runtime-overlay.d.ts +11 -0
- package/dist/src/runtime-overlay.js +71 -0
- package/dist/src/runtime-paths.d.ts +21 -0
- package/dist/src/runtime-paths.js +181 -0
- package/dist/src/runtime-provisioning-env.d.ts +5 -0
- package/dist/src/runtime-provisioning-env.js +217 -0
- package/dist/src/runtime-runner-context.d.ts +12 -0
- package/dist/src/runtime-runner-context.js +1 -0
- package/dist/src/safe-identifiers.d.ts +44 -0
- package/dist/src/safe-identifiers.js +96 -0
- package/dist/src/scope-rules.d.ts +4 -0
- package/dist/src/scope-rules.js +21 -0
- package/dist/src/server-paths.d.ts +26 -0
- package/dist/src/server-paths.js +308 -0
- package/dist/src/setup-version.d.ts +3 -0
- package/dist/src/setup-version.js +14 -0
- package/dist/src/task-record-reader.d.ts +3 -0
- package/dist/src/task-record-reader.js +9 -0
- package/dist/src/validator-registry.d.ts +27 -0
- package/dist/src/validator-registry.js +64 -0
- package/package.json +146 -10
- package/dist/src/engineReadModelReducer.js +0 -1780
- package/dist/src/rig-init-builder.js +0 -57
- package/dist/src/rigSelectors.js +0 -293
- package/dist/src/taskGraph.js +0 -64
- package/dist/src/taskGraphCodes.js +0 -26
- package/dist/src/taskGraphLayout.js +0 -374
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RIG_ARTIFACTS_DIRNAME, RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, type RigLayout, type RuntimeWorkspaceLayout } from "@rig/contracts";
|
|
2
|
+
import { resolveCheckoutRoot } from "./checkout-root";
|
|
3
|
+
declare const resolveMonorepoRoot: typeof resolveCheckoutRoot;
|
|
4
|
+
export { resolveMonorepoRoot };
|
|
5
|
+
export type { RigLayout, RuntimeWorkspaceLayout };
|
|
6
|
+
export { RIG_ARTIFACTS_DIRNAME, RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME };
|
|
7
|
+
export declare function resolveNearestRigProjectRoot(startDir: string): string;
|
|
8
|
+
export declare function resolveRigDataRoot(projectRoot: string): string;
|
|
9
|
+
export declare function resolveRuntimeWorkspaceLayout(workspaceDir: string): RuntimeWorkspaceLayout;
|
|
10
|
+
export declare function resolveRigLayout(projectRoot: string): RigLayout;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/layout.ts
|
|
3
|
+
import { existsSync as existsSync2 } from "fs";
|
|
4
|
+
import { resolve as resolve2 } from "path";
|
|
5
|
+
import {
|
|
6
|
+
RIG_ARTIFACTS_DIRNAME,
|
|
7
|
+
RIG_DEFINITION_DIRNAME,
|
|
8
|
+
RIG_STATE_DIRNAME
|
|
9
|
+
} from "@rig/contracts";
|
|
10
|
+
|
|
11
|
+
// packages/core/src/checkout-root.ts
|
|
12
|
+
import { dirname, resolve } from "path";
|
|
13
|
+
import { existsSync } from "fs";
|
|
14
|
+
function findNearestGitCheckoutRoot(startDir) {
|
|
15
|
+
let current = resolve(startDir);
|
|
16
|
+
for (;; ) {
|
|
17
|
+
if (existsSync(resolve(current, ".git")))
|
|
18
|
+
return current;
|
|
19
|
+
const parent = dirname(current);
|
|
20
|
+
if (parent === current)
|
|
21
|
+
return null;
|
|
22
|
+
current = parent;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function resolveCheckoutRoot(projectRoot) {
|
|
26
|
+
const normalizedProjectRoot = resolve(projectRoot);
|
|
27
|
+
const explicit = process.env.MONOREPO_ROOT?.trim();
|
|
28
|
+
if (explicit) {
|
|
29
|
+
const explicitRoot = resolve(explicit);
|
|
30
|
+
const gitRoot = findNearestGitCheckoutRoot(explicitRoot);
|
|
31
|
+
if (gitRoot)
|
|
32
|
+
return gitRoot;
|
|
33
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there or above it.`);
|
|
34
|
+
}
|
|
35
|
+
return findNearestGitCheckoutRoot(normalizedProjectRoot) ?? normalizedProjectRoot;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// packages/core/src/layout.ts
|
|
39
|
+
var resolveMonorepoRoot = resolveCheckoutRoot;
|
|
40
|
+
function resolveNearestRigProjectRoot(startDir) {
|
|
41
|
+
let current = resolve2(startDir);
|
|
42
|
+
let weakMarkerCandidate = null;
|
|
43
|
+
let projectCandidate = null;
|
|
44
|
+
for (;; ) {
|
|
45
|
+
const hasDefinition = existsSync2(resolve2(current, RIG_DEFINITION_DIRNAME));
|
|
46
|
+
const hasState = existsSync2(resolve2(current, RIG_STATE_DIRNAME));
|
|
47
|
+
const hasTaskConfig = existsSync2(resolve2(current, RIG_STATE_DIRNAME, "task-config.json"));
|
|
48
|
+
const hasConfig = existsSync2(resolve2(current, "rig.config.ts")) || existsSync2(resolve2(current, "rig.config.json"));
|
|
49
|
+
const hasGit = existsSync2(resolve2(current, ".git"));
|
|
50
|
+
const hasControlPlane = existsSync2(resolve2(current, "packages", "cli", "bin", "rig.ts")) || existsSync2(resolve2(current, "packages", "server"));
|
|
51
|
+
if ((hasDefinition || hasState || hasConfig) && weakMarkerCandidate === null) {
|
|
52
|
+
weakMarkerCandidate = current;
|
|
53
|
+
}
|
|
54
|
+
if ((hasControlPlane || hasConfig || hasTaskConfig) && projectCandidate === null) {
|
|
55
|
+
projectCandidate = current;
|
|
56
|
+
}
|
|
57
|
+
if (hasGit) {
|
|
58
|
+
return projectCandidate ?? current;
|
|
59
|
+
}
|
|
60
|
+
const parent = resolve2(current, "..");
|
|
61
|
+
if (parent === current) {
|
|
62
|
+
return projectCandidate ?? weakMarkerCandidate ?? resolve2(startDir);
|
|
63
|
+
}
|
|
64
|
+
current = parent;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function resolveRigDataRoot(projectRoot) {
|
|
68
|
+
return resolveMonorepoRoot(projectRoot);
|
|
69
|
+
}
|
|
70
|
+
function resolveRuntimeWorkspaceLayout(workspaceDir) {
|
|
71
|
+
const root = resolve2(workspaceDir);
|
|
72
|
+
const rigRoot = resolve2(root, ".rig");
|
|
73
|
+
const logsDir = resolve2(rigRoot, "logs");
|
|
74
|
+
const stateDir = resolve2(rigRoot, "state");
|
|
75
|
+
const runtimeDir = resolve2(rigRoot, "runtime");
|
|
76
|
+
const binDir = resolve2(rigRoot, "bin");
|
|
77
|
+
return {
|
|
78
|
+
workspaceDir: root,
|
|
79
|
+
rigRoot,
|
|
80
|
+
stateDir,
|
|
81
|
+
logsDir,
|
|
82
|
+
artifactsRoot: resolve2(root, RIG_ARTIFACTS_DIRNAME),
|
|
83
|
+
runtimeDir,
|
|
84
|
+
homeDir: resolve2(rigRoot, "home"),
|
|
85
|
+
tmpDir: resolve2(rigRoot, "tmp"),
|
|
86
|
+
cacheDir: resolve2(rigRoot, "cache"),
|
|
87
|
+
sessionDir: resolve2(rigRoot, "session"),
|
|
88
|
+
binDir,
|
|
89
|
+
distDir: resolve2(rigRoot, "dist"),
|
|
90
|
+
pluginBinDir: resolve2(binDir, "plugins"),
|
|
91
|
+
contextPath: resolve2(rigRoot, "runtime-context.json"),
|
|
92
|
+
controlPlaneEventsFile: resolve2(logsDir, "control-plane.events.jsonl")
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function resolveActiveRuntimeWorkspaceRoot(_monorepoRoot) {
|
|
96
|
+
const explicit = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
97
|
+
if (!explicit) {
|
|
98
|
+
throw new Error("No active runtime workspace. Set RIG_TASK_WORKSPACE or provision a task runtime first.");
|
|
99
|
+
}
|
|
100
|
+
return resolve2(explicit);
|
|
101
|
+
}
|
|
102
|
+
function resolveRigLayout(projectRoot) {
|
|
103
|
+
const monorepoRoot = resolveMonorepoRoot(projectRoot);
|
|
104
|
+
const definitionRoot = resolve2(projectRoot, RIG_DEFINITION_DIRNAME);
|
|
105
|
+
const runtimeWorkspaceRoot = resolveActiveRuntimeWorkspaceRoot(monorepoRoot);
|
|
106
|
+
const runtimeLayout = resolveRuntimeWorkspaceLayout(runtimeWorkspaceRoot);
|
|
107
|
+
const policyDir = resolve2(definitionRoot, "policy");
|
|
108
|
+
return {
|
|
109
|
+
projectRoot,
|
|
110
|
+
monorepoRoot,
|
|
111
|
+
definitionRoot,
|
|
112
|
+
runtimeWorkspaceRoot,
|
|
113
|
+
stateRoot: runtimeLayout.rigRoot,
|
|
114
|
+
artifactsRoot: runtimeLayout.artifactsRoot,
|
|
115
|
+
configPath: resolve2(definitionRoot, "config.sh"),
|
|
116
|
+
taskConfigPath: resolve2(runtimeWorkspaceRoot, ".rig", "task-config.json"),
|
|
117
|
+
policyDir,
|
|
118
|
+
policyFile: resolve2(policyDir, "policy.json"),
|
|
119
|
+
pluginsDir: resolve2(definitionRoot, "plugins"),
|
|
120
|
+
hooksDir: resolve2(definitionRoot, "hooks"),
|
|
121
|
+
toolsDir: resolve2(definitionRoot, "tools"),
|
|
122
|
+
templatesDir: resolve2(definitionRoot, "templates"),
|
|
123
|
+
validationDir: resolve2(definitionRoot, "validation"),
|
|
124
|
+
stateDir: runtimeLayout.stateDir,
|
|
125
|
+
logsDir: runtimeLayout.logsDir,
|
|
126
|
+
notificationsDir: resolve2(definitionRoot, "notifications"),
|
|
127
|
+
runtimeDir: runtimeLayout.runtimeDir,
|
|
128
|
+
distDir: runtimeLayout.distDir,
|
|
129
|
+
binDir: runtimeLayout.binDir,
|
|
130
|
+
pluginBinDir: runtimeLayout.pluginBinDir,
|
|
131
|
+
keybindingsPath: resolve2(definitionRoot, "keybindings.json"),
|
|
132
|
+
controlPlaneEventsFile: runtimeLayout.controlPlaneEventsFile
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export {
|
|
136
|
+
resolveRuntimeWorkspaceLayout,
|
|
137
|
+
resolveRigLayout,
|
|
138
|
+
resolveRigDataRoot,
|
|
139
|
+
resolveNearestRigProjectRoot,
|
|
140
|
+
resolveMonorepoRoot,
|
|
141
|
+
RIG_STATE_DIRNAME,
|
|
142
|
+
RIG_DEFINITION_DIRNAME,
|
|
143
|
+
RIG_ARTIFACTS_DIRNAME
|
|
144
|
+
};
|
package/dist/src/load-config.js
CHANGED
|
@@ -1,48 +1,441 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/core/src/load-config.ts
|
|
3
|
-
import { existsSync, readFileSync } from "fs";
|
|
4
|
-
import {
|
|
3
|
+
import { existsSync as existsSync2, mkdirSync, mkdtempSync, readFileSync as readFileSync2, readdirSync, rmSync, statSync } from "fs";
|
|
4
|
+
import { isBuiltin } from "module";
|
|
5
|
+
import { dirname, isAbsolute, join as join2, relative, resolve } from "path";
|
|
5
6
|
import { pathToFileURL } from "url";
|
|
7
|
+
import { Schema as Schema3 } from "effect";
|
|
8
|
+
import { RigConfig as RigConfig3 } from "@rig/contracts";
|
|
9
|
+
|
|
10
|
+
// packages/core/src/define-config.ts
|
|
6
11
|
import { Schema } from "effect";
|
|
7
12
|
import { RigConfig } from "@rig/contracts";
|
|
13
|
+
function normalizeWorkspaceConfig(raw) {
|
|
14
|
+
const workspace = raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : {};
|
|
15
|
+
if (workspace.mainRepo === undefined)
|
|
16
|
+
workspace.mainRepo = ".";
|
|
17
|
+
if (workspace.checkout === undefined && workspace.isolation !== undefined)
|
|
18
|
+
workspace.checkout = workspace.isolation;
|
|
19
|
+
if (workspace.isolation === undefined && workspace.checkout !== undefined)
|
|
20
|
+
workspace.isolation = workspace.checkout;
|
|
21
|
+
return workspace;
|
|
22
|
+
}
|
|
23
|
+
function applyConfigDefaults(raw) {
|
|
24
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
25
|
+
return raw;
|
|
26
|
+
const record = raw;
|
|
27
|
+
return {
|
|
28
|
+
...record,
|
|
29
|
+
plugins: Array.isArray(record.plugins) ? record.plugins.flat() : [],
|
|
30
|
+
workspace: normalizeWorkspaceConfig(record.workspace)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// packages/core/src/declarative-config.ts
|
|
35
|
+
import { existsSync, readFileSync } from "fs";
|
|
36
|
+
import { join } from "path";
|
|
37
|
+
import { parse as parseToml } from "smol-toml";
|
|
38
|
+
import { Schema as Schema2 } from "effect";
|
|
39
|
+
import { RigConfig as RigConfig2 } from "@rig/contracts";
|
|
40
|
+
|
|
41
|
+
// packages/core/src/embedded-plugins.ts
|
|
42
|
+
var registered = null;
|
|
43
|
+
function getStandardPluginsResolver() {
|
|
44
|
+
return registered;
|
|
45
|
+
}
|
|
46
|
+
var bakedProjectConfig = null;
|
|
47
|
+
function getEmbeddedProjectConfig() {
|
|
48
|
+
return bakedProjectConfig;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// packages/core/src/declarative-config.ts
|
|
52
|
+
var DECLARATIVE_CONFIG_NAMES = ["rigfig.toml", "rigfig.json"];
|
|
53
|
+
function findDeclarativeConfigPath(cwd) {
|
|
54
|
+
const dir = join(cwd, ".rig");
|
|
55
|
+
for (const name of DECLARATIVE_CONFIG_NAMES) {
|
|
56
|
+
const candidate = join(dir, name);
|
|
57
|
+
if (existsSync(candidate))
|
|
58
|
+
return candidate;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
function parseDeclarativeFile(path) {
|
|
63
|
+
const raw = readFileSync(path, "utf8");
|
|
64
|
+
const parsed = path.endsWith(".json") ? JSON.parse(raw) : parseToml(raw);
|
|
65
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
66
|
+
throw new Error(`Declarative config ${path} must parse to an object.`);
|
|
67
|
+
}
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
function loadDeclarativeConfig(path) {
|
|
71
|
+
const data = parseDeclarativeFile(path);
|
|
72
|
+
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard : {};
|
|
73
|
+
const useStandard = standardSection.enabled !== false;
|
|
74
|
+
let plugins = [];
|
|
75
|
+
if (useStandard) {
|
|
76
|
+
const resolver = getStandardPluginsResolver();
|
|
77
|
+
if (!resolver) {
|
|
78
|
+
throw new Error(`Declarative config ${path} needs the embedded standard plugins, but none were registered. ` + `This is a seed/boot wiring error (the binary entrypoint must import the standard-plugin registration).`);
|
|
79
|
+
}
|
|
80
|
+
plugins = resolver(data);
|
|
81
|
+
}
|
|
82
|
+
const { standard: _standardDirective, ...configFields } = data;
|
|
83
|
+
const withDefaults = applyConfigDefaults({ ...configFields, plugins });
|
|
84
|
+
const explicitPlugins = Array.isArray(withDefaults.plugins) ? [...withDefaults.plugins] : [];
|
|
85
|
+
const decoded = Schema2.decodeUnknownSync(RigConfig2)({
|
|
86
|
+
...withDefaults,
|
|
87
|
+
plugins: explicitPlugins
|
|
88
|
+
});
|
|
89
|
+
return { ...decoded, plugins: explicitPlugins };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// packages/core/src/load-config.ts
|
|
8
93
|
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
9
94
|
var JSON_NAMES = ["rig.config.json"];
|
|
95
|
+
function isModuleResolutionError(error) {
|
|
96
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
97
|
+
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
98
|
+
}
|
|
99
|
+
function runningFromCompiledBinary() {
|
|
100
|
+
return import.meta.url.includes("$bunfs");
|
|
101
|
+
}
|
|
102
|
+
function packageNameAndSubpath(specifier) {
|
|
103
|
+
if (specifier.startsWith(".") || specifier.startsWith("/") || /^[a-zA-Z]+:/.test(specifier))
|
|
104
|
+
return null;
|
|
105
|
+
const parts = specifier.split("/");
|
|
106
|
+
const packageName = specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
|
|
107
|
+
if (!packageName)
|
|
108
|
+
return null;
|
|
109
|
+
const rest = parts.slice(specifier.startsWith("@") ? 2 : 1).join("/");
|
|
110
|
+
return { packageName, subpath: rest ? `./${rest}` : "." };
|
|
111
|
+
}
|
|
112
|
+
function exportTargetFromEntry(entry) {
|
|
113
|
+
if (typeof entry === "string")
|
|
114
|
+
return entry;
|
|
115
|
+
if (entry && typeof entry === "object" && !Array.isArray(entry)) {
|
|
116
|
+
const conditions = entry;
|
|
117
|
+
for (const key of ["bun", "import", "default", "require"]) {
|
|
118
|
+
if (typeof conditions[key] === "string")
|
|
119
|
+
return conditions[key];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
function patternExportTarget(record, subpath) {
|
|
125
|
+
for (const [pattern, entry] of Object.entries(record)) {
|
|
126
|
+
if (!pattern.includes("*"))
|
|
127
|
+
continue;
|
|
128
|
+
const [prefix = "", suffix = ""] = pattern.split("*");
|
|
129
|
+
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
|
|
130
|
+
continue;
|
|
131
|
+
const replacement = subpath.slice(prefix.length, subpath.length - suffix.length);
|
|
132
|
+
const target = exportTargetFromEntry(entry);
|
|
133
|
+
if (target)
|
|
134
|
+
return target.replace("*", replacement);
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
function exportTargetFromPackageJson(pkg, subpath) {
|
|
139
|
+
const exportsField = pkg.exports;
|
|
140
|
+
const target = (() => {
|
|
141
|
+
if (typeof exportsField === "string" && subpath === ".")
|
|
142
|
+
return exportsField;
|
|
143
|
+
if (!exportsField || typeof exportsField !== "object" || Array.isArray(exportsField))
|
|
144
|
+
return null;
|
|
145
|
+
const record = exportsField;
|
|
146
|
+
return exportTargetFromEntry(record[subpath] ?? (subpath === "." ? record["."] : undefined)) ?? patternExportTarget(record, subpath);
|
|
147
|
+
})();
|
|
148
|
+
if (target)
|
|
149
|
+
return target;
|
|
150
|
+
return subpath === "." && typeof pkg.module === "string" ? pkg.module : subpath === "." && typeof pkg.main === "string" ? pkg.main : null;
|
|
151
|
+
}
|
|
152
|
+
function resolvePackageDirFromBunStore(packageName, nodeModulesDir) {
|
|
153
|
+
const storeDir = join2(nodeModulesDir, ".bun");
|
|
154
|
+
if (!existsSync2(storeDir))
|
|
155
|
+
return null;
|
|
156
|
+
const encoded = packageName.replace("/", "+");
|
|
157
|
+
try {
|
|
158
|
+
const candidates = readdirSync(storeDir).filter((entry) => entry.startsWith(`${encoded}@`)).map((entry) => {
|
|
159
|
+
const candidateDir = join2(storeDir, entry, "node_modules", packageName);
|
|
160
|
+
const packageJsonPath = join2(candidateDir, "package.json");
|
|
161
|
+
if (!existsSync2(packageJsonPath))
|
|
162
|
+
return null;
|
|
163
|
+
try {
|
|
164
|
+
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
165
|
+
return {
|
|
166
|
+
dir: candidateDir,
|
|
167
|
+
sortKey: pkg.version?.trim() || entry
|
|
168
|
+
};
|
|
169
|
+
} catch {
|
|
170
|
+
return {
|
|
171
|
+
dir: candidateDir,
|
|
172
|
+
sortKey: entry
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}).filter((candidate) => candidate !== null).sort((a, b) => b.sortKey.localeCompare(a.sortKey, undefined, { numeric: true, sensitivity: "base" }));
|
|
176
|
+
return candidates[0]?.dir ?? null;
|
|
177
|
+
} catch {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function resolveDirectoryModulePath(directoryPath) {
|
|
182
|
+
const packageJsonPath = join2(directoryPath, "package.json");
|
|
183
|
+
if (existsSync2(packageJsonPath)) {
|
|
184
|
+
try {
|
|
185
|
+
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
186
|
+
const target = exportTargetFromPackageJson(pkg, ".");
|
|
187
|
+
if (target) {
|
|
188
|
+
const resolved = resolveModulePath(join2(directoryPath, target));
|
|
189
|
+
if (resolved)
|
|
190
|
+
return resolved;
|
|
191
|
+
}
|
|
192
|
+
} catch {}
|
|
193
|
+
}
|
|
194
|
+
for (const candidate of ["index.js", "index.mjs", "index.cjs", "index.ts", "index.json"]) {
|
|
195
|
+
const resolved = resolveModulePath(join2(directoryPath, candidate));
|
|
196
|
+
if (resolved)
|
|
197
|
+
return resolved;
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
function resolveModulePath(candidatePath) {
|
|
202
|
+
if (!existsSync2(candidatePath)) {
|
|
203
|
+
for (const extension of [".ts", ".mts", ".tsx", ".js", ".mjs", ".cjs", ".json"]) {
|
|
204
|
+
const withExtension = `${candidatePath}${extension}`;
|
|
205
|
+
if (existsSync2(withExtension))
|
|
206
|
+
return resolveModulePath(withExtension);
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
const stat = statSync(candidatePath);
|
|
212
|
+
if (stat.isFile())
|
|
213
|
+
return candidatePath;
|
|
214
|
+
if (stat.isDirectory())
|
|
215
|
+
return resolveDirectoryModulePath(candidatePath);
|
|
216
|
+
} catch {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
function resolvePackageExportFromDir(packageDir, subpath) {
|
|
222
|
+
const packageJsonPath = join2(packageDir, "package.json");
|
|
223
|
+
if (existsSync2(packageJsonPath)) {
|
|
224
|
+
try {
|
|
225
|
+
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
226
|
+
const target = exportTargetFromPackageJson(pkg, subpath);
|
|
227
|
+
if (target) {
|
|
228
|
+
const resolved = resolveModulePath(join2(packageDir, target));
|
|
229
|
+
if (resolved)
|
|
230
|
+
return resolved;
|
|
231
|
+
}
|
|
232
|
+
} catch {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (subpath !== ".") {
|
|
237
|
+
const legacySubpath = subpath.replace(/^\.\//, "");
|
|
238
|
+
for (const candidate of [
|
|
239
|
+
join2(packageDir, legacySubpath),
|
|
240
|
+
join2(packageDir, `${legacySubpath}.js`),
|
|
241
|
+
join2(packageDir, `${legacySubpath}.mjs`),
|
|
242
|
+
join2(packageDir, `${legacySubpath}.cjs`),
|
|
243
|
+
join2(packageDir, `${legacySubpath}.ts`),
|
|
244
|
+
join2(packageDir, `${legacySubpath}.json`)
|
|
245
|
+
]) {
|
|
246
|
+
const resolved = resolveModulePath(candidate);
|
|
247
|
+
if (resolved)
|
|
248
|
+
return resolved;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return subpath === "." ? resolveDirectoryModulePath(packageDir) : null;
|
|
252
|
+
}
|
|
253
|
+
var runtimeBundleQueue = Promise.resolve();
|
|
254
|
+
function enqueueRuntimeBundle(operation) {
|
|
255
|
+
const next = runtimeBundleQueue.then(operation, operation);
|
|
256
|
+
runtimeBundleQueue = next.then(() => {
|
|
257
|
+
return;
|
|
258
|
+
}, () => {
|
|
259
|
+
return;
|
|
260
|
+
});
|
|
261
|
+
return next;
|
|
262
|
+
}
|
|
263
|
+
function isWithinDir(candidatePath, rootPath) {
|
|
264
|
+
const rel = relative(resolve(rootPath), resolve(candidatePath));
|
|
265
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
266
|
+
}
|
|
267
|
+
function resolvedFilePath(path, rootPath) {
|
|
268
|
+
if (!path || !isAbsolute(path))
|
|
269
|
+
return null;
|
|
270
|
+
const resolved = resolveModulePath(path);
|
|
271
|
+
if (!resolved)
|
|
272
|
+
return null;
|
|
273
|
+
return rootPath && !isWithinDir(resolved, rootPath) ? null : resolved;
|
|
274
|
+
}
|
|
275
|
+
function resolveProjectPackageImport(specifier, configDir) {
|
|
276
|
+
const parsed = packageNameAndSubpath(specifier);
|
|
277
|
+
if (!parsed)
|
|
278
|
+
return null;
|
|
279
|
+
const nodeModulesDir = join2(configDir, "node_modules");
|
|
280
|
+
const directPackageDir = join2(nodeModulesDir, parsed.packageName);
|
|
281
|
+
const packageDir = existsSync2(join2(directPackageDir, "package.json")) ? directPackageDir : resolvePackageDirFromBunStore(parsed.packageName, nodeModulesDir);
|
|
282
|
+
return packageDir ? resolvePackageExportFromDir(packageDir, parsed.subpath) : null;
|
|
283
|
+
}
|
|
284
|
+
function canImportRigWorkspacePackagesDirectly(source, configDir) {
|
|
285
|
+
const packageNames = new Set;
|
|
286
|
+
for (const match of source.matchAll(/(?:from\s*|import\s*\(\s*|import\s*)["'](@rig\/[^"']+)["']/g)) {
|
|
287
|
+
const parsed = packageNameAndSubpath(match[1] ?? "");
|
|
288
|
+
if (parsed?.packageName)
|
|
289
|
+
packageNames.add(parsed.packageName);
|
|
290
|
+
}
|
|
291
|
+
if (packageNames.size === 0)
|
|
292
|
+
return false;
|
|
293
|
+
for (const packageName of packageNames) {
|
|
294
|
+
const shortName = packageName.replace(/^@rig\//, "");
|
|
295
|
+
const manifestPath = join2(configDir, "packages", shortName, "package.json");
|
|
296
|
+
if (!existsSync2(manifestPath))
|
|
297
|
+
return false;
|
|
298
|
+
try {
|
|
299
|
+
const parsed = JSON.parse(readFileSync2(manifestPath, "utf8"));
|
|
300
|
+
if (parsed.name !== packageName)
|
|
301
|
+
return false;
|
|
302
|
+
} catch {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
async function importConfigViaRuntimeBundleUnserialized(configPath) {
|
|
309
|
+
const bun = globalThis.Bun;
|
|
310
|
+
if (!bun?.build) {
|
|
311
|
+
throw new Error(`Failed to import ${configPath}: bare imports could not be resolved and no Bun.build runtime bundler is available.`);
|
|
312
|
+
}
|
|
313
|
+
const RUNTIME_ONLY_EXTERNAL_PACKAGES = new Set(["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"]);
|
|
314
|
+
const configDir = dirname(configPath);
|
|
315
|
+
const UNRESOLVED_NAMESPACE = "rig-config-unresolved";
|
|
316
|
+
const unresolvedLocalPlugin = {
|
|
317
|
+
name: "rig-config-unresolved-local",
|
|
318
|
+
setup(build) {
|
|
319
|
+
build.onLoad({ filter: /\.(?:html|txt)$/ }, (args) => ({
|
|
320
|
+
loader: "js",
|
|
321
|
+
contents: `export default ${JSON.stringify(readFileSync2(args.path, "utf8"))};
|
|
322
|
+
`
|
|
323
|
+
}));
|
|
324
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
325
|
+
const directFilePath = resolvedFilePath(args.path, configDir);
|
|
326
|
+
if (directFilePath)
|
|
327
|
+
return { path: directFilePath };
|
|
328
|
+
const packageImport = packageNameAndSubpath(args.path);
|
|
329
|
+
if (packageImport && (packageImport.packageName.startsWith("@rig/") || RUNTIME_ONLY_EXTERNAL_PACKAGES.has(packageImport.packageName))) {
|
|
330
|
+
return { path: args.path, external: true };
|
|
331
|
+
}
|
|
332
|
+
const projectPackagePath = resolveProjectPackageImport(args.path, configDir);
|
|
333
|
+
if (projectPackagePath)
|
|
334
|
+
return { path: projectPackagePath };
|
|
335
|
+
if (/^(?:node|bun):/.test(args.path) || isBuiltin(args.path))
|
|
336
|
+
return;
|
|
337
|
+
if (packageImport)
|
|
338
|
+
return { path: args.path, external: true };
|
|
339
|
+
const parentCandidates = args.path.startsWith(".") ? [args.importer && isAbsolute(args.importer) ? dirname(args.importer) : null, configDir].filter((value) => Boolean(value)) : [args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configDir];
|
|
340
|
+
for (const parent2 of parentCandidates) {
|
|
341
|
+
const filePath = resolvedFilePath(resolve(parent2, args.path), configDir);
|
|
342
|
+
if (filePath)
|
|
343
|
+
return { path: filePath };
|
|
344
|
+
}
|
|
345
|
+
const parent = parentCandidates[0] ?? configDir;
|
|
346
|
+
try {
|
|
347
|
+
const resolved = bun.resolveSync?.(args.path, parent) ?? resolve(parent, args.path);
|
|
348
|
+
const filePath = resolvedFilePath(resolved, configDir);
|
|
349
|
+
if (filePath)
|
|
350
|
+
return { path: filePath };
|
|
351
|
+
} catch {}
|
|
352
|
+
return { path: args.path, namespace: UNRESOLVED_NAMESPACE };
|
|
353
|
+
});
|
|
354
|
+
build.onLoad({ filter: /.*/, namespace: UNRESOLVED_NAMESPACE }, (args) => ({
|
|
355
|
+
loader: "js",
|
|
356
|
+
contents: `module.exports = {};
|
|
357
|
+
throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not resolve local import "${args.path}". Maybe you need to fix a relative import in rig.config.ts or install project deps.`)});
|
|
358
|
+
`
|
|
359
|
+
}));
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
const result = await bun.build({
|
|
363
|
+
entrypoints: [configPath],
|
|
364
|
+
target: "bun",
|
|
365
|
+
external: ["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"],
|
|
366
|
+
format: "esm",
|
|
367
|
+
throw: false,
|
|
368
|
+
packages: "bundle",
|
|
369
|
+
plugins: [unresolvedLocalPlugin]
|
|
370
|
+
});
|
|
371
|
+
if (!result.success || !result.outputs[0]) {
|
|
372
|
+
const detail = result.logs.map((log) => String(log)).join(`
|
|
373
|
+
`);
|
|
374
|
+
throw new Error(`Failed to bundle ${configPath}: ${detail || "unknown bundler error"}`);
|
|
375
|
+
}
|
|
376
|
+
const bundleParentDir = join2(configDir, ".rig", "tmp");
|
|
377
|
+
mkdirSync(bundleParentDir, { recursive: true });
|
|
378
|
+
const dir = mkdtempSync(join2(bundleParentDir, "rig-config-bundle-"));
|
|
379
|
+
try {
|
|
380
|
+
const bundledPath = join2(dir, "rig.config.bundled.js");
|
|
381
|
+
await bun.write(bundledPath, await result.outputs[0].text());
|
|
382
|
+
return await import(pathToFileURL(bundledPath).href);
|
|
383
|
+
} finally {
|
|
384
|
+
try {
|
|
385
|
+
rmSync(dir, { recursive: true, force: true });
|
|
386
|
+
} catch {}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
10
389
|
async function loadConfig(cwd) {
|
|
390
|
+
const baked = getEmbeddedProjectConfig();
|
|
391
|
+
if (baked && resolve(baked.projectRoot) === resolve(cwd)) {
|
|
392
|
+
return decodeExplicitPluginConfig(baked.raw);
|
|
393
|
+
}
|
|
11
394
|
for (const name of TS_NAMES) {
|
|
12
|
-
const p =
|
|
13
|
-
if (
|
|
14
|
-
const mod = await
|
|
395
|
+
const p = join2(cwd, name);
|
|
396
|
+
if (existsSync2(p)) {
|
|
397
|
+
const mod = await enqueueRuntimeBundle(async () => {
|
|
398
|
+
if (runningFromCompiledBinary()) {
|
|
399
|
+
return importConfigViaRuntimeBundleUnserialized(p);
|
|
400
|
+
}
|
|
401
|
+
const source = readFileSync2(p, "utf8");
|
|
402
|
+
const importsRigHostPackages = /(?:import\s+[^;]*?from\s*|import\s*\()\s*["']@rig\//.test(source);
|
|
403
|
+
if (importsRigHostPackages && !canImportRigWorkspacePackagesDirectly(source, cwd)) {
|
|
404
|
+
return importConfigViaRuntimeBundleUnserialized(p);
|
|
405
|
+
}
|
|
406
|
+
try {
|
|
407
|
+
return await import(pathToFileURL(p).href);
|
|
408
|
+
} catch (error) {
|
|
409
|
+
if (!isModuleResolutionError(error))
|
|
410
|
+
throw error;
|
|
411
|
+
return importConfigViaRuntimeBundleUnserialized(p);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
15
414
|
const raw = mod.default ?? mod.config;
|
|
16
|
-
return
|
|
415
|
+
return decodeExplicitPluginConfig(raw);
|
|
17
416
|
}
|
|
18
417
|
}
|
|
418
|
+
const declarativePath = findDeclarativeConfigPath(cwd);
|
|
419
|
+
if (declarativePath) {
|
|
420
|
+
return loadDeclarativeConfig(declarativePath);
|
|
421
|
+
}
|
|
19
422
|
for (const name of JSON_NAMES) {
|
|
20
|
-
const p =
|
|
21
|
-
if (
|
|
22
|
-
const raw = JSON.parse(
|
|
23
|
-
return
|
|
423
|
+
const p = join2(cwd, name);
|
|
424
|
+
if (existsSync2(p)) {
|
|
425
|
+
const raw = JSON.parse(readFileSync2(p, "utf-8"));
|
|
426
|
+
return decodeExplicitPluginConfig(raw);
|
|
24
427
|
}
|
|
25
428
|
}
|
|
26
|
-
throw new Error(`no rig.config.{ts,mts,json} found in ${cwd}`);
|
|
429
|
+
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
27
430
|
}
|
|
28
|
-
function
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
runtimeByName.set(plugin.name, plugin.__runtime);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const decoded = Schema.decodeUnknownSync(RigConfig)(raw);
|
|
39
|
-
const plugins = decoded.plugins.map((p) => {
|
|
40
|
-
const runtime = runtimeByName.get(p.name);
|
|
41
|
-
if (!runtime)
|
|
42
|
-
return p;
|
|
43
|
-
return { ...p, __runtime: runtime };
|
|
431
|
+
function decodeExplicitPluginConfig(raw) {
|
|
432
|
+
const withDefaults = applyConfigDefaults(raw);
|
|
433
|
+
const explicitPlugins = Array.isArray(withDefaults.plugins) ? [...withDefaults.plugins] : [];
|
|
434
|
+
const decoded = Schema3.decodeUnknownSync(RigConfig3)({
|
|
435
|
+
...withDefaults,
|
|
436
|
+
plugins: explicitPlugins
|
|
44
437
|
});
|
|
45
|
-
return { ...decoded, plugins };
|
|
438
|
+
return { ...decoded, plugins: explicitPlugins };
|
|
46
439
|
}
|
|
47
440
|
export {
|
|
48
441
|
loadConfig
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type PlacementKind = "local" | "remote";
|
|
2
|
+
export type Placement = {
|
|
3
|
+
readonly alias: string;
|
|
4
|
+
readonly kind: PlacementKind;
|
|
5
|
+
readonly host?: string | null;
|
|
6
|
+
readonly port?: number | null;
|
|
7
|
+
readonly baseUrl?: string | null;
|
|
8
|
+
readonly projectRoot?: string | null;
|
|
9
|
+
readonly status?: string | null;
|
|
10
|
+
readonly taskSource?: string | null;
|
|
11
|
+
};
|
|
12
|
+
export type RepoConnectionState = {
|
|
13
|
+
selected: string;
|
|
14
|
+
project?: string;
|
|
15
|
+
linkedAt?: string;
|
|
16
|
+
serverProjectRoot?: string;
|
|
17
|
+
serverProjectRootAlias?: string;
|
|
18
|
+
serverProjectRootBaseUrl?: string;
|
|
19
|
+
};
|
|
20
|
+
export type AddPlacementInput = {
|
|
21
|
+
readonly alias: string;
|
|
22
|
+
readonly host: string;
|
|
23
|
+
readonly port?: number;
|
|
24
|
+
readonly token?: string | null;
|
|
25
|
+
readonly select?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export declare function resolveRepoConnectionPath(projectRoot: string): string;
|
|
28
|
+
export declare function readSelection(projectRoot: string): RepoConnectionState | null;
|
|
29
|
+
export declare const readRepoConnection: typeof readSelection;
|
|
30
|
+
export declare function writeSelection(projectRoot: string, state: RepoConnectionState): void;
|
|
31
|
+
export declare const writeRepoConnection: typeof writeSelection;
|
|
32
|
+
export declare function readPlacement(projectRoot: string, env?: NodeJS.ProcessEnv): Promise<Placement>;
|
|
33
|
+
export declare const readSelectedTarget: typeof readPlacement;
|
|
34
|
+
export declare function listPlacements(projectRoot: string): Placement[];
|
|
35
|
+
export declare const listServerTargets: typeof listPlacements;
|
|
36
|
+
export declare function selectPlacement(projectRoot: string, alias: string, options?: {
|
|
37
|
+
dryRun?: boolean;
|
|
38
|
+
}): Placement;
|
|
39
|
+
export declare const selectServerTarget: typeof selectPlacement;
|
|
40
|
+
export declare function addPlacement(projectRoot: string, input: AddPlacementInput, options?: {
|
|
41
|
+
dryRun?: boolean;
|
|
42
|
+
}): Placement;
|
|
43
|
+
export declare const addRemoteTarget: typeof addPlacement;
|
|
44
|
+
export declare function removePlacement(projectRoot: string, alias: string, options?: {
|
|
45
|
+
dryRun?: boolean;
|
|
46
|
+
}): {
|
|
47
|
+
readonly alias: string;
|
|
48
|
+
readonly removed: boolean;
|
|
49
|
+
};
|
|
50
|
+
export declare const removeServerTarget: typeof removePlacement;
|