@h-rig/core 0.0.6-alpha.176 → 0.0.6-alpha.178

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.
@@ -1,6 +1,3 @@
1
- export type RuntimeSecretKey = "ANTHROPIC_API_KEY" | "OPENAI_API_KEY" | "OPENROUTER_API_KEY" | "AI_REVIEW_MODE" | "AI_REVIEW_PROVIDER" | "GREPTILE_API_BASE" | "GREPTILE_REMOTE" | "GREPTILE_REPOSITORY" | "GREPTILE_CONTEXT_BRANCH" | "GREPTILE_DEFAULT_BRANCH" | "GREPTILE_API_KEY" | "GREPTILE_GITHUB_TOKEN" | "GREPTILE_POLL_ATTEMPTS" | "GREPTILE_POLL_INTERVAL_MS" | "GH_TOKEN" | "GITHUB_TOKEN" | "GITHUB_SSH_KEY" | "AWS_ACCESS_KEY_ID" | "AWS_SECRET_ACCESS_KEY" | "AWS_REGION" | "LINEAR_API_KEY" | "LINEAR_WEBHOOK_SECRET";
2
- export type RuntimeSecrets = Partial<Record<RuntimeSecretKey, string>>;
3
- export declare const BAKED_RUNTIME_SECRETS: RuntimeSecrets;
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
- var BAKED_RUNTIME_SECRETS = {
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 keys = new Set([
32
- ...Object.keys(BAKED_RUNTIME_SECRETS),
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 loadDotEnvSecrets(projectRoot, env = process.env) {
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 in BAKED_RUNTIME_SECRETS)) {
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
- secretDefinesFromEnv,
118
- resolveRuntimeSecrets,
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
- const useStandard = standardSection.enabled !== false;
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 (entry && typeof entry === "object" && !Array.isArray(entry)) {
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
- if (typeof conditions[key] === "string")
342
- return conditions[key];
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
- for (const [pattern, entry] of Object.entries(record)) {
349
- if (!pattern.includes("*"))
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 target = exportTargetFromPackageJson(pkg, subpath);
450
- if (target) {
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 && (packageImport.packageName.startsWith("@rig/") || RUNTIME_ONLY_EXTERNAL_PACKAGES.has(packageImport.packageName))) {
553
- return { path: args.path, external: true };
633
+ if (packageImport?.packageName === "uhyphen" && packageImport.subpath === ".") {
634
+ const uhyphenPath = resolveProjectPackageImport("uhyphen", configProjectRoot);
635
+ if (uhyphenPath)
636
+ return { path: uhyphenPath };
554
637
  }
555
- const projectPackagePath = resolveProjectPackageImport(args.path, configDir);
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 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];
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), configDir);
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, configDir);
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(configDir, ".rig", "tmp");
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
- const useStandard = standardSection.enabled !== false;
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
- taskConfigPath,
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 { HookEvent, HookRegistration } from "@rig/contracts";
2
- export interface PluginHookEntry {
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/runtime` in
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 (e.g. running from a compiled binary whose
22
- * modules live under the virtual $bunfs root), fall back to the consumer
23
- * project's own node_modules via `$CLAUDE_PROJECT_DIR` Claude Code expands
24
- * that variable when it runs the hook command.
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
- * typed implementation, and bridges stdin/stdout to the hook protocol.
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
- };