@h-rig/core 0.0.6-alpha.164 → 0.0.6-alpha.166
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/capability-loaders.js +15 -6
- package/dist/src/default-kernel.d.ts +1 -0
- package/dist/src/default-kernel.js +12 -0
- package/dist/src/hook-materializer.js +12 -5
- package/dist/src/hook-protocol.d.ts +2 -0
- package/dist/src/hook-protocol.js +462 -0
- package/dist/src/hook-runner.js +8 -4
- package/dist/src/hook-runtime.d.ts +42 -1
- package/dist/src/hook-runtime.js +159 -4
- package/dist/src/kernel-boot.d.ts +2 -0
- package/dist/src/kernel-boot.js +10 -0
- package/dist/src/kernel-entrypoint.d.ts +2 -2
- package/dist/src/kernel-entrypoint.js +16 -5
- package/dist/src/kernel-plugin-abi.d.ts +1 -0
- package/dist/src/kernel-plugin-abi.js +1 -0
- package/dist/src/kernel-resolver.d.ts +2 -0
- package/dist/src/kernel-resolver.js +6 -0
- package/dist/src/layout.js +1 -1
- package/dist/src/load-config.js +3 -3
- package/dist/src/placement.js +3 -3
- package/dist/src/plugin-host-context.js +28 -12
- package/dist/src/project-plugins.js +17 -7
- package/package.json +23 -3
|
@@ -313,8 +313,8 @@ function loadDeclarativeConfig(path) {
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
// packages/core/src/load-config.ts
|
|
316
|
-
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
317
|
-
var JSON_NAMES = ["rig.config.json"];
|
|
316
|
+
var TS_NAMES = [".rig/rig.config.ts", ".rig/rig.config.mts"];
|
|
317
|
+
var JSON_NAMES = [".rig/rig.config.json"];
|
|
318
318
|
function isModuleResolutionError(error) {
|
|
319
319
|
const message = error instanceof Error ? error.message : String(error);
|
|
320
320
|
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
@@ -649,7 +649,7 @@ async function loadConfig(cwd) {
|
|
|
649
649
|
return decodeExplicitPluginConfig(raw);
|
|
650
650
|
}
|
|
651
651
|
}
|
|
652
|
-
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
652
|
+
throw new Error(`no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
653
653
|
}
|
|
654
654
|
function decodeExplicitPluginConfig(raw) {
|
|
655
655
|
const withDefaults = applyConfigDefaults(raw);
|
|
@@ -662,10 +662,19 @@ function decodeExplicitPluginConfig(raw) {
|
|
|
662
662
|
}
|
|
663
663
|
|
|
664
664
|
// packages/core/src/project-plugins.ts
|
|
665
|
-
var
|
|
665
|
+
var TS_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts"];
|
|
666
|
+
var JSON_CONFIG_FILENAMES = ["rig.config.json"];
|
|
666
667
|
function findProjectConfigPath(projectRoot) {
|
|
667
|
-
for (const name of
|
|
668
|
-
const path = resolve2(projectRoot, name);
|
|
668
|
+
for (const name of TS_CONFIG_FILENAMES) {
|
|
669
|
+
const path = resolve2(projectRoot, ".rig", name);
|
|
670
|
+
if (existsSync3(path))
|
|
671
|
+
return path;
|
|
672
|
+
}
|
|
673
|
+
const declarativePath = findDeclarativeConfigPath(projectRoot);
|
|
674
|
+
if (declarativePath)
|
|
675
|
+
return declarativePath;
|
|
676
|
+
for (const name of JSON_CONFIG_FILENAMES) {
|
|
677
|
+
const path = resolve2(projectRoot, ".rig", name);
|
|
669
678
|
if (existsSync3(path))
|
|
670
679
|
return path;
|
|
671
680
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createDefaultKernel, createDefaultKernelPlugin, createPlacementTransportPlugin, } from "@rig/kernel-seed/default-kernel";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/default-kernel.ts
|
|
3
|
+
import {
|
|
4
|
+
createDefaultKernel,
|
|
5
|
+
createDefaultKernelPlugin,
|
|
6
|
+
createPlacementTransportPlugin
|
|
7
|
+
} from "@rig/kernel-seed/default-kernel";
|
|
8
|
+
export {
|
|
9
|
+
createPlacementTransportPlugin,
|
|
10
|
+
createDefaultKernelPlugin,
|
|
11
|
+
createDefaultKernel
|
|
12
|
+
};
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/core/src/hook-materializer.ts
|
|
3
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
3
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
4
4
|
import { dirname, resolve as resolve2 } from "path";
|
|
5
5
|
|
|
6
6
|
// packages/core/src/hook-runtime.ts
|
|
7
|
-
import { existsSync, readFileSync, realpathSync, writeSync } from "fs";
|
|
7
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeSync } from "fs";
|
|
8
8
|
import { resolve } from "path";
|
|
9
9
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME } from "@rig/contracts";
|
|
10
|
+
function bunRuntime() {
|
|
11
|
+
const runtime = globalThis;
|
|
12
|
+
return runtime.Bun;
|
|
13
|
+
}
|
|
10
14
|
function normalizeBuildConfig(value) {
|
|
11
15
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
12
16
|
return {};
|
|
@@ -30,7 +34,11 @@ function readBuildConfigForCoreHooks() {
|
|
|
30
34
|
var BUILD_CONFIG = readBuildConfigForCoreHooks();
|
|
31
35
|
var BAKED_PROJECT_ROOT = BUILD_CONFIG.AGENT_PROJECT_ROOT ?? "";
|
|
32
36
|
var BAKED_TASK_ID = BUILD_CONFIG.AGENT_TASK_ID ?? "";
|
|
37
|
+
var BAKED_STATE_DIR = BUILD_CONFIG.AGENT_STATE_DIR ?? "";
|
|
33
38
|
var BAKED_BUN_PATH = BUILD_CONFIG.AGENT_BUN_PATH ?? "";
|
|
39
|
+
var BAKED_TASK_CONFIG = BUILD_CONFIG.AGENT_TASK_CONFIG ?? "";
|
|
40
|
+
var BAKED_POLICY_CONTENT = BUILD_CONFIG.AGENT_POLICY_CONTENT ?? "";
|
|
41
|
+
var BAKED_TASK_SCOPES = BUILD_CONFIG.AGENT_TASK_SCOPES ?? "";
|
|
34
42
|
function normalizeExecutablePath(candidate) {
|
|
35
43
|
if (!candidate) {
|
|
36
44
|
return "";
|
|
@@ -54,8 +62,7 @@ function resolveBunBinaryPath() {
|
|
|
54
62
|
if (explicit) {
|
|
55
63
|
return explicit;
|
|
56
64
|
}
|
|
57
|
-
const
|
|
58
|
-
const bunWhich = bunGlobal?.which?.("bun");
|
|
65
|
+
const bunWhich = bunRuntime()?.which?.("bun");
|
|
59
66
|
const pathBun = normalizeExecutablePath(bunWhich?.trim());
|
|
60
67
|
if (pathBun && !looksLikeRuntimeGateway(pathBun)) {
|
|
61
68
|
return pathBun;
|
|
@@ -245,7 +252,7 @@ function writeClaudeCodeHookSettings(projectRoot, entries) {
|
|
|
245
252
|
const settingsPath = resolve2(projectRoot, ".claude", "settings.json");
|
|
246
253
|
const existing = existsSync2(settingsPath) ? safeReadJson(settingsPath) : {};
|
|
247
254
|
const { settings, events } = applyClaudeCodeSessionHooksToSettings(existing, entries, projectRoot);
|
|
248
|
-
|
|
255
|
+
mkdirSync2(dirname(settingsPath), { recursive: true });
|
|
249
256
|
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
|
|
250
257
|
`, "utf-8");
|
|
251
258
|
return {
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export type { HookInput, ParsedHookInput, TypedHookOptions } from "./hook-runtime";
|
|
2
|
+
export { BAKED_BUN_PATH, BAKED_POLICY_CONTENT, BAKED_PROJECT_ROOT, BAKED_STATE_DIR, BAKED_TASK_CONFIG, BAKED_TASK_ID, BAKED_TASK_SCOPES, block, buildPluginHookContext, escapeRegExp, extractToolFilePaths, hookResultToProtocol, isTestFilePath, readHookInput, resolveBunCli, resolveBunCliInvocation, resolvePolicyContent, resolveProjectRoot, resolveTaskConfig, resolveTaskIdForHook, resolveTaskScopes, runTypedHook, } from "./hook-runtime";
|
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/hook-runtime.ts
|
|
3
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeSync } from "fs";
|
|
4
|
+
import { resolve } from "path";
|
|
5
|
+
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME } from "@rig/contracts";
|
|
6
|
+
function bunRuntime() {
|
|
7
|
+
const runtime = globalThis;
|
|
8
|
+
return runtime.Bun;
|
|
9
|
+
}
|
|
10
|
+
function normalizeBuildConfig(value) {
|
|
11
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
|
|
15
|
+
}
|
|
16
|
+
function readBuildConfigForCoreHooks() {
|
|
17
|
+
if (typeof __RIG_BUILD_CONFIG__ !== "undefined") {
|
|
18
|
+
return normalizeBuildConfig(__RIG_BUILD_CONFIG__);
|
|
19
|
+
}
|
|
20
|
+
const raw = process.env.RIG_BUILD_CONFIG_JSON?.trim();
|
|
21
|
+
if (!raw) {
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
return normalizeBuildConfig(JSON.parse(raw));
|
|
26
|
+
} catch {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
var BUILD_CONFIG = readBuildConfigForCoreHooks();
|
|
31
|
+
var BAKED_PROJECT_ROOT = BUILD_CONFIG.AGENT_PROJECT_ROOT ?? "";
|
|
32
|
+
var BAKED_TASK_ID = BUILD_CONFIG.AGENT_TASK_ID ?? "";
|
|
33
|
+
var BAKED_STATE_DIR = BUILD_CONFIG.AGENT_STATE_DIR ?? "";
|
|
34
|
+
var BAKED_BUN_PATH = BUILD_CONFIG.AGENT_BUN_PATH ?? "";
|
|
35
|
+
var BAKED_TASK_CONFIG = BUILD_CONFIG.AGENT_TASK_CONFIG ?? "";
|
|
36
|
+
var BAKED_POLICY_CONTENT = BUILD_CONFIG.AGENT_POLICY_CONTENT ?? "";
|
|
37
|
+
var BAKED_TASK_SCOPES = BUILD_CONFIG.AGENT_TASK_SCOPES ?? "";
|
|
38
|
+
var RUNTIME_CONTEXT_ENV = "RIG_RUNTIME_CONTEXT_FILE";
|
|
39
|
+
function isPlainObject(value) {
|
|
40
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41
|
+
}
|
|
42
|
+
function isStringArray(value) {
|
|
43
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
44
|
+
}
|
|
45
|
+
function loadHookContextFromEnv() {
|
|
46
|
+
const contextFile = process.env[RUNTIME_CONTEXT_ENV]?.trim();
|
|
47
|
+
let filePath = contextFile || "";
|
|
48
|
+
if (!filePath) {
|
|
49
|
+
let current = resolve(process.cwd());
|
|
50
|
+
while (true) {
|
|
51
|
+
const candidate = resolve(current, "runtime-context.json");
|
|
52
|
+
if (existsSync(candidate)) {
|
|
53
|
+
filePath = candidate;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
const parent = resolve(current, "..");
|
|
57
|
+
if (parent === current) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
current = parent;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!filePath || !existsSync(filePath)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const raw = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
68
|
+
if (!isPlainObject(raw)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const taskId = typeof raw.taskId === "string" ? raw.taskId : "";
|
|
72
|
+
const role = typeof raw.role === "string" ? raw.role : "";
|
|
73
|
+
const scopes = isStringArray(raw.scopes) ? raw.scopes : [];
|
|
74
|
+
const validation = isStringArray(raw.validation) ? raw.validation : [];
|
|
75
|
+
const hostProjectRoot = typeof raw.hostProjectRoot === "string" ? raw.hostProjectRoot : undefined;
|
|
76
|
+
const monorepoMainRoot = typeof raw.monorepoMainRoot === "string" ? raw.monorepoMainRoot : undefined;
|
|
77
|
+
const stateDir = typeof raw.stateDir === "string" ? raw.stateDir : "";
|
|
78
|
+
const policyFile = typeof raw.policyFile === "string" ? raw.policyFile : "";
|
|
79
|
+
if (!taskId || !stateDir) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
taskId,
|
|
84
|
+
role,
|
|
85
|
+
scopes,
|
|
86
|
+
validation,
|
|
87
|
+
hostProjectRoot,
|
|
88
|
+
monorepoMainRoot,
|
|
89
|
+
stateDir,
|
|
90
|
+
policyFile
|
|
91
|
+
};
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
var cachedContext;
|
|
97
|
+
function getContext() {
|
|
98
|
+
if (cachedContext !== undefined) {
|
|
99
|
+
return cachedContext;
|
|
100
|
+
}
|
|
101
|
+
cachedContext = loadHookContextFromEnv();
|
|
102
|
+
return cachedContext;
|
|
103
|
+
}
|
|
104
|
+
function resolveProjectRoot() {
|
|
105
|
+
const ctx = getContext();
|
|
106
|
+
if (ctx?.hostProjectRoot)
|
|
107
|
+
return ctx.hostProjectRoot;
|
|
108
|
+
if (BAKED_PROJECT_ROOT) {
|
|
109
|
+
return BAKED_PROJECT_ROOT;
|
|
110
|
+
}
|
|
111
|
+
if (process.env.PROJECT_RIG_ROOT) {
|
|
112
|
+
return process.env.PROJECT_RIG_ROOT;
|
|
113
|
+
}
|
|
114
|
+
const candidates = [process.cwd(), resolve(import.meta.dirname, "../..")];
|
|
115
|
+
for (const candidate of candidates) {
|
|
116
|
+
if (existsSync(resolve(candidate, RIG_DEFINITION_DIRNAME)) || existsSync(resolve(candidate, RIG_STATE_DIRNAME))) {
|
|
117
|
+
return candidate;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return resolve(import.meta.dirname, "../..");
|
|
121
|
+
}
|
|
122
|
+
function resolveTaskIdForHook(_projectRoot) {
|
|
123
|
+
const ctx = getContext();
|
|
124
|
+
if (ctx)
|
|
125
|
+
return ctx.taskId;
|
|
126
|
+
if (BAKED_TASK_ID) {
|
|
127
|
+
return BAKED_TASK_ID;
|
|
128
|
+
}
|
|
129
|
+
const fromEnv = (process.env.RIG_TASK_ID || "").trim();
|
|
130
|
+
if (fromEnv) {
|
|
131
|
+
return fromEnv;
|
|
132
|
+
}
|
|
133
|
+
const runtimeId = (process.env.RIG_TASK_RUNTIME_ID || "").trim();
|
|
134
|
+
if (runtimeId.startsWith("task-") && runtimeId.length > "task-".length) {
|
|
135
|
+
return runtimeId.slice("task-".length);
|
|
136
|
+
}
|
|
137
|
+
return "";
|
|
138
|
+
}
|
|
139
|
+
function isTaskConfigEntry(value) {
|
|
140
|
+
if (!isPlainObject(value)) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if ("role" in value && value.role !== undefined && typeof value.role !== "string") {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if ("scope" in value && value.scope !== undefined && !isStringArray(value.scope)) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
if ("validation" in value && value.validation !== undefined && !isStringArray(value.validation)) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
async function readTaskConfigFromDisk(configPath) {
|
|
155
|
+
if (!existsSync(configPath)) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const bunFile = bunRuntime()?.file;
|
|
160
|
+
const content = bunFile ? await bunFile(configPath).json() : JSON.parse(readFileSync(configPath, "utf-8"));
|
|
161
|
+
return isPlainObject(content) ? content : null;
|
|
162
|
+
} catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function taskConfigCandidates(ctx) {
|
|
167
|
+
const taskWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
168
|
+
return [
|
|
169
|
+
ctx?.monorepoMainRoot ? resolve(ctx.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
170
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
171
|
+
taskWorkspace ? resolve(taskWorkspace, ".rig", "task-config.json") : ""
|
|
172
|
+
].filter(Boolean);
|
|
173
|
+
}
|
|
174
|
+
async function resolveTaskConfig(_projectRoot, _taskId) {
|
|
175
|
+
const ctx = getContext();
|
|
176
|
+
if (ctx) {
|
|
177
|
+
return {
|
|
178
|
+
scope: ctx.scopes,
|
|
179
|
+
validation: ctx.validation,
|
|
180
|
+
role: ctx.role
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (BAKED_TASK_CONFIG) {
|
|
184
|
+
try {
|
|
185
|
+
const parsed = JSON.parse(BAKED_TASK_CONFIG);
|
|
186
|
+
if (isTaskConfigEntry(parsed) && Object.keys(parsed).length > 0) {
|
|
187
|
+
return parsed;
|
|
188
|
+
}
|
|
189
|
+
} catch {}
|
|
190
|
+
}
|
|
191
|
+
for (const configPath of taskConfigCandidates(ctx)) {
|
|
192
|
+
const config = await readTaskConfigFromDisk(configPath);
|
|
193
|
+
if (!config) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const taskEntry = config[_taskId];
|
|
197
|
+
if (isTaskConfigEntry(taskEntry)) {
|
|
198
|
+
return taskEntry;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return {};
|
|
202
|
+
}
|
|
203
|
+
async function resolveTaskScopes(projectRoot, taskId) {
|
|
204
|
+
const ctx = getContext();
|
|
205
|
+
if (ctx && ctx.scopes.length > 0)
|
|
206
|
+
return ctx.scopes;
|
|
207
|
+
if (BAKED_TASK_SCOPES) {
|
|
208
|
+
try {
|
|
209
|
+
const parsed = JSON.parse(BAKED_TASK_SCOPES);
|
|
210
|
+
if (Array.isArray(parsed) && parsed.length > 0 && parsed.every((item) => typeof item === "string")) {
|
|
211
|
+
return parsed;
|
|
212
|
+
}
|
|
213
|
+
} catch {}
|
|
214
|
+
}
|
|
215
|
+
return (await resolveTaskConfig(projectRoot, taskId)).scope || [];
|
|
216
|
+
}
|
|
217
|
+
function resolvePolicyContent(projectRoot) {
|
|
218
|
+
const ctx = getContext();
|
|
219
|
+
if (ctx?.policyFile && existsSync(ctx.policyFile)) {
|
|
220
|
+
return readFileSync(ctx.policyFile, "utf-8");
|
|
221
|
+
}
|
|
222
|
+
if (BAKED_POLICY_CONTENT)
|
|
223
|
+
return BAKED_POLICY_CONTENT;
|
|
224
|
+
const policyPath = resolve(projectRoot, "rig/policy/policy.json");
|
|
225
|
+
if (existsSync(policyPath))
|
|
226
|
+
return readFileSync(policyPath, "utf-8");
|
|
227
|
+
return "{}";
|
|
228
|
+
}
|
|
229
|
+
async function readHookInput() {
|
|
230
|
+
let text = "";
|
|
231
|
+
const inputFile = process.env.RIG_HOOK_INPUT_FILE?.trim();
|
|
232
|
+
if (inputFile) {
|
|
233
|
+
text = readFileSync(inputFile, "utf-8");
|
|
234
|
+
} else {
|
|
235
|
+
try {
|
|
236
|
+
text = readFileSync("/dev/stdin", "utf-8");
|
|
237
|
+
} catch {
|
|
238
|
+
text = readFileSync(0, "utf-8");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (!text.trim()) {
|
|
242
|
+
return { input: {}, valid: true, hadPayload: false };
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
return {
|
|
246
|
+
input: JSON.parse(text),
|
|
247
|
+
valid: true,
|
|
248
|
+
hadPayload: true
|
|
249
|
+
};
|
|
250
|
+
} catch {
|
|
251
|
+
return { input: {}, valid: false, hadPayload: true };
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function extractToolFilePaths(toolName, input) {
|
|
255
|
+
const paths = [];
|
|
256
|
+
const add = (value) => {
|
|
257
|
+
if (typeof value === "string" && value.trim()) {
|
|
258
|
+
paths.push(value.trim());
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
if (toolName === "Read" || toolName === "Write" || toolName === "Edit" || toolName === "MultiEdit") {
|
|
262
|
+
add(input.file_path);
|
|
263
|
+
add(input.path);
|
|
264
|
+
} else if (toolName === "Glob") {
|
|
265
|
+
add(input.path);
|
|
266
|
+
} else if (toolName === "Grep") {
|
|
267
|
+
add(input.path);
|
|
268
|
+
} else {
|
|
269
|
+
add(input.file_path);
|
|
270
|
+
add(input.path);
|
|
271
|
+
}
|
|
272
|
+
return paths;
|
|
273
|
+
}
|
|
274
|
+
function isTestFilePath(path) {
|
|
275
|
+
return /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(path) || /\/(__tests__|tests|test)\//.test(path);
|
|
276
|
+
}
|
|
277
|
+
function buildPluginHookContext(parsed, opts) {
|
|
278
|
+
const toolName = parsed.input.tool_name;
|
|
279
|
+
const toolInput = parsed.input.tool_input ?? {};
|
|
280
|
+
return {
|
|
281
|
+
event: opts.event,
|
|
282
|
+
toolName,
|
|
283
|
+
toolInput,
|
|
284
|
+
filePaths: toolName ? extractToolFilePaths(toolName, toolInput) : [],
|
|
285
|
+
projectRoot: opts.projectRoot,
|
|
286
|
+
taskId: opts.taskId
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function hookResultToProtocol(result) {
|
|
290
|
+
if (result.decision === "block") {
|
|
291
|
+
const lines = [`BLOCKED: ${result.reason ?? "blocked by plugin hook"}`];
|
|
292
|
+
if (result.systemMessage) {
|
|
293
|
+
lines.push(result.systemMessage);
|
|
294
|
+
}
|
|
295
|
+
return { exitCode: 1, stdout: `${lines.join(`
|
|
296
|
+
`)}
|
|
297
|
+
` };
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
exitCode: 0,
|
|
301
|
+
stdout: result.systemMessage ? `${result.systemMessage}
|
|
302
|
+
` : ""
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function escapeRegExp(value) {
|
|
306
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
307
|
+
}
|
|
308
|
+
function block(hookName, message, projectRoot) {
|
|
309
|
+
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
310
|
+
const stateDir = BAKED_STATE_DIR || (runtimeWorkspace ? resolve(runtimeWorkspace, ".rig", "state") : resolve(projectRoot, ".rig", "state"));
|
|
311
|
+
mkdirSync(stateDir, { recursive: true });
|
|
312
|
+
const tripLog = resolve(stateDir, "hook_trips.log");
|
|
313
|
+
let count = 0;
|
|
314
|
+
if (existsSync(tripLog)) {
|
|
315
|
+
const content = readFileSync(tripLog, "utf-8");
|
|
316
|
+
count = (content.match(new RegExp(`^${escapeRegExp(hookName)}\\s`, "gm")) || []).length;
|
|
317
|
+
}
|
|
318
|
+
appendFileSync(tripLog, `${hookName} ${new Date().toISOString()}
|
|
319
|
+
`, "utf-8");
|
|
320
|
+
count += 1;
|
|
321
|
+
const lines = [
|
|
322
|
+
`BLOCKED: ${message}`,
|
|
323
|
+
"",
|
|
324
|
+
"Re-read CLAUDE.md safety rules before your next action."
|
|
325
|
+
];
|
|
326
|
+
if (count >= 3) {
|
|
327
|
+
lines.push("");
|
|
328
|
+
lines.push(`REPEATED VIOLATION (${count}x ${hookName}).`);
|
|
329
|
+
lines.push("STOP. Read the FULL CLAUDE.md from top to bottom.");
|
|
330
|
+
lines.push("If stuck, write the problem to .rig/state/failed_approaches.md and request help.");
|
|
331
|
+
}
|
|
332
|
+
writeSync(1, `${lines.join(`
|
|
333
|
+
`)}
|
|
334
|
+
`);
|
|
335
|
+
process.exit(1);
|
|
336
|
+
}
|
|
337
|
+
function normalizeExecutablePath(candidate) {
|
|
338
|
+
if (!candidate) {
|
|
339
|
+
return "";
|
|
340
|
+
}
|
|
341
|
+
const normalized = resolve(candidate);
|
|
342
|
+
if (!existsSync(normalized)) {
|
|
343
|
+
return "";
|
|
344
|
+
}
|
|
345
|
+
try {
|
|
346
|
+
return realpathSync(normalized);
|
|
347
|
+
} catch {
|
|
348
|
+
return normalized;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function looksLikeRuntimeGateway(candidate) {
|
|
352
|
+
const normalized = resolve(candidate).replace(/\\/g, "/");
|
|
353
|
+
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
354
|
+
}
|
|
355
|
+
function resolveBunBinaryPath() {
|
|
356
|
+
const explicit = normalizeExecutablePath(process.env.RIG_BUN_PATH?.trim());
|
|
357
|
+
if (explicit) {
|
|
358
|
+
return explicit;
|
|
359
|
+
}
|
|
360
|
+
const bunWhich = bunRuntime()?.which?.("bun");
|
|
361
|
+
const pathBun = normalizeExecutablePath(bunWhich?.trim());
|
|
362
|
+
if (pathBun && !looksLikeRuntimeGateway(pathBun)) {
|
|
363
|
+
return pathBun;
|
|
364
|
+
}
|
|
365
|
+
const home = process.env.HOME?.trim();
|
|
366
|
+
const fallbackCandidates = [
|
|
367
|
+
home ? resolve(home, ".bun/bin/bun") : "",
|
|
368
|
+
"/opt/homebrew/bin/bun",
|
|
369
|
+
"/usr/local/bin/bun",
|
|
370
|
+
"/usr/bin/bun"
|
|
371
|
+
];
|
|
372
|
+
for (const candidate of fallbackCandidates) {
|
|
373
|
+
const normalized = normalizeExecutablePath(candidate);
|
|
374
|
+
if (normalized) {
|
|
375
|
+
return normalized;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const execPath = normalizeExecutablePath(process.execPath?.trim());
|
|
379
|
+
if (execPath && !looksLikeRuntimeGateway(execPath)) {
|
|
380
|
+
return execPath;
|
|
381
|
+
}
|
|
382
|
+
throw new Error("bun not found in PATH");
|
|
383
|
+
}
|
|
384
|
+
function resolveBunCli() {
|
|
385
|
+
return resolveBunCliInvocation().command;
|
|
386
|
+
}
|
|
387
|
+
function resolveBunCliInvocation() {
|
|
388
|
+
if (BAKED_BUN_PATH) {
|
|
389
|
+
return {
|
|
390
|
+
command: BAKED_BUN_PATH,
|
|
391
|
+
env: {}
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
395
|
+
return {
|
|
396
|
+
command: process.env.RIG_BUN_PATH.trim(),
|
|
397
|
+
env: {}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
try {
|
|
401
|
+
const systemBun = resolveBunBinaryPath();
|
|
402
|
+
return {
|
|
403
|
+
command: systemBun,
|
|
404
|
+
env: {}
|
|
405
|
+
};
|
|
406
|
+
} catch {}
|
|
407
|
+
if (process.execPath?.trim()) {
|
|
408
|
+
return {
|
|
409
|
+
command: process.execPath,
|
|
410
|
+
env: { BUN_BE_BUN: "1" }
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
return { command: "bun", env: {} };
|
|
414
|
+
}
|
|
415
|
+
async function runTypedHook(fn, opts) {
|
|
416
|
+
const parsed = await readHookInput();
|
|
417
|
+
const projectRoot = opts.projectRoot ?? resolveProjectRoot();
|
|
418
|
+
const taskId = opts.taskId ?? resolveTaskIdForHook(projectRoot);
|
|
419
|
+
const ctx = buildPluginHookContext(parsed, {
|
|
420
|
+
event: opts.event,
|
|
421
|
+
projectRoot,
|
|
422
|
+
taskId
|
|
423
|
+
});
|
|
424
|
+
let result;
|
|
425
|
+
try {
|
|
426
|
+
result = await fn(ctx);
|
|
427
|
+
} catch (err) {
|
|
428
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
429
|
+
writeSync(2, `[rig hook] typed hook threw: ${message}
|
|
430
|
+
`);
|
|
431
|
+
process.exit(0);
|
|
432
|
+
}
|
|
433
|
+
const { exitCode, stdout } = hookResultToProtocol(result);
|
|
434
|
+
if (stdout) {
|
|
435
|
+
writeSync(1, stdout);
|
|
436
|
+
}
|
|
437
|
+
process.exit(exitCode);
|
|
438
|
+
}
|
|
439
|
+
export {
|
|
440
|
+
runTypedHook,
|
|
441
|
+
resolveTaskScopes,
|
|
442
|
+
resolveTaskIdForHook,
|
|
443
|
+
resolveTaskConfig,
|
|
444
|
+
resolveProjectRoot,
|
|
445
|
+
resolvePolicyContent,
|
|
446
|
+
resolveBunCliInvocation,
|
|
447
|
+
resolveBunCli,
|
|
448
|
+
readHookInput,
|
|
449
|
+
isTestFilePath,
|
|
450
|
+
hookResultToProtocol,
|
|
451
|
+
extractToolFilePaths,
|
|
452
|
+
escapeRegExp,
|
|
453
|
+
buildPluginHookContext,
|
|
454
|
+
block,
|
|
455
|
+
BAKED_TASK_SCOPES,
|
|
456
|
+
BAKED_TASK_ID,
|
|
457
|
+
BAKED_TASK_CONFIG,
|
|
458
|
+
BAKED_STATE_DIR,
|
|
459
|
+
BAKED_PROJECT_ROOT,
|
|
460
|
+
BAKED_POLICY_CONTENT,
|
|
461
|
+
BAKED_BUN_PATH
|
|
462
|
+
};
|
package/dist/src/hook-runner.js
CHANGED
|
@@ -90,8 +90,8 @@ function loadDeclarativeConfig(path) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// packages/core/src/load-config.ts
|
|
93
|
-
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
94
|
-
var JSON_NAMES = ["rig.config.json"];
|
|
93
|
+
var TS_NAMES = [".rig/rig.config.ts", ".rig/rig.config.mts"];
|
|
94
|
+
var JSON_NAMES = [".rig/rig.config.json"];
|
|
95
95
|
function isModuleResolutionError(error) {
|
|
96
96
|
const message = error instanceof Error ? error.message : String(error);
|
|
97
97
|
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
@@ -426,7 +426,7 @@ async function loadConfig(cwd) {
|
|
|
426
426
|
return decodeExplicitPluginConfig(raw);
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
|
-
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
429
|
+
throw new Error(`no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
430
430
|
}
|
|
431
431
|
function decodeExplicitPluginConfig(raw) {
|
|
432
432
|
const withDefaults = applyConfigDefaults(raw);
|
|
@@ -439,7 +439,7 @@ function decodeExplicitPluginConfig(raw) {
|
|
|
439
439
|
}
|
|
440
440
|
|
|
441
441
|
// packages/core/src/hook-runtime.ts
|
|
442
|
-
import { existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, writeSync } from "fs";
|
|
442
|
+
import { appendFileSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync, writeSync } from "fs";
|
|
443
443
|
import { resolve as resolve2 } from "path";
|
|
444
444
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME } from "@rig/contracts";
|
|
445
445
|
function normalizeBuildConfig(value) {
|
|
@@ -465,7 +465,11 @@ function readBuildConfigForCoreHooks() {
|
|
|
465
465
|
var BUILD_CONFIG = readBuildConfigForCoreHooks();
|
|
466
466
|
var BAKED_PROJECT_ROOT = BUILD_CONFIG.AGENT_PROJECT_ROOT ?? "";
|
|
467
467
|
var BAKED_TASK_ID = BUILD_CONFIG.AGENT_TASK_ID ?? "";
|
|
468
|
+
var BAKED_STATE_DIR = BUILD_CONFIG.AGENT_STATE_DIR ?? "";
|
|
468
469
|
var BAKED_BUN_PATH = BUILD_CONFIG.AGENT_BUN_PATH ?? "";
|
|
470
|
+
var BAKED_TASK_CONFIG = BUILD_CONFIG.AGENT_TASK_CONFIG ?? "";
|
|
471
|
+
var BAKED_POLICY_CONTENT = BUILD_CONFIG.AGENT_POLICY_CONTENT ?? "";
|
|
472
|
+
var BAKED_TASK_SCOPES = BUILD_CONFIG.AGENT_TASK_SCOPES ?? "";
|
|
469
473
|
var RUNTIME_CONTEXT_ENV = "RIG_RUNTIME_CONTEXT_FILE";
|
|
470
474
|
function isPlainObject(value) {
|
|
471
475
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1,9 +1,50 @@
|
|
|
1
|
-
import { type HookEvent, type HookImplementation } from "@rig/contracts";
|
|
1
|
+
import { type HookContext as PluginHookContext, type HookEvent, type HookImplementation, type HookResult } from "@rig/contracts";
|
|
2
|
+
export type HookInput = {
|
|
3
|
+
tool_name?: string;
|
|
4
|
+
tool_input?: Record<string, unknown>;
|
|
5
|
+
command?: string;
|
|
6
|
+
};
|
|
7
|
+
export type ParsedHookInput = {
|
|
8
|
+
input: HookInput;
|
|
9
|
+
valid: boolean;
|
|
10
|
+
hadPayload: boolean;
|
|
11
|
+
};
|
|
2
12
|
export interface TypedHookOptions {
|
|
3
13
|
readonly event: HookEvent;
|
|
4
14
|
readonly projectRoot?: string;
|
|
5
15
|
readonly taskId?: string;
|
|
6
16
|
}
|
|
17
|
+
export declare const BAKED_PROJECT_ROOT: string;
|
|
18
|
+
export declare const BAKED_TASK_ID: string;
|
|
19
|
+
export declare const BAKED_STATE_DIR: string;
|
|
20
|
+
export declare const BAKED_BUN_PATH: string;
|
|
21
|
+
export declare const BAKED_TASK_CONFIG: string;
|
|
22
|
+
export declare const BAKED_POLICY_CONTENT: string;
|
|
23
|
+
export declare const BAKED_TASK_SCOPES: string;
|
|
24
|
+
export declare function resolveProjectRoot(): string;
|
|
25
|
+
export declare function resolveTaskIdForHook(_projectRoot: string): string;
|
|
26
|
+
export declare function resolveTaskConfig(_projectRoot: string, _taskId: string): Promise<{
|
|
27
|
+
scope?: string[];
|
|
28
|
+
validation?: string[];
|
|
29
|
+
role?: string;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function resolveTaskScopes(projectRoot: string, taskId: string): Promise<string[]>;
|
|
32
|
+
export declare function resolvePolicyContent(projectRoot: string): string;
|
|
33
|
+
export declare function readHookInput(): Promise<ParsedHookInput>;
|
|
34
|
+
export declare function extractToolFilePaths(toolName: string, input: Record<string, unknown>): string[];
|
|
35
|
+
export declare function isTestFilePath(path: string): boolean;
|
|
36
|
+
export declare function buildPluginHookContext(parsed: ParsedHookInput, opts: {
|
|
37
|
+
event: HookEvent;
|
|
38
|
+
projectRoot: string;
|
|
39
|
+
taskId: string;
|
|
40
|
+
}): PluginHookContext;
|
|
41
|
+
export declare function hookResultToProtocol(result: HookResult): {
|
|
42
|
+
exitCode: 0 | 1;
|
|
43
|
+
stdout: string;
|
|
44
|
+
};
|
|
45
|
+
export declare function escapeRegExp(value: string): string;
|
|
46
|
+
export declare function block(hookName: string, message: string, projectRoot: string): never;
|
|
47
|
+
export declare function resolveBunCli(): string;
|
|
7
48
|
export declare function resolveBunCliInvocation(): {
|
|
8
49
|
command: string;
|
|
9
50
|
env: Record<string, string>;
|
package/dist/src/hook-runtime.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/core/src/hook-runtime.ts
|
|
3
|
-
import { existsSync, readFileSync, realpathSync, writeSync } from "fs";
|
|
3
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeSync } from "fs";
|
|
4
4
|
import { resolve } from "path";
|
|
5
5
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME } from "@rig/contracts";
|
|
6
|
+
function bunRuntime() {
|
|
7
|
+
const runtime = globalThis;
|
|
8
|
+
return runtime.Bun;
|
|
9
|
+
}
|
|
6
10
|
function normalizeBuildConfig(value) {
|
|
7
11
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
8
12
|
return {};
|
|
@@ -26,7 +30,11 @@ function readBuildConfigForCoreHooks() {
|
|
|
26
30
|
var BUILD_CONFIG = readBuildConfigForCoreHooks();
|
|
27
31
|
var BAKED_PROJECT_ROOT = BUILD_CONFIG.AGENT_PROJECT_ROOT ?? "";
|
|
28
32
|
var BAKED_TASK_ID = BUILD_CONFIG.AGENT_TASK_ID ?? "";
|
|
33
|
+
var BAKED_STATE_DIR = BUILD_CONFIG.AGENT_STATE_DIR ?? "";
|
|
29
34
|
var BAKED_BUN_PATH = BUILD_CONFIG.AGENT_BUN_PATH ?? "";
|
|
35
|
+
var BAKED_TASK_CONFIG = BUILD_CONFIG.AGENT_TASK_CONFIG ?? "";
|
|
36
|
+
var BAKED_POLICY_CONTENT = BUILD_CONFIG.AGENT_POLICY_CONTENT ?? "";
|
|
37
|
+
var BAKED_TASK_SCOPES = BUILD_CONFIG.AGENT_TASK_SCOPES ?? "";
|
|
30
38
|
var RUNTIME_CONTEXT_ENV = "RIG_RUNTIME_CONTEXT_FILE";
|
|
31
39
|
function isPlainObject(value) {
|
|
32
40
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -128,6 +136,96 @@ function resolveTaskIdForHook(_projectRoot) {
|
|
|
128
136
|
}
|
|
129
137
|
return "";
|
|
130
138
|
}
|
|
139
|
+
function isTaskConfigEntry(value) {
|
|
140
|
+
if (!isPlainObject(value)) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if ("role" in value && value.role !== undefined && typeof value.role !== "string") {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if ("scope" in value && value.scope !== undefined && !isStringArray(value.scope)) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
if ("validation" in value && value.validation !== undefined && !isStringArray(value.validation)) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
async function readTaskConfigFromDisk(configPath) {
|
|
155
|
+
if (!existsSync(configPath)) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const bunFile = bunRuntime()?.file;
|
|
160
|
+
const content = bunFile ? await bunFile(configPath).json() : JSON.parse(readFileSync(configPath, "utf-8"));
|
|
161
|
+
return isPlainObject(content) ? content : null;
|
|
162
|
+
} catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function taskConfigCandidates(ctx) {
|
|
167
|
+
const taskWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
168
|
+
return [
|
|
169
|
+
ctx?.monorepoMainRoot ? resolve(ctx.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
170
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
171
|
+
taskWorkspace ? resolve(taskWorkspace, ".rig", "task-config.json") : ""
|
|
172
|
+
].filter(Boolean);
|
|
173
|
+
}
|
|
174
|
+
async function resolveTaskConfig(_projectRoot, _taskId) {
|
|
175
|
+
const ctx = getContext();
|
|
176
|
+
if (ctx) {
|
|
177
|
+
return {
|
|
178
|
+
scope: ctx.scopes,
|
|
179
|
+
validation: ctx.validation,
|
|
180
|
+
role: ctx.role
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (BAKED_TASK_CONFIG) {
|
|
184
|
+
try {
|
|
185
|
+
const parsed = JSON.parse(BAKED_TASK_CONFIG);
|
|
186
|
+
if (isTaskConfigEntry(parsed) && Object.keys(parsed).length > 0) {
|
|
187
|
+
return parsed;
|
|
188
|
+
}
|
|
189
|
+
} catch {}
|
|
190
|
+
}
|
|
191
|
+
for (const configPath of taskConfigCandidates(ctx)) {
|
|
192
|
+
const config = await readTaskConfigFromDisk(configPath);
|
|
193
|
+
if (!config) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const taskEntry = config[_taskId];
|
|
197
|
+
if (isTaskConfigEntry(taskEntry)) {
|
|
198
|
+
return taskEntry;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return {};
|
|
202
|
+
}
|
|
203
|
+
async function resolveTaskScopes(projectRoot, taskId) {
|
|
204
|
+
const ctx = getContext();
|
|
205
|
+
if (ctx && ctx.scopes.length > 0)
|
|
206
|
+
return ctx.scopes;
|
|
207
|
+
if (BAKED_TASK_SCOPES) {
|
|
208
|
+
try {
|
|
209
|
+
const parsed = JSON.parse(BAKED_TASK_SCOPES);
|
|
210
|
+
if (Array.isArray(parsed) && parsed.length > 0 && parsed.every((item) => typeof item === "string")) {
|
|
211
|
+
return parsed;
|
|
212
|
+
}
|
|
213
|
+
} catch {}
|
|
214
|
+
}
|
|
215
|
+
return (await resolveTaskConfig(projectRoot, taskId)).scope || [];
|
|
216
|
+
}
|
|
217
|
+
function resolvePolicyContent(projectRoot) {
|
|
218
|
+
const ctx = getContext();
|
|
219
|
+
if (ctx?.policyFile && existsSync(ctx.policyFile)) {
|
|
220
|
+
return readFileSync(ctx.policyFile, "utf-8");
|
|
221
|
+
}
|
|
222
|
+
if (BAKED_POLICY_CONTENT)
|
|
223
|
+
return BAKED_POLICY_CONTENT;
|
|
224
|
+
const policyPath = resolve(projectRoot, "rig/policy/policy.json");
|
|
225
|
+
if (existsSync(policyPath))
|
|
226
|
+
return readFileSync(policyPath, "utf-8");
|
|
227
|
+
return "{}";
|
|
228
|
+
}
|
|
131
229
|
async function readHookInput() {
|
|
132
230
|
let text = "";
|
|
133
231
|
const inputFile = process.env.RIG_HOOK_INPUT_FILE?.trim();
|
|
@@ -173,6 +271,9 @@ function extractToolFilePaths(toolName, input) {
|
|
|
173
271
|
}
|
|
174
272
|
return paths;
|
|
175
273
|
}
|
|
274
|
+
function isTestFilePath(path) {
|
|
275
|
+
return /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(path) || /\/(__tests__|tests|test)\//.test(path);
|
|
276
|
+
}
|
|
176
277
|
function buildPluginHookContext(parsed, opts) {
|
|
177
278
|
const toolName = parsed.input.tool_name;
|
|
178
279
|
const toolInput = parsed.input.tool_input ?? {};
|
|
@@ -201,6 +302,38 @@ function hookResultToProtocol(result) {
|
|
|
201
302
|
` : ""
|
|
202
303
|
};
|
|
203
304
|
}
|
|
305
|
+
function escapeRegExp(value) {
|
|
306
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
307
|
+
}
|
|
308
|
+
function block(hookName, message, projectRoot) {
|
|
309
|
+
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
310
|
+
const stateDir = BAKED_STATE_DIR || (runtimeWorkspace ? resolve(runtimeWorkspace, ".rig", "state") : resolve(projectRoot, ".rig", "state"));
|
|
311
|
+
mkdirSync(stateDir, { recursive: true });
|
|
312
|
+
const tripLog = resolve(stateDir, "hook_trips.log");
|
|
313
|
+
let count = 0;
|
|
314
|
+
if (existsSync(tripLog)) {
|
|
315
|
+
const content = readFileSync(tripLog, "utf-8");
|
|
316
|
+
count = (content.match(new RegExp(`^${escapeRegExp(hookName)}\\s`, "gm")) || []).length;
|
|
317
|
+
}
|
|
318
|
+
appendFileSync(tripLog, `${hookName} ${new Date().toISOString()}
|
|
319
|
+
`, "utf-8");
|
|
320
|
+
count += 1;
|
|
321
|
+
const lines = [
|
|
322
|
+
`BLOCKED: ${message}`,
|
|
323
|
+
"",
|
|
324
|
+
"Re-read CLAUDE.md safety rules before your next action."
|
|
325
|
+
];
|
|
326
|
+
if (count >= 3) {
|
|
327
|
+
lines.push("");
|
|
328
|
+
lines.push(`REPEATED VIOLATION (${count}x ${hookName}).`);
|
|
329
|
+
lines.push("STOP. Read the FULL CLAUDE.md from top to bottom.");
|
|
330
|
+
lines.push("If stuck, write the problem to .rig/state/failed_approaches.md and request help.");
|
|
331
|
+
}
|
|
332
|
+
writeSync(1, `${lines.join(`
|
|
333
|
+
`)}
|
|
334
|
+
`);
|
|
335
|
+
process.exit(1);
|
|
336
|
+
}
|
|
204
337
|
function normalizeExecutablePath(candidate) {
|
|
205
338
|
if (!candidate) {
|
|
206
339
|
return "";
|
|
@@ -224,8 +357,7 @@ function resolveBunBinaryPath() {
|
|
|
224
357
|
if (explicit) {
|
|
225
358
|
return explicit;
|
|
226
359
|
}
|
|
227
|
-
const
|
|
228
|
-
const bunWhich = bunGlobal?.which?.("bun");
|
|
360
|
+
const bunWhich = bunRuntime()?.which?.("bun");
|
|
229
361
|
const pathBun = normalizeExecutablePath(bunWhich?.trim());
|
|
230
362
|
if (pathBun && !looksLikeRuntimeGateway(pathBun)) {
|
|
231
363
|
return pathBun;
|
|
@@ -249,6 +381,9 @@ function resolveBunBinaryPath() {
|
|
|
249
381
|
}
|
|
250
382
|
throw new Error("bun not found in PATH");
|
|
251
383
|
}
|
|
384
|
+
function resolveBunCli() {
|
|
385
|
+
return resolveBunCliInvocation().command;
|
|
386
|
+
}
|
|
252
387
|
function resolveBunCliInvocation() {
|
|
253
388
|
if (BAKED_BUN_PATH) {
|
|
254
389
|
return {
|
|
@@ -303,5 +438,25 @@ async function runTypedHook(fn, opts) {
|
|
|
303
438
|
}
|
|
304
439
|
export {
|
|
305
440
|
runTypedHook,
|
|
306
|
-
|
|
441
|
+
resolveTaskScopes,
|
|
442
|
+
resolveTaskIdForHook,
|
|
443
|
+
resolveTaskConfig,
|
|
444
|
+
resolveProjectRoot,
|
|
445
|
+
resolvePolicyContent,
|
|
446
|
+
resolveBunCliInvocation,
|
|
447
|
+
resolveBunCli,
|
|
448
|
+
readHookInput,
|
|
449
|
+
isTestFilePath,
|
|
450
|
+
hookResultToProtocol,
|
|
451
|
+
extractToolFilePaths,
|
|
452
|
+
escapeRegExp,
|
|
453
|
+
buildPluginHookContext,
|
|
454
|
+
block,
|
|
455
|
+
BAKED_TASK_SCOPES,
|
|
456
|
+
BAKED_TASK_ID,
|
|
457
|
+
BAKED_TASK_CONFIG,
|
|
458
|
+
BAKED_STATE_DIR,
|
|
459
|
+
BAKED_PROJECT_ROOT,
|
|
460
|
+
BAKED_POLICY_CONTENT,
|
|
461
|
+
BAKED_BUN_PATH
|
|
307
462
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JournalCapability, TransportCapability } from "@rig/contracts";
|
|
2
|
-
import { type DefaultKernelBootRecord } from "
|
|
3
|
-
import type { CapabilityProviderPlugin } from "
|
|
2
|
+
import { type DefaultKernelBootRecord } from "./kernel-boot";
|
|
3
|
+
import type { CapabilityProviderPlugin } from "./kernel-plugin-abi";
|
|
4
4
|
export type HydrationResult = {
|
|
5
5
|
readonly projectRoot: string;
|
|
6
6
|
readonly dotenvLoaded: boolean;
|
|
@@ -2,8 +2,19 @@
|
|
|
2
2
|
// packages/core/src/kernel-entrypoint.ts
|
|
3
3
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
4
4
|
import { resolve as resolve2 } from "path";
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
// packages/core/src/kernel-boot.ts
|
|
7
|
+
import {
|
|
8
|
+
bootDefaultKernelIntoProcess,
|
|
9
|
+
getProcessKernel
|
|
10
|
+
} from "@rig/kernel-seed/boot-default";
|
|
11
|
+
|
|
12
|
+
// packages/core/src/default-kernel.ts
|
|
13
|
+
import {
|
|
14
|
+
createDefaultKernel,
|
|
15
|
+
createDefaultKernelPlugin,
|
|
16
|
+
createPlacementTransportPlugin
|
|
17
|
+
} from "@rig/kernel-seed/default-kernel";
|
|
7
18
|
|
|
8
19
|
// packages/core/src/config-env.ts
|
|
9
20
|
function applyConfigEnv(config, env = process.env) {
|
|
@@ -114,8 +125,8 @@ function loadDeclarativeConfig(path) {
|
|
|
114
125
|
}
|
|
115
126
|
|
|
116
127
|
// packages/core/src/load-config.ts
|
|
117
|
-
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
118
|
-
var JSON_NAMES = ["rig.config.json"];
|
|
128
|
+
var TS_NAMES = [".rig/rig.config.ts", ".rig/rig.config.mts"];
|
|
129
|
+
var JSON_NAMES = [".rig/rig.config.json"];
|
|
119
130
|
function isModuleResolutionError(error) {
|
|
120
131
|
const message = error instanceof Error ? error.message : String(error);
|
|
121
132
|
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
@@ -450,7 +461,7 @@ async function loadConfig(cwd) {
|
|
|
450
461
|
return decodeExplicitPluginConfig(raw);
|
|
451
462
|
}
|
|
452
463
|
}
|
|
453
|
-
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
464
|
+
throw new Error(`no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
454
465
|
}
|
|
455
466
|
function decodeExplicitPluginConfig(raw) {
|
|
456
467
|
const withDefaults = applyConfigDefaults(raw);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { CapabilityProviderPlugin } from "@rig/kernel-seed/plugin-abi";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// @bun
|
package/dist/src/layout.js
CHANGED
|
@@ -45,7 +45,7 @@ function resolveNearestRigProjectRoot(startDir) {
|
|
|
45
45
|
const hasDefinition = existsSync2(resolve2(current, RIG_DEFINITION_DIRNAME));
|
|
46
46
|
const hasState = existsSync2(resolve2(current, RIG_STATE_DIRNAME));
|
|
47
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"));
|
|
48
|
+
const hasConfig = existsSync2(resolve2(current, ".rig", "rig.config.ts")) || existsSync2(resolve2(current, ".rig", "rig.config.json"));
|
|
49
49
|
const hasGit = existsSync2(resolve2(current, ".git"));
|
|
50
50
|
const hasControlPlane = existsSync2(resolve2(current, "packages", "cli", "bin", "rig.ts")) || existsSync2(resolve2(current, "packages", "server"));
|
|
51
51
|
if ((hasDefinition || hasState || hasConfig) && weakMarkerCandidate === null) {
|
package/dist/src/load-config.js
CHANGED
|
@@ -90,8 +90,8 @@ function loadDeclarativeConfig(path) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// packages/core/src/load-config.ts
|
|
93
|
-
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
94
|
-
var JSON_NAMES = ["rig.config.json"];
|
|
93
|
+
var TS_NAMES = [".rig/rig.config.ts", ".rig/rig.config.mts"];
|
|
94
|
+
var JSON_NAMES = [".rig/rig.config.json"];
|
|
95
95
|
function isModuleResolutionError(error) {
|
|
96
96
|
const message = error instanceof Error ? error.message : String(error);
|
|
97
97
|
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
@@ -426,7 +426,7 @@ async function loadConfig(cwd) {
|
|
|
426
426
|
return decodeExplicitPluginConfig(raw);
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
|
-
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
429
|
+
throw new Error(`no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
430
430
|
}
|
|
431
431
|
function decodeExplicitPluginConfig(raw) {
|
|
432
432
|
const withDefaults = applyConfigDefaults(raw);
|
package/dist/src/placement.js
CHANGED
|
@@ -94,8 +94,8 @@ function loadDeclarativeConfig(path) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// packages/core/src/load-config.ts
|
|
97
|
-
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
98
|
-
var JSON_NAMES = ["rig.config.json"];
|
|
97
|
+
var TS_NAMES = [".rig/rig.config.ts", ".rig/rig.config.mts"];
|
|
98
|
+
var JSON_NAMES = [".rig/rig.config.json"];
|
|
99
99
|
function isModuleResolutionError(error) {
|
|
100
100
|
const message = error instanceof Error ? error.message : String(error);
|
|
101
101
|
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
@@ -430,7 +430,7 @@ async function loadConfig(cwd) {
|
|
|
430
430
|
return decodeExplicitPluginConfig(raw);
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
|
-
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
433
|
+
throw new Error(`no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
434
434
|
}
|
|
435
435
|
function decodeExplicitPluginConfig(raw) {
|
|
436
436
|
const withDefaults = applyConfigDefaults(raw);
|
|
@@ -313,8 +313,8 @@ function loadDeclarativeConfig(path) {
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
// packages/core/src/load-config.ts
|
|
316
|
-
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
317
|
-
var JSON_NAMES = ["rig.config.json"];
|
|
316
|
+
var TS_NAMES = [".rig/rig.config.ts", ".rig/rig.config.mts"];
|
|
317
|
+
var JSON_NAMES = [".rig/rig.config.json"];
|
|
318
318
|
function isModuleResolutionError(error) {
|
|
319
319
|
const message = error instanceof Error ? error.message : String(error);
|
|
320
320
|
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
@@ -649,7 +649,7 @@ async function loadConfig(cwd) {
|
|
|
649
649
|
return decodeExplicitPluginConfig(raw);
|
|
650
650
|
}
|
|
651
651
|
}
|
|
652
|
-
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
652
|
+
throw new Error(`no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
653
653
|
}
|
|
654
654
|
function decodeExplicitPluginConfig(raw) {
|
|
655
655
|
const withDefaults = applyConfigDefaults(raw);
|
|
@@ -662,10 +662,19 @@ function decodeExplicitPluginConfig(raw) {
|
|
|
662
662
|
}
|
|
663
663
|
|
|
664
664
|
// packages/core/src/project-plugins.ts
|
|
665
|
-
var
|
|
665
|
+
var TS_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts"];
|
|
666
|
+
var JSON_CONFIG_FILENAMES = ["rig.config.json"];
|
|
666
667
|
function findProjectConfigPath(projectRoot) {
|
|
667
|
-
for (const name of
|
|
668
|
-
const path = resolve2(projectRoot, name);
|
|
668
|
+
for (const name of TS_CONFIG_FILENAMES) {
|
|
669
|
+
const path = resolve2(projectRoot, ".rig", name);
|
|
670
|
+
if (existsSync3(path))
|
|
671
|
+
return path;
|
|
672
|
+
}
|
|
673
|
+
const declarativePath = findDeclarativeConfigPath(projectRoot);
|
|
674
|
+
if (declarativePath)
|
|
675
|
+
return declarativePath;
|
|
676
|
+
for (const name of JSON_CONFIG_FILENAMES) {
|
|
677
|
+
const path = resolve2(projectRoot, ".rig", name);
|
|
669
678
|
if (existsSync3(path))
|
|
670
679
|
return path;
|
|
671
680
|
}
|
|
@@ -937,13 +946,17 @@ function setScopeRules(rules) {
|
|
|
937
946
|
}
|
|
938
947
|
|
|
939
948
|
// packages/core/src/hook-materializer.ts
|
|
940
|
-
import { existsSync as existsSync6, mkdirSync as
|
|
949
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync } from "fs";
|
|
941
950
|
import { dirname as dirname2, resolve as resolve4 } from "path";
|
|
942
951
|
|
|
943
952
|
// packages/core/src/hook-runtime.ts
|
|
944
|
-
import { existsSync as existsSync5, readFileSync as readFileSync3, realpathSync, writeSync } from "fs";
|
|
953
|
+
import { appendFileSync, existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync, writeSync } from "fs";
|
|
945
954
|
import { resolve as resolve3 } from "path";
|
|
946
955
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME } from "@rig/contracts";
|
|
956
|
+
function bunRuntime() {
|
|
957
|
+
const runtime = globalThis;
|
|
958
|
+
return runtime.Bun;
|
|
959
|
+
}
|
|
947
960
|
function normalizeBuildConfig(value) {
|
|
948
961
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
949
962
|
return {};
|
|
@@ -967,7 +980,11 @@ function readBuildConfigForCoreHooks() {
|
|
|
967
980
|
var BUILD_CONFIG = readBuildConfigForCoreHooks();
|
|
968
981
|
var BAKED_PROJECT_ROOT = BUILD_CONFIG.AGENT_PROJECT_ROOT ?? "";
|
|
969
982
|
var BAKED_TASK_ID = BUILD_CONFIG.AGENT_TASK_ID ?? "";
|
|
983
|
+
var BAKED_STATE_DIR = BUILD_CONFIG.AGENT_STATE_DIR ?? "";
|
|
970
984
|
var BAKED_BUN_PATH = BUILD_CONFIG.AGENT_BUN_PATH ?? "";
|
|
985
|
+
var BAKED_TASK_CONFIG = BUILD_CONFIG.AGENT_TASK_CONFIG ?? "";
|
|
986
|
+
var BAKED_POLICY_CONTENT = BUILD_CONFIG.AGENT_POLICY_CONTENT ?? "";
|
|
987
|
+
var BAKED_TASK_SCOPES = BUILD_CONFIG.AGENT_TASK_SCOPES ?? "";
|
|
971
988
|
function normalizeExecutablePath(candidate) {
|
|
972
989
|
if (!candidate) {
|
|
973
990
|
return "";
|
|
@@ -991,8 +1008,7 @@ function resolveBunBinaryPath() {
|
|
|
991
1008
|
if (explicit) {
|
|
992
1009
|
return explicit;
|
|
993
1010
|
}
|
|
994
|
-
const
|
|
995
|
-
const bunWhich = bunGlobal?.which?.("bun");
|
|
1011
|
+
const bunWhich = bunRuntime()?.which?.("bun");
|
|
996
1012
|
const pathBun = normalizeExecutablePath(bunWhich?.trim());
|
|
997
1013
|
if (pathBun && !looksLikeRuntimeGateway(pathBun)) {
|
|
998
1014
|
return pathBun;
|
|
@@ -1178,7 +1194,7 @@ function writeClaudeCodeHookSettings(projectRoot, entries) {
|
|
|
1178
1194
|
const settingsPath = resolve4(projectRoot, ".claude", "settings.json");
|
|
1179
1195
|
const existing = existsSync6(settingsPath) ? safeReadJson(settingsPath) : {};
|
|
1180
1196
|
const { settings, events } = applyClaudeCodeSessionHooksToSettings(existing, entries, projectRoot);
|
|
1181
|
-
|
|
1197
|
+
mkdirSync3(dirname2(settingsPath), { recursive: true });
|
|
1182
1198
|
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
|
|
1183
1199
|
`, "utf-8");
|
|
1184
1200
|
return {
|
|
@@ -1208,7 +1224,7 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
1208
1224
|
({ config, host: pluginHost } = await resolvePluginHost(projectRoot));
|
|
1209
1225
|
} catch (err) {
|
|
1210
1226
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1211
|
-
if (msg.includes("no rig.config")) {
|
|
1227
|
+
if (msg.includes("no .rig/rig.config") || msg.includes("no rig.config")) {
|
|
1212
1228
|
return null;
|
|
1213
1229
|
}
|
|
1214
1230
|
throw err;
|
|
@@ -313,8 +313,8 @@ function loadDeclarativeConfig(path) {
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
// packages/core/src/load-config.ts
|
|
316
|
-
var TS_NAMES = ["rig.config.ts", "rig.config.mts"];
|
|
317
|
-
var JSON_NAMES = ["rig.config.json"];
|
|
316
|
+
var TS_NAMES = [".rig/rig.config.ts", ".rig/rig.config.mts"];
|
|
317
|
+
var JSON_NAMES = [".rig/rig.config.json"];
|
|
318
318
|
function isModuleResolutionError(error) {
|
|
319
319
|
const message = error instanceof Error ? error.message : String(error);
|
|
320
320
|
return message.includes("Cannot find module") || message.includes("Could not resolve");
|
|
@@ -649,7 +649,7 @@ async function loadConfig(cwd) {
|
|
|
649
649
|
return decodeExplicitPluginConfig(raw);
|
|
650
650
|
}
|
|
651
651
|
}
|
|
652
|
-
throw new Error(`no rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
652
|
+
throw new Error(`no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ${cwd}`);
|
|
653
653
|
}
|
|
654
654
|
function decodeExplicitPluginConfig(raw) {
|
|
655
655
|
const withDefaults = applyConfigDefaults(raw);
|
|
@@ -662,17 +662,27 @@ function decodeExplicitPluginConfig(raw) {
|
|
|
662
662
|
}
|
|
663
663
|
|
|
664
664
|
// packages/core/src/project-plugins.ts
|
|
665
|
-
var
|
|
665
|
+
var TS_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts"];
|
|
666
|
+
var JSON_CONFIG_FILENAMES = ["rig.config.json"];
|
|
667
|
+
var MISSING_CONFIG_PREFIX = "no .rig/rig.config.{ts,mts,json} or .rig/rigfig.{toml,json} found in ";
|
|
666
668
|
function findProjectConfigPath(projectRoot) {
|
|
667
|
-
for (const name of
|
|
668
|
-
const path = resolve2(projectRoot, name);
|
|
669
|
+
for (const name of TS_CONFIG_FILENAMES) {
|
|
670
|
+
const path = resolve2(projectRoot, ".rig", name);
|
|
671
|
+
if (existsSync3(path))
|
|
672
|
+
return path;
|
|
673
|
+
}
|
|
674
|
+
const declarativePath = findDeclarativeConfigPath(projectRoot);
|
|
675
|
+
if (declarativePath)
|
|
676
|
+
return declarativePath;
|
|
677
|
+
for (const name of JSON_CONFIG_FILENAMES) {
|
|
678
|
+
const path = resolve2(projectRoot, ".rig", name);
|
|
669
679
|
if (existsSync3(path))
|
|
670
680
|
return path;
|
|
671
681
|
}
|
|
672
682
|
return null;
|
|
673
683
|
}
|
|
674
684
|
function isMissingProjectConfigError(error) {
|
|
675
|
-
return error instanceof Error && error.message.startsWith("no rig.config.{ts,mts,json} found in ");
|
|
685
|
+
return error instanceof Error && (error.message.startsWith(MISSING_CONFIG_PREFIX) || error.message.startsWith("no rig.config.{ts,mts,json} found in "));
|
|
676
686
|
}
|
|
677
687
|
async function loadProjectPluginSet(projectRootOrOptions, maybeOptions = {}) {
|
|
678
688
|
const projectRoot = typeof projectRootOrOptions === "string" ? projectRootOrOptions : projectRootOrOptions.projectRoot;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/core",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.166",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Config and plugin composition library for Rig's OMP extension ecosystem; not a product host/runtime.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -53,6 +53,22 @@
|
|
|
53
53
|
"types": "./dist/src/kernel-entrypoint.d.ts",
|
|
54
54
|
"import": "./dist/src/kernel-entrypoint.js"
|
|
55
55
|
},
|
|
56
|
+
"./kernel-boot": {
|
|
57
|
+
"types": "./dist/src/kernel-boot.d.ts",
|
|
58
|
+
"import": "./dist/src/kernel-boot.js"
|
|
59
|
+
},
|
|
60
|
+
"./default-kernel": {
|
|
61
|
+
"types": "./dist/src/default-kernel.d.ts",
|
|
62
|
+
"import": "./dist/src/default-kernel.js"
|
|
63
|
+
},
|
|
64
|
+
"./kernel-resolver": {
|
|
65
|
+
"types": "./dist/src/kernel-resolver.d.ts",
|
|
66
|
+
"import": "./dist/src/kernel-resolver.js"
|
|
67
|
+
},
|
|
68
|
+
"./kernel-plugin-abi": {
|
|
69
|
+
"types": "./dist/src/kernel-plugin-abi.d.ts",
|
|
70
|
+
"import": "./dist/src/kernel-plugin-abi.js"
|
|
71
|
+
},
|
|
56
72
|
"./setup-version": {
|
|
57
73
|
"types": "./dist/src/setup-version.d.ts",
|
|
58
74
|
"import": "./dist/src/setup-version.js"
|
|
@@ -113,6 +129,10 @@
|
|
|
113
129
|
"types": "./dist/src/hook-runner.d.ts",
|
|
114
130
|
"import": "./dist/src/hook-runner.js"
|
|
115
131
|
},
|
|
132
|
+
"./hook-protocol": {
|
|
133
|
+
"types": "./dist/src/hook-protocol.d.ts",
|
|
134
|
+
"import": "./dist/src/hook-protocol.js"
|
|
135
|
+
},
|
|
116
136
|
"./plugin-host-registries": {
|
|
117
137
|
"types": "./dist/src/plugin-host-registries.d.ts",
|
|
118
138
|
"import": "./dist/src/plugin-host-registries.js"
|
|
@@ -165,8 +185,8 @@
|
|
|
165
185
|
"module": "./dist/src/index.js",
|
|
166
186
|
"types": "./dist/src/index.d.ts",
|
|
167
187
|
"dependencies": {
|
|
168
|
-
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.
|
|
169
|
-
"@rig/kernel-seed": "npm:@h-rig/kernel-seed@0.0.6-alpha.
|
|
188
|
+
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.166",
|
|
189
|
+
"@rig/kernel-seed": "npm:@h-rig/kernel-seed@0.0.6-alpha.166",
|
|
170
190
|
"effect": "4.0.0-beta.90",
|
|
171
191
|
"smol-toml": "^1.6.0"
|
|
172
192
|
}
|