@h-rig/core 0.0.6-alpha.176 → 0.0.6-alpha.177
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/baked-secrets.d.ts +3 -6
- package/dist/src/baked-secrets.js +9 -67
- package/dist/src/capability-loaders.js +132 -20
- package/dist/src/declarative-config.js +5 -2
- package/dist/src/harness-paths.d.ts +0 -9
- package/dist/src/harness-paths.js +1 -16
- package/dist/src/hook-materializer.d.ts +9 -60
- package/dist/src/hook-materializer.js +3 -132
- package/dist/src/hook-protocol.js +1 -31
- package/dist/src/hook-runner.d.ts +3 -3
- package/dist/src/hook-runner.js +132 -20
- package/dist/src/hook-runtime.js +1 -31
- package/dist/src/json-files.js +0 -1
- package/dist/src/kernel-entrypoint.js +132 -20
- package/dist/src/layout.d.ts +2 -2
- package/dist/src/layout.js +2 -8
- package/dist/src/load-config.js +132 -20
- package/dist/src/placement.d.ts +16 -8
- package/dist/src/placement.js +18 -961
- package/dist/src/plugin-host-context.d.ts +2 -3
- package/dist/src/plugin-host-context.js +170 -294
- package/dist/src/project-plugins.js +132 -20
- package/dist/src/remote-config.d.ts +38 -96
- package/dist/src/remote-config.js +35 -524
- package/dist/src/root-resolver.js +0 -1
- package/dist/src/run-provisioning.d.ts +17 -38
- package/dist/src/run-provisioning.js +19 -112
- package/dist/src/runtime-events.js +0 -4
- package/dist/src/runtime-overlay.js +0 -2
- package/dist/src/server-paths.d.ts +0 -4
- package/dist/src/server-paths.js +36 -125
- package/package.json +3 -7
- package/dist/src/profile-ops.d.ts +0 -9
- package/dist/src/profile-ops.js +0 -252
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export
|
|
3
|
-
export declare
|
|
4
|
-
export declare function resolveRuntimeSecrets(env: Record<string, string | undefined>, baked?: RuntimeSecrets): RuntimeSecrets;
|
|
5
|
-
export declare function loadDotEnvSecrets(projectRoot: string, env?: Record<string, string | undefined>): RuntimeSecrets;
|
|
6
|
-
export declare function secretDefinesFromEnv(env?: Record<string, string | undefined>, projectRoot?: string): Record<string, string>;
|
|
1
|
+
export type RuntimeConfigValues = Record<string, string>;
|
|
2
|
+
export declare function resolveRuntimeConfigValues(env: Record<string, string | undefined>, keys: Iterable<string>, baked?: Record<string, string | undefined>): RuntimeConfigValues;
|
|
3
|
+
export declare function loadDotEnvValues(projectRoot: string, keys: Iterable<string>, env?: Record<string, string | undefined>): RuntimeConfigValues;
|
|
@@ -2,37 +2,10 @@
|
|
|
2
2
|
// packages/core/src/baked-secrets.ts
|
|
3
3
|
import { existsSync, readFileSync } from "fs";
|
|
4
4
|
import { resolve } from "path";
|
|
5
|
-
|
|
6
|
-
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
7
|
-
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
8
|
-
OPENROUTER_API_KEY: typeof RIG_BAKED_OPENROUTER_API_KEY !== "undefined" ? RIG_BAKED_OPENROUTER_API_KEY : "",
|
|
9
|
-
AI_REVIEW_MODE: typeof RIG_BAKED_AI_REVIEW_MODE !== "undefined" ? RIG_BAKED_AI_REVIEW_MODE : "",
|
|
10
|
-
AI_REVIEW_PROVIDER: typeof RIG_BAKED_AI_REVIEW_PROVIDER !== "undefined" ? RIG_BAKED_AI_REVIEW_PROVIDER : "",
|
|
11
|
-
GREPTILE_API_BASE: typeof RIG_BAKED_GREPTILE_API_BASE !== "undefined" ? RIG_BAKED_GREPTILE_API_BASE : "",
|
|
12
|
-
GREPTILE_REMOTE: typeof RIG_BAKED_GREPTILE_REMOTE !== "undefined" ? RIG_BAKED_GREPTILE_REMOTE : "",
|
|
13
|
-
GREPTILE_REPOSITORY: typeof RIG_BAKED_GREPTILE_REPOSITORY !== "undefined" ? RIG_BAKED_GREPTILE_REPOSITORY : "",
|
|
14
|
-
GREPTILE_CONTEXT_BRANCH: typeof RIG_BAKED_GREPTILE_CONTEXT_BRANCH !== "undefined" ? RIG_BAKED_GREPTILE_CONTEXT_BRANCH : "",
|
|
15
|
-
GREPTILE_DEFAULT_BRANCH: typeof RIG_BAKED_GREPTILE_DEFAULT_BRANCH !== "undefined" ? RIG_BAKED_GREPTILE_DEFAULT_BRANCH : "",
|
|
16
|
-
GREPTILE_API_KEY: typeof RIG_BAKED_GREPTILE_API_KEY !== "undefined" ? RIG_BAKED_GREPTILE_API_KEY : "",
|
|
17
|
-
GREPTILE_GITHUB_TOKEN: typeof RIG_BAKED_GREPTILE_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GREPTILE_GITHUB_TOKEN : "",
|
|
18
|
-
GREPTILE_POLL_ATTEMPTS: typeof RIG_BAKED_GREPTILE_POLL_ATTEMPTS !== "undefined" ? RIG_BAKED_GREPTILE_POLL_ATTEMPTS : "",
|
|
19
|
-
GREPTILE_POLL_INTERVAL_MS: typeof RIG_BAKED_GREPTILE_POLL_INTERVAL_MS !== "undefined" ? RIG_BAKED_GREPTILE_POLL_INTERVAL_MS : "",
|
|
20
|
-
GH_TOKEN: typeof RIG_BAKED_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GITHUB_TOKEN : "",
|
|
21
|
-
GITHUB_TOKEN: typeof RIG_BAKED_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GITHUB_TOKEN : "",
|
|
22
|
-
GITHUB_SSH_KEY: typeof RIG_BAKED_GITHUB_SSH_KEY !== "undefined" ? RIG_BAKED_GITHUB_SSH_KEY : "",
|
|
23
|
-
AWS_ACCESS_KEY_ID: typeof RIG_BAKED_AWS_ACCESS_KEY_ID !== "undefined" ? RIG_BAKED_AWS_ACCESS_KEY_ID : "",
|
|
24
|
-
AWS_SECRET_ACCESS_KEY: typeof RIG_BAKED_AWS_SECRET_ACCESS_KEY !== "undefined" ? RIG_BAKED_AWS_SECRET_ACCESS_KEY : "",
|
|
25
|
-
AWS_REGION: typeof RIG_BAKED_AWS_REGION !== "undefined" ? RIG_BAKED_AWS_REGION : "",
|
|
26
|
-
LINEAR_API_KEY: typeof RIG_BAKED_LINEAR_API_KEY !== "undefined" ? RIG_BAKED_LINEAR_API_KEY : "",
|
|
27
|
-
LINEAR_WEBHOOK_SECRET: typeof RIG_BAKED_LINEAR_WEBHOOK_SECRET !== "undefined" ? RIG_BAKED_LINEAR_WEBHOOK_SECRET : ""
|
|
28
|
-
};
|
|
29
|
-
function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
5
|
+
function resolveRuntimeConfigValues(env, keys, baked = {}) {
|
|
30
6
|
const resolved = {};
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
...Object.keys(baked)
|
|
34
|
-
]);
|
|
35
|
-
for (const key of keys) {
|
|
7
|
+
const allKeys = new Set([...keys, ...Object.keys(baked)]);
|
|
8
|
+
for (const key of allKeys) {
|
|
36
9
|
const envValue = env[key]?.trim();
|
|
37
10
|
const bakedValue = baked[key]?.trim();
|
|
38
11
|
if (envValue) {
|
|
@@ -43,11 +16,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
43
16
|
}
|
|
44
17
|
return resolved;
|
|
45
18
|
}
|
|
46
|
-
function
|
|
19
|
+
function loadDotEnvValues(projectRoot, keys, env = process.env) {
|
|
47
20
|
const dotenvPath = resolve(projectRoot, ".env");
|
|
48
21
|
if (!existsSync(dotenvPath)) {
|
|
49
22
|
return {};
|
|
50
23
|
}
|
|
24
|
+
const allowedKeys = new Set(keys);
|
|
51
25
|
const parsed = {};
|
|
52
26
|
const lines = readFileSync(dotenvPath, "utf-8").split(/\r?\n/);
|
|
53
27
|
for (const rawLine of lines) {
|
|
@@ -59,8 +33,8 @@ function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
|
59
33
|
if (!exportMatch) {
|
|
60
34
|
continue;
|
|
61
35
|
}
|
|
62
|
-
const key = exportMatch[1];
|
|
63
|
-
if (!(key
|
|
36
|
+
const key = exportMatch[1] ?? "";
|
|
37
|
+
if (!allowedKeys.has(key)) {
|
|
64
38
|
continue;
|
|
65
39
|
}
|
|
66
40
|
const value = expandShellValue(exportMatch[2] ?? "", { ...env, ...parsed });
|
|
@@ -70,36 +44,6 @@ function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
|
70
44
|
}
|
|
71
45
|
return parsed;
|
|
72
46
|
}
|
|
73
|
-
function secretDefinesFromEnv(env = process.env, projectRoot) {
|
|
74
|
-
const dotenvSecrets = projectRoot ? loadDotEnvSecrets(projectRoot, env) : {};
|
|
75
|
-
const resolved = resolveRuntimeSecrets(env, {
|
|
76
|
-
...BAKED_RUNTIME_SECRETS,
|
|
77
|
-
...dotenvSecrets
|
|
78
|
-
});
|
|
79
|
-
return {
|
|
80
|
-
RIG_BAKED_ANTHROPIC_API_KEY: resolved.ANTHROPIC_API_KEY || "",
|
|
81
|
-
RIG_BAKED_OPENAI_API_KEY: resolved.OPENAI_API_KEY || "",
|
|
82
|
-
RIG_BAKED_OPENROUTER_API_KEY: resolved.OPENROUTER_API_KEY || "",
|
|
83
|
-
RIG_BAKED_AI_REVIEW_MODE: resolved.AI_REVIEW_MODE || "",
|
|
84
|
-
RIG_BAKED_AI_REVIEW_PROVIDER: resolved.AI_REVIEW_PROVIDER || "",
|
|
85
|
-
RIG_BAKED_GREPTILE_API_BASE: resolved.GREPTILE_API_BASE || "",
|
|
86
|
-
RIG_BAKED_GREPTILE_REMOTE: resolved.GREPTILE_REMOTE || "",
|
|
87
|
-
RIG_BAKED_GREPTILE_REPOSITORY: resolved.GREPTILE_REPOSITORY || "",
|
|
88
|
-
RIG_BAKED_GREPTILE_CONTEXT_BRANCH: resolved.GREPTILE_CONTEXT_BRANCH || "",
|
|
89
|
-
RIG_BAKED_GREPTILE_DEFAULT_BRANCH: resolved.GREPTILE_DEFAULT_BRANCH || "",
|
|
90
|
-
RIG_BAKED_GREPTILE_API_KEY: resolved.GREPTILE_API_KEY || "",
|
|
91
|
-
RIG_BAKED_GREPTILE_GITHUB_TOKEN: resolved.GREPTILE_GITHUB_TOKEN || "",
|
|
92
|
-
RIG_BAKED_GREPTILE_POLL_ATTEMPTS: resolved.GREPTILE_POLL_ATTEMPTS || "",
|
|
93
|
-
RIG_BAKED_GREPTILE_POLL_INTERVAL_MS: resolved.GREPTILE_POLL_INTERVAL_MS || "",
|
|
94
|
-
RIG_BAKED_GITHUB_TOKEN: resolved.GITHUB_TOKEN || resolved.GH_TOKEN || "",
|
|
95
|
-
RIG_BAKED_GITHUB_SSH_KEY: resolved.GITHUB_SSH_KEY || "",
|
|
96
|
-
RIG_BAKED_AWS_ACCESS_KEY_ID: resolved.AWS_ACCESS_KEY_ID || "",
|
|
97
|
-
RIG_BAKED_AWS_SECRET_ACCESS_KEY: resolved.AWS_SECRET_ACCESS_KEY || "",
|
|
98
|
-
RIG_BAKED_AWS_REGION: resolved.AWS_REGION || "",
|
|
99
|
-
RIG_BAKED_LINEAR_API_KEY: resolved.LINEAR_API_KEY || "",
|
|
100
|
-
RIG_BAKED_LINEAR_WEBHOOK_SECRET: resolved.LINEAR_WEBHOOK_SECRET || ""
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
47
|
function expandShellValue(rawValue, env) {
|
|
104
48
|
let value = rawValue.trim();
|
|
105
49
|
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
@@ -114,8 +58,6 @@ function expandShellValue(rawValue, env) {
|
|
|
114
58
|
});
|
|
115
59
|
}
|
|
116
60
|
export {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
loadDotEnvSecrets,
|
|
120
|
-
BAKED_RUNTIME_SECRETS
|
|
61
|
+
resolveRuntimeConfigValues,
|
|
62
|
+
loadDotEnvValues
|
|
121
63
|
};
|
|
@@ -225,7 +225,7 @@ function createPluginHost(plugins) {
|
|
|
225
225
|
// packages/core/src/load-config.ts
|
|
226
226
|
import { existsSync as existsSync2, mkdirSync, mkdtempSync, readFileSync as readFileSync2, readdirSync, rmSync, statSync } from "fs";
|
|
227
227
|
import { isBuiltin } from "module";
|
|
228
|
-
import { dirname, isAbsolute, join as join2, relative, resolve } from "path";
|
|
228
|
+
import { basename, dirname, isAbsolute, join as join2, relative, resolve } from "path";
|
|
229
229
|
import { pathToFileURL } from "url";
|
|
230
230
|
import { Schema as Schema3 } from "effect";
|
|
231
231
|
import { RigConfig as RigConfig3 } from "@rig/contracts";
|
|
@@ -292,8 +292,11 @@ function parseDeclarativeFile(path) {
|
|
|
292
292
|
}
|
|
293
293
|
function loadDeclarativeConfig(path) {
|
|
294
294
|
const data = parseDeclarativeFile(path);
|
|
295
|
-
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard :
|
|
296
|
-
|
|
295
|
+
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard : null;
|
|
296
|
+
if (standardSection?.enabled !== true && standardSection?.enabled !== false) {
|
|
297
|
+
throw new Error(`Declarative config ${path} must explicitly set [standard] enabled = true or false.`);
|
|
298
|
+
}
|
|
299
|
+
const useStandard = standardSection.enabled === true;
|
|
297
300
|
let plugins = [];
|
|
298
301
|
if (useStandard) {
|
|
299
302
|
const resolver = getStandardPluginsResolver();
|
|
@@ -335,19 +338,27 @@ function packageNameAndSubpath(specifier) {
|
|
|
335
338
|
function exportTargetFromEntry(entry) {
|
|
336
339
|
if (typeof entry === "string")
|
|
337
340
|
return entry;
|
|
338
|
-
if (
|
|
341
|
+
if (Array.isArray(entry)) {
|
|
342
|
+
for (const candidate of entry) {
|
|
343
|
+
const target = exportTargetFromEntry(candidate);
|
|
344
|
+
if (target)
|
|
345
|
+
return target;
|
|
346
|
+
}
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
if (entry && typeof entry === "object") {
|
|
339
350
|
const conditions = entry;
|
|
340
|
-
for (const key of ["bun", "import", "default", "require"]) {
|
|
341
|
-
|
|
342
|
-
|
|
351
|
+
for (const key of ["bun", "node", "import", "default", "require"]) {
|
|
352
|
+
const target = exportTargetFromEntry(conditions[key]);
|
|
353
|
+
if (target)
|
|
354
|
+
return target;
|
|
343
355
|
}
|
|
344
356
|
}
|
|
345
357
|
return null;
|
|
346
358
|
}
|
|
347
359
|
function patternExportTarget(record, subpath) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
continue;
|
|
360
|
+
const entries = Object.entries(record).filter(([pattern]) => pattern.includes("*")).sort(([a], [b]) => b.replace("*", "").length - a.replace("*", "").length);
|
|
361
|
+
for (const [pattern, entry] of entries) {
|
|
351
362
|
const [prefix = "", suffix = ""] = pattern.split("*");
|
|
352
363
|
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
|
|
353
364
|
continue;
|
|
@@ -372,6 +383,49 @@ function exportTargetFromPackageJson(pkg, subpath) {
|
|
|
372
383
|
return target;
|
|
373
384
|
return subpath === "." && typeof pkg.module === "string" ? pkg.module : subpath === "." && typeof pkg.main === "string" ? pkg.main : null;
|
|
374
385
|
}
|
|
386
|
+
function patternImportTarget(record, specifier) {
|
|
387
|
+
for (const [pattern, entry] of Object.entries(record)) {
|
|
388
|
+
if (!pattern.includes("*"))
|
|
389
|
+
continue;
|
|
390
|
+
const [prefix = "", suffix = ""] = pattern.split("*");
|
|
391
|
+
if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix))
|
|
392
|
+
continue;
|
|
393
|
+
const replacement = specifier.slice(prefix.length, specifier.length - suffix.length);
|
|
394
|
+
const target = exportTargetFromEntry(entry);
|
|
395
|
+
if (target)
|
|
396
|
+
return target.replace("*", replacement);
|
|
397
|
+
}
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
function resolvePackagePrivateImport(specifier, importer, projectRoot) {
|
|
401
|
+
if (!specifier.startsWith("#") || !importer || !isAbsolute(importer))
|
|
402
|
+
return null;
|
|
403
|
+
let dir = dirname(importer);
|
|
404
|
+
const stop = resolve(projectRoot);
|
|
405
|
+
while (isWithinDir(dir, stop)) {
|
|
406
|
+
const packageJsonPath = join2(dir, "package.json");
|
|
407
|
+
if (existsSync2(packageJsonPath)) {
|
|
408
|
+
try {
|
|
409
|
+
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
410
|
+
const imports = pkg.imports;
|
|
411
|
+
if (imports && typeof imports === "object" && !Array.isArray(imports)) {
|
|
412
|
+
const record = imports;
|
|
413
|
+
const target = exportTargetFromEntry(record[specifier]) ?? patternImportTarget(record, specifier);
|
|
414
|
+
if (target)
|
|
415
|
+
return resolveModulePath(join2(dir, target));
|
|
416
|
+
}
|
|
417
|
+
} catch {
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
const parent = dirname(dir);
|
|
423
|
+
if (parent === dir)
|
|
424
|
+
return null;
|
|
425
|
+
dir = parent;
|
|
426
|
+
}
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
375
429
|
function resolvePackageDirFromBunStore(packageName, nodeModulesDir) {
|
|
376
430
|
const storeDir = join2(nodeModulesDir, ".bun");
|
|
377
431
|
if (!existsSync2(storeDir))
|
|
@@ -446,8 +500,15 @@ function resolvePackageExportFromDir(packageDir, subpath) {
|
|
|
446
500
|
if (existsSync2(packageJsonPath)) {
|
|
447
501
|
try {
|
|
448
502
|
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
449
|
-
const
|
|
450
|
-
|
|
503
|
+
const targets = [
|
|
504
|
+
exportTargetFromPackageJson(pkg, subpath),
|
|
505
|
+
...subpath === "." ? [typeof pkg.module === "string" ? pkg.module : null, typeof pkg.main === "string" ? pkg.main : null] : []
|
|
506
|
+
];
|
|
507
|
+
const seen = new Set;
|
|
508
|
+
for (const target of targets) {
|
|
509
|
+
if (!target || seen.has(target))
|
|
510
|
+
continue;
|
|
511
|
+
seen.add(target);
|
|
451
512
|
const resolved = resolveModulePath(join2(packageDir, target));
|
|
452
513
|
if (resolved)
|
|
453
514
|
return resolved;
|
|
@@ -535,10 +596,17 @@ async function importConfigViaRuntimeBundleUnserialized(configPath) {
|
|
|
535
596
|
}
|
|
536
597
|
const RUNTIME_ONLY_EXTERNAL_PACKAGES = new Set(["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"]);
|
|
537
598
|
const configDir = dirname(configPath);
|
|
599
|
+
const configProjectRoot = basename(configDir) === ".rig" ? dirname(configDir) : configDir;
|
|
538
600
|
const UNRESOLVED_NAMESPACE = "rig-config-unresolved";
|
|
601
|
+
const ABSOLUTE_EXTERNAL_NAMESPACE = "rig-config-absolute-external";
|
|
539
602
|
const unresolvedLocalPlugin = {
|
|
540
603
|
name: "rig-config-unresolved-local",
|
|
541
604
|
setup(build) {
|
|
605
|
+
build.onLoad({ filter: /[\\/]@oh-my-pi[\\/]pi-coding-agent[\\/]src[\\/]export[\\/]html[\\/](?:template\.css|template\.html|template\.js|tool-views\.generated\.js)$/ }, (args) => ({
|
|
606
|
+
loader: "js",
|
|
607
|
+
contents: `export default ${JSON.stringify(readFileSync2(args.path, "utf8"))};
|
|
608
|
+
`
|
|
609
|
+
}));
|
|
542
610
|
build.onLoad({ filter: /\.(?:html|txt)$/ }, (args) => ({
|
|
543
611
|
loader: "js",
|
|
544
612
|
contents: `export default ${JSON.stringify(readFileSync2(args.path, "utf8"))};
|
|
@@ -548,32 +616,77 @@ async function importConfigViaRuntimeBundleUnserialized(configPath) {
|
|
|
548
616
|
const directFilePath = resolvedFilePath(args.path, configDir);
|
|
549
617
|
if (directFilePath)
|
|
550
618
|
return { path: directFilePath };
|
|
619
|
+
if (args.path.startsWith("#")) {
|
|
620
|
+
const packagePrivatePath = resolvePackagePrivateImport(args.path, args.importer, configProjectRoot);
|
|
621
|
+
if (packagePrivatePath)
|
|
622
|
+
return { path: packagePrivatePath };
|
|
623
|
+
try {
|
|
624
|
+
const parent2 = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configProjectRoot;
|
|
625
|
+
const resolved = bun.resolveSync?.(args.path, parent2);
|
|
626
|
+
const filePath = resolvedFilePath(resolved, configProjectRoot);
|
|
627
|
+
if (filePath)
|
|
628
|
+
return { path: filePath };
|
|
629
|
+
} catch {}
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
551
632
|
const packageImport = packageNameAndSubpath(args.path);
|
|
552
|
-
if (packageImport &&
|
|
553
|
-
|
|
633
|
+
if (packageImport?.packageName === "uhyphen" && packageImport.subpath === ".") {
|
|
634
|
+
const uhyphenPath = resolveProjectPackageImport("uhyphen", configProjectRoot);
|
|
635
|
+
if (uhyphenPath)
|
|
636
|
+
return { path: uhyphenPath };
|
|
554
637
|
}
|
|
555
|
-
|
|
638
|
+
if (packageImport && packageImport.packageName !== "uhyphen") {
|
|
639
|
+
try {
|
|
640
|
+
const parent2 = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configProjectRoot;
|
|
641
|
+
const resolved = bun.resolveSync?.(args.path, parent2);
|
|
642
|
+
const filePath = resolvedFilePath(resolved, configProjectRoot);
|
|
643
|
+
if (filePath)
|
|
644
|
+
return { path: filePath };
|
|
645
|
+
} catch {}
|
|
646
|
+
}
|
|
647
|
+
const projectPackagePath = packageImport ? resolveProjectPackageImport(args.path, configProjectRoot) : null;
|
|
556
648
|
if (projectPackagePath)
|
|
557
649
|
return { path: projectPackagePath };
|
|
650
|
+
if (packageImport && (packageImport.packageName.startsWith("@rig/") || RUNTIME_ONLY_EXTERNAL_PACKAGES.has(packageImport.packageName))) {
|
|
651
|
+
return { path: args.path, external: true };
|
|
652
|
+
}
|
|
558
653
|
if (/^(?:node|bun):/.test(args.path) || isBuiltin(args.path))
|
|
559
654
|
return;
|
|
560
655
|
if (packageImport)
|
|
561
656
|
return { path: args.path, external: true };
|
|
562
|
-
const
|
|
657
|
+
const importerDir = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : null;
|
|
658
|
+
if (args.path.startsWith(".") && importerDir) {
|
|
659
|
+
const fromImporter = resolveModulePath(resolve(importerDir, args.path));
|
|
660
|
+
if (fromImporter)
|
|
661
|
+
return { path: fromImporter };
|
|
662
|
+
if (/[\\/]node_modules[\\/]/.test(args.importer ?? ""))
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
const parentCandidates = args.path.startsWith(".") ? [importerDir, configDir].filter((value) => Boolean(value)) : [importerDir ?? configDir];
|
|
563
666
|
for (const parent2 of parentCandidates) {
|
|
564
|
-
const filePath = resolvedFilePath(resolve(parent2, args.path),
|
|
667
|
+
const filePath = resolvedFilePath(resolve(parent2, args.path), configProjectRoot);
|
|
565
668
|
if (filePath)
|
|
566
669
|
return { path: filePath };
|
|
567
670
|
}
|
|
568
671
|
const parent = parentCandidates[0] ?? configDir;
|
|
569
672
|
try {
|
|
570
673
|
const resolved = bun.resolveSync?.(args.path, parent) ?? resolve(parent, args.path);
|
|
571
|
-
const filePath = resolvedFilePath(resolved,
|
|
674
|
+
const filePath = resolvedFilePath(resolved, configProjectRoot);
|
|
572
675
|
if (filePath)
|
|
573
676
|
return { path: filePath };
|
|
574
677
|
} catch {}
|
|
575
678
|
return { path: args.path, namespace: UNRESOLVED_NAMESPACE };
|
|
576
679
|
});
|
|
680
|
+
build.onLoad({ filter: /.*/, namespace: ABSOLUTE_EXTERNAL_NAMESPACE }, (args) => {
|
|
681
|
+
const href = pathToFileURL(args.path).href;
|
|
682
|
+
return {
|
|
683
|
+
loader: "js",
|
|
684
|
+
contents: `export * from ${JSON.stringify(href)};
|
|
685
|
+
const mod = await import(${JSON.stringify(href)});
|
|
686
|
+
export default (mod && "default" in mod) ? mod.default : mod;
|
|
687
|
+
`
|
|
688
|
+
};
|
|
689
|
+
});
|
|
577
690
|
build.onLoad({ filter: /.*/, namespace: UNRESOLVED_NAMESPACE }, (args) => ({
|
|
578
691
|
loader: "js",
|
|
579
692
|
contents: `module.exports = {};
|
|
@@ -585,7 +698,6 @@ throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not reso
|
|
|
585
698
|
const result = await bun.build({
|
|
586
699
|
entrypoints: [configPath],
|
|
587
700
|
target: "bun",
|
|
588
|
-
external: ["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"],
|
|
589
701
|
format: "esm",
|
|
590
702
|
throw: false,
|
|
591
703
|
packages: "bundle",
|
|
@@ -596,7 +708,7 @@ throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not reso
|
|
|
596
708
|
`);
|
|
597
709
|
throw new Error(`Failed to bundle ${configPath}: ${detail || "unknown bundler error"}`);
|
|
598
710
|
}
|
|
599
|
-
const bundleParentDir = join2(
|
|
711
|
+
const bundleParentDir = join2(configProjectRoot, ".rig", "tmp");
|
|
600
712
|
mkdirSync(bundleParentDir, { recursive: true });
|
|
601
713
|
const dir = mkdtempSync(join2(bundleParentDir, "rig-config-bundle-"));
|
|
602
714
|
try {
|
|
@@ -57,8 +57,11 @@ function parseDeclarativeFile(path) {
|
|
|
57
57
|
}
|
|
58
58
|
function loadDeclarativeConfig(path) {
|
|
59
59
|
const data = parseDeclarativeFile(path);
|
|
60
|
-
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard :
|
|
61
|
-
|
|
60
|
+
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard : null;
|
|
61
|
+
if (standardSection?.enabled !== true && standardSection?.enabled !== false) {
|
|
62
|
+
throw new Error(`Declarative config ${path} must explicitly set [standard] enabled = true or false.`);
|
|
63
|
+
}
|
|
64
|
+
const useStandard = standardSection.enabled === true;
|
|
62
65
|
let plugins = [];
|
|
63
66
|
if (useStandard) {
|
|
64
67
|
const resolver = getStandardPluginsResolver();
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
export declare function resolveHarnessPaths(projectRoot: string): {
|
|
2
2
|
harnessRoot: string;
|
|
3
3
|
stateDir: string;
|
|
4
|
-
artifactsDir: string;
|
|
5
4
|
logsDir: string;
|
|
6
5
|
binDir: string;
|
|
7
6
|
hooksDir: string;
|
|
8
7
|
validationDir: string;
|
|
9
|
-
taskConfigPath: string;
|
|
10
|
-
sessionPath: string;
|
|
11
8
|
monorepoRoot: string;
|
|
12
|
-
tsApiTestsDir: string;
|
|
13
|
-
taskRepoCommitsPath: string;
|
|
14
|
-
baseRepoPinsPath: string;
|
|
15
|
-
failedApproachesPath: string;
|
|
16
|
-
agentProfilePath: string;
|
|
17
|
-
reviewProfilePath: string;
|
|
18
9
|
};
|
|
@@ -5,7 +5,6 @@ import { resolve as resolve3 } from "path";
|
|
|
5
5
|
// packages/core/src/layout.ts
|
|
6
6
|
import { resolve as resolve2 } from "path";
|
|
7
7
|
import {
|
|
8
|
-
RIG_ARTIFACTS_DIRNAME,
|
|
9
8
|
RIG_DEFINITION_DIRNAME,
|
|
10
9
|
RIG_STATE_DIRNAME
|
|
11
10
|
} from "@rig/contracts";
|
|
@@ -51,7 +50,6 @@ function resolveRuntimeWorkspaceLayout(workspaceDir) {
|
|
|
51
50
|
rigRoot,
|
|
52
51
|
stateDir,
|
|
53
52
|
logsDir,
|
|
54
|
-
artifactsRoot: resolve2(root, RIG_ARTIFACTS_DIRNAME),
|
|
55
53
|
runtimeDir,
|
|
56
54
|
homeDir: resolve2(rigRoot, "home"),
|
|
57
55
|
tmpDir: resolve2(rigRoot, "tmp"),
|
|
@@ -83,9 +81,7 @@ function resolveRigLayout(projectRoot) {
|
|
|
83
81
|
definitionRoot,
|
|
84
82
|
runtimeWorkspaceRoot,
|
|
85
83
|
stateRoot: runtimeLayout.rigRoot,
|
|
86
|
-
artifactsRoot: runtimeLayout.artifactsRoot,
|
|
87
84
|
configPath: resolve2(definitionRoot, "config.sh"),
|
|
88
|
-
taskConfigPath: resolve2(runtimeWorkspaceRoot, ".rig", "task-config.json"),
|
|
89
85
|
policyDir,
|
|
90
86
|
policyFile: resolve2(policyDir, "policy.json"),
|
|
91
87
|
pluginsDir: resolve2(definitionRoot, "plugins"),
|
|
@@ -114,26 +110,15 @@ function resolveHarnessPaths(projectRoot) {
|
|
|
114
110
|
const layout = hasRuntimeWorkspace ? resolveRigLayout(projectRoot) : null;
|
|
115
111
|
const stateDir = layout?.stateDir ?? resolve3(stateRoot, "state");
|
|
116
112
|
const logsDir = layout?.logsDir ?? resolve3(stateRoot, "logs");
|
|
117
|
-
const artifactsDir = layout?.artifactsRoot ?? resolve3(monorepoRoot, "artifacts");
|
|
118
|
-
const taskConfigPath = layout?.taskConfigPath ?? resolve3(monorepoRoot, ".rig", "task-config.json");
|
|
119
113
|
const binDir = layout?.binDir ?? resolve3(stateRoot, "bin");
|
|
120
114
|
return {
|
|
121
115
|
harnessRoot,
|
|
122
116
|
stateDir: process.env.RIG_STATE_DIR || stateDir,
|
|
123
|
-
artifactsDir,
|
|
124
117
|
logsDir: process.env.RIG_LOGS_DIR || logsDir,
|
|
125
118
|
binDir,
|
|
126
119
|
hooksDir: resolve3(harnessRoot, "hooks"),
|
|
127
120
|
validationDir: resolve3(harnessRoot, "validation"),
|
|
128
|
-
|
|
129
|
-
sessionPath: process.env.RIG_SESSION_FILE || resolve3(stateRoot, "session", "session.json"),
|
|
130
|
-
monorepoRoot,
|
|
131
|
-
tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve3(monorepoRoot, "TSAPITests"),
|
|
132
|
-
taskRepoCommitsPath: resolve3(stateDir, "task-repo-commits.json"),
|
|
133
|
-
baseRepoPinsPath: resolve3(stateDir, "base-repo-pins.json"),
|
|
134
|
-
failedApproachesPath: resolve3(stateDir, "failed_approaches.md"),
|
|
135
|
-
agentProfilePath: resolve3(stateDir, "agent-profile.json"),
|
|
136
|
-
reviewProfilePath: resolve3(stateDir, "review-profile.json")
|
|
121
|
+
monorepoRoot
|
|
137
122
|
};
|
|
138
123
|
}
|
|
139
124
|
export {
|
|
@@ -1,72 +1,21 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export
|
|
3
|
-
/** The plugin that owns this hook. Used as the `_rigPlugin` marker. */
|
|
4
|
-
pluginName: string;
|
|
5
|
-
/** The plugin's hook registration. Either `command` must be set or the
|
|
6
|
-
* entry must be marked `typed`; hooks with neither (pure metadata) are
|
|
7
|
-
* skipped during materialization. */
|
|
8
|
-
hook: HookRegistration;
|
|
9
|
-
/** True when the plugin ships a typed implementation for this hook via
|
|
10
|
-
* definePlugin runtime fields (`{ hooks: { [id]: fn } }`). The
|
|
11
|
-
* materializer then writes a shim command that routes the invocation
|
|
12
|
-
* through `control-plane/hook-runner.ts` instead of requiring a raw
|
|
13
|
-
* `command` string. */
|
|
14
|
-
typed?: boolean;
|
|
15
|
-
}
|
|
1
|
+
import type { HookRegistration } from "@rig/contracts";
|
|
2
|
+
export type { PluginHookEntry } from "@rig/contracts";
|
|
16
3
|
/**
|
|
17
4
|
* Resolve the path to the typed-hook runner entrypoint.
|
|
18
5
|
*
|
|
19
|
-
* Workspace/dev checkouts (and consumer projects with `@rig/
|
|
6
|
+
* Workspace/dev checkouts (and consumer projects with `@rig/core` in
|
|
20
7
|
* node_modules of THIS process) resolve the sibling source file directly.
|
|
21
|
-
* When that file isn't on disk (
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
8
|
+
* When that file isn't on disk (for example a compiled/virtualized runtime),
|
|
9
|
+
* fall back to the consumer project's own node_modules via
|
|
10
|
+
* `$CLAUDE_PROJECT_DIR`; Claude Code expands that variable when it runs the
|
|
11
|
+
* hook command.
|
|
25
12
|
*/
|
|
26
13
|
export declare function resolveHookRunnerPath(): string;
|
|
27
14
|
/**
|
|
28
15
|
* Build the shell shim command for a typed hook. The command invokes the
|
|
29
|
-
* hook-runner, which loads the project's rig config, finds the plugin's
|
|
30
|
-
*
|
|
16
|
+
* hook-runner, which loads the project's rig config, finds the plugin's typed
|
|
17
|
+
* implementation, and bridges stdin/stdout to the hook protocol.
|
|
31
18
|
* `--event` is informational (the runner trusts the metadata registration);
|
|
32
19
|
* `--plugin`/`--hook`/`--project-root` are the runner's actual inputs.
|
|
33
20
|
*/
|
|
34
21
|
export declare function buildTypedHookShimCommand(pluginName: string, hook: HookRegistration, projectRoot: string): string;
|
|
35
|
-
export type SessionHookAdapterResult = {
|
|
36
|
-
readonly adapterId: "claude-code";
|
|
37
|
-
readonly status: "materialized";
|
|
38
|
-
readonly path: string;
|
|
39
|
-
readonly events: readonly HookEvent[];
|
|
40
|
-
} | {
|
|
41
|
-
readonly adapterId: "pi";
|
|
42
|
-
readonly status: "skipped";
|
|
43
|
-
readonly reason: string;
|
|
44
|
-
};
|
|
45
|
-
export interface AgentSessionHookAdapter {
|
|
46
|
-
readonly id: "claude-code" | "pi";
|
|
47
|
-
materialize(projectRoot: string, entries: readonly PluginHookEntry[]): SessionHookAdapterResult;
|
|
48
|
-
}
|
|
49
|
-
export declare function createPiNoopSessionHookAdapter(): AgentSessionHookAdapter;
|
|
50
|
-
export declare function createClaudeCodeSessionHookAdapter(): AgentSessionHookAdapter;
|
|
51
|
-
export type AgentSessionHookAdapterEnv = Record<string, string | undefined>;
|
|
52
|
-
export declare function defaultAgentSessionHookAdapters(env?: AgentSessionHookAdapterEnv): readonly AgentSessionHookAdapter[];
|
|
53
|
-
export declare function materializeSessionHookAdapters(projectRoot: string, entries: readonly PluginHookEntry[], adapters?: readonly AgentSessionHookAdapter[]): readonly SessionHookAdapterResult[];
|
|
54
|
-
/**
|
|
55
|
-
* Materialize plugin-contributed hooks into `.claude/settings.json` via the
|
|
56
|
-
* Claude Code session-hook adapter.
|
|
57
|
-
*
|
|
58
|
-
* Removes any previously-materialized plugin entries (marked with
|
|
59
|
-
* `_rigPlugin`) before re-inserting the current set. Operator-authored
|
|
60
|
-
* entries (without the marker) are preserved untouched. The function is
|
|
61
|
-
* idempotent — running it twice with the same input is a no-op.
|
|
62
|
-
*
|
|
63
|
-
* @returns the absolute path to the settings file that was written.
|
|
64
|
-
*/
|
|
65
|
-
export declare function materializeHooks(projectRoot: string, entries: readonly PluginHookEntry[]): string;
|
|
66
|
-
export type ApplyClaudeCodeSessionHooksOptions = {
|
|
67
|
-
readonly replacePluginOwned?: boolean;
|
|
68
|
-
};
|
|
69
|
-
export declare function applyClaudeCodeSessionHooksToSettings(existing: Record<string, unknown>, entries: readonly PluginHookEntry[], projectRoot: string, options?: ApplyClaudeCodeSessionHooksOptions): {
|
|
70
|
-
readonly settings: Record<string, unknown>;
|
|
71
|
-
readonly events: readonly HookEvent[];
|
|
72
|
-
};
|