@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.
@@ -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 {
@@ -1,38 +1,16 @@
1
- export declare const DEFAULT_REMOTE_PORT = 7890;
2
- /**
3
- * Register the transport-owned relay/registry/sshTarget defaults. Called at the
4
- * transport plugin module's load (plugin → floor). The floor keeps NO product
5
- * host string or remote-execution target of its own; this is the only way the
6
- * runtime fallback acquires those defaults. Idempotent and last-write-wins;
7
- * absent/empty values are ignored so a second caller cannot clear a prior
8
- * registration.
9
- */
10
- export declare function registerBackboneDefaults(defaults: {
11
- relayUrl?: string;
12
- registryBaseUrl?: string;
13
- sshTarget?: string;
14
- }): void;
15
- /**
16
- * The collab relay URL: rig.config.ts (propagated to RIG_COLLAB_RELAY by the CLI)
17
- * → env → the transport plugin's injected default (see registerBackboneDefaults)
18
- * → "" (the floor bakes no product host).
19
- */
20
- export declare function resolveRelayUrl(env?: NodeJS.ProcessEnv): string;
21
1
  /**
22
- * The remote execution sshTarget: rig.config.ts `runtime.server.sshTarget`
23
- * (propagated to RIG_SSH_TARGET by the CLI) env → the transport plugin's
24
- * injected default (see registerBackboneDefaults) "" (the floor bakes no
25
- * product remote target). This is a SEPARATE axis from the backbone server:
26
- * picking a backbone never changes where runs execute, and vice versa.
2
+ * Deprecated compatibility subpath. Remote transport configuration, registry /
3
+ * relay defaults, managed endpoints, dispatch placement, and owner namespace
4
+ * resolution are owned by @rig/transport-plugin. Core must not implement this
5
+ * product behavior.
27
6
  */
28
- export declare function resolveSshTarget(env?: NodeJS.ProcessEnv): string;
29
- export declare const REMOTES_CONFIG_PATH: string;
30
- type JsonRecord = Record<string, unknown>;
7
+ export declare const DEFAULT_REMOTE_PORT = 7890;
8
+ export declare const REMOTES_CONFIG_PATH = "";
31
9
  export declare class RemoteCliError extends Error {
32
10
  readonly code: string;
33
11
  readonly exitCode: number;
34
- readonly details: JsonRecord | undefined;
35
- constructor(code: string, message: string, exitCode?: number, details?: JsonRecord);
12
+ readonly details: Record<string, unknown> | undefined;
13
+ constructor(code: string, message: string, exitCode?: number, details?: Record<string, unknown>);
36
14
  }
37
15
  export type RemoteConfigEntry = {
38
16
  host?: string;
@@ -91,14 +69,6 @@ export type ManagedRemoteEndpoint = {
91
69
  addedAt: string | null;
92
70
  lastConnected: string | null;
93
71
  };
94
- export declare function loadRemotesConfig(configPath?: string): RemotesToml;
95
- /**
96
- * GitHub owner namespace key that scopes the relay registry. The run (which
97
- * registers a room) and the cockpit (which lists rooms) MUST derive the SAME
98
- * value or `list` returns empty. Order: env override → github-auth.userNamespaceKey
99
- * → derived `gh:${userId}`.
100
- */
101
- export declare function resolveOwnerNamespaceKey(projectRoot: string, env?: NodeJS.ProcessEnv): string | undefined;
102
72
  export type SelectedRemote = {
103
73
  alias: string;
104
74
  host: string;
@@ -119,65 +89,37 @@ export type DispatchTransportPlacement = {
119
89
  readonly sshTarget: string;
120
90
  readonly selected: SelectedRemote | null;
121
91
  };
122
- /**
123
- * Canonical dispatch-time transport placement. Kernel adoption can happen before
124
- * a CLI has resolved projectRoot or hydrated env, so transport providers call
125
- * this at dispatch time instead of letting command/capability callers branch.
126
- */
127
- export declare function resolveDispatchTransportPlacement(projectRoot: string, env?: NodeJS.ProcessEnv): DispatchTransportPlacement;
128
- /**
129
- * Selected remote placement from connection.json.selected matched against
130
- * endpoints.toml.alias. Returns null => LOCAL placement. RIG_REMOTE_ALIAS overrides
131
- * the persisted selection.
132
- */
133
- export declare function resolveSelectedRemote(projectRoot: string, env?: NodeJS.ProcessEnv): SelectedRemote | null;
134
- /**
135
- * Registry base URL for the selected target (remote), else the transport plugin's
136
- * injected backbone default (see registerBackboneDefaults), else "" — the floor
137
- * bakes no product host.
138
- */
139
- export declare function resolveRegistryBaseUrl(projectRoot: string, env?: NodeJS.ProcessEnv): string;
140
- /**
141
- * The OMP `--config` overlay, DERIVED from rig.config.ts-propagated values
142
- * (relay/registry via the resolvers above: ambient env → rig.config.ts-filled env →
143
- * computed default) plus cockpit-quiet. Written to a real temp file so OMP's
144
- * `--config` gets a normal path; memoized per process. Single source for BOTH the
145
- * CLI launch and the in-pty agent session (rig-host), so rig.config.ts values
146
- * propagate identically — no checked-in/embedded YAML, so the binary is self-contained.
147
- */
148
- export declare function resolveRigOmpConfigOverlayPath(projectRoot?: string): string;
149
- export declare function listAuthorityRemoteEndpoints(projectRoot: string): AuthorityMaterializedRemoteEndpoint[];
150
- export declare function updateAuthorityRemoteEndpoint(projectRoot: string, input: {
151
- endpointId?: string | undefined;
152
- alias?: string | undefined;
153
- host?: string | undefined;
154
- port?: number | undefined;
155
- token?: string | undefined;
156
- autoConnect?: boolean | undefined;
157
- transport?: string | undefined;
158
- labels?: string[] | undefined;
159
- capabilities?: string[] | undefined;
160
- }): AuthorityMaterializedRemoteEndpoint | null;
161
- export declare function markAuthorityRemoteEndpointConnected(projectRoot: string, endpointId: string, connectedAt?: string): void;
162
- export declare function importLegacyRemoteEndpoints(projectRoot: string, legacyPath?: string): {
163
- imported: number;
164
- skipped: number;
165
- sourcePath: string;
166
- };
167
- export declare function doctorAuthorityRemoteEndpoints(projectRoot: string): {
168
- manifestPath: string;
169
- secretsPath: string;
170
- endpointCount: number;
171
- missingSecrets: string[];
172
- warnings: string[];
173
- };
174
- export declare function listManagedRemoteEndpoints(configPath?: string, projectRoot?: string): ManagedRemoteEndpoint[];
175
- export declare function upsertManagedRemoteEndpoint(input: {
92
+ export declare function registerBackboneDefaults(_defaults: {
93
+ relayUrl?: string;
94
+ registryBaseUrl?: string;
95
+ sshTarget?: string;
96
+ }): void;
97
+ export declare function resolveRelayUrl(_env?: NodeJS.ProcessEnv): string;
98
+ export declare function resolveSshTarget(_env?: NodeJS.ProcessEnv): string;
99
+ export declare function loadRemotesConfig(_configPath?: string): RemotesToml;
100
+ export declare function listManagedRemoteEndpoints(_configPath?: string, _projectRoot?: string): ManagedRemoteEndpoint[];
101
+ export declare function resolveManagedRemoteEndpoint(_alias: string, _configPath?: string, _projectRoot?: string): SelectedRemote | null;
102
+ export declare function upsertManagedRemoteEndpoint(_input: {
176
103
  alias: string;
177
104
  host: string;
178
105
  port: number;
179
106
  token?: string;
180
- }, configPath?: string, projectRoot?: string): ManagedRemoteEndpoint;
181
- export declare function removeManagedRemoteEndpoint(alias: string, configPath?: string, projectRoot?: string): boolean;
182
- export declare function normalizeString(value: string | null | undefined): string;
183
- export {};
107
+ }, _configPath?: string, _projectRoot?: string): ManagedRemoteEndpoint;
108
+ export declare function updateAuthorityRemoteEndpoint(_projectRoot: string, _input: {
109
+ endpointId?: string;
110
+ alias?: string;
111
+ host?: string;
112
+ port?: number;
113
+ token?: string;
114
+ autoConnect?: boolean;
115
+ transport?: string;
116
+ labels?: string[];
117
+ capabilities?: string[];
118
+ }): AuthorityMaterializedRemoteEndpoint | null;
119
+ export declare function removeManagedRemoteEndpoint(_alias: string, _configPath?: string, _projectRoot?: string): boolean;
120
+ export declare function resolveSelectedRemote(_projectRoot: string, _env?: NodeJS.ProcessEnv): SelectedRemote | null;
121
+ export declare function resolveDispatchTransportPlacement(_projectRoot: string, _env?: NodeJS.ProcessEnv): DispatchTransportPlacement;
122
+ export declare function resolveRegistryBaseUrl(_projectRoot: string, _env?: NodeJS.ProcessEnv): string;
123
+ export declare function resolveOwnerNamespaceKey(_projectRoot: string, _env?: NodeJS.ProcessEnv): string | undefined;
124
+ export declare function resolveRigOmpConfigOverlayPath(_projectRoot?: string): string;
125
+ export declare function materializeRigOmpConfigOverlay(_projectRoot: string, _env?: NodeJS.ProcessEnv): string;